Skip to content

autopilot mode + secondary chat input toolbar#296691

Draft
justschen wants to merge 37 commits intomainfrom
justin/whimsicott
Draft

autopilot mode + secondary chat input toolbar#296691
justschen wants to merge 37 commits intomainfrom
justin/whimsicott

Conversation

@justschen
Copy link
Collaborator

@justschen justschen commented Feb 21, 2026

fix #296662 and #297815

/yolo and /autoApprove moved to #297158.

whatsthat 547-Whimsicott

Copilot AI review requested due to automatic review settings February 21, 2026 05:24
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 an “Autopilot” chat mode and a /yolo slash command path to enable auto-approval of tool calls, wiring the new mode through chat mode selection, telemetry, and tool-confirmation logic.

Changes:

  • Introduces ChatModeKind.Autopilot and surfaces it in mode lists/context keys/UI (mode picker icons, MCP command enablement, command detection exclusions).
  • Adds autoApprove plumbing for modes/agents (prompt header auto-approve, ICustomAgent.autoApprove, IChatRequestModeInfo.autoApprove).
  • Implements session-scoped and next-request YOLO behavior in LanguageModelToolsService and adds a /yolo slash command + a command palette action to toggle global auto-approve.

Reviewed changes

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

Show a summary per file
File Description
src/vs/workbench/contrib/mcp/browser/mcpCommands.ts Allows MCP server listing command in Autopilot mode via context key expression.
src/vs/workbench/contrib/editTelemetry/browser/telemetry/aiEditTelemetry/aiEditTelemetryServiceImpl.ts Extends telemetry modeId union to include autopilot.
src/vs/workbench/contrib/editTelemetry/browser/telemetry/aiEditTelemetry/aiEditTelemetryService.ts Documents and adds autopilot to EditTelemetryModeId.
src/vs/workbench/contrib/chat/test/common/tools/mockLanguageModelToolsService.ts Updates mock to satisfy new YOLO methods on ILanguageModelToolsService.
src/vs/workbench/contrib/chat/common/tools/languageModelToolsService.ts Extends tools service interface with session/next-request YOLO APIs.
src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsServiceImpl.ts Adds autoApprove to loaded custom agent data from prompt AST header.
src/vs/workbench/contrib/chat/common/promptSyntax/service/promptsService.ts Adds ICustomAgent.autoApprove contract.
src/vs/workbench/contrib/chat/common/promptSyntax/promptFileParser.ts Adds auto-approve header attribute + parsed accessor.
src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptValidator.ts Allows auto-approve in agent headers (attribute list).
src/vs/workbench/contrib/chat/common/participants/chatAgents.ts Treats Autopilot as Agent when resolving default agent selection.
src/vs/workbench/contrib/chat/common/model/chatModel.ts Extends request mode info to include autopilot and autoApprove.
src/vs/workbench/contrib/chat/common/editing/chatEditingService.ts Updates telemetry modeId union for chat editing telemetry.
src/vs/workbench/contrib/chat/common/constants.ts Adds ChatModeKind.Autopilot and validates it.
src/vs/workbench/contrib/chat/common/chatService/chatServiceImpl.ts Excludes Autopilot from command detection logic (alongside Agent/Edit).
src/vs/workbench/contrib/chat/common/chatModes.ts Adds built-in Autopilot mode and autoApprove observable support.
src/vs/workbench/contrib/chat/common/actions/chatContextKeys.ts Treats Autopilot as “editing mode” for relevant context expressions.
src/vs/workbench/contrib/chat/browser/widget/input/modePickerActionItem.ts Provides a rocket icon for Autopilot in the mode picker.
src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.ts Propagates modeId + autoApprove into currentModeInfo.
src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.ts Implements YOLO state + uses mode/session YOLO in auto-confirm decisions.
src/vs/workbench/contrib/chat/browser/chatSlashCommands.ts Adds /yolo command to toggle session YOLO or enable next-request YOLO.
src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingSessionStorage.ts Extends stored telemetry DTO union to include autopilot.
src/vs/workbench/contrib/chat/browser/actions/chatActions.ts Adds command palette action to toggle global auto-approve (“YOLO Mode”).
Comments suppressed due to low confidence (3)

