private get _storageUri(): URI {
return isDefaultChatUri(this._chatChannelUri) ? this.sessionUri : this._chatChannelUri;
copilotAgentSession.ts
}
/**
Frontier kind: Code frontier
unlabeled · c_05edd6f91da9
259 tests · 43094 LOC · 242 files · introduces 0 tests · 128 LOC · 2 files
The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.
Introduced files, introduced tests, and structurally relevant concept specialization
In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.
Graph controls are ready.
Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.
Every exact file and test below is linked only from the concept that introduces it.
mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/copilotAgentSession.test|title=CopilotAgentSession permission handling auto-approves read permission for session-state plan files|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/copilotAgentSession.test|title=CopilotAgentSession permission handling resolves native environment through INativeEnvironmentService registration|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/copilotAgentSession.test|title=CopilotAgentSession `/env` falls through to a normal SDK send when not listed|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/copilotAgentSession.test|title=CopilotAgentSession `/security-review` falls through to normal send when runtime command is unavailable|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/copilotAgentSession.test|title=CopilotAgentSession permission handling per-request permissions: Autopilot with Ask When Needed keeps SDK approval mode off|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/copilotAgentSession.test|title=CopilotAgentSession permission handling per-request sandbox: applies the configured policy under default approvals|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/copilotAgentSession.test|title=CopilotAgentSession instructionsCollected telemetry skips SDK-injected messages (source !== "user")|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/copilotAgentSession.test|title=CopilotAgentSession instructionsCollected telemetry skips subagent user messages|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/buffer.test|title=Buffer fromString|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/buffer.test|title=Buffer issue #251527 - VSBuffer#toString preserves BOM character in filenames|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/instantiation/test/common/instantiationService.test|title=Instantiation Service @Param - fixed args|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/instantiation/test/common/instantiationService.test|title=Instantiation Service @Param - simple clase|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/common/commandLineHelpers.test|title=stripRedundantCdPrefix matches backslash extracted dir against backslash native wd on Windows|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/common/commandLineHelpers.test|title=stripRedundantCdPrefix matches mixed path separators (forward-slash extracted vs native fsPath wd)|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/lifecycle.test|title=Lifecycle Action bar has broken accessibility #100273|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/lifecycle.test|title=Lifecycle dispose disposable array|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/common/agentHostSchema.test|title=agentHostSchema createSchema toProtocol emits a JSON-Schema-compatible object|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/common/agentHostSchema.test|title=agentHostSchema platformSessionSchema exposes approval choices in picker order with current copy|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication creates new entry when none exists|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication duplicate IDs with existing entry - fixed version reuses existing|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication duplicate status IDs - buggy version leaks entry|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication duplicate status IDs - fixed version reuses entry from current update|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication mixed unique and duplicate IDs|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/languageStatus/test/common/languageStatusDedupe.test|title=LanguageStatus - Dedicated Entry Deduplication reuses existing entry from previous update|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/toolSearchDeferral.test|title=toolSearchDeferral constants non-deferred client allowlist holds the core VS Code tools, not the search tool|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/toolSearchDeferral.test|title=toolSearchDeferral constants runtime / client tool-search names are distinct and stable|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/charCode.test|title=CharCode has good values|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/path.test|title=Paths (Node Implementation) path|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/uri.test|title=URI File paths containing apostrophes break URI parsing and cannot be opened #276075|occurrence=1mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/uri.test|title=URI URI#file, win-speciale|occurrence=1Every collected test enters the hierarchy at exactly one concept.
No tests are introduced at this concept. Its intent tests are introduced by other concepts.
Every collected source range enters the hierarchy at exactly one concept.
2 files ranked by introduced lines: 128 introduced LOC across 25 ranges. Expand a file to inspect source; the > gutter marks introduced lines.
private get _storageUri(): URI {
return isDefaultChatUri(this._chatChannelUri) ? this.sessionUri : this._chatChannelUri;
copilotAgentSession.ts
}
/**
constructor(
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@ILogService private readonly _logService: ILogService,
@ISessionDataService sessionDataService: ISessionDataService,
@IFileService private readonly _fileService: IFileService,
@INativeEnvironmentService private readonly _environmentService: INativeEnvironmentService,
@IAgentConfigurationService private readonly _configurationService: IAgentConfigurationService,
@IAgentHostStateManager private readonly _stateManager: AgentHostStateManager,
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@ICopilotApiService private readonly _copilotApiService: ICopilotApiService,
) {
super();
this.sessionId = options.rawSessionId;
this.sessionUri = options.sessionUri;
this._slashCommandProvider = new CopilotSlashCommandProvider(() => this._wrapper.session.rpc.commands.list({ includeBuiltins: true, includeSkills: true, includeClientCommands: true }).then(c => c.commands), this._logService);
this._chatChannelUri = options.chatChannelUri;
this._onDidSessionProgress = options.onDidSessionProgress;
this._sessionLauncher = options.sessionLauncher;
this._launchPlan = options.launchPlan;
this._isLaunchTokenStillCurrent = options.isLaunchTokenCurrent ?? (() => true);
this._shellManager = options.shellManager;
this._nonPtyShellTerminals = this._register(this._instantiationService.createInstance(NonPtyShellTerminalStreams, options.sessionUri));
this._workingDirectory = options.workingDirectory;
this._customizationDirectory = options.customizationDirectory;
this._serverToolHost = options.serverToolHost;
this._platform = options.platform ?? process.platform;
this._telemetryReporter = new AgentHostTelemetryReporter(this._telemetryService);
this._repoInfoTelemetry = this._register(this._instantiationService.createInstance(AgentHostRepoInfoTelemetry, this._telemetryReporter));
this._appliedSnapshot = options.clientSnapshot ?? { tools: [], plugins: [], mcpServers: {} };
this._clientToolNames = clientToolNamesFromSnapshot(this._appliedSnapshot);
const model = this._launchPlan.kind === 'create' ? this._launchPlan.model : this._launchPlan.fallback.model;
// Capability decisions use the family-aliased selection so an aliased
// preview model agrees with the launcher's tool-search gating (which
// also aliases before checking); the wire model id is unaffected.
const effectiveModel = applyModelFamilyAlias(model, this._configurationService.getRootValue(copilotCliConfigSchema, CopilotCliConfigKey.ModelCapabilityOverrides));
this._toolSearchActive = this._configurationService.getRootValue(copilotCliConfigSchema, CopilotCliConfigKey.ToolSearchEnabled) === true
&& agentHostModelSupportsToolSearch(effectiveModel?.id)
&& this._clientToolNames.has(CLIENT_TOOL_SEARCH_REFERENCE_NAME);
// contributions (and owner identity) are observed at stamp time.
// Standalone / test construction uses a fresh empty registry, which
// leaves client tool calls unstamped (no owning client).
this._activeClientToolSet = options.activeClientToolSet ?? new ActiveClientToolSet();
this._databaseRef = sessionDataService.openDatabase(this._storageUri);
this._register(toDisposable(() => this._databaseRef.dispose()));
this._sessionDataDir = sessionDataService.getSessionDataDir(this._storageUri);
this._editTracker = this._instantiationService.createInstance(FileEditTracker, this._storageUri.toString(), this._databaseRef.object);
this._mcpCustomizations = this._register(this._instantiationService.createInstance(McpCustomizationController, {
providerId: this.sessionUri.scheme,
sessionId: this.sessionId,
sessionUri: this.sessionUri,
resolveChildId: options.resolveMcpChildId,
emit: action => this._emitAction(action),
}));
this._register(toDisposable(() => this._denyPendingPermissions()));
this._register(toDisposable(() => this._shellManager?.dispose()));
this._register(toDisposable(() => this._cancelPendingUserInputs()));
this._register(toDisposable(() => this._cancelPendingElicitations()));
this._register(toDisposable(() => this._cancelPendingPlanReviews()));
this._register(toDisposable(() => this._drainPendingSteeringFlips()));
this._register(toDisposable(() => this._cancelPendingMcpSamplings()));
this._register(toDisposable(() => this._cancelPendingMcpAuthRequests()));
// When a shell tool associates a terminal with a tool call, fire a
// tool_content_changed event so the UI can connect to the terminal
// while the command is still running.
if (this._shellManager) {
this._register(this._shellManager.onDidAssociateTerminal(({ toolCallId, terminalUri, displayName }) => {
const tracked = this._activeToolCalls.get(toolCallId);
}));
}
this._register(toDisposable(() => this._cancelPendingClientToolCalls()));
copilotAgentSession.ts
this._register(toDisposable(() => {
for (const pending of this._pendingAutoApprovals.values()) {
pending.complete(undefined);
}
}));
}
// ---- AgentSignal helpers ------------------------------------------------
*/
private _drainPendingSteeringFlips(): void {
return;
}
*/
async initializeSession(): Promise<void> {
const wrapper = await this._sessionLauncher.launch(this._launchPlan, this._createRuntimeAdapter());
copilotAgentSession.ts
// The session may have been disposed while we were awaiting the
// launcher. If so, dispose the freshly-created wrapper and
// see them as server-provided. Execution happens in-process via the SDK
// tool handlers built in `_createServerSdkTools`.
}
private _setPromptCacheState(promptCache: { readonly modelId: string; readonly cacheExpiresAt: string } | undefined): void {
private _createRuntimeAdapter(): ICopilotSessionRuntime {
handlePermissionRequest: request => this._handlePermissionRequest(request),
handleExitPlanModeRequest: (request, invocation) => this._handleExitPlanModeRequest(request, invocation),
handleUserInputRequest: (request, invocation) => this._handleUserInputRequest(request, invocation),
handleElicitationRequest: context => this._handleElicitationRequest(context),
handleMcpAuthRequest: request => this._handleMcpAuthRequest(request),
requestUnsandboxedCommandConfirmation: request => this._requestUnsandboxedCommandConfirmation(request),
createClientSdkTools: () => this._createClientSdkTools(),
createServerSdkTools: () => this._createServerSdkTools(),
handlePreToolUse: input => this._handlePreToolUse(input),
handlePostToolUse: input => this._handlePostToolUse(input),
};
}
async resolveMcpAuthentication(params: AuthenticateParams): Promise<boolean> {
private _cancelPendingMcpAuthRequests(): void {
pending.deferred.complete({ kind: 'cancelled' });
}
}
private _cancelPendingMcpAuthRequestsForServer(serverName: string): void {
private _denyPendingPermissions(): void {
this._deletePendingEditContent(toolCallId);
deferred.complete({ kind: 'reject' });
}
this._approvedDuplicablePermissionSignatures.clear();
}
/**
private _cancelPendingUserInputs(): void {
pending.deferred.complete({ response: ChatInputResponseKind.Cancel });
}
}
private _cancelPendingElicitations(): void {
pending.deferred.complete({ response: ChatInputResponseKind.Cancel });
}
}
private _cancelPendingPlanReviews(): void {
pending.deferred.complete({ approved: false });
}
}
private _cancelPendingMcpSamplings(): void {
this._pendingMcpSamplings.clear();
for (const requestId of pending) {
this._wrapper.session.rpc.mcp.cancelSamplingExecution({ requestId }).catch(() => {
// Best-effort: SDK may have already torn down.
});
}
private _cancelPendingClientToolCalls(): void {
this._pendingClientToolCalls.denyAll({ textResultForLlm: 'Tool call cancelled: session ended', resultType: 'failure', error: 'Session ended' });
copilotAgentSession.ts
}
}
constructor(
@IAgentHostTerminalManager private readonly _terminalManager: IAgentHostTerminalManager,
) {
super();
this._register(toDisposable(() => {
for (const stream of this._streams.values()) {
if (stream.created) {
this._terminalManager.disposeTerminal(stream.uri);
}
}
}));
}
/**