Refactor workingDirectory, isolationEnabled and worktreeProperties and collapse into an existing single type (#4276)

* Refactor Copilot CLI session handling to utilize workspace information

- Introduced IWorkspaceInfo interface to encapsulate workspace-related data.
- Updated session creation and retrieval methods to accept workspaceInfo instead of individual parameters.
- Refactored tests to align with the new workspaceInfo structure.
- Enhanced session management by ensuring consistent handling of working directories and isolation settings.
- Improved prompt resolution by passing workspaceInfo to relevant methods.

* Updates

* Refactor CopilotCLISessionOptions to remove workingDirectory property and streamline working directory retrieval

* Fixes
This commit is contained in:
Don Jayamanne
2026-03-07 23:33:47 +11:00
committed by GitHub
parent 90402b4400
commit 79d6023696
15 changed files with 255 additions and 178 deletions
@@ -26,6 +26,7 @@ import { IInstantiationService } from '../../../../util/vs/platform/instantiatio
import { ChatSessionStatus } from '../../../../vscodeTypes';
import { stripReminders } from '../common/copilotCLITools';
import { ICustomSessionTitleService } from '../common/customSessionTitleService';
import { emptyWorkspaceInfo, IWorkspaceInfo } from '../../common/workspaceInfo';
import { CopilotCLISessionOptions, ICopilotCLIAgents, ICopilotCLISDK } from './copilotCli';
import { CopilotCLISession, ICopilotCLISession } from './copilotcliSession';
import { ICopilotCLIMCPHandler } from './mcpHandler';
@@ -60,8 +61,8 @@ export interface ICopilotCLISessionService {
renameSession(sessionId: string, title: string): Promise<void>;
// Session wrapper tracking
getSession(sessionId: string, options: { model?: string; workingDirectory?: Uri; isolationEnabled?: boolean; readonly: boolean; agent?: SweCustomAgent }, token: CancellationToken): Promise<IReference<ICopilotCLISession> | undefined>;
createSession(options: { model?: string; workingDirectory?: Uri; isolationEnabled?: boolean; agent?: SweCustomAgent }, token: CancellationToken): Promise<IReference<ICopilotCLISession>>;
getSession(sessionId: string, options: { model?: string; workspaceInfo: IWorkspaceInfo; readonly: boolean; agent?: SweCustomAgent }, token: CancellationToken): Promise<IReference<ICopilotCLISession> | undefined>;
createSession(options: { model?: string; workspaceInfo: IWorkspaceInfo; agent?: SweCustomAgent }, token: CancellationToken): Promise<IReference<ICopilotCLISession>>;
}
export const ICopilotCLISessionService = createServiceIdentifier<ICopilotCLISessionService>('ICopilotCLISessionService');
@@ -202,7 +203,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
}
try {
// Get the full session to access chat messages
const session = await this.getSession(metadata.sessionId, { readonly: true }, token);
const session = await this.getSession(metadata.sessionId, { readonly: true, workspaceInfo: emptyWorkspaceInfo() }, token);
const firstUserMessage = session?.object ? session.object.sdkSession.getEvents().find((msg: SessionEvent) => msg.type === 'user.message')?.data.content : undefined;
session?.dispose();
@@ -260,10 +261,10 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
}
}
public async createSession({ model, workingDirectory, isolationEnabled, agent }: { model?: string; workingDirectory?: Uri; isolationEnabled?: boolean; agent?: SweCustomAgent }, token: CancellationToken): Promise<RefCountedSession> {
public async createSession({ model, workspaceInfo, agent }: { model?: string; workspaceInfo: IWorkspaceInfo; agent?: SweCustomAgent }, token: CancellationToken): Promise<RefCountedSession> {
const mcpServers = await this.mcpHandler.loadMcpConfig();
const copilotUrl = this.configurationService.getConfig(ConfigKey.Shared.DebugOverrideProxyUrl) || undefined;
const options = await this.createSessionsOptions({ model, workingDirectory, isolationEnabled, mcpServers, agent, copilotUrl });
const options = await this.createSessionsOptions({ model, workspaceInfo, mcpServers, agent, copilotUrl });
const sessionManager = await raceCancellationError(this.getSessionManager(), token);
const sdkSession = await sessionManager.createSession(options.toSessionOptions());
if (copilotUrl) {
@@ -284,7 +285,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
return this.createCopilotSession(sdkSession, options, sessionManager);
}
protected async createSessionsOptions(options: { model?: string; isolationEnabled?: boolean; workingDirectory?: Uri; mcpServers?: SessionOptions['mcpServers']; agent: SweCustomAgent | undefined; copilotUrl?: string }, readonly?: boolean): Promise<CopilotCLISessionOptions> {
protected async createSessionsOptions(options: { model?: string; workspaceInfo: IWorkspaceInfo; mcpServers?: SessionOptions['mcpServers']; agent: SweCustomAgent | undefined; copilotUrl?: string }, readonly?: boolean): Promise<CopilotCLISessionOptions> {
const [customAgents, skillLocations] = await Promise.all([
this.agents.getAgents(),
readonly ? Promise.resolve([]) : this.copilotCLISkills.getSkillsLocations(),
@@ -292,7 +293,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
return new CopilotCLISessionOptions({ ...options, customAgents, skillLocations }, this.logService);
}
public async getSession(sessionId: string, { model, workingDirectory, isolationEnabled, readonly, agent }: { model?: string; workingDirectory?: Uri; isolationEnabled?: boolean; readonly: boolean; agent?: SweCustomAgent }, token: CancellationToken): Promise<RefCountedSession | undefined> {
public async getSession(sessionId: string, { model, workspaceInfo, readonly, agent }: { model?: string; workspaceInfo: IWorkspaceInfo; readonly: boolean; agent?: SweCustomAgent }, token: CancellationToken): Promise<RefCountedSession | undefined> {
// https://github.com/microsoft/vscode/issues/276573
const lock = this.sessionMutexForGetSession.get(sessionId) ?? new Mutex();
this.sessionMutexForGetSession.set(sessionId, lock);
@@ -324,7 +325,7 @@ export class CopilotCLISessionService extends Disposable implements ICopilotCLIS
this.mcpHandler.loadMcpConfig(),
]);
const copilotUrl = this.configurationService.getConfig(ConfigKey.Shared.DebugOverrideProxyUrl) || undefined;
const options = await this.createSessionsOptions({ model, workingDirectory, agent, isolationEnabled, mcpServers, copilotUrl }, readonly);
const options = await this.createSessionsOptions({ model, agent, workspaceInfo, mcpServers, copilotUrl }, readonly);
const sdkSession = await sessionManager.getSession({ ...options.toSessionOptions(), sessionId }, !readonly);
if (!sdkSession) {