src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.ts:1107

  • Mode-level autoApprove is determined by looking at model.getRequests().at(-1). In sessions with queued requests, the last request may not be the request that is currently invoking the tool, so tool confirmations could be auto-approved (or not) based on the wrong request/mode. Since IToolInvocation already carries chatRequestId, consider threading that through and resolving the request by id (falling back to last request only when needed).
			// Mode-level auto-approve (e.g. autopilot agent with auto-approve: true)
			const model = this._chatService.getSession(chatSessionResource);
			const request = model?.getRequests().at(-1);
			if (request?.modeInfo?.autoApprove) {
				return { type: ToolConfirmKind.Setting, id: 'chat.mode.autoApprove' };
			}

src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.ts:1158

  • Same issue as pre-execution: post-execution auto-confirm checks model.getRequests().at(-1) to decide whether the current request has modeInfo.autoApprove. With queued requests, this can consult the wrong request. Consider using the chatRequestId associated with the tool invocation to locate the correct request when deciding mode-level auto-approve.
			// Mode-level auto-approve
			const model = this._chatService.getSession(chatSessionResource);
			const request = model?.getRequests().at(-1);
			if (request?.modeInfo?.autoApprove) {
				return { type: ToolConfirmKind.Setting, id: 'chat.mode.autoApprove' };
			}

