Skip to content

Align local & remote agent host sessionType IDs#311301

Draft
roblourens wants to merge 1 commit intomainfrom
roblou/agents/remote-agent-session-routing-fix
Draft

Align local & remote agent host sessionType IDs#311301
roblourens wants to merge 1 commit intomainfrom
roblou/agents/remote-agent-session-routing-fix

Conversation

@roblourens
Copy link
Copy Markdown
Member

Fixes a routing bug in the Agents window where, after switching from a remote-agent-host workspace to a local-agent-host workspace (or vice versa) for the same project path, the next "Send" was sometimes routed to the previous (wrong) host. This happened when both hosts had a coincidentally-identical project path on disk.

Root cause

SessionTypePicker.selectedType mirrors the active session's ISession.sessionType, which was per-provider scoped:

  • Local copilot's logical sessionType was agent-host-copilot
  • Remote copilot's was copilotcli

When the user picked a workspace served by a different provider, the stale id was forwarded to SessionsManagementService.createNewSession(), which forwarded it to the target provider, which threw because the id was unknown to it. The throw was unhandled in the picker's selection emitter, so the active session was never replaced — the picker label updated, giving false confidence — and the user's next request went to the still-active wrong-provider session.

Fix

Local copilot now aliases its logical ISession.sessionType to COPILOT_CLI_SESSION_TYPE (copilotcli), matching what remote already did. Both sides advertise the same logical sessionType for copilot, so the picker's stale-id forwarding no longer mismatches when crossing local↔remote.

Resource URI schemes still differ (agent-host-copilot for local, remote-<auth>-copilot for remote) — that's necessary for routing.

Cleanup along the way

  • Hoisted WELL_KNOWN_AGENT_SESSION_TYPES, wellKnownSessionType, wellKnownAgentProvider, DEFAULT_AGENT_HOST_PROVIDER from the remote provider into BaseAgentHostSessionsProvider.
  • Hoisted _syncSessionTypesFromRootState and logicalSessionTypeForProvider into the base; the base now defines the shape and the subclasses supply only resourceSchemeForProvider, _formatSessionTypeLabel, and an _onSessionTypesUpdated hook.
  • Removed _getSessionTypesFromContributions from LocalAgentHostSessionsProvider — it was a pre-rootState-hydration fallback that could never fire in production (the only registrant of agent-host-* contributions, AgentHostChatContribution, is also driven by IAgentHostService.rootState).

To do before merge

  • Remove diagnostic logService.info calls in NewChatViewPane._createNewSession and SessionsManagementService.createNewSession (and the export on SessionsManagementService that was left over from a deleted test).

(Written by Copilot)

Fixes a routing bug in the Agents window where, after switching from a
remote-agent-host workspace to a local-agent-host workspace (or vice
versa) for the same project path, the next 'Send' was sometimes routed
to the previous (wrong) host. This happened when both hosts had a
coincidentally-identical project path on disk.

Root cause:
SessionTypePicker.selectedType mirrors the active session's
ISession.sessionType (which was per-provider scoped). Local copilot's
logical sessionType was 'agent-host-copilot', while remote copilot's
was 'copilotcli'. When the user picked a workspace served by a
different provider, the stale id was forwarded to
SessionsManagementService.createNewSession(), which forwarded it to the
target provider, which threw because the id was unknown to it. The
throw was unhandled in the picker's selection emitter, so the active
session was never  the picker label updated, giving falsereplaced
 and the user's next request went to the still-activeconfidence
wrong-provider session.

Fix:
Local copilot now aliases its logical ISession.sessionType to
COPILOT_CLI_SESSION_TYPE ('copilotcli'), matching what remote already
did. Both sides advertise the same logical sessionType for copilot, so
the picker's stale-id forwarding no longer mismatches when crossing
remote. Resource URI schemes still differlocal
('agent-host-copilot' for local, 'remote-<auth>-copilot' for remote)
that's necessary for routing.

Cleanup:
- Hoisted WELL_KNOWN_AGENT_SESSION_TYPES, wellKnownSessionType,
  wellKnownAgentProvider, DEFAULT_AGENT_HOST_PROVIDER from the remote
  provider into BaseAgentHostSessionsProvider.
- Hoisted _syncSessionTypesFromRootState and
  logicalSessionTypeForProvider into the base; the base now defines
  the shape and the subclasses supply only resourceSchemeForProvider,
  _formatSessionTypeLabel, and an _onSessionTypesUpdated hook.
- Removed _getSessionTypesFromContributions from
   it was a pre-rootState-hydrationLocalAgentHostSessionsProvider
  fallback that could never fire in production (the only registrant of
  agent-host-* contributions, AgentHostChatContribution, is also
  driven by IAgentHostService.rootState).

