* Fix steer/queue keybinding labels in picker dropdown
The queue/steer picker dropdown was showing inverted keybinding labels:
e.g. Steer showed 'Alt+Enter' but Enter actually steered.
Root cause: ActionWidgetDropdown looked up keybindings via the global
IKeybindingService context. The queue/steer keybindings' when-clauses
require inChatInput and requestInProgress, which are scoped context keys
not visible globally. lookupPrimaryKeybinding fell back to the last
registered binding for each the opposite of what was active.command
Fix:
- Add optional keybinding field to IActionWidgetDropdownAction so callers
can override the global lookup with a pre-resolved keybinding.
- In ChatQueuePickerActionItem, resolve Enter / Alt+Enter directly and
assign them to queue/steer based on the user's configured default,
so labels always match what is actually bound.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Use scoped context for keybinding lookup
Address PR review: resolve queue/steer dropdown keybinding labels via the
scoped contextKeyService instead of hard-coding Enter/Alt+Enter. This
respects user customizations and scoped overrides (e.g. editingRequestType
when editing a queued/steer request).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add chatInputHasText to lookup overlay; add unit test
The keybinding when clauses also require chatInputHasText. Without
including it in the overlay used to look up display labels, the picker
silently fell back to no label. Add it (the picker is only shown when
there is text to send) and add a unit test that asserts the resolved
keybinding for both default=steer and default=queue.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Refine animated chat input working border
- Refactor animated ring to a ::before pseudo-element with mask trick so it
can fade in/out via opacity when the .working class toggles
- Slow the spin from 1.2s to 3s for a calmer cadence
- Replace the static pulsing box-shadow with a 3-step keyframed glow that
cycles through the same three theme colors as the conic ring, in sync
with the spin (so the halo appears to emanate from the gradient)
- Drop the now-unused --chat-input-working-fill override in sessions and
the matching entry in the stylelint allowlist
* feat(chat): add working border colors for chat input in light and dark themes
* feat(chat): update working border colors for chat input
* Update src/vs/workbench/contrib/chat/browser/widget/media/chat.css
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* feat(chat): add transition effect to chat input container
---------
Co-authored-by: mrleemurray <mrleemurray@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix(chat): enable scrollbar for height-capped code blocks in tool confirmations (#283242)
* fix(chat): use chat scrollbar width for capped code blocks
(Written by Copilot)
---------
Co-authored-by: Rob Lourens <roblourens@gmail.com>
* developer joy animation around input box
* add back removed stuff
* don't show border while stuff is working
* better css
* add color components and cleanup
* progress border
* Spawn agent host immediately when chat.agentHost.enabled flips on
Previously, toggling chat.agentHost.enabled at runtime required an app
restart before the local agent host process actually spawned and the
chat/sessions integrations registered. The setting was checked exactly
once at construction time in four places, all of which early-returned if
disabled.
Each site now also registers a one-shot onDidChangeConfiguration listener
true flip triggers setup without a restart:
- src/vs/code/electron-main/app.ts: wraps the
ElectronAgentHostStarter + AgentHostProcessManager construction.
- src/vs/platform/agentHost/electron-browser/agentHostService.ts:
AgentHostServiceClient calls _connect() on flip.
- src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/
agentHostChatContribution.ts: extracted constructor body into _enable().
- src/vs/sessions/contrib/agentHost/browser/localAgentHost.contribution.ts:
same one-shot pattern.
Disable still requires a restart (no teardown of the singleton renderer
service or utility process).
Adds 5 unit tests in agentHostChatContribution.test.ts covering the
gating behavior and the one-shot semantics.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Prompt restart when chat.agentHost.enabled changes
Replace the previous approach (one-shot config listeners in 4 files) with a
single entry in SettingsChangeRelauncher.SETTINGS. Toggling the setting now
shows the standard 'restart required' dialog, which is simpler and avoids
races between renderer and main process setup.
(Written by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Initial framework of Claude sessions in the Agents app
This is barely functional, but it _is_ possible to chat with Claude through it.
Bugs:
First sent message from the welcome chat behavior is VERY strange. The chat is shown completely blank. Then I see the chat under "Unknown" section in the sessions list. I click it, it disappears after a second and reappears in the "Unknown" section. I click it again, it re-appears in the correct place... then I can start chatting with it.
Secondly, no dropdowns show in the existing chat so you can't change the permission mode once you start.
I put all of this behind a setting since it's not really ready yet.. but I wanted to get more eyes on these bugs.
Co-authored-by: Copilot <copilot@github.com>
* feedback
Co-authored-by: Copilot <copilot@github.com>
---------
Co-authored-by: Copilot <copilot@github.com>
* Improve tunnel connection reliability: malformed-frame hardening, auth short-circuit, host-online resume, session cleanup
Transport layer:
- Add malformed-frame detection across all three transports (WebSocketClientTransport,
TunnelConnectionTransport, TunnelRelayTransport): warn log first 5 per connection,
force-close transport after >10 to trigger reconnect loop instead of silently
dropping corrupt data. Shared constants in new transportConstants.ts.
Reconnect logic (tunnelAgentHost.contribution.ts):
- Auth-error short-circuit: authExpired/auth errors immediately pause reconnects
instead of burning 10 retry slots, resume driven by onDidChangeSessions.
- Host-online auto-resume: _silentStatusCheck detects when a host-offline-paused
tunnel comes back online and auto-resumes without needing a wake/visibility event.
- Session-removal cleanup: react to github session removal by tearing down matching
tunnel state and best-effort disconnect.
- Richer _categorizeError: distinguish authExpired (401/403/token expired) from
generic auth, add ECONN/ENOTFOUND/ETIMEDOUT to network category.
Telemetry:
- Add authExpired to TunnelConnectErrorCategory and TunnelConnectFailureReason types.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix review findings: token regex over-match, auto-cached authProvider
- _categorizeError: remove \btoken\b from auth regex to avoid matching
'connection token' protocol errors. Use 'auth.*(fail|error|invalid)'
instead, which catches real auth failures without over-matching.
- _silentStatusCheck: pass 'github' authProvider to cacheTunnel() so
auto-discovered tunnels are properly matched by _handleSessionsChange
for teardown on session removal.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address PR review comments
- Pass actual errorCategory ('auth'|'authExpired') to _pauseReconnect
instead of always using 'authExpired'. Add 'auth' to
TunnelConnectFailureReason type.
- Update telemetry classification comments to list all current enum
members (authExpired for errorCategory, auth/authExpired for
failureReason).
- Log actual data type (ArrayBuffer/Blob) and byte length for non-string
WebSocket frames instead of coercing to empty string.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Hide 'View Extension' hover action for core chat agents
Core agents (e.g. the agent host) register with a placeholder
extension id and have no real extension to view. Skip adding the
'View Extension' hover action when the agent has isCore: true.
Fixes#311510
(Written by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix TDZ in getChatAgentHoverOptions, defer agent lookup
Some callers construct the hover options before the surrounding
template variable is initialized, so resolving the agent eagerly
hits a TDZ. Make 'actions' a lazy getter so the agent is only
read when the hover is actually shown.
(Written by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Reuse PermissionPickerActionItem for agent host auto-approve picker
Previously the agent host had its own custom auto-approve picker that
duplicated most of the workbench PermissionPickerActionItem widget. This
refactor reuses the workbench widget when the active session's
autoApprove session-config property uses the well-known schema (string
type, enum subset of {default, autoApprove, autopilot} containing
'default'). Sessions that match get the workbench widget; non-conforming
agents fall back to the existing generic per-property picker.
- Adds AgentHostPermissionPickerDelegate and a thin
AgentHostPermissionPickerActionItem subclass that toggles its
visibility reactively as the active session changes.
- Generalizes the warning/info color rules in chat.css so they live
with the widget rather than being scoped to .chat-secondary-toolbar.
- Groups all agent-host-only files under
src/vs/sessions/contrib/chat/browser/agentHost/.
- Fixes a regression where the picker would stay hidden after
navigating back to the new-chat view; the IActionViewItemService
factory only runs once per render, so visibility must be reactive
rather than gated at construction.
(Written by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Refactor: agent host reuses PermissionPicker (sessions) instead of PermissionPickerActionItem (workbench)
Both pickers now render in the same context (new-chat-page action bar), so
the previously-needed CSS specificity overrides (icon/font sizing,
padding, color rule un-scoping in chat.css) all go away.
Changes:
- Add IPermissionPickerDelegate to permissionPicker.ts: optional
currentLevel observable, optional isApplicable observable, setLevel.
- Refactor PermissionPicker to take a delegate. When currentLevel is
provided, the picker label tracks it reactively. When isApplicable is
provided, the picker hides itself when false.
- Add CopilotPermissionPickerDelegate (writes through to the active
CopilotChatSessionsProvider session). Preserves today's behavior.
- Move AgentHostPermissionPickerDelegate to its own file under
agentHost/, retargeted at the new interface (currentLevel,
isApplicable, setLevel).
- agentHostSessionConfigPicker.ts now constructs PermissionPicker with
the agent host delegate and wraps in PickerActionViewItem.
- Delete agentHostPermissionPickerActionItem.ts (the workbench widget
subclass) and its CSS overrides.
- Revert chat.css warning/info color un-scoping (no longer needed since
agent host doesn't use the workbench widget anymore).
- Rename the test file to match the new product file. Tests cover the
delegate's permission-level mapping, isApplicable reactivity, and
isWellKnownAutoApproveSchema.
(Written by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Use PermissionPickerActionItem for ChatInputSecondary, PermissionPicker for NewSessionControl
Restore the contextual split: agent host now uses each widget where it's
expected to render. The new-chat page (NewSessionControl) keeps the
sessions PermissionPicker (matches surrounding sessions pickers); the
running chat widget (ChatInputSecondary) uses the workbench
PermissionPickerActionItem (matches the rest of the chat-input
secondary toolbar that the extension-host CLI already uses).
Both share AgentHostPermissionPickerDelegate. To make the same delegate
satisfy both consumers, rename its members to
currentPermissionLevel/setPermissionLevel (matching the workbench's
IPermissionPickerDelegate).
(Written by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Consolidate duplicate AUTO_APPROVE_PROPERTY constant
Both `agentHostPermissionPickerDelegate.ts` and
`agentHostSessionConfigPicker.ts` had identical `'autoApprove'` string
constants (one called `AUTO_APPROVE_SESSION_CONFIG_PROPERTY`, the other
`AUTO_APPROVE_PROPERTY`). Standardize on the shorter name and import it
in the picker. Also drops a now-unused `KNOWN_AUTO_APPROVE_VALUES` set
that was left behind in the picker file. (Written by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address Copilot review comments
- Dispose `onDidChangeProviders` Emitter in delegate test setup so the
suite-level leak detector is happy. Refactor `setup()` to take the
leak-tracking store and register all created disposables itself, so
individual tests don't repeat the boilerplate.
- Fix corrupted JSDoc on `CopilotPermissionPickerDelegate` (sentence
was mangled across an inline-code span). (Written by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Drop redundant `_slot` field from PermissionPicker
The `slot` local in `render()` is in scope for the `autorun` closures, so
storing it on `this` is unnecessary. Removing the field also drops the
needless null-check inside the visibility autorun. (Written by Copilot)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>