From 66e4f9d719f536378ccd193fb80ad127fc85e20f Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 3 May 2026 19:58:41 -0700 Subject: [PATCH 1/2] sessions: skip slash command expansion in agent host sessions Agent host sessions support prompt/skill slash commands natively, so the CLI-friendly markdown reference ("Use the skill located at ...") should not be appended. Wire a `shouldExpandPromptSlashCommand` callback through `NewChatInputWidget` and have both the new-session and new-chat-in-session panes opt out when the target provider matches `ANY_AGENT_HOST_PROVIDER_RE`. Copilot CLI and other providers are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../chat/browser/newChatInSessionViewPane.ts | 5 +++++ .../contrib/chat/browser/newChatInput.ts | 18 ++++++++++++++---- .../contrib/chat/browser/newChatViewPane.ts | 5 +++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/vs/sessions/contrib/chat/browser/newChatInSessionViewPane.ts b/src/vs/sessions/contrib/chat/browser/newChatInSessionViewPane.ts index e1b192116e080..b23e819122ede 100644 --- a/src/vs/sessions/contrib/chat/browser/newChatInSessionViewPane.ts +++ b/src/vs/sessions/contrib/chat/browser/newChatInSessionViewPane.ts @@ -28,6 +28,7 @@ import { IViewDescriptorService } from '../../../../workbench/common/views.js'; import { IViewPaneOptions, ViewPane } from '../../../../workbench/browser/parts/views/viewPane.js'; import { NewChatInputWidget } from './newChatInput.js'; import { IChatRequestVariableEntry } from '../../../../workbench/contrib/chat/common/attachments/chatVariableEntries.js'; +import { ANY_AGENT_HOST_PROVIDER_RE } from '../../../common/agentHostSessionsProvider.js'; // #region --- New Chat In Session Widget --- @@ -65,6 +66,10 @@ class NewChatInSessionWidget extends Disposable { loading, minEditorHeight: 64, placeholder: localize('newChatInSessionPlaceholder', 'Ask a follow-up question or start a new topic within this session...'), + shouldExpandPromptSlashCommand: () => { + const providerId = this.sessionsManagementService.activeSession.get()?.providerId; + return !providerId || !ANY_AGENT_HOST_PROVIDER_RE.test(providerId); + }, })); } diff --git a/src/vs/sessions/contrib/chat/browser/newChatInput.ts b/src/vs/sessions/contrib/chat/browser/newChatInput.ts index 9c0072a284942..557389544e48d 100644 --- a/src/vs/sessions/contrib/chat/browser/newChatInput.ts +++ b/src/vs/sessions/contrib/chat/browser/newChatInput.ts @@ -143,6 +143,13 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation loading: IObservable; minEditorHeight?: number; placeholder?: string; + /** + * If provided and returns `false`, prompt/skill slash commands are sent + * verbatim instead of being expanded into a CLI-friendly markdown + * reference. Agent host sessions support slash commands natively, so + * the expansion should be skipped for them. + */ + shouldExpandPromptSlashCommand?: () => boolean; }, @IInstantiationService private readonly instantiationService: IInstantiationService, @IModelService private readonly modelService: IModelService, @@ -500,10 +507,13 @@ export class NewChatInputWidget extends Disposable implements IHistoryNavigation return; } - // Expand prompt/skill slash commands into a CLI-friendly reference - const expanded = this._slashCommandHandler?.tryExpandPromptSlashCommand(query); - if (expanded) { - query = expanded; + // Expand prompt/skill slash commands into a CLI-friendly reference, + // unless the target session natively supports slash commands. + if (this.options.shouldExpandPromptSlashCommand?.() ?? true) { + const expanded = this._slashCommandHandler?.tryExpandPromptSlashCommand(query); + if (expanded) { + query = expanded; + } } const attachedContext = this._contextAttachments.attachments.length > 0 diff --git a/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts b/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts index aed583a1c3be7..88c23fbf876e4 100644 --- a/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts +++ b/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts @@ -29,6 +29,7 @@ import { WorkspacePicker, IWorkspaceSelection } from './sessionWorkspacePicker.j import { ScopedWorkspacePicker } from './scopedWorkspacePicker.js'; import { NewChatInputWidget } from './newChatInput.js'; import { IChatRequestVariableEntry } from '../../../../workbench/contrib/chat/common/attachments/chatVariableEntries.js'; +import { ANY_AGENT_HOST_PROVIDER_RE } from '../../../common/agentHostSessionsProvider.js'; // #region --- New Chat Widget --- @@ -71,6 +72,10 @@ class NewChatWidget extends Disposable { sendRequest: async (text: string, attachedContext?: IChatRequestVariableEntry[]) => this._send(text, attachedContext), canSendRequest, loading, + shouldExpandPromptSlashCommand: () => { + const providerId = this._workspacePicker.selectedProject?.providerId; + return !providerId || !ANY_AGENT_HOST_PROVIDER_RE.test(providerId); + }, })); this._register(this._workspacePicker.onDidSelectWorkspace(async workspace => { From b2d04b21da84137cea8e9cdfd5034e7cded86478 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Sun, 3 May 2026 20:32:31 -0700 Subject: [PATCH 2/2] sessions: base slash expansion on active session, not picker _send() targets the current active session, which can lag behind the workspace picker selection while trust approval or session-type discovery is in flight. Read providerId from the active session so the expansion decision matches the session that actually receives the request. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/vs/sessions/contrib/chat/browser/newChatViewPane.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts b/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts index 88c23fbf876e4..ceaa4ff70664d 100644 --- a/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts +++ b/src/vs/sessions/contrib/chat/browser/newChatViewPane.ts @@ -73,7 +73,10 @@ class NewChatWidget extends Disposable { canSendRequest, loading, shouldExpandPromptSlashCommand: () => { - const providerId = this._workspacePicker.selectedProject?.providerId; + // Mirror what `_send()` does: it sends to the current active + // session, which can lag behind the workspace picker selection + // while trust approval or session-type discovery is in flight. + const providerId = this.sessionsManagementService.activeSession.get()?.providerId; return !providerId || !ANY_AGENT_HOST_PROVIDER_RE.test(providerId); }, }));