Skip to content

support autopilot mode#4055

Draft
justschen wants to merge 3 commits intomainfrom
justin/archeops
Draft

support autopilot mode#4055
justschen wants to merge 3 commits intomainfrom
justin/archeops

Conversation

@justschen
Copy link
Contributor

checks for tool calls, loops on max requests

ref microsoft/vscode#296691

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for an “autopilot” permission level in chat requests and adapts the tool-calling loop behavior to continue iterating without user confirmation, aiming to keep the agent running until explicit completion.

Changes:

  • Introduces permissionLevel on ChatRequest (private proposed API) to convey auto-approval/autopilot behavior.
  • Updates ToolCallingLoop to (a) extend the max-iteration limit automatically for autoApprove/autopilot, and (b) add an internal “autopilot stop hook” that tries to continue until task_complete.
  • Filters task_complete out of tool lists outside autopilot mode.

Reviewed changes

Copilot reviewed 1 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/extension/vscode.proposed.chatParticipantPrivate.d.ts Adds permissionLevel to ChatRequest to signal auto-approval/autopilot behavior.
src/extension/intents/node/toolCallingLoop.ts Extends iteration limits for auto-approval modes and adds an autopilot continuation mechanism based on task_complete.

Comment on lines +927 to +930
// In autopilot mode, ensure the task_complete tool is included.
// Outside autopilot, filter it out so it doesn't confuse the model.
if (this.options.request.permissionLevel !== 'autopilot' && promptContextTools) {
promptContextTools = promptContextTools.filter(t => t.name !== ToolCallingLoop.TASK_COMPLETE_TOOL_NAME);
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says autopilot mode "ensures the task_complete tool is included", but this code only filters task_complete out when not in autopilot; it never adds the tool if it isn’t already present. Additionally, there doesn’t appear to be any registered/implemented task_complete tool elsewhere in the repo, so the model may never be able to call it successfully, and autopilot completion would be unreliable. Consider explicitly injecting a no-op task_complete tool definition in autopilot mode (and handling it as a completion signal) or wiring it through the normal tool registry so it’s actually available.

Suggested change
// In autopilot mode, ensure the task_complete tool is included.
// Outside autopilot, filter it out so it doesn't confuse the model.
if (this.options.request.permissionLevel !== 'autopilot' && promptContextTools) {
promptContextTools = promptContextTools.filter(t => t.name !== ToolCallingLoop.TASK_COMPLETE_TOOL_NAME);
// In autopilot mode, ensure the task_complete tool is included so the model
// can explicitly signal when it is done with the task.
// Outside autopilot, filter it out so it doesn't confuse the model.
if (promptContextTools) {
if (this.options.request.permissionLevel === 'autopilot') {
if (!promptContextTools.some(t => t.name === ToolCallingLoop.TASK_COMPLETE_TOOL_NAME)) {
promptContextTools.push({
name: ToolCallingLoop.TASK_COMPLETE_TOOL_NAME,
description: 'Call this tool when you have completed the user\'s task and no further tool calls are needed.',
parameters: {
type: 'object',
properties: {
reason: {
type: 'string',
description: 'A short explanation of why the task is complete.',
},
},
required: ['reason'],
},
});
}
} else {
promptContextTools = promptContextTools.filter(t => t.name !== ToolCallingLoop.TASK_COMPLETE_TOOL_NAME);
}

Copilot uses AI. Check for mistakes.
Comment on lines 681 to 690
// In Autopilot mode, check if the task is actually done before stopping.
// This acts as an internal stop hook that keeps the agent churning until completion.
if (this.options.request.permissionLevel === 'autopilot' && result.response.type === ChatFetchResponseType.Success) {
const autopilotContinue = this.shouldAutopilotContinue(result, stopHookActive);
if (autopilotContinue) {
this._logService.info(`[ToolCallingLoop] Autopilot internal stop hook: continuing because task may not be complete`);
this.stopHookReason = autopilotContinue;
result.round.hookContext = formatHookContext([autopilotContinue]);
stopHookActive = true;
continue;
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAX_AUTOPILOT_CONTINUATIONS/autopilotContinuationCount suggest autopilot can nudge multiple times, but stopHookActive is never reset to false in run(). After the first autopilot nudge sets stopHookActive = true, subsequent calls to shouldAutopilotContinue(..., stopHookActive) will immediately return undefined due to stopHookAlreadyActive, so autopilot continuation effectively happens at most once and the max-continuations logic is never exercised. Consider separating the autopilot internal-stop-hook state from stopHookActive, or resetting stopHookActive once a continuation has been consumed / progress has resumed.

Copilot uses AI. Check for mistakes.
Comment on lines 606 to 615
if (lastResult && i++ >= this.options.toolCallLimit) {
lastResult = this.hitToolCallLimit(outputStream, lastResult);
break;
// In AutoApprove or Autopilot mode, silently increase the limit and continue
// without showing the confirmation dialog.
const permLevel = this.options.request.permissionLevel;
if (permLevel === 'autoApprove' || permLevel === 'autopilot') {
this.options.toolCallLimit = Math.round(this.options.toolCallLimit * 3 / 2);
} else {
lastResult = this.hitToolCallLimit(outputStream, lastResult);
break;
}
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In autoApprove/autopilot mode, hitting toolCallLimit now silently increases the limit and continues with no upper bound. This removes the primary safety brake against runaway tool-calling loops and can lead to unbounded network usage/costs if a model gets stuck. Consider adding a hard cap (even in these modes), and/or recording maxToolCallsExceeded metadata when the configured limit is first exceeded so telemetry and downstream logic can still detect the condition.

Copilot uses AI. Check for mistakes.
Comment on lines 606 to 693
@@ -627,6 +677,20 @@ export abstract class ToolCallingLoop<TOptions extends IToolCallingLoopOptions =
continue;
}
}

// In Autopilot mode, check if the task is actually done before stopping.
// This acts as an internal stop hook that keeps the agent churning until completion.
if (this.options.request.permissionLevel === 'autopilot' && result.response.type === ChatFetchResponseType.Success) {
const autopilotContinue = this.shouldAutopilotContinue(result, stopHookActive);
if (autopilotContinue) {
this._logService.info(`[ToolCallingLoop] Autopilot internal stop hook: continuing because task may not be complete`);
this.stopHookReason = autopilotContinue;
result.round.hookContext = formatHookContext([autopilotContinue]);
stopHookActive = true;
continue;
}
}

Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New control-flow has been added for permissionLevel === 'autoApprove' | 'autopilot' (limit-extension, internal autopilot stop hook, and task_complete tool filtering), but there are no unit tests exercising these branches. Since ToolCallingLoop already has dedicated unit tests, it would be good to add coverage for: (1) extending the limit in autoApprove/autopilot, (2) continuing on stop until task_complete is observed, and (3) filtering/including task_complete based on permission level.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants