copilotAgent.ts ×22

Frontier kind: Code frontier

unlabeled · c_d81fcc8d5b86

127 tests · 51132 LOC · 300 files · introduces 0 tests · 135 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
22 ranges135 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
4830 ranges51132 lines · 300 files · Browse complete extent
All tests (intent)
127 testsBrowse complete intent

Neighbourhood graph

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.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 135 introduced LOC across 22 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/copilot/copilotAgent.ts 135 introduced LOC · 22 ranges

Open complete file

420
421 constructor(
422 > @ILogService private readonly _logService: ILogService, copilotAgent.ts
423 > @IInstantiationService private readonly _instantiationService: IInstantiationService,
424 > @ISessionDataService private readonly _sessionDataService: ISessionDataService,
425 > @IAgentHostGitService private readonly _gitService: IAgentHostGitService,
426 > @IAgentConfigurationService private readonly _configurationService: IAgentConfigurationService,
427 > @IAgentHostStateManager private readonly _stateManager: AgentHostStateManager,
428 > @IAgentHostGitHubEndpointService private readonly _gitHubEndpointService: IAgentHostGitHubEndpointService,
429 > @IAgentHostOTelService private readonly _otelService: IAgentHostOTelService,
430 > @IAgentHostCompletions completions: IAgentHostCompletions,
431 > @IAgentHostCheckpointService private readonly _checkpointService: IAgentHostCheckpointService,
432 > @IAgentHostReviewService private readonly _reviewService: IAgentHostReviewService,
433 > @INativeEnvironmentService private readonly _environmentService: INativeEnvironmentService,
434 > @IByokLmBridgeRegistry private readonly _byokBridgeRegistry: IByokLmBridgeRegistry,
435 > @ITelemetryService private readonly _telemetryService: ITelemetryService,
436 > @ICopilotApiService private readonly _copilotApiService: ICopilotApiService,
437 > @IAgentHostProxyResolver private readonly _proxyResolver: IAgentHostProxyResolver,
438 > ) {
439 > super();
440 > this._plugins = this._register(this._instantiationService.createInstance(PluginController, () => this._ensureClient()));
441 > this._sessionLauncher = this._instantiationService.createInstance(CopilotSessionLauncher);
442 > this._gitHubTelemetryForwarder = this._instantiationService.createInstance(CopilotGitHubTelemetryForwarder, () => this._restrictedTelemetryEnabled);
443 > this._slashCommandProvider = new CopilotSlashCommandProvider(() => this._ensureClient().then(c => c.rpc.commands.list().then(c => c.commands)), this._logService);
444 > this._githubTelemetryRouter = isAgentHostTelemetryService(this._telemetryService)
445 ? new AgentHostGitHubTelemetryRouter(this._telemetryService)
446 : undefined;
447 > this.onDidCustomizationsChange = this._plugins.onDidChange; copilotAgent.ts
448 > // Mirror the sub-agent fan-out signals onto the first-class spawned-
449 > // chat channel so the orchestrator manages sub-agent chats
450 > // through the same membership path as user-driven chats.
451 > this._register(this._onDidSessionProgress.event(signal => this._emitSpawnedChatForSubagentSignal(signal)));
452 > this._register(completions.registerProvider(new CopilotSlashCommandCompletionProvider(this.id,
453 > {
454 > isRubberDuckEnabled: () => this._isRubberDuckEnabled(),
455 > getRuntimeSlashCommands: (sessionId, options) => this._getRuntimeSlashCommands(sessionId, options),
456 > getSessionCustomizations: (sessionId) => this.getSessionCustomizations(AgentSession.uri(this.id, sessionId)),
457 > getSessionConfigState: (sessionId) => this._getSessionConfigState(sessionId),
458 > },
459 > RUNTIME_SLASH_COMMAND_COMPLETION_WAIT_MS,
460 > )));
461 >
462 > // Restart the CLI client when a setting baked into the client/subprocess at
463 > // startup changes, disposing any active sessions. These values are applied in
464 > // `_ensureClient`, so they only take effect on the next client start.
465 > this._register(this._configurationService.onDidRootConfigChange(() => {
466 this._restartClientIfStartupConfigChanged().catch(err =>
467 this._logService.error('[Copilot] Failed to apply root config change', err)
468 );
469 > })); copilotAgent.ts
470 >
471 > // Surface renderer BYOK models in the picker: republish them whenever the
472 > // set of connected renderer bridges, or any renderer's models, change.
473 > // The registry is only populated when `chat.agentHost.byokModels.enabled`
474 > // is on, so this stays a no-op (empty list) while the feature is off.
475 > this._register(this._byokBridgeRegistry.onDidChangeModels(() => {
476 this._logService.info('[Copilot] BYOK bridge changed; refreshing models');
477 this._refreshByokModels();
478 > })); copilotAgent.ts
479 >
480 > // `COPILOT_GH_HOST` is a subprocess env var (applied in `_ensureClient`) the
481 > // CLI reads only at spawn time. When the configured GitHub Enterprise host
482 > // changes - notably the startup race where the workbench pushes
483 > // `githubEnterpriseUri` just after the client's initial spawn - restart the
484 > // client so it comes up pointed at the right host. Driven off the endpoint
485 > // service's `onDidChange` (which fires after its endpoints are recomputed)
486 > // rather than the raw config event, so `getEnterpriseHost()` is current here.
487 > this._register(this._gitHubEndpointService.onDidChange(() => {
488 this._restartClientIfStartupConfigChanged().catch(err =>
489 this._logService.error('[Copilot] Failed to restart client after endpoint change', err)
490 );
491 > })); copilotAgent.ts
492 > }
493
494 /**
514
515 private _isSessionSyncEnabled(): boolean {
516 > return this._configurationService.getRootValue(platformRootSchema, AgentHostSessionSyncEnabledConfigKey) === true; copilotAgent.ts
517 > }
518
519 private _isRubberDuckEnabled(): boolean {
520 > return this._configurationService.getRootValue(copilotCliConfigSchema, CopilotCliConfigKey.RubberDuck) === true; copilotAgent.ts
521 > }
522
523 private _getCopilotSdkLogLevelSetting(): CopilotSdkLogLevelSetting {
524 > return this._configurationService.getRootValue(copilotCliConfigSchema, CopilotCliConfigKey.CopilotSdkLogLevel) ?? 'info'; copilotAgent.ts
525 > }
526
527 private _resolveCopilotSdkLogLevel(configured: CopilotSdkLogLevelSetting): NonNullable<CopilotClientOptions['logLevel']> {
530
531 private _getEnterpriseHost(): string | undefined {
532 > return this._gitHubEndpointService.getEnterpriseHost(); copilotAgent.ts
533 > }
534
535 private _isPreferLongContextEnabled(): boolean {
538
539 private _isSystemProxyEnabled(): boolean {
540 > return this._configurationService.getRootValue(platformRootSchema, AgentHostSystemProxyEnabledConfigKey) !== false; copilotAgent.ts
541 > }
542
543 /**
973
974 private _stopClient(): Promise<void> {
975 > if (this._clientStopping) { copilotAgent.ts
976 return this._clientStopping;
977 }
978 > const stopping = (async () => { copilotAgent.ts
979 > const clientStarting = this._clientStarting;
980 > if (clientStarting) {
981 try {
982 await clientStarting;
986 }
987 }
988 > const client = this._client; copilotAgent.ts
989 > this._client = undefined;
990 > this._clientStarting = undefined;
991 > await client?.stop();
992 > // The runtime subprocess is now dead, so it is safe to release the BYOK
993 > // proxy handle: the next session launch mints a fresh nonce. See the
994 > // ownership invariant on `CopilotSessionLauncher.disposeByokProxyHandle`.
995 > await this._sessionLauncher.disposeByokProxyHandle();
996 > })().finally(() => {
997 > if (this._clientStopping === stopping) {
998 > this._clientStopping = undefined;
999 > }
1000 > });
1001 > this._clientStopping = stopping;
1002 > return stopping;
1003 > }
1004
1005 /**
2816
2817 async shutdown(): Promise<void> {
2818 > this._shutdownPromise ??= (async () => { copilotAgent.ts
2819 > // Invalidate any request that started before teardown. Token
2820 > // identity alone does not change during shutdown, so without this
2821 > // guard a late success could republish after the host stopped.
2822 > this._modelCatalogGeneration++;
2823 > this._modelRefreshSchedule.clear();
2824 > this._scheduledModelRefresh?.deferred.complete();
2825 > this._scheduledModelRefresh = undefined;
2826 > // Cancel any pending model-refresh retry so its timer cannot fire
2827 > // after teardown and resurrect the client.
2828 > this._modelRefreshRetry.clear();
2829 > this._logService.info('[Copilot] Shutting down...');
2830 > const sessionIds = new Set([...this._sessions.keys()]);
2831 > for (const sessionId of sessionIds) {
2832 await this._sessionSequencer.queue(sessionId, () => this._destroyAndDisposeSession(sessionId));
2833 }
2834 > await this._stopClient(); copilotAgent.ts
2835 > })();
2836 > return this._shutdownPromise;
2837 > }
2838
2839 respondToPermissionRequest(requestId: string, approved: boolean): void {
3367
3368 override dispose(): void {
3369 > for (const ac of this._activeClients.values()) { copilotAgent.ts
3370 ac.dispose();
3371 }
3372 > this._activeClients.clear(); copilotAgent.ts
3373 > this.shutdown().catch(err => {
3374 this._logService.warn('[Copilot] Shutdown failed during dispose', err);
3375 > }).finally(() => super.dispose()); copilotAgent.ts
3376 > }
3377 }
3378
3720
3721 constructor(
3722 > private readonly _getClient: () => Promise<CopilotClient>, copilotAgent.ts
3723 > @IAgentPluginManager public readonly pluginManager: IAgentPluginManager,
3724 > @ILogService private readonly _logService: ILogService,
3725 > @IFileService private readonly _fileService: IFileService,
3726 > @IAgentConfigurationService private readonly _configurationService: IAgentConfigurationService,
3727 > @IInstantiationService private readonly _instantiationService: IInstantiationService,
3728 > @INativeEnvironmentService private readonly _environmentService: INativeEnvironmentService,
3729 > ) {
3730 > super();
3731 >
3732 > // Seed from current root config and subscribe to future changes.
3733 > this._applyHostCustomizations();
3734 > this._register(this._configurationService.onDidRootConfigChange(() => {
3735 this._applyHostCustomizations();
3736 > })); copilotAgent.ts
3737 > }
3738
3739 public getConfiguredHostCustomizations(): readonly Customization[] {
3782 */
3783 private _applyHostCustomizations(): void {
3784 > const entries = this._configurationService.getRootValue(agentHostCustomizationConfigSchema, AgentHostConfigKey.Customizations) ?? []; copilotAgent.ts
3785 > const customizations = entries.map(toContainerCustomization);
3786 > if (equals(customizations, this._lastAppliedRefs)) {
3787 > return;
3788 > }
3789 this._lastAppliedRefs = customizations;
3790
3807 }
3808 });
3809 > } copilotAgent.ts
3810
3811 public async resolveConfiguredCustomization(customization: PluginCustomization): Promise<IResolvedCustomization> {