Skip to content

vscode to agents window handoff#316565

Draft
justschen wants to merge 1 commit into
mainfrom
justin/grubbin
Draft

vscode to agents window handoff#316565
justschen wants to merge 1 commit into
mainfrom
justin/grubbin

Conversation

@justschen
Copy link
Copy Markdown
Collaborator

Screen.Recording.2026-05-14.at.10.02.42.PM.mov

Copilot AI review requested due to automatic review settings May 15, 2026 05:29
Copy link
Copy Markdown
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

This PR adds a “handoff” path from VS Code’s workbench chat experience to the standalone Agents window, including the ability to open the Agents window seeded with either (a) an initial query or (b) an existing contributed chat session resource.

Changes:

  • Extend the native/electron “open Agents window” plumbing to optionally carry initialQuery and sessionResource through to the Agents window via IPC.
  • Add workbench chat entry points for handoff: a chat title-bar action (“Open in Agents Window”) plus a chat-input tip notification scoped to eligible session types.
  • Update chat input notification infrastructure to support session-type scoping and dismissal events; refactor plan review UX/behavior (notably around feedback/submit flows).
Show a summary per file
File Description
src/vs/workbench/test/electron-browser/workbenchTestServices.ts Updates test native host service signature for the expanded openAgentsWindow options.
src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostPermissionUiContribution.test.ts Adjusts a fake notification service mock to match the updated notification service interface (partially).
src/vs/workbench/contrib/chat/electron-browser/chat.contribution.ts Registers new chat actions/contributions related to Agents window handoff.
src/vs/workbench/contrib/chat/electron-browser/agentSessions/agentSessionsActions.ts Adds “Open session in Agents window” action and a chat-input tip contribution with per-session dismissal.
src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.ts Passes session type provider into the notification widget and triggers rerender on session-type changes.
src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationWidget.ts Adds session-type filtering, external rerender support, and defers dismissal to a microtask.
src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationService.ts Extends notification model with sessionTypes allow-list and adds onDidDismiss.
src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts Adds explanatory comment for showing an “Open in Agents Window” card (no functional change in shown hunk).
src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSuggestNextWidget.ts Adds a “Continue in Agents Window” suggested prompt button that opens Agents with an initial query.
src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.ts Large plan review UX/flow refactor (feedback mode, submission handling, keyboard behavior).
src/vs/sessions/contrib/chat/electron-browser/chat.contribution.ts Implements Agents window IPC handler to select folder, open an existing session, or submit an initial query.
src/vs/platform/windows/electron-main/windowsMainService.ts Sends a single IPC with folder/query/sessionResource to the Agents window after opening it.
src/vs/platform/windows/electron-main/windows.ts Extends IWindowsMainService.openAgentsWindow signature to carry query/session resource.
src/vs/platform/native/electron-main/nativeHostMainService.ts Extends native host main service openAgentsWindow to pass query/session resource through.
src/vs/platform/native/common/native.ts Extends ICommonNativeHostService.openAgentsWindow options type accordingly.

Copilot's findings

Comments suppressed due to low confidence (1)

src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.ts:699

  • submitRejection now submits { rejected: true } without including any overall feedback from the textarea. If the textarea is meant to collect user feedback to the agent, this looks like a regression—consider passing feedback/feedbackOverall along with the rejection result (or disabling the textarea when it won’t be submitted).
		this._isSubmitted = true;
		this._options.onSubmit({ rejected: true });
		this.markUsed();
	}
  • Files reviewed: 15/15 changed files
  • Comments generated: 9

Comment on lines +197 to +200
// No plan file: keep the textarea visible from the start and
// treat as already in feedback mode.
this._isFeedbackMode = true;
this.domNode.classList.add('chat-plan-review-feedback-mode');
Comment on lines 687 to 690
this._isSubmitted = true;
// Only the textarea-only flow (no planUri) attaches a draft to the action click.
const ridesAlong = !this.review.planUri;
const textareaFeedback = ridesAlong ? this._feedbackTextarea?.value.trim() : undefined;
this._options.onSubmit({
action: action.label,
...(action.id ? { actionId: action.id } : {}),
rejected: false,
...(textareaFeedback ? { feedback: textareaFeedback, feedbackOverall: textareaFeedback } : {}),
});
void this.markUsed();
this._options.onSubmit({ action: action.label, rejected: false });
this.markUsed();
}
Comment on lines +328 to +332
if (ev.keyCode === KeyCode.Enter && !ev.shiftKey) {
e.preventDefault();
e.stopPropagation();
this.submitFeedback();
}
Comment on lines 34 to +40
ipcRenderer.on('vscode:selectAgentsFolder', (_: unknown, ...args: unknown[]) => {
const folderUri = URI.revive(args[0] as UriComponents);
this.selectFolder(folderUri);
const folderUri = args[0] ? URI.revive(args[0] as UriComponents) : undefined;
const initialQuery = typeof args[1] === 'string' ? args[1] : undefined;
const sessionResource = args[2] ? URI.revive(args[2] as UriComponents) : undefined;
this.logService.info(`[AgentsHandoff] IPC received: folderUri=${folderUri?.toString() ?? '(none)'} initialQuery=${initialQuery ? 'yes' : 'no'} sessionResource=${sessionResource?.toString() ?? '(none)'}`);
this.handleOpenIntent(folderUri, initialQuery, sessionResource);
});
const initialQuery = typeof args[1] === 'string' ? args[1] : undefined;
const sessionResource = args[2] ? URI.revive(args[2] as UriComponents) : undefined;
this.logService.info(`[AgentsHandoff] IPC received: folderUri=${folderUri?.toString() ?? '(none)'} initialQuery=${initialQuery ? 'yes' : 'no'} sessionResource=${sessionResource?.toString() ?? '(none)'}`);
this.handleOpenIntent(folderUri, initialQuery, sessionResource);
Comment on lines +146 to +165
private waitForActiveSession(timeoutMs = 8000): Promise<boolean> {
if (this.sessionsManagementService.activeSession.get()) {
return Promise.resolve(true);
}
return new Promise<boolean>(resolve => {
const store = new DisposableStore();
const handle = setTimeout(() => {
store.dispose();
resolve(!!this.sessionsManagementService.activeSession.get());
}, timeoutMs);
store.add(autorun(reader => {
if (this.sessionsManagementService.activeSession.read(reader)) {
clearTimeout(handle);
store.dispose();
resolve(true);
}
}));
});
}

Comment on lines 54 to +62
constructor(
sessionTypeProvider: (() => string | undefined) | undefined,
@IChatInputNotificationService private readonly _notificationService: IChatInputNotificationService,
@ICommandService private readonly _commandService: ICommandService,
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@IMarkdownRendererService private readonly _markdownRendererService: IMarkdownRendererService,
) {
super();
this._sessionTypeProvider = sessionTypeProvider;
Comment on lines 45 to +52
export interface IChatInputNotificationService {
readonly _serviceBrand: undefined;

readonly onDidChange: Event<void>;

/** Fires when a notification is dismissed by the user (via the X button). */
readonly onDidDismiss: Event<string>;

Comment on lines 41 to 45
class FakeNotificationService implements IChatInputNotificationService {
declare readonly _serviceBrand: undefined;
readonly onDidChange: Event<void> = Event.None;
readonly onDidDismiss: Event<string> = Event.None;
readonly setCalls: IChatInputNotification[] = [];
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