Skip to content

Floating chat-input window with multi-session routing#326698

Draft
meganrogge wants to merge 6 commits into
mainfrom
megrogge/chat-input-window
Draft

Floating chat-input window with multi-session routing#326698
meganrogge wants to merge 6 commits into
mainfrom
megrogge/chat-input-window

Conversation

@meganrogge

@meganrogge meganrogge commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Fixes https://github.com/microsoft/vscode-internalbacklog/issues/8461

What

Adds a floating, frameless, always-on-top chat-input window that hosts the real chat input — dictation, voice mode, and the input glow — via a compact, input-only ChatWidget. Submissions are routed to the best-matching existing session by a new ISessionRouter.

Toggle with the command "Toggle Floating Chat Input Window" (workbench.action.chat.toggleInputWindow).

Routing — three outcomes

The submitted utterance is scored against the current session list (IAgentSessionsService), then:

  1. Low confidence (no candidate above threshold) → start a brand-new session for the request.
  2. Ambiguous (several comparable high matches within a confidence margin) → quick-pick asking the user which session (each option shows its N% match + rationale), plus a "Start a new session" option.
  3. Single clear match → dispatch straight to it via acquireOrLoadSession + sendRequest.

Every failure path degrades gracefully to a new/local session with a warning. Thresholds are constants: ROUTE_CONFIDENCE_THRESHOLD, ROUTE_AMBIGUITY_MARGIN, ROUTE_MAX_CHOICES.

Design

  • ISessionRouter (chat/common/sessionRouter.ts) keeps prompt/parse/heuristic logic pure so the scoring backend (renderer language model now; CAPI utility completion or a local model later) can be swapped without changing the contract. It degrades to a zero-dependency token-overlap heuristic when no model is available.
  • ChatInputWindowService (chat/browser/chatInputWindow/) mirrors the proven AgentsVoiceWindowService aux-window shell and hosts a ChatWidget with renderStyle:'compact', renderInputOnTop, filter:() => false (input-only), and enableImplicitContext:false (no attachment row). The glow applies for free since the aux container tracks the monaco-workbench class.
  • The window's own session is a scratch input buffer only; it is excluded from routing candidates so it can never route to itself.

Files

  • chat/common/sessionRouter.ts, chat/browser/sessionRouter/sessionRouterService.ts (+ unit test)
  • chat/common/chatInputWindow.ts, chat/browser/chatInputWindow/{chatInputWindowService,chatInputWindow.contribution}.ts
  • Registrations in chat.shared.contribution.ts and workbench.common.main.ts

Notes / follow-ups

  • Draft: needs in-app testing of the aux window (glow, dictation, voice mode) on a supported platform.
  • The disambiguation quick-pick currently attaches to the workbench (may surface in the main window rather than the aux window).
  • Thresholds could be promoted to settings.

🤖 Generated with GitHub Copilot CLI

Introduces a frameless, always-on-top auxiliary window that hosts the real
chat input (dictation, voice mode, and the input glow) via a compact,
input-only ChatWidget. Submissions are scored against the current session
list by a new ISessionRouter and dispatched with three outcomes:

- low confidence -> start a brand-new session
- several comparable high matches -> ask the user which session
- a single clear match -> dispatch straight to it

ISessionRouter keeps prompt/parse/heuristic logic pure so the scoring
backend (renderer language model now; CAPI utility or a local model later)
can be swapped without changing the contract; it degrades to a token-overlap
heuristic when no model is available. Toggle via the command
"Toggle Floating Chat Input Window".

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: aba188ca-29fb-4099-b0f9-e460fcb20613
Copilot AI review requested due to automatic review settings July 20, 2026 18:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a floating chat-input window that routes requests to matching agent sessions.

Changes:

  • Adds model-backed and heuristic session routing.
  • Adds the floating ChatWidget, disambiguation picker, and fallback routing.
  • Registers the services, command, contribution, and helper tests.
Show a summary per file
File Description
src/vs/workbench/workbench.common.main.ts Loads the floating-window contribution.
src/vs/workbench/contrib/chat/test/common/sessionRouter.test.ts Tests routing helpers.
src/vs/workbench/contrib/chat/common/sessionRouter.ts Defines routing contracts and pure helpers.
src/vs/workbench/contrib/chat/common/chatInputWindow.ts Defines the window service contract.
src/vs/workbench/contrib/chat/browser/sessionRouter/sessionRouterService.ts Implements model-backed routing.
src/vs/workbench/contrib/chat/browser/chatInputWindow/chatInputWindowService.ts Implements the window and dispatch workflow.
src/vs/workbench/contrib/chat/browser/chatInputWindow/chatInputWindow.contribution.ts Registers the toggle command.
src/vs/workbench/contrib/chat/browser/chat.shared.contribution.ts Registers the router service.

Review details

  • Files reviewed: 8/8 changed files
  • Comments generated: 16
  • Review effort level: Medium

Comment thread src/vs/workbench/contrib/chat/browser/chatInputWindow/chatInputWindowService.ts Outdated
Comment thread src/vs/workbench/contrib/chat/browser/chatInputWindow/chatInputWindowService.ts Outdated
Comment thread src/vs/workbench/contrib/chat/common/sessionRouter.ts Outdated
Comment thread src/vs/workbench/contrib/chat/browser/chatInputWindow/chatInputWindowService.ts Outdated
@meganrogge meganrogge self-assigned this Jul 20, 2026
@meganrogge meganrogge added this to the 1.131.0 milestone Jul 20, 2026
meganrogge and others added 5 commits July 20, 2026 14:32
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- Fix hygiene failure: replace non-ASCII box-drawing separator comment in
  sessionRouter.ts with ASCII; move $(add) icon outside the localized string.
- Draggable frameless window: add a -webkit-app-region drag handle strip.
- Localize the window document title with a placeholder.
- Reapply themed colors on onDidColorThemeChange.
- Dedicated accessibility help (routing + how to close) via inChatInputWindow
  context key, outranking the generic Quick Chat help.
- Forward and clear explicit attachments through the routing submit contract.
- Dedicated scoped ChatInputWindowSide menu + Close action (no longer closes
  the unrelated Quick Chat surface).
- Only clear the input if the editor still holds the submitted text.
- Window-scoped submission CancellationTokenSource, canceled on close.
- Await agent-sessions model.resolve before snapshotting candidates.
- Retain at most one session reference per resource (ResourceMap dedupe).
- Calibrate the offline heuristic against candidate metadata + threshold test.
- Coalesce concurrent openWindow calls; guard unload cleanup by window identity.
- Use dom.addDisposableListener for the beforeunload listener.
- Rethrow CancellationError from the router instead of degrading to heuristic.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8904e5b5-6e65-4b9c-8ec5-ac060df81978
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