agent host: negotiate protocol version + surface incompatibility in UI#314262
Merged
connor4312 merged 1 commit intomainfrom May 4, 2026
Merged
agent host: negotiate protocol version + surface incompatibility in UI#314262connor4312 merged 1 commit intomainfrom
connor4312 merged 1 commit intomainfrom
Conversation
Adopt the AHP protocol's WebSocket-style version negotiation: clients now
send `protocolVersions: string[]` (SemVer) and the server picks one,
returning `UnsupportedProtocolVersion` (-32005) with a typed
`UnsupportedProtocolVersionErrorData { supportedVersions }` payload when
nothing matches. Removes the legacy numeric `PROTOCOL_VERSION` /
`MIN_PROTOCOL_VERSION` / `capabilitiesForVersion` API in favor of the
generated registry under `state/protocol/version/`.
Surface the new error to users in the agents workspace picker:
- `RemoteAgentHostConnectionStatus` is now a discriminated union with a
new `incompatible` variant that carries the host's rejection message,
the versions we offered, and the versions the host advertised.
- The picker entry for an incompatible host renders with `Codicon.warning`,
an "Incompatible" label, and a hover that includes the host's message.
- Clicking the entry opens the management quickpick with a title
("Options for <label> (<address>)") and a sticky `Severity.Warning`
validation banner explaining the version mismatch and pointing at how
to recover. Other failure states are unchanged.
- Auto-reconnect is suppressed only on -32005; network-level failures
keep their existing exponential backoff. Manual Reconnect clears the
state and retries. WebSocket, SSH, and tunnel paths share one helper
(`RemoteAgentHostConnectionStatus.fromConnectError`) so they all
surface incompatibility identically.
Tests updated to the new wire shape; new server-side test covers the
-32005 rejection path, new client-side tests cover the offered SemVer
array and the typed error data, new tests cover the picker label,
hover, and validation banner.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates Agent Host Protocol (AHP) handshake/versioning to use SemVer-based version negotiation (protocolVersions: string[]) and surfaces protocol incompatibility (-32005) as a first-class “incompatible” connection status in the Agents workspace picker UI.
Changes:
- Replaced legacy numeric protocol versioning/capabilities with SemVer constants and per-action/per-notification version gating via the generated registry.
- Added
RemoteAgentHostConnectionStatus.incompatible(...)+ UI affordances (label/hover/warning state) and suppressed auto-reconnect on protocol incompatibility. - Updated client/server tests to the new handshake wire format and added coverage for the -32005 rejection path.
Show a summary per file
| File | Description |
|---|---|
| src/vs/sessions/contrib/remoteAgentHost/test/browser/remoteHostOptions.test.ts | Adds tests for incompatible status label/hover behavior. |
| src/vs/sessions/contrib/remoteAgentHost/test/browser/agentHostFilterService.test.ts | Updates tests for new connection status representation. |
| src/vs/sessions/contrib/remoteAgentHost/browser/tunnelAgentHost.contribution.ts | Preserves incompatible state, suppresses reconnect on -32005, uses helpers for status checks. |
| src/vs/sessions/contrib/remoteAgentHost/browser/remoteHostOptions.ts | Adds “Incompatible” status UI + warning validation banner in the management quick pick. |
| src/vs/sessions/contrib/remoteAgentHost/browser/remoteAgentHostTerminal.contribution.ts | Uses isConnected helper for filtering. |
| src/vs/sessions/contrib/remoteAgentHost/browser/remoteAgentHostSessionsProvider.ts | Updates default observable connection status. |
| src/vs/sessions/contrib/remoteAgentHost/browser/remoteAgentHost.contribution.ts | Preserves incompatible state and surfaces protocol mismatch on SSH reconnect failures. |
| src/vs/sessions/contrib/remoteAgentHost/browser/agentHostFilterService.ts | Maps new status variants into filter status model. |
| src/vs/sessions/contrib/chat/test/browser/sessionWorkspacePicker.test.ts | Updates workspace picker connection-status tests to new status constants. |
| src/vs/sessions/contrib/chat/browser/sessionWorkspacePicker.ts | Treats incompatible as unavailable/disconnected and updates icon/hover behavior. |
| src/vs/platform/agentHost/test/node/protocolServerHandler.test.ts | Updates handshake tests and adds unsupported-version rejection coverage (-32005). |
| src/vs/platform/agentHost/test/node/protocol/toolApprovalRealSdk.integrationTest.ts | Updates initialize handshake to send protocolVersions. |
| src/vs/platform/agentHost/test/node/protocol/testHelpers.ts | Updates handshake helper to send protocolVersions. |
| src/vs/platform/agentHost/test/node/protocol/sessionLifecycle.integrationTest.ts | Updates initialize handshake to send protocolVersions. |
| src/vs/platform/agentHost/test/node/protocol/sessionFeatures.integrationTest.ts | Updates initialize handshake to send protocolVersions. |
| src/vs/platform/agentHost/test/node/protocol/sessionDiffsRealSdk.integrationTest.ts | Updates initialize handshake to send protocolVersions. |
| src/vs/platform/agentHost/test/node/protocol/sessionDiffs.integrationTest.ts | Updates initialize handshake to send protocolVersions. |
| src/vs/platform/agentHost/test/node/protocol/sessionConfig.integrationTest.ts | Updates initialize handshake to send protocolVersions. |
| src/vs/platform/agentHost/test/node/protocol/multiClient.integrationTest.ts | Updates initialize handshake to send protocolVersions. |
| src/vs/platform/agentHost/test/node/protocol/handshake.integrationTest.ts | Updates initialize handshake to send protocolVersions. |
| src/vs/platform/agentHost/test/node/protocol/agentHostServer.integrationTest.ts | Updates initialize handshake to send protocolVersions. |
| src/vs/platform/agentHost/test/electron-browser/remoteAgentHostService.test.ts | Updates status comparisons to helper functions / new constants. |
| src/vs/platform/agentHost/test/electron-browser/remoteAgentHostProtocolClient.test.ts | Adds client-side tests for protocolVersions and typed -32005 error data. |
| src/vs/platform/agentHost/node/protocolServerHandler.ts | Implements offered-version list handshake and emits -32005 with typed payload. |
| src/vs/platform/agentHost/common/state/sessionCapabilities.ts | Removes legacy numeric version/capabilities module. |
| src/vs/platform/agentHost/common/state/protocol/version/registry.ts | Switches protocol versioning to SemVer + version comparison + version-introduced maps. |
| src/vs/platform/agentHost/common/state/protocol/state.ts | Updates protocol types (model _meta, new response part kind). |
| src/vs/platform/agentHost/common/state/protocol/errors.ts | Adds typed UnsupportedProtocolVersionErrorData and maps it in error details. |
| src/vs/platform/agentHost/common/state/protocol/commands.ts | Updates initialize params/result to protocolVersions/SemVer. |
| src/vs/platform/agentHost/common/state/protocol/.ahp-version | Bumps protocol schema revision. |
| src/vs/platform/agentHost/common/remoteAgentHostService.ts | Reworks connection status into a discriminated union with incompatible support. |
| src/vs/platform/agentHost/browser/remoteAgentHostServiceImpl.ts | Suppresses reconnect on incompatibility and surfaces incompatible status to UI. |
| src/vs/platform/agentHost/browser/remoteAgentHostProtocolClient.ts | Updates initialize call to send protocolVersions. |
Copilot's findings
Comments suppressed due to low confidence (3)
src/vs/sessions/contrib/remoteAgentHost/browser/remoteHostOptions.ts:131
- The client-side validation message has an extra leading space after
\n\n("\n\n Ensure..."), which will render oddly in the banner. Also, since{0}is a comma-joined list, “We speak {0}”/“protocol version” reads as singular. Consider removing the stray whitespace and adjusting wording to match the plural/list form (“protocol versions”).
picker.validationMessage = served
? localize('workspacePicker.incompatibleValidationServer', "Incompatible protocol version. We speak {0}, but {1} speaks {2}. Ensure {3} and {1} are both up to date.", offered, provider.label, served, productService.nameShort)
: localize('workspacePicker.incompatibleValidationClient', "Incompatible protocol version. We speak {0}. Error from {1}: {2}\n\n Ensure {3} and {1} are both up to date.", offered, provider.label, status.message, productService.nameShort);
src/vs/platform/agentHost/node/protocolServerHandler.ts:320
- Reconnect hardcodes
client.protocolVersiontoPROTOCOL_VERSIONandReconnectParamsdoesn’t carry a negotiated version. If/when the server supports multiple protocol versions, this can cause the server to replay/send actions that an older reconnecting client doesn’t understand. Consider persisting the negotiated version perclientId(from initialize) for reconnects, or extending the reconnect request to re-negotiate/declareprotocolVersions.
const client: IConnectedClient = {
clientId: params.clientId,
protocolVersion: PROTOCOL_VERSION,
transport,
subscriptions: new Set(),
src/vs/platform/agentHost/browser/remoteAgentHostProtocolClient.ts:150
- The new handshake contract requires clients to use
InitializeResult.protocolVersion(the server-selected version) for the rest of the connection, but the client currently ignoresresult.protocolVersion. Even if today the offered list is a single entry, storing/validating the negotiated version (and using it for any future version-gated behavior) would better match the negotiated-protocol design and prevent subtle mismatches later.
const result = await this._sendRequest('initialize', {
protocolVersions: [PROTOCOL_VERSION],
clientId: this._clientId,
initialSubscriptions: [ROOT_STATE_URI],
});
this._serverSeq = result.serverSeq;
- Files reviewed: 33/33 changed files
- Comments generated: 3
Contributor
Screenshot ChangesBase: Changed (7)Errored (18)Fixtures that failed to render — no screenshot was produced.
|
dmitrivMS
approved these changes
May 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adopt the AHP protocol's WebSocket-style version negotiation: clients now send
protocolVersions: string[](SemVer) and the server picks one, returningUnsupportedProtocolVersion(-32005) with a typedUnsupportedProtocolVersionErrorData { supportedVersions }payload when nothing matches. Removes the legacy numericPROTOCOL_VERSION/MIN_PROTOCOL_VERSION/capabilitiesForVersionAPI in favor of the generated registry understate/protocol/version/.Surface the new error to users in the agents workspace picker:
RemoteAgentHostConnectionStatusis now a discriminated union with a newincompatiblevariant that carries the host's rejection message, the versions we offered, and the versions the host advertised.Codicon.warning, an "Incompatible" label, and a hover that includes the host's message.Severity.Warningvalidation banner explaining the version mismatch and pointing at how to recover. Other failure states are unchanged.RemoteAgentHostConnectionStatus.fromConnectError) so they all surface incompatibility identically.Tests updated to the new wire shape; new server-side test covers the -32005 rejection path, new client-side tests cover the offered SemVer array and the typed error data, new tests cover the picker label, hover, and validation banner.