From 7a7d6adee8b2e8df59752c4e9856db72cabd2def Mon Sep 17 00:00:00 2001 From: Vijay Upadya <41652029+vijayupadya@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:41:36 -0700 Subject: [PATCH] Feedback update --- .../browser/baseAgentHostSessionsProvider.ts | 20 ----------------- .../browser/localAgentHostSessionsProvider.ts | 22 +++++++++++++++++++ .../browser/sessionsManagementService.test.ts | 20 +++++++++++++++++ 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/vs/sessions/contrib/providers/agentHost/browser/baseAgentHostSessionsProvider.ts b/src/vs/sessions/contrib/providers/agentHost/browser/baseAgentHostSessionsProvider.ts index 8213e43335c..a8e87e89658 100644 --- a/src/vs/sessions/contrib/providers/agentHost/browser/baseAgentHostSessionsProvider.ts +++ b/src/vs/sessions/contrib/providers/agentHost/browser/baseAgentHostSessionsProvider.ts @@ -40,8 +40,6 @@ import { IWorkspaceTrustManagementService } from '../../../../../platform/worksp import { AgentHostDownloadProgress } from '../../../../../workbench/contrib/chat/browser/agentSessions/agentHost/agentHostDownloadProgress.js'; import { IAgentCustomizationScope, IAgentHostActiveClientService } from '../../../../../workbench/contrib/chat/browser/agentSessions/agentHost/agentHostActiveClientService.js'; import { IChatWidgetService } from '../../../../../workbench/contrib/chat/browser/chat.js'; -import { getCopilotCliSessionRawId, migratedCopilotCliResource } from '../../../../../workbench/contrib/chat/browser/copilotCliEventsUri.js'; -import { adoptLegacyCopilotCliResource } from '../../../../../workbench/contrib/chat/browser/agentSessions/agentHost/agentHostLegacyMigration.js'; import { ChatMode } from '../../../../../workbench/contrib/chat/common/chatModes.js'; import { IChatSendRequestOptions, IChatService, type IChatModelReference } from '../../../../../workbench/contrib/chat/common/chatService/chatService.js'; import { IChatSessionFileChange, IChatSessionFileChange2, IChatSessionsService } from '../../../../../workbench/contrib/chat/common/chatSessionsService.js'; @@ -5076,24 +5074,6 @@ export abstract class BaseAgentHostSessionsProvider extends Disposable implement this._refreshSessions(); } - /** - * Redirects a legacy extension-host Copilot CLI resource to its agent-host - * twin, adopting it on the way. - * - * Subscribing to the twin is what performs adoption: the host restores the - * session, which runs its own provenance and working-directory checks. A - * session that is not ours to adopt fails that subscribe, and the caller - * falls back to the legacy resource — the same outcome as before, so an - * external session is never worse off than it is today. - */ - async resolveSessionResource(resource: URI): Promise { - const rawId = getCopilotCliSessionRawId(migratedCopilotCliResource(resource)); - if (rawId && this._sessionCache.has(rawId)) { - return migratedCopilotCliResource(resource); // already adopted; no round-trip - } - return adoptLegacyCopilotCliResource(this.connection, resource, this._logService); - } - protected async _refreshSessions(announceExistingAsAdded = false): Promise { const connection = this.connection; if (!connection) { diff --git a/src/vs/sessions/contrib/providers/agentHost/browser/localAgentHostSessionsProvider.ts b/src/vs/sessions/contrib/providers/agentHost/browser/localAgentHostSessionsProvider.ts index 268938524a7..83deb7549c5 100644 --- a/src/vs/sessions/contrib/providers/agentHost/browser/localAgentHostSessionsProvider.ts +++ b/src/vs/sessions/contrib/providers/agentHost/browser/localAgentHostSessionsProvider.ts @@ -28,6 +28,8 @@ import { providerAutomationStorageKey } from '../../../automations/common/automa import { ISessionsProviderAutomations } from '../../../../services/sessions/common/sessionsProvider.js'; import { IAgentHostActiveClientService } from '../../../../../workbench/contrib/chat/browser/agentSessions/agentHost/agentHostActiveClientService.js'; import { IChatWidgetService } from '../../../../../workbench/contrib/chat/browser/chat.js'; +import { getCopilotCliSessionRawId, migratedCopilotCliResource } from '../../../../../workbench/contrib/chat/browser/copilotCliEventsUri.js'; +import { adoptLegacyCopilotCliResource } from '../../../../../workbench/contrib/chat/browser/agentSessions/agentHost/agentHostLegacyMigration.js'; import { IChatService } from '../../../../../workbench/contrib/chat/common/chatService/chatService.js'; import { IChatSessionsService } from '../../../../../workbench/contrib/chat/common/chatSessionsService.js'; import { ILanguageModelsService } from '../../../../../workbench/contrib/chat/common/languageModels.js'; @@ -76,6 +78,26 @@ export class LocalAgentHostSessionsProvider extends BaseAgentHostSessionsProvide return -1; } + /** + * Redirects a legacy extension-host Copilot CLI resource to its agent-host + * twin, adopting it on the way. + * + * Subscribing to the twin is what performs adoption: the host restores the + * session, which runs its own provenance and working-directory checks. A + * session that is not ours to adopt fails that subscribe, and the caller falls + * back to the legacy resource, so an external session is never worse off. + * + * Local-only by definition: `copilotcli:` and `agent-host-copilotcli:` name + * sessions on this machine, so a remote host must never claim or probe them. + */ + async resolveSessionResource(resource: URI): Promise { + const rawId = getCopilotCliSessionRawId(migratedCopilotCliResource(resource)); + if (rawId && this._sessionCache.has(rawId)) { + return migratedCopilotCliResource(resource); // already adopted; no round-trip + } + return adoptLegacyCopilotCliResource(this.connection, resource, this._logService); + } + constructor( @IAgentHostService private readonly _agentHostService: IAgentHostService, @IChatSessionsService chatSessionsService: IChatSessionsService, diff --git a/src/vs/sessions/services/sessions/test/browser/sessionsManagementService.test.ts b/src/vs/sessions/services/sessions/test/browser/sessionsManagementService.test.ts index 8df8f9e9976..0659d0b7451 100644 --- a/src/vs/sessions/services/sessions/test/browser/sessionsManagementService.test.ts +++ b/src/vs/sessions/services/sessions/test/browser/sessionsManagementService.test.ts @@ -3247,6 +3247,26 @@ suite('SessionsManagementService', () => { const resolved = await service.resolveSessionResource(native); assert.deepStrictEqual({ resolved: resolved.toString(), seen }, { resolved: native.toString(), seen: [native.toString()] }); }); + + test('a provider that declines does not stop a later provider from claiming', async () => { + const session = legacyCliSession(); + const declining = new class extends TestSessionsProvider { + constructor() { super(session); } + override readonly id = 'declining'; + override getSessions(): ISession[] { return [session]; } + override resolveSessionResource(): Promise { return Promise.resolve(undefined); } + }; + const claiming = new class extends TestSessionsProvider { + constructor() { super(session); } + override readonly id = LOCAL_AGENT_HOST_PROVIDER_ID; + override readonly order = 1; + override getSessions(): ISession[] { return [session]; } + override resolveSessionResource(): Promise { return Promise.resolve(twinResource); } + }; + const service = createSessionsManagementService(session, disposables, [declining, claiming]).service; + + assert.strictEqual((await service.resolveSessionResource(legacyResource)).toString(), twinResource.toString()); + }); }); function serviceWithSessions(sessions: readonly ISession[]): ISessionsManagementService {