Diagnostics:
Diagnostic logs added in NewChatViewPane._createNewSession and
SessionsManagementService.createNewSession will be removed before
merge.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 20, 2026 04:29
@github-actions
Copy link
Copy Markdown
Contributor

Screenshot Changes

Base: 173f07e5 Current: 19492c61

Changed (5)

chat/aiCustomizations/aiCustomizationManagementEditor/McpBrowseMode/Light
Before After
before after
editor/inlineCompletions/other/JumpToHint/Dark
Before After
before after
agentSessionsViewer/CompletedUnread/Dark
Before After
before after
agentSessionsViewer/WithBadge/Dark
Before After
before after
agentSessionsViewer/WithBadge/Light
Before After
before after

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a session routing bug in the Agents window by ensuring Copilot sessions use the same logical ISession.sessionType (copilotcli) across both local and remote agent-host providers, preventing stale picker IDs from being forwarded to the wrong provider after switching workspaces.

Changes:

  • Centralized “well-known” agent provider → logical sessionType aliasing (notably copilotcopilotcli) in BaseAgentHostSessionsProvider.
  • Updated local and remote agent-host session providers to use shared logical-type/resource-scheme mapping logic (resource schemes remain host/connection-specific for routing).
  • Updated local provider tests to reflect the new logical sessionType behavior and removed the pre-hydration contribution fallback behavior.
Show a summary per file
File Description
src/vs/sessions/services/sessions/browser/sessionsManagementService.ts Exports the service class and adds additional create-session logging.
src/vs/sessions/contrib/remoteAgentHost/browser/remoteAgentHostSessionsProvider.ts Adopts shared base logic for logical session types and resource-scheme mapping; rebuilds type→scheme map via base hook.
src/vs/sessions/contrib/chat/browser/newChatViewPane.ts Adds diagnostic logging when creating a new session from picker selection.
src/vs/sessions/contrib/agentHost/test/browser/localAgentHostSessionsProvider.test.ts Updates expectations: local Copilot advertises logical sessionType copilotcli; adjusts hydration-related tests.
src/vs/sessions/contrib/agentHost/browser/localAgentHostSessionsProvider.ts Uses base logical session-type aliasing; separates logical sessionType from routing scheme (agent-host-*).
src/vs/sessions/contrib/agentHost/browser/baseAgentHostSessionsProvider.ts Introduces shared well-known sessionType aliasing and shared rootState→sessionTypes reconciliation logic.

Copilot's findings

Comments suppressed due to low confidence (1)

src/vs/sessions/services/sessions/browser/sessionsManagementService.ts:273

  • These new logService.info calls log repository URIs / resource schemes and will add noisy info-level logging (potentially including local paths / remote authorities). This should be removed before merge (or downgraded to trace with appropriate redaction).
		this.logService.info(`[SessionsManagementService] createNewSession providerId='${providerId}' repositoryUri='${repositoryUri.toString()}' sessionTypeId='${sessionTypeId}'`);

		const session = provider.createNewSession(repositoryUri, sessionTypeId);
		this.logService.info(`[SessionsManagementService] createNewSession created session sessionId='${session.sessionId}' sessionType='${session.sessionType}' resourceScheme='${session.resource.scheme}' providerId='${session.providerId}'`);
  • Files reviewed: 6/6 changed files
  • Comments generated: 2

const ACTIVE_PROVIDER_KEY = 'sessions.activeProviderId';

class SessionsManagementService extends Disposable implements ISessionsManagementService {
export class SessionsManagementService extends Disposable implements ISessionsManagementService {
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

The class was made export but there are no imports of SessionsManagementService in the repo; exposing it increases the module’s public surface area unnecessarily. Please revert this to a non-exported class and keep the service reachable via ISessionsManagementService/registerSingleton only.

This issue also appears on line 270 of the same file.

Suggested change
export class SessionsManagementService extends Disposable implements ISessionsManagementService {
class SessionsManagementService extends Disposable implements ISessionsManagementService {

Copilot uses AI. Check for mistakes.
}

private _createNewSession(selection: IWorkspaceSelection, sessionTypeId: string | undefined): void {
this.logService.info(`[NewChatViewPane] _createNewSession providerId='${selection.providerId}' workspaceUri='${selection.workspace.repositories[0].uri.toString()}' sessionTypeId(from picker)='${sessionTypeId}'`);
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

This new info-level log line includes the selected workspace URI (often a local file path) and is likely diagnostic-only. Please remove it before merge (or downgrade to trace with redaction) to avoid log noise and leaking paths.

Suggested change
this.logService.info(`[NewChatViewPane] _createNewSession providerId='${selection.providerId}' workspaceUri='${selection.workspace.repositories[0].uri.toString()}' sessionTypeId(from picker)='${sessionTypeId}'`);

Copilot uses AI. Check for mistakes.
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