Commit Graph

159655 Commits

Author SHA1 Message Date
Sandeep Somavarapu
5bcfb040f4 sessions: support multi-session delete via session capability (#322310)
* sessions: support multi-session delete via session capability

Enable deleting multiple sessions at once and consolidate the delete
action into the sessions workbench core instead of each provider.

- Add required `deleteSessions(sessionIds)` batch API to `ISessionsProvider`
  and `deleteSessions(sessions)` to the sessions management service, which
  groups sessions by provider before delegating.
- Implement a real batch delete in the agent host base provider that
  resolves all targets synchronously up front before disposing, avoiding a
  reconcile dropping not-yet-processed cached sessions.
- Introduce a `supportsDelete` session capability and a
  `chatSessionSupportsDelete` context key, mirroring the `supportsRename`
  pattern. A single core `DeleteSessionAction` (gated on the capability)
  replaces the per-provider delete actions and the delete-session helper.
- Move the delete confirmation dialog into the action and remove it from
  the provider implementations.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* sessions: address CCR feedback on multi-session delete

- Filter the action's incoming context to sessions that advertise
  `capabilities.supportsDelete`, so a mixed multi-selection never deletes
  sessions that don't support it.
- Use a singular vs plural delete error message and distinct localization
  keys instead of a plural-only message.
- Make the management service batch delete best-effort: continue deleting
  other providers' sessions if one provider rejects, then surface the first
  error. Emit `onDidDeleteSession` only for providers that succeeded.
- Clarify the `deleteSessions` JSDoc to say implementations may batch or
  delegate to `deleteSession`.
- Revert the unrelated "Copilot CLI" -> "Copilot" session type label change.
- Add a best-effort batch delete test to the management service suite.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-21 18:12:34 -07:00
Rob Lourens
88313d3dcc Respect workspace trust for the local agent host (#322308)
* Respect workspace trust for the local agent host

Gate spawning local agent-host sessions on workspace trust as a UI-layer
concern, mirroring how extension-host chat is gated. Viewing chat and the
agent list does not require trust; sending the first message prompts to
trust the workspace, and no session is ever spawned (even eagerly) in an
untrusted folder.

Editor window:
- AgentHostSessionHandler._invokeAgent requests workspace trust before
  spawning a session and aborts cleanly on decline.
- AgentHostUntitledProvisionalSessionService.getOrCreate no longer
  eagerly pre-warms a backend session in an untrusted workspace.

Agents window:
- baseAgentHostSessionsProvider skips the eager createSession when the
  target folder is untrusted (defense-in-depth; the interactive prompt
  stays at folder-pick time). Config resolution for the picker remains
  ungated. Remote providers (requiresWorkspaceTrust: false) are
  unaffected.

Refs microsoft/vscode-internalbacklog#8082

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address Copilot review: gate provisional on folder trust, guard stale eager-create

- AgentHostUntitledProvisionalSessionService.getOrCreate now gates on the
  trust of the actual target working directory (which can be a standalone
  folder outside the open workspace) via getUriTrustInfo, falling back to
  whole-workspace trust only when no working directory is known. The check
  moved into the creation path so existing/inflight fast paths are intact.
- baseAgentHostSessionsProvider: after awaiting trust info in the eager
  create path, bail if the NewSession draft was abandoned/replaced, to
  avoid spawning a backend session for a stale entry.
- Add tests for the untrusted/trusted working-directory-folder cases.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 00:38:27 +02:00
Rob Lourens
033e0befbe agentHost: centralize and type-check AHP _meta access (#322304)
* agentHost: centralize and type-check AHP `_meta` access

The Agent Host Protocol uses an open `_meta` bag (`Record<string, unknown>`)
on many protocol/state messages to carry well-known extra data between server
and client. This was read in an ad-hoc, untyped way in many places.

This change makes all `_meta` access type-safe and centralized:

- Add typed reader/builder functions per well-known slot, grouped under
  `platform/agentHost/common/meta/`, so nothing reads `_meta` untyped.
- Readers take their parent object (e.g. `ToolCallState`, `AgentCustomization`,
  `RootState`, `ErrorInfo`, `UsageInfo`) and read `source._meta` internally, so
  passing the wrong slot's bag is a compile error. `readSessionGitState` stays a
  raw-value reader (the sessions provider holds a detached `_meta` snapshot).
- De-duplicate the feedback-annotation slot: the sessions browser layer now maps
  the shared validated wire shape into its client view instead of re-declaring
  and re-validating it.
- Replace a serialize-then-reparse round-trip in the Claude subagent signal path
  with a direct typed builder.
- Add a syntactic local ESLint rule `code-no-untyped-meta-access` that flags
  member access off / casts of `x._meta`, scoped to the agent host surface.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* agentHost: address Copilot review on `_meta` type-safety PR

- protocolUpgrade: `readUnsupportedProtocolVersionErrorMeta` now returns
  `undefined` (not an empty `{}`) when `_meta` has no validated fields, matching
  its documented contract so presence checks stay correct.
- code-no-untyped-meta-access: update the rule's header comment and diagnostic
  messages to recommend the new parent-object reader form
  (`readToolCallMeta(toolCall)`) instead of the old bag form.
- stateToProgressAdapter: drop unreachable `resourceUri.length === 0` /
  `channel.length === 0` guards — `readToolCallMeta().ui` already guarantees a
  non-empty `resourceUri` and only sets `channel` when non-empty.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 00:24:08 +02:00
Rob Lourens
45caa18d67 sessions: add command palette entry to update an incompatible remote agent host server (#322305)
* sessions: add command palette entry to update an incompatible remote agent host server

Expose the existing remote agent host server upgrade flow ("Update Server")
as a command palette command. Connecting to a remote agent host that runs an
old build leaves it in the `incompatible` state; when that host was spawned by
a VS Code CLI willing to receive upgrade signals it advertises an upgrade
method. Previously this was only reachable from the incompatible notification
or the per-host options quickpick.

The new "Update Remote Agent Host Server..." command (f1, Sessions category,
gated on chat.remoteAgentHostsEnabled) collects incompatible hosts that
advertise an upgrade method, prompts when there is more than one, and reuses
the shared runServerUpgrade flow.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* sessions: clarify message when no incompatible host can be updated in place

Address Copilot review feedback: the previous "No remote agent hosts need
updating." message was misleading when incompatible hosts exist but none was
spawned by a VS Code CLI that can update it in place. Distinguish the two cases
so users who can see an Incompatible host get an accurate explanation.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 00:23:50 +02:00
Sandeep Somavarapu
767e9e56b4 sessions: hide session picker groups when no duplicate session names (#322307)
* sessions: hide session picker groups when no duplicate session names

Section headers in the session type picker exist to disambiguate session
types that share a label across providers (e.g. two providers both
offering "Claude"). When every type's label is unique there is nothing
to disambiguate, so render a flat list without group headers even when
multiple providers contribute.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* sessions: rename Copilot CLI session type label to "Copilot"

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test: update Agents Window smoke test for renamed Copilot label

The Copilot CLI session type label was renamed to "Copilot" (shared
CopilotCLISessionType used by the Copilot Chat provider), so the picker
no longer exposes a "Copilot CLI" entry. Select "Copilot" instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 00:23:00 +02:00
Sandeep Somavarapu
98bf19c30c agent host: fix custom agent selection and per-chat agent/model changes (#322300)
* agent host: fix custom agent selection and per-chat agent/model changes

Two fixes for Copilot CLI agent-host sessions:

- The selected custom agent (e.g. a plugin/extension agent like "Inbox")
  failed with "Custom agent '<name>' not found". The SDK validates the
  session-start `agent:` option against `customAgents` by name and does not
  consult `pluginDirectories`, but file-dir plugin agents were excluded from
  `customAgents`. The new `toSdkSessionCustomAgents` helper force-includes the
  resolved selected agent while other file-dir agents still load via
  `pluginDirectories`.

- An additional (peer) chat in a session did not respect agent/model changes.
  `SessionAgentChanged`/`SessionModelChanged` were dispatched to the session
  URI (the default chat) instead of the per-chat turn channel, and the
  `chatChannel` was dropped before reaching `changeAgent`/`changeModel`. These
  now route to the peer chat's backend conversation in `_chatSessions`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* sessions: address Copilot code review feedback

- Trim SDK custom-agent names to match parseAgentFile so a whitespace-padded
  frontmatter name still matches the resolved selected agent (CCR finding 3).
- Dedup peer-chat agent/model side-channel dispatch against the last value
  sent for that chat (tracked on AgentHostChatSession) instead of the session
  summary, which only exists for the default chat (CCR findings 1 & 2).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 00:02:32 +02:00
Benjamin Christopher Simmonds
beef62f279 agentHost: route comments tools to the main session resource (#322306)
A session can contain multiple peer chats that share the same context/workspace, each addressed by its own ahp-chat URI. The feedback (comments) server tools received the chat URI, so comments were stored on the individual chat's annotations channel instead of the session's. Resolve the URI back to its owning session before reading/writing annotations so comments always target the main session.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-21 21:43:37 +00:00
Sandeep Somavarapu
a0f60b2860 extensions: show configured auto-update delay in delayed label (#322301)
* extensions: show configured auto-update delay in delayed label

The extension status label hardcoded "2 hours" as the auto-update delay,
so changing extensions.autoUpdateDelay still showed 2h. Add a
getAutoUpdateDelay() method that returns the configured delay and use it
to format the label dynamically.

Fixes #321577

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* extensions: format auto-update delay as a duration

Use a past timestamp with fromNow so the configured delay reads as a
duration (e.g. "2 hours") instead of "in 2 hours".

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-21 21:35:13 +00:00
Benjamin Christopher Simmonds
13112d5489 sessions: only show agent feedback input for non-empty selections (#322303)
The agent feedback editor input previously appeared for empty selections
when the cursor was inside a diff hunk. The input should only appear for
non-empty selections, so remove the diff-hunk special casing and hide the
widget whenever the selection is empty.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-21 21:22:44 +00:00
chen
f5b37a939e fix: registerToolDefinition loss tags (#319922) 2026-06-21 20:27:24 +00:00
Ladislau Szomoru
031f8831a1 AgentHost - unblock pull request creation (#322296)
* AgentHost - unblock pull request creation

* Fix tests
2026-06-21 13:26:51 -07:00
dileepyavan
dacafdda2b Update to git commands chaining in sandbox (#322249)
update to git commands in sandbox
2026-06-21 13:25:58 -07:00
Martin Aeschlimann
1eb92e30e0 Copilot AH: show hooks in customizations (#322294) 2026-06-21 21:43:29 +02:00
Martin Aeschlimann
a083fe227a Skills from plugins have wrong name (#322292) 2026-06-21 21:43:02 +02:00
João Moreno
8efe757281 cleanup collaborators list (#321369) 2026-06-21 18:33:46 +00:00
vs-code-engineering[bot]
cb128cbeff fix: tolerate invalid tool-call JSON in language model wrapper (fixes #322123) (#322127)
The model can stream malformed JSON for tool-call arguments. The language model wrapper threw a bare Error from a fire-and-forget finished callback, producing an unhandled rejection in error telemetry without cleanly aborting the response. Align with the other tool-call consumers (langModelServer, messagesApi) by logging the diagnostic and falling back to empty parameters so the tool call is still surfaced to the consuming extension.

Co-authored-by: vs-code-engineering[bot] <122617954+vs-code-engineering[bot]@users.noreply.github.com>
2026-06-21 08:52:11 +00:00
Paul
cfb41fb566 Fix model context resolution (#322256) 2026-06-20 22:53:12 -07:00
Justin Chen
2b59f152a6 Rename chat.agentSessions.defaultConfiguration setting to chat.defaultConfiguration (#322229)
* Rename chat.agentSessions.defaultConfiguration to chat.defaultConfiguration

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add migration for renamed setting and make enum/interface names surface-agnostic

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove accidentally committed audit log

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-21 04:42:58 +00:00
Connor Peet
0c5ea4988a agent host: fix blank response after aborting a turn with a queued message (#322228)
* agent host: fix blank response after aborting a turn with a queued message

When a running turn was aborted while a follow-up message was queued, the
Copilot SDK's asynchronous terminal `session.idle` (delivered after the
abort teardown) completed the wrong turn: the queued message's send() had
already reassigned the session's current turn id, so the stale idle emitted
an empty ChatTurnComplete for the freshly-started turn and orphaned its real
response and pending permission prompt.

Read the SDK's authoritative `IdleData.aborted` flag, and replace the
scattered per-turn fields (turn id, usage counter, streaming part-id maps)
with a single CopilotTurn object carrying an explicit lifecycle state
(pending | running | completed | aborted). A turn is pending between send()
and the first SDK event and running thereafter; an abort's idle tears down a
running turn (the client's ChatTurnCancelled finalizes it) and leaves a
pending queued turn open, so the next turn's response is no longer orphaned.
Steering turns are marked running on creation since they are promoted
mid-loop.

Also assert that cancelling a turn intentionally does not drain queued
messages (they stay for manual dequeue), and keep the subagent routing map
session-scoped since background subagents can outlive a turn.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* agent host: address PR review feedback

- Log an error and drop markdown/reasoning deltas emitted with no active
  turn (previously a no-op set that re-allocated a part per delta).
- Split the abort-idle trace message by turn state (running turns are torn
  down, not left open).
- Tidy a test title to sentence case.
- Give delta/plan-mode mapping tests an active turn instead of relying on
  the old emit-without-a-turn behavior; assert the new drop+log behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-21 04:05:25 +00:00
Bhavya U
db0cabd800 Gate memoryInstructions on the memory tool being enabled (#322250)
Render the memory instructions and context blocks only when the memory
tool is in availableTools, so the prompt and available tools stay in sync.

Fixes #321833

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-20 20:53:25 -07:00
Bhavya U
bcf17876c3 Fix /compact failing on streaming models (Gemini): don't force stream:false (#322255)
The off-flag conversation summarization path forced `stream: false` on the
chat request. The response processor is selected by the endpoint's static
`supportsStreaming` capability, not by this flag, so for a streaming Chat
Completions model (e.g. gemini-3-flash) the single non-streamed JSON blob is
still routed through the SSE processor, which fails to parse it and reports a
spurious RESPONSE_CONTAINED_NO_CHOICES failure. Both Full and Simple modes hit
this, so /compact reported failure even though the model returned valid
summaries.

Removing `stream: false` lets the request stream (the safe default for every
endpoint type); `interceptBody` still forces `stream: false` for models that
genuinely don't support streaming.

Fixes #321085
2026-06-20 20:53:22 -07:00
Bhavya U
2e52a6b834 Update model capabilities (#322237)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-21 00:21:22 +00:00
Alexandru Dima
30cd6adcce agentHost: fix Windows CI write auto-approval test using Azure temp dir (#322240)
The SessionPermissionManager 'auto-approves a normal file inside the
working directory' test failed on Windows CI because it chose its temp
base via `process.env.RUNNER_TEMP || tmpdir()`. `RUNNER_TEMP` is a
GitHub Actions variable and is unset on VS Code's Azure DevOps CI, so it
fell back to `os.tmpdir()`, an 8.3 short path containing a `~1`
segment. `fs.realpathSync` does not expand short names to long form, so
`workDir` kept the `~1` segment and `assertPathIsSafe` rejected it,
making write auto-approval return undefined instead of NotNeeded.

Use `AGENT_TEMPDIRECTORY` (set by Azure DevOps, a long path) ahead of
`RUNNER_TEMP`, matching how the rest of the VS Code build resolves the
CI temp directory.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-21 00:02:09 +02:00
Alexandru Dima
f7bc66f118 smoke: fix flaky Chat Sessions copilot-chat activation race (#322187)
The Chat Sessions smoke test runs right after the Chat Disabled suite,
which disables AI features. When the suite re-enables them, there is a
brief window where copilot-chat is still disabled and its commands are
not yet registered. The smoke helper invoked
'github.copilot.debug.extensionState' to force-activate copilot-chat,
but that executeCommand rejected with 'command not found' during this
window, aborting the handler before it could open the chat editor and
causing a 60s timeout on '.editor-instance .interactive-session'.

Wait for the diagnostic command to be registered (via the existing
waitForCommand helper) before invoking it, so the handler no longer
races copilot-chat enablement/activation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-20 23:14:01 +02:00
Alexandru Dima
9a13e891e4 extensions: capture raw ext host stdout/stderr in smoke tests (#322186)
Native extension host crashes (e.g. from a faulty native addon such as the
node-pty bundled with the Copilot CLI SDK) print to the process' stderr but
never reach the JavaScript layer: there is no JS stack and, for utility
processes, frequently no crash dump either. The output is also only forwarded
to the renderer DevTools console debounced, so the final pre-crash bytes can be
lost.

Capture the raw, undebounced extension host stdout/stderr from the renderer
side (which survives the crash) into the renderer log so such crashes remain
diagnosable from the published smoke-test log artifacts. Gated to smoke tests
via the existing --enable-smoke-test-driver flag so regular sessions are
unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-20 14:08:08 -07:00
Bhavya U
d778afd715 Fix tool_search for GPT models; scope tool_search to deferred tools (#322235)
getAvailableTools(): skip virtual-tool grouping for any tool-search-capable endpoint (not just Anthropic). Previously GPT-5.4/5.5 ran virtual-tool grouping AND responses-API client tool search simultaneously, so real MCP tools were hidden behind activate_* groups (or trimmed) and never appeared in the request's tools map - making them searchable via tool_search but not callable.

toolSearchTool: exclude always-available (non-deferred) tools from the tool_search candidate set so the limited result slots only go to tools that actually need loading.

Fixes #317998
Fixes #317992
2026-06-20 22:44:38 +02:00
Bhavya U
17e4035061 Add per-model system-prompt registry for Copilot agent-host sessions (#321864)
* Add per-model system-prompt registry for Copilot agent-host sessions

Introduces a prompt registry (mirroring the Copilot extension's PromptRegistry/IAgentPrompt) so Copilot CLI agent-host sessions resolve their SDK system message per model instead of a single hardcoded constant. First contributor: a Claude Opus 4.8 resolver applying customize-mode section overrides, opt-in via the new chat.agentHost.opus48Prompt.enabled setting (forwarded into the local agent host root config). Forwarding is registered for the VS Code workbench only, not the Agents window.

* Address PR review: empty section overrides fall back to default; strongly type test schema helper

- promptRegistry: treat an empty resolveSectionOverrides() result as 'no override' so the default identity customization is preserved instead of emitting customize-mode with empty sections.
- agentHostCopilotPromptContribution.test: import ConfigPropertySchema and type makeRootStateWithSchema, removing the unsafe Record<string, never> cast.
- agentHostPromptRegistry.test: add regression test for the empty-overrides fallback.
- anthropicPrompt: lead the Opus 4.8 tone append with a newline so it doesn't run on from the SDK foundation tone.
2026-06-20 20:26:35 +00:00
Rob Lourens
ab0cc74805 Agent Host: fix Copilot real-SDK integration tests (#322226)
* Fix Copilot real-SDK agent host integration tests

The Copilot real-SDK suite (gated behind AGENT_HOST_REAL_SDK=1) had drifted
from the agent host protocol. This adapts the test harness to the current
behavior so the suite is green again (12 passing, 1 pending, 0 failing):

- Multi-chat channel migration: chat actions are now emitted on a session's
  default chat channel (buildDefaultChatUri(sessionUri)) rather than the bare
  session URI. Update the usage-action channel assertion and the subagent
  test's channel filters/subscriptions accordingly, and subscribe to the
  worktree session's default chat channel.
- driveTurn dispatched chat actions (toolCallConfirmed / inputCompleted)
  without a top-level channel, crashing the server in buildDefaultChatUri.
  Include the channel and drop the now-dead session field from the bodies.
- Plan-mode answers: prefer the exit_only option so approving a plan ends the
  turn instead of continuing to implement in-turn, which surfaced tool-call
  confirmations the planning test asserts against.
- Worktree test: the host custom terminal tool became opt-in
  (EnableCustomTerminalTool defaults off). Enable it via a root/configChanged
  action before the session launches so the shell tool routes through the
  host terminal manager.

These are test-harness adaptations only; no product behavior changes.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add required confirmed/reason fields to toolCallConfirmed dispatches

The real-SDK test harness dispatched chat/toolCallConfirmed approve
actions without the required `confirmed` field (and the deny action
without the required `reason` field), so the chat reducer stored
`undefined` for those properties, violating the protocol action shape.
Populate `confirmed: ToolCallConfirmationReason.UserAction` on approvals
and `reason: ToolCallCancellationReason.Denied` on the denial path.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add typed dispatch helper to agent host test client

The test client's `notify(method, params?: unknown)` erased all action-shape
type checking, which is why a missing required `confirmed` field on
`chat/toolCallConfirmed` dispatches slipped past the compiler.

Add a typed `dispatch(params: DispatchActionParams)` method to
`TestProtocolClient` so dispatched actions are validated against the
`StateAction` union at compile time, and migrate the real-StateAction
dispatch sites in the Copilot real-SDK test files to it (using `ActionType`
enum members instead of raw strings). This also fixed a malformed dispatch in
copilotRealSdk.integrationTest.ts that was missing its channel and `confirmed`
field and carried a bogus `session` field.

The two `session/abortTurn` sites are left on raw `notify` since that action
is not part of the `StateAction` union.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-20 13:11:55 -07:00
Harald Kirschner
3f10235996 fix: handle pending_confirmation signals when no active protocol turn exists (#321843)
* fix: handle pending_confirmation signals when no active protocol turn exists

When a hook-triggered continuation (e.g. userPromptSubmitted) runs after
the protocol turn has already completed, the state manager has no active
turn. Action signals use a fallback path that dispatches with an empty
turnId, but pending_confirmation signals were silently dropped. This
caused the permission deferred promise to never resolve, blocking the SDK
session indefinitely (stuck in 'thinking').

Fix: route pending_confirmation through _handleToolReady with an empty
turnId in the no-active-turn fallback, matching the action signal path.
Also fix the subagent path to always call _handleToolReady (using empty
string fallback) instead of conditionally skipping when subTurnId is
undefined.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test: deterministic regression test for pending_confirmation without active turn

Adds an end-to-end integration test that drives the real agent host
server, AHP protocol, AgentSideEffects signal handling, and permission
manager to guard the fix for pending_confirmation signals arriving after
the protocol turn has completed.

A new ScriptedMockAgent 'orphan-confirmation' scenario completes a turn,
then emits a tool + pending_confirmation with no active turn (simulating
a hook-triggered continuation). The test asserts the confirmation is
dispatched and the session continues instead of hanging. Reverting the
production fix makes the test time out.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Rob Lourens <roblourens@gmail.com>
2026-06-20 11:50:49 -07:00
dileepyavan
c3dee0ca54 Check terminal sandbox file access directly (#322021)
* Protect terminal sandbox settings file

* Check terminal sandbox file access directly

* Restore session customization discovery baseline

* Remove whitespace-only PR changes

* Remove obsolete terminal sandbox guidance

* Revert package lockfile changes
2026-06-20 17:49:04 +00:00
Connor Peet
edc7e043f8 Merge pull request #322224 from microsoft/connor4312/sessionperm-realpath-flake
agentHost: fix flaky write auto-approval on Windows from native realpath
2026-06-20 10:41:19 -07:00
Connor Peet
a014adb161 Merge pull request #322223 from microsoft/connor/agent-host-connection-unification
Agent-host MCP servers + unify local/remote connection access
2026-06-20 10:40:55 -07:00
Connor Peet
89c9d5f18e agentHost: address Copilot review feedback
- toSdkMcpServersFromConfigMap: treat the user-controlled root mcpServers map
  as Record<string, unknown> and skip entries that don't match a supported
  shape (stdio+command / http+url), so malformed config can't surface as
  command/url: undefined in the SDK config.
- copilotAgent._getMcpServers: clone via structuredClone instead of
  JSON.parse(JSON.stringify(...)) (cheaper, value-preserving) on the
  snapshot/restart path.
- IAgentHostConnectionsService.connections: correct the doc — the ambient
  entry always has a live connection; only remote entries may be undefined.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-20 10:20:00 -07:00
Connor Peet
918743e368 agentHost: fix flaky write auto-approval on Windows from native realpath
`resolveRealPathForNonexistent` imported `realpath` from `fs/promises`,
which internally calls `fs.realpath.native`. On Windows that resolves
subst drives to their target (and normalizes differently) than the JS
`fs.realpath` implementation the tests use via `fs.realpathSync`. The
symlink-resolved path could then diverge from the working directory and
be judged outside it, so `getAutoApproval` returned `undefined` instead
of `NotNeeded`.

Use `Promises.realpath` from `vs/base/node/pfs`, which deliberately
avoids `fs.realpath.native` (see microsoft/vscode#118562), aligning
production with the test and the rest of the codebase.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-20 08:18:03 -07:00
Connor Peet
eb6773e66d Merge remote-tracking branch 'origin/main' into connor/agent-host-connection-unification 2026-06-20 08:05:14 -07:00
Rob Lourens
43e100f3ff chat: hide Agent Host Copilot response identity (#322203)
Hide the chat response username and avatar for Agent Host Copilot responses so they match the default Copilot presentation while keeping other Agent Host agents distinguishable.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-20 02:50:16 -07:00
Rob Lourens
06d84f5a8c chat: Suppress missing Agent Host file read logs (#322200)
* chat: Suppress missing Agent Host file read logs

Suppress expected NotFound logging for file resource reads on both protocol client and server handling paths, while preserving warnings for synthetic resources, non-read requests, and non-missing read failures.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chat: Address Agent Host file read review

Share missing file-read log suppression logic across protocol client and server paths, and avoid assuming read failures are always Error instances.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-19 22:26:42 -07:00
Rob Lourens
8c2e53656e chat: simplify Agent Host Copilot label (#322179)
* chat: simplify Agent Host Copilot label

Use the shorter Copilot label for the Agent Host Copilot session when the local editor agent is disabled, while keeping the Agent Host-disambiguated name when both implementations can appear. (Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* test: update Agent Host Copilot naming expectations (Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chat: always simplify Agent Host Copilot label (Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chat: rename Agent Host Copilot display name

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chat: use Agent Host advertised names

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* chat: remove redundant Agent Host Copilot label cases

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-19 22:18:29 -07:00
Rob Lourens
d6085d180c Fix Agent Host chat picker disposal (#322195)
Cancel pending initial config resolution before the picker render store is disposed, and ignore late render attempts after disposal.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-19 22:18:08 -07:00
Rob Lourens
5389822279 Add build-fast npm script for fast full builds (#322181)
* Add build-fast npm script for fast full builds

Adds a 'build-fast' script that fully builds the repo with as little
typechecking as possible by composing existing tasks: esbuild transpile
for the core (transpile-client), tsgo compile for extensions
(compile-extensions + compile-extension-media), the copilot extension
(compile-copilot), and the codicon.ttf copy (copy-codicons).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove transpile and transpile-extensions scripts in favor of build-fast

build-fast replaces the transpile script. The transpile-extensions npm
script is no longer needed; CI invokes the gulp transpile-extensions
task directly via `npm run gulp`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-19 18:24:28 -07:00
Rob Lourens
551477a8c6 sessions: avoid classic agent host list in agents window (#322182)
Move the local agent host chat-session item controller into an editor-window-only contribution so the Agents window keeps using its sessions provider list path without loading AgentHostSessionListController. Keep the shared agent-host contribution focused on chat content, models, auth, and customization wiring, and add focused tests for editor-window registration versus sessions-window suppression.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-19 18:24:03 -07:00
Alexandru Dima
4a6e32fc1f copilot: disable process.report in copilot extension (#322178)
Disable process.report in copilot extension

Override process.report.getReport to return undefined, loaded as the first import in the copilot extension entrypoint. Cherry-picked from #321998 and #322036.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-19 17:08:10 -07:00
Megan Rogge
8d8f1028df Integrate voice mode panel with chat input and improve floating window (#321957) 2026-06-19 17:07:44 -07:00
Vijay Upadya
4e116aaf70 Gemini: Fix tool-call validation for Gemini flattened argument keys (#322165)
* Gemini: Fix tool-call validation for Gemini flattened argument keys

* Feedback updates
2026-06-20 01:47:03 +02:00
Connor Peet
75d61a59ae Update CLI agent commands for AHP 0.4 (#322173)
AHP 0.4 moves turns/active_turn off SessionState onto per-chat ChatState
(SessionState now carries a `chats` catalog), and SessionStatus is now a
newtype bitset instead of a repr enum.

- agent_ps: use SessionStatus::bits()/from_bits().contains() instead of
  `as u32` casts
- agent_stop: resolve in-progress chats from the session catalog, subscribe
  to each chat to find its active turn, and dispatch the renamed
  StateAction::ChatTurnCancelled to the chat URI
- agent_logs: print the session's chats catalog instead of the removed
  turns/active_turn

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-20 01:30:32 +02:00
dependabot[bot]
8b458a5d61 build(deps): bump undici from 7.26.0 to 7.28.0 (#322102)
* build(deps): bump undici from 7.26.0 to 7.28.0

Bumps [undici](https://github.com/nodejs/undici) from 7.26.0 to 7.28.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v7.26.0...v7.28.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 7.28.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: restore cpu-features entry in package-lock.json

Co-authored-by: rzhao271 <7199958+rzhao271@users.noreply.github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Martin Aeschlimann <martinae@microsoft.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rzhao271 <7199958+rzhao271@users.noreply.github.com>
2026-06-19 23:17:11 +00:00
Alexandru Dima
16c0598ca1 smoke: fix flaky Agents Window Copilot CLI session activation (#322170)
The "Agents Window > Test Copilot CLI session" smoke test flakily timed
out at `activateSessionByLabel`, which located the just-completed session
row by its title and expected it to equal the mocked reply
`MOCKED_COPILOT_RESPONSE`. That title is set asynchronously by a utility
model after the first turn and races the untitled->committed session
swap, so it is non-deterministically either the user's prompt (the
synchronous fallback) or the generated reply. The test passed on macOS
(title-gen landed) and failed on Linux (it didn't) in the same run.

Decouple row identification from response verification:
`activateSessionByLabel` now accepts one or several row substrings and
matches a row containing ANY of them, while a separate `responseLabel`
is verified against the active session's response bubble. The smoke test
passes both the first prompt and the reply, so activation is
deterministic regardless of when title generation completes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-20 01:15:46 +02:00
Megan Rogge
68f213e0be Don't dispose user-revealed terminals on session switch (#322121)
Fixes microsoft/vscode#321049

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-19 22:53:00 +00:00
Connor Peet
81d0c7de4b Stop worktreeCreated tasks when a session is marked done (#322153)
The WorktreeCreatedTaskDispatcher launched setup/build tasks but never
stopped them, so their (potentially remote) host processes leaked when a
session was archived ("Mark as Done"). See #321021.

Task runners now return an IDisposable stop handle. The dispatcher tracks
these per session and disposes them when the session is archived or
removed, terminating the launched terminals/processes. Agent-host task
terminals are disposed directly (prompt-free) so the AgentHostPty shuts
down and the node-pty process on the host is killed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-19 15:50:28 -07:00
Connor Peet
411a997c16 agent host: bring tool approval to parity with the extension (#322151)
* agent host: bring tool approval to parity with the extension

- The agent host auto-approved write tool calls using only working-directory
  and glob checks, while the extension's edit-confirmation pipeline also guards
  against unsafe paths, system/platform-config locations, and symlinks that
  redirect edits outside the workspace; this closes that gap so the agent host
  no longer silently approves edits the extension would prompt for.
- Resolves symlinks (including not-yet-created ancestors) so a link cannot be
  used to escape the working directory, and treats permission-denied resolution
  as requiring confirmation.
- Makes the approval path async rather than relying on synchronous filesystem
  calls, while keeping the shell-command approver synchronous so its existing
  behavior and tests are unaffected.
- Adds unit tests covering the new path-safety, platform-restriction, and
  symlink-escape checks.

(Commit message generated by Copilot)

* agent host: address review feedback and fix async approval tests

- Treat EACCES like EPERM when resolving symlinks so an execute-only
  directory cannot be used to bypass the working-directory check; permission
  errors now require confirmation rather than silently checking the literal
  path.
- Fix mis-indented JSDoc in claudeCanUseTool.
- Update AgentSideEffects tests to await the now-async tool-approval dispatch
  via a deterministic waitForState helper (re-checks on each state emit)
  instead of depending on a fixed timing delay.

(Commit message generated by Copilot)

* agent host: fix SessionPermissionManager test on Windows CI

- The test built its working directory under `os.tmpdir()`, which on Windows
  CI is an 8.3 short path (`C:\Users\RUNNER~1\...`). `assertPathIsSafe`
  correctly rejects the `~1` segment, so every auto-approval returned
  "needs confirmation" and the suite failed. Base the temp dir on
  `RUNNER_TEMP` (a plain long path) when available so the working directory
  is free of 8.3 short names.

(Commit message generated by Copilot)
2026-06-19 15:49:53 -07:00