Skip to content

Commit 3e1d4d2

Browse files
vritant24Copilot
andcommitted
Preserve MCP migration roots during session start
Use the provisional session's creation roots until the Agent Host session snapshot arrives so first-request migration hints assess the correct scope. Confirmed session state remains authoritative once hydrated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 79e1ad7 commit 3e1d4d2

3 files changed

Lines changed: 36 additions & 2 deletions

File tree

src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostCustomizationService.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -484,14 +484,17 @@ class WorkbenchAgentHostCustomizationService extends AbstractAgentHostCustomizat
484484
return undefined;
485485
}
486486
const sessionState = this._readSessionState(sessionResource);
487+
const workingDirectories = sessionState === undefined
488+
? this._provisionalSessionService.getProvisionalWorkingDirectories(sessionResource)?.map(uri => uri.toString())
489+
: sessionState.workingDirectories;
487490
const rootState = target.connection.rootState.value;
488491
const channel = target.backendSession.toString();
489492
return {
490493
customizations: sessionState?.customizations ?? [],
491494
resourceUris: target.connection.resourceUris,
492495
folderPickerDecision: readSessionFolderPickerDecision(sessionState?._meta),
493-
workingDirectory: sessionState?.workingDirectories?.[0],
494-
workingDirectories: sessionState?.workingDirectories,
496+
workingDirectory: workingDirectories?.[0],
497+
workingDirectories,
495498
rootConfig: rootState && !(rootState instanceof Error) ? rootState.config : undefined,
496499
isBundledMcpServer: (pluginUri, serverName) => this._activeClientService.isBundledMcpServer(pluginUri, serverName),
497500
authenticate: request => target.connection.authenticate(request),

src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostUntitledProvisionalSessionService.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ export interface IAgentHostUntitledProvisionalSessionService {
105105
*/
106106
get(sessionResource: URI): URI | undefined;
107107

108+
/** Working directories used to create the current provisional generation. */
109+
getProvisionalWorkingDirectories(sessionResource: URI): readonly URI[] | undefined;
110+
108111
/**
109112
* Initial config the editor window applies to every new Agent Host session.
110113
* Returns `undefined` in the Agents window, where the sessions provider owns
@@ -373,6 +376,14 @@ export class AgentHostUntitledProvisionalSessionService extends Disposable imple
373376
return this._generationMatchingDesiredState(entry)?.backendSession;
374377
}
375378

379+
getProvisionalWorkingDirectories(sessionResource: URI): readonly URI[] | undefined {
380+
const entry = this._entries.get(sessionResource);
381+
if (!entry || entry.disposed) {
382+
return undefined;
383+
}
384+
return this._generationMatchingDesiredState(entry)?.workingDirectories;
385+
}
386+
376387
private _computeWorkingDirectories(primary: URI | undefined, provider: string): readonly URI[] | undefined {
377388
return computeWorkingDirectories(primary, this._workspaceContextService.getWorkspace().folders.map(folder => folder.uri), this._agentHostService.rootState.value, provider);
378389
}

src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostUntitledProvisionalSessionService.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,26 @@ suite('AgentHostUntitledProvisionalSessionService', () => {
14941494
});
14951495
});
14961496

1497+
test('retains working directories after rebinding a provisional session', async () => {
1498+
const folderA = URI.file('/repoA');
1499+
const folderB = URI.file('/repoB');
1500+
workspaceFolders = [folderA, folderB];
1501+
agentHost.rootStateAgents = [agentInfo('copilot', true)];
1502+
const untitled = untitledChatUri('rebind-roots');
1503+
const real = URI.from({ scheme: 'agent-host-copilot', path: '/real-rebind-roots' });
1504+
1505+
await provisional.getOrCreate(untitled, 'copilot', folderA);
1506+
await provisional.tryRebind(untitled, real, 'copilot');
1507+
1508+
assert.deepStrictEqual({
1509+
untitled: provisional.getProvisionalWorkingDirectories(untitled),
1510+
real: provisional.getProvisionalWorkingDirectories(real)?.map(directory => directory.toString()),
1511+
}, {
1512+
untitled: undefined,
1513+
real: [folderA.toString(), folderB.toString()],
1514+
});
1515+
});
1516+
14971517
test('sends only the primary when the provider does not advertise multiple working directories', async () => {
14981518
const folderA = URI.file('/repoA');
14991519
const folderB = URI.file('/repoB');

0 commit comments

Comments
 (0)