src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.ts:1158

  • Post-execution YOLO/mode auto-approve returns ToolConfirmKind.Setting with ids that aren’t actual settings ('chat.yolo.session', 'chat.mode.autoApprove'). This will surface as a broken “Auto approved by …” settings link in the tool invocation UI. Consider using LmServicePerTool / ConfirmationNotNeeded (or a real setting key) instead of ToolConfirmKind.Setting here.
		// Session-scoped YOLO mode bypasses all post-execution confirmations
		if (chatSessionResource) {
			const key = chatSessionResource.toString();
			if (this._yoloSessions.has(key) || this._yoloNextRequestSessions.has(key)) {
				return { type: ToolConfirmKind.Setting, id: 'chat.yolo.session' };
			}

			// Mode-level auto-approve
			const model = this._chatService.getSession(chatSessionResource);
			const request = model?.getRequests().at(-1);
			if (request?.modeInfo?.autoApprove) {
				return { type: ToolConfirmKind.Setting, id: 'chat.mode.autoApprove' };
			}

@justschen justschen changed the title autopilot mode + /yolo commands autopilot mode + secondary chat input toolbar Feb 25, 2026
justschen and others added 7 commits February 26, 2026 00:23
- Move context usage widget to secondary toolbar with percentage label on hover
- Adjust secondary toolbar padding/gap and input part bottom padding
- Lower icon-only threshold to 300px
- Darken input placeholder foreground in 2026 dark theme
- Update agent mode description
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

Copilot reviewed 20 out of 21 changed files in this pull request and generated 8 comments.

Comments suppressed due to low confidence (4)

src/vs/workbench/contrib/chat/common/chatService/chatServiceImpl.ts:1278

  • The new auto-retry behavior should be covered by tests in the existing chat service test suite (e.g. verify no retry occurs after cancellation, max retry cap is honored, and rate-limited/quota errors are not retried).
	private static readonly MAX_AUTO_RETRIES = 5;

	private _shouldAutoRetry(options: IChatSendRequestOptions | undefined, attempt: number, errorDetails?: IChatResponseErrorDetails): boolean {
		if (!isAutoApproveLevel(options?.modeInfo?.permissionLevel)) {
			return false;
		}
		if (attempt >= ChatService.MAX_AUTO_RETRIES) {
			return false;
		}
		// Don't retry rate-limited or quota-exceeded errors
		if (errorDetails?.isRateLimited || errorDetails?.isQuotaExceeded) {
			return false;
		}
		return true;
	}

	private _scheduleAutoRetry(request: IChatRequestModel, options: IChatSendRequestOptions | undefined, attempt: number): void {
		const nextAttempt = attempt + 1;
		this.logService.info(`[ChatService] Auto-retrying request (attempt ${nextAttempt}/${ChatService.MAX_AUTO_RETRIES}) due to auto-approve-all permission level`);
		timeout(1000).then(() => {
			this.resendRequest(request, { ...options, attempt: nextAttempt });
		});

src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.ts:1092

  • Same issue as pre-exec auto-confirm: this uses model.getRequests().at(-1) to decide whether to bypass post-execution confirmations. Please resolve the correct request (by chatRequestId) so permission level is applied to the right interaction.
		if (chatSessionResource) {
			const model = this._chatService.getSession(chatSessionResource);
			const request = model?.getRequests().at(-1);
			if (isAutoApproveLevel(request?.modeInfo?.permissionLevel)) {
				return { type: ToolConfirmKind.ConfirmationNotNeeded, reason: 'auto-approve-all' };

src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.ts:1172

  • cancelToolCallsForRequest now removes pending streaming invocations from _pendingToolCalls without cancelling them (cancelFromStreaming(...) was removed). If the invocation was already appended to the request as progress, it will remain stuck in Streaming state in the UI. Consider cancelling the invocation (e.g. Skipped) before deleting so the transcript state is consistent.
		// Clean up any pending tool calls that belong to this request
		for (const [toolCallId, invocation] of this._pendingToolCalls) {
			if (invocation.chatRequestId === requestId) {
				this._pendingToolCalls.delete(toolCallId);
			}
		}

src/vs/workbench/contrib/chat/browser/tools/languageModelToolsService.ts:1092

  • New permission-level auto-confirm behavior (and request selection by chatRequestId) should be covered by unit tests in the existing languageModelToolsService.test.ts suite, including: (1) bypass confirmation only for the matching request, and (2) cancellation marks streaming invocations as cancelled/skipped rather than leaving them in Streaming.
		if (chatSessionResource) {
			const model = this._chatService.getSession(chatSessionResource);
			const request = model?.getRequests().at(-1);
			if (isAutoApproveLevel(request?.modeInfo?.permissionLevel)) {
				return { type: ToolConfirmKind.ConfirmationNotNeeded, reason: 'auto-approve-all' };
			}
		}

		if (!this.isToolEligibleForAutoApproval(tool.data)) {
			return undefined;
		}

		const reason = this._confirmationService.getPreConfirmAction({ toolId, source, parameters, chatSessionResource });
		if (reason) {
			return reason;
		}

		const config = this._configurationService.inspect<boolean | Record<string, boolean>>(ChatConfiguration.GlobalAutoApprove);

		// If we know the tool runs at a global level, only consider the global config.
		// If we know the tool runs at a workspace level, use those specific settings when appropriate.
		let value = config.value ?? config.defaultValue;
		if (typeof runsInWorkspace === 'boolean') {
			value = config.userLocalValue ?? config.applicationValue;
			if (runsInWorkspace) {
				value = config.workspaceValue ?? config.workspaceFolderValue ?? config.userRemoteValue ?? value;
			}
		}

		const autoConfirm = value === true || (typeof value === 'object' && value.hasOwnProperty(toolId) && value[toolId] === true);
		if (autoConfirm) {
			if (await this._checkGlobalAutoApprove()) {
				return { type: ToolConfirmKind.Setting, id: ChatConfiguration.GlobalAutoApprove };
			}
		}

		return undefined;
	}

	private async shouldAutoConfirmPostExecution(toolId: string, runsInWorkspace: boolean | undefined, source: ToolDataSource, parameters: unknown, chatSessionResource: URI | undefined): Promise<ConfirmedReason | undefined> {
		// Auto-Approve All permission level bypasses all post-execution confirmations
		if (chatSessionResource) {
			const model = this._chatService.getSession(chatSessionResource);
			const request = model?.getRequests().at(-1);
			if (isAutoApproveLevel(request?.modeInfo?.permissionLevel)) {
				return { type: ToolConfirmKind.ConfirmationNotNeeded, reason: 'auto-approve-all' };

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.

Add Autopilot Agent Mode

3 participants