Skip to content

Let agent host sessions tolerate hosts that differ from the client - #332456

Merged
Osvaldo Ortega (osortega) merged 4 commits into
mainfrom
osortega/agenthost-tolerate-divergent-hosts
Aug 25, 2026
Merged

Let agent host sessions tolerate hosts that differ from the client#332456
Osvaldo Ortega (osortega) merged 4 commits into
mainfrom
osortega/agenthost-tolerate-divergent-hosts

Conversation

@osortega

@osortega Osvaldo Ortega (osortega) commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Three ways a session against a host that is older than, or shaped differently from, the client would fail outright. All three surfaced against a remote host running an older copilotd, but none of the fixes are specific to it — AgentHostSessionHandler serves local, SSH and tunnel sessions too.

1. Customization shape skew

Customizations moved from an enabled boolean to list-shaped enablement in protocol 0.8.0. A host below that version expects the superseded shape and rejects the whole request with invalid params: missing field "enabled", failing createSession and leaving no session at all.

Client-published customizations are now dropped for such a host, degrading to a session without them — which is what that host would have made of them anyway; the alternative is no session.

The gate is applied on both paths that publish an active client. Reconciliation republishes it after creation, so gating only createSession leaves the second path broken.

Worth noting for reviewers: the version registry has exhaustive, compile-enforced maps for actions and notifications, but nothing for field-level shape changes like this one, so the version constant here is hand-maintained.

2. Working directories the host cannot address

A workspace may be the repository itself (https://github.com/owner/repo) while the agent runs against a checkout on the host’s own disk. Sending the remote URI fails createSession with unsupported scheme "https"; expected "file".

Directories the host cannot address are now dropped, falling back to undefined so it chooses its own. The host’s reported defaultDirectory names the scheme it can address, so this adapts per host rather than hardcoding file. Hosts that report no default are left alone.

3. "Couldn’t open session" for a session that does not exist yet

A provider can legitimately address a session id before the host knows it, with createSession bringing it into being. Subscribing first fails with NotFound, which rendered a failure banner that the very next step resolved.

The banner is suppressed for NotFound specifically — a genuine open failure still renders, which a test covers directly so the suppression cannot quietly widen.

Risk

All three are no-ops for a current host with matching schemes: the version gate passes, every directory is addressable, and sessions resolve. The blast radius is wider than the case that motivated them, so the no-op paths are the ones worth checking.

Validation

  • npm run typecheck-client
  • ./scripts/test.sh --glob "**/agentHostChatContribution.test.js" — 328 passing, including 6 new tests covering both sides of each fix (drops and keeps, suppresses and still renders).

Note on the NotFound suppression

The suppression is deliberately broad: it covers every AHP NotFound, not only a session the client minted and expects to create on first send.

This costs a notice, not a capability. A session the host does not know is unreadable either way and is recreated on the next send in both cases, so the only difference is that "Couldn't open session" no longer appears. Cloud sandbox sessions are unaffected entirely, since Mission Control mirrors their history at /events and a dormant environment opens read-only from that rather than reaching this path.

The remaining case — a persisted local/SSH/tunnel session the host has lost — is also short-lived, because _refreshSessions evicts any cached session the host does not list. Narrowing the suppression would need a positive provider-level signal that the client minted the id; not worth the API surface for a missing notice in that window.

Copilot AI balanced review requested due to automatic review settings August 25, 2026 00:08
Three ways a session against a host that is older than, or shaped
differently from, the client would fail outright.

Customizations changed from an `enabled` boolean to list-shaped `enablement`
in protocol 0.8.0. A host below that version expects the superseded shape and
rejects the whole request with `invalid params: missing field 'enabled'`,
which fails `createSession` and leaves no session at all. Client-published
customizations are now dropped for such a host, degrading to a session
without them. The gate is applied on both paths that publish an active
client, since reconciliation republishes it after creation.

A host can also address only certain working directory schemes. A remote
workspace may be the repository itself (`https://github.com/owner/repo`)
while the agent runs against a checkout on its own disk, and sending the
remote URI fails `createSession` with `unsupported scheme 'https'; expected
'file'`. Working directories the host cannot address are now dropped, falling
back to letting it choose its own. The host's reported `defaultDirectory`
names the scheme it can address, so this adapts per host rather than
hardcoding one.

Finally, a session the host has never heard of rendered "Couldn't open
session". A provider can legitimately address a session id before the host
knows it, with `createSession` bringing it into being, so the banner is now
suppressed for `NotFound` specifically. Genuine open failures still render,
which a test covers directly.

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

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

Improves Agent Host compatibility with older or differently shaped hosts.

Changes:

  • Gates customization payloads by protocol version.
  • Filters unsupported working-directory schemes.
  • Suppresses expected pre-creation NotFound errors and adds tests.
Show a summary per file
File Description
agentHostSessionHandler.ts Adds compatibility handling for customizations, directories, and missing sessions.
agentHostChatContribution.test.ts Adds compatibility regression tests.
sessionProtocol.ts Exposes the generic AHP NotFound code.

Review details

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Suppressed comments (1)

src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionHandler.ts:5605

  • computeWorkingDirectories guarantees that index 0 is the primary directory. In a mixed-scheme multi-root workspace, filtering can remove that primary while retaining a later entry, silently promoting the secondary to the host's working directory instead of letting the host choose its default. Preserve the primary-first invariant: if the primary is not addressable, return undefined; only filter secondary entries when the primary remains.
		return addressable.length > 0 ? addressable : undefined;
  • Files reviewed: 3/3 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Remote folders travel as `vscode-agent-host:` wrappers on the client and are
unwrapped by `createSession` before being sent, so comparing the wrapper
scheme against the host's `defaultDirectory` dropped SSH and tunnel working
directories the host addresses perfectly well. Compare the unwrapped scheme
instead, which is what the host actually receives.

Also covers the reconciliation republish path, which had no test even though
an ungated republish is enough for an older host to reject the update.

Both tests were checked against the bugs they describe by reverting each fix
and confirming the matching test fails.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The gate only exists because reachable hosts still speak 0.7.0, and a host on
that version silently loses its client customizations. Nothing in the code
said when it should go, so it would outlive the reason for it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@osortega
Osvaldo Ortega (osortega) marked this pull request as ready for review August 25, 2026 03:43
@osortega
Osvaldo Ortega (osortega) enabled auto-merge (squash) August 25, 2026 03:44
@osortega
Osvaldo Ortega (osortega) merged commit 908ab0d into main Aug 25, 2026
27 checks passed
@osortega
Osvaldo Ortega (osortega) deleted the osortega/agenthost-tolerate-divergent-hosts branch August 25, 2026 06:45
@vs-code-engineering vs-code-engineering Bot added this to the 1.136.0 milestone Aug 25, 2026
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.

3 participants