agentService.ts ×10

Frontier kind: Code frontier

unlabeled · c_8950c93e53c7

150 tests · 47310 LOC · 285 files · introduces 0 tests · 259 LOC · 12 files

Introduces — evidence that enters the hierarchy at this concept

Code
26 ranges259 lines · 12 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
4521 ranges47310 lines · 285 files · Browse complete extent
All tests (intent)
150 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.

12 files ranked by introduced lines: 259 introduced LOC across 26 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/agentService.ts 163 introduced LOC · 10 ranges

Open complete file

349
350 constructor(
351 > private readonly _logService: ILogService, agentService.ts
352 > private readonly _fileService: IFileService,
353 > private readonly _sessionDataService: ISessionDataService,
354 > private readonly _productService: IProductService,
355 > private readonly _gitService: IAgentHostGitService,
356 > private readonly _checkpointService: IAgentHostCheckpointService = NULL_CHECKPOINT_SERVICE,
357 > private readonly _rootConfigResource?: URI,
358 > private readonly _telemetryService: ITelemetryService = NullTelemetryService,
359 > _fileMonitorService?: IAgentHostFileMonitorService,
360 > copilotApiService?: ICopilotApiService,
361 > fetchFn?: typeof globalThis.fetch,
362 > providerConfigurations: readonly IAgentCustomizationSettingsRegistration[] = [],
363 > ) {
364 > super();
365 > this._logService.info('AgentService initialized');
366 > this._authService = new AgentHostAuthenticationService(_logService);
367 > this._stateManager = this._register(new AgentHostStateManager(_logService, {
368 > hostBuildInfo: hostBuildInfoFromProduct(this._productService),
369 > changesetStateRetention: {
370 > // The cache calls this lazily after construction. If a future state-manager
371 > // initialization path registers changesets before `_changesets` is assigned,
372 > // keep the entry pinned rather than evicting with incomplete liveness data.
373 > canEvict: changeset => this._changesets ? this._isChangesetEvictable(changeset) : false,
374 > },
375 > }));
376 > this._register(this._stateManager.onDidEmitEnvelope(e => this._onDidAction.fire(e)));
377 > this._register(this._stateManager.onDidEmitEnvelope(e => this._trackPendingSubagentChatFromEnvelope(e)));
378 > this._register(this._stateManager.onDidEmitNotification(e => this._onDidNotification.fire(e)));
379 >
380 > // Build a local instantiation scope so downstream components can
381 > // consume {@link IAgentConfigurationService} (and later {@link ILogService})
382 > // via DI rather than being plumbed plain-class references.
383 > const configurationService = this._register(new AgentConfigurationService(this._stateManager, this._logService, this._rootConfigResource, providerConfigurations));
384 > this._configurationService = configurationService;
385 > const fileMonitorService = _fileMonitorService ?? this._register(new AgentHostFileMonitorService(this._fileService, this._logService));
386 > updateAgentHostTelemetryLevelFromConfig(this._telemetryService, this._stateManager.rootState.config?.values);
387 > const services = new ServiceCollection(
388 > [ILogService, this._logService],
389 > [IAgentService, this],
390 > [IProductService, this._productService],
391 > [IAgentConfigurationService, configurationService],
392 > [IAgentHostStateManager, this._stateManager],
393 > [IAgentHostFileMonitorService, fileMonitorService],
394 > [IAgentHostGitService, this._gitService],
395 > [ITelemetryService, this._telemetryService],
396 > // The outer agent-host process DI registers `ISessionDataService`,
397 > // but this nested strict `InstantiationService` does not inherit it.
398 > // Add it explicitly so `@ISessionDataService` injection into the
399 > // changeset service (and any future sibling) resolves correctly.
400 > [ISessionDataService, this._sessionDataService],
401 > );
402 > const instantiationService = this._register(new InstantiationService(services, /*strict*/ true));
403 > this._gitHubEndpointService = this._register(instantiationService.createInstance(AgentHostGitHubEndpointService));
404 > services.set(IAgentHostGitHubEndpointService, this._gitHubEndpointService);
405 > // A GitHub Enterprise URI change repoints every agent's GitHub resource
406 > // identity to a different authorization server, so the client must obtain a
407 > // token for the new resource. One root-channel `auth/required` covers all
408 > // agents (the URI is host-level config).
409 > this._register(this._gitHubEndpointService.onDidChange(() => {
410 this._stateManager.emitAuthRequired({
411 resource: this._gitHubEndpointService.getCopilotResource().resource,
412 reason: AuthRequiredReason.Required,
413 });
414 > })); agentService.ts
415 > const agentHostOctoKitService = instantiationService.createInstance(AgentHostOctoKitService, fetchFn);
416 > services.set(IAgentHostOctoKitService, agentHostOctoKitService);
417 > const effectiveCopilotApiService = copilotApiService ?? instantiationService.createInstance(CopilotApiService, fetchFn);
418 > services.set(ICopilotApiService, effectiveCopilotApiService);
419 >
420 > this._gitStateService = this._register(instantiationService.createInstance(AgentHostGitStateService));
421 > services.set(IAgentHostGitStateService, this._gitStateService);
422 >
423 > // The checkpoint service is constructed in the outer agent-host
424 > // DI scope and passed via {@link _checkpointService}; register it
425 > // in the inner service collection so the changeset service /
426 > // side effects can resolve it via DI.
427 > services.set(IAgentHostCheckpointService, this._checkpointService);
428 >
429 > // The subscription service manages the lifecycle of changeset subscriptions. The service
430 > // is also consulted by other services when refreshing changesets and changeset operations.
431 > this._changesetSubscriptions = instantiationService.createInstance(AgentHostChangesetSubscriptionService);
432 > services.set(IAgentHostChangesetSubscriptionService, this._changesetSubscriptions);
433 >
434 > // The operation contribution service manages the lifecycle of changeset operations.
435 > this._changesetOperationService = this._register(instantiationService.createInstance(AgentHostChangesetOperationService));
436 > services.set(IAgentHostChangesetOperationService, this._changesetOperationService);
437 >
438 > // The changes review service is responsible for managing review/unreview state for changeset changes.
439 > this._reviewService = this._register(instantiationService.createInstance(AgentHostReviewService));
440 > services.set(IAgentHostReviewService, this._reviewService);
441 >
442 > // The changeset service is responsible for computing, publishing, and persisting changesets.
443 > this._changesets = this._register(instantiationService.createInstance(AgentHostChangesetService));
444 > services.set(IAgentHostChangesetService, this._changesets);
445 >
446 > // The coordinator owns all AgentService-side orchestration of the changeset feature: lifecycle
447 > // hooks, listSessions overlay, subscription URI routing, and the deferred-refresh state machine.
448 > this._changesetCoordinator = this._register(instantiationService.createInstance(AgentHostChangesetCoordinator));
449 > this._register(this._stateManager.onDidChangeSessionActiveTurn(e => this._changesetCoordinator.onSessionTurnActiveChanged(e.session, e.active)));
450 >
451 > // Register the changeset operation contributions.
452 > this._register(this._changesetOperationService.registerContribution(instantiationService.createInstance(AgentHostCommitOperationContribution)));
453 > this._register(this._changesetOperationService.registerContribution(instantiationService.createInstance(AgentHostPullRequestOperationContribution)));
454 > this._register(this._changesetOperationService.registerContribution(instantiationService.createInstance(AgentHostSyncOperationContribution)));
455 > this._register(this._changesetOperationService.registerContribution(instantiationService.createInstance(AgentHostDiscardChangesOperationContribution)));
456 >
457 > this._completions = this._register(instantiationService.createInstance(AgentHostCompletions));
458 > // Built-in generic provider: completes files in the session's workspace folder.
459 > const workspaceFiles = this._register(instantiationService.createInstance(AgentHostWorkspaceFiles));
460 > this._register(this._completions.registerProvider(
461 > new AgentHostFileCompletionProvider(this._stateManager, workspaceFiles),
462 > ));
463 > // Built-in generic provider: offers the `/rename` slash command for any
464 > // session that already has history. Execution is handled server-side in
465 > // AgentSideEffects (redirected to a SessionTitleChanged action).
466 > this._register(this._completions.registerProvider(
467 > new AgentHostRenameCompletionProvider(
468 > session => (this._stateManager.getSessionState(session)?.turns.length ?? 0) > 0,
469 > ),
470 > ));
471 >
472 > // Terminal management — the terminal manager listens to the state
473 > // manager's action stream and dispatches PTY output back through it.
474 > // Created before AgentSideEffects and registered in the local scope so
475 > // AgentSideEffects can consume it via DI (for inline `!command`
476 > // execution).
477 > this._terminalManager = this._register(instantiationService.createInstance(AgentHostTerminalManager));
478 > services.set(IAgentHostTerminalManager, this._terminalManager);
479 >
480 > this._localTurns = new AgentHostLocalTurns(this._sessionDataService, this._logService);
481 >
482 > this._sideEffects = this._register(instantiationService.createInstance(AgentSideEffects, this._stateManager, {
483 > getAgent: session => this._findProviderForSession(session),
484 > sessionDataService: this._sessionDataService,
485 > localTurns: this._localTurns,
486 > agents: this._agents,
487 > copilotApiService: effectiveCopilotApiService,
488 > getGitHubCopilotToken: () => {
489 return this.getAuthToken({
490 resource: this._gitHubEndpointService.getCopilotResource().resource,
492 });
493 },
494 > resolveWorkingDirectoryBeforeSend: params => this._resolveWorkingDirectoryBeforeSend(params), agentService.ts
495 > resolveChatAttachmentTurns: resource => this._resolveChatAttachmentTurns(resource),
496 > onTurnComplete: async session => {
497 // Refresh the git state for the session.
498 const workingDirStr = this._stateManager.getSessionState(session)?.workingDirectories?.[0];
502 void this._gitStateService.attachSessionGitHubPullRequest(session.toString());
503 },
504 > })); agentService.ts
505 >
506 > // Server-side tools, executed in-process against each session's own
507 > // state. The set of groups (and their display) is the single source of
508 > // truth in `serverToolGroups.ts`; the session-management group's runtime
509 > // dependency (this service) is injected via the accessor.
510 > this._serverToolHost = new AgentServerToolHost(this._stateManager, buildServerToolGroups(this._createSessionServerToolAccessor()));
511 > }
512
513 /**
717 */
718 private _createSessionServerToolAccessor(): ISessionServerToolAccessor {
719 > return { agentService.ts
720 > listSessions: () => this.listSessions(),
721 > createSession: config => this.createSession(config),
722 > getModels: () => {
723 const models: IAgentModelInfo[] = [];
724 for (const provider of this._providers.values()) {
727 return models;
728 },
729 > startPrompt: (session, chat, prompt) => this._startSessionPrompt(session, chat, prompt), agentService.ts
730 > createChat: (session, chat, options) => this.createChat(session, chat, (options?.title !== undefined || options?.model !== undefined)
731 ? { ...(options.title !== undefined ? { title: options.title } : {}), ...(options.model !== undefined ? { model: { id: options.model.id } } : {}) }
732 : undefined),
733 > deleteSession: session => this.disposeSession(session), agentService.ts
734 > getChatContext: (session, chatId) => this._getChatContext(session, chatId),
735 > // Reads the `create_session` spawn depth from a session's `_meta` (0 when absent).
736 > getSessionSpawnDepth: session => readSessionSpawnDepth(this._stateManager.getSessionSummary(session.toString())?._meta),
737 > // Stamps a session's `create_session` spawn depth into its `_meta` (merging existing keys).
738 > setSessionSpawnDepth: (session, depth) => this._stateManager.dispatchServerAction(session.toString(), {
739 type: ActionType.SessionMetaChanged,
740 _meta: withSessionSpawnDepth(this._stateManager.getSessionSummary(session.toString())?._meta, depth),
741 }),
742 > }; agentService.ts
743 > }
744
745 /**
3834
3835 override dispose(): void {
3836 > for (const provider of this._providers.values()) { agentService.ts
3837 provider.dispose();
3838 }
3839 > this._providers.clear(); agentService.ts
3840 > super.dispose();
3841 > }
3842 }
3843
src/vs/platform/agentHost/node/agentHostPullRequestOperationProvider.ts 17 introduced LOC · 1 range

Open complete file

26
27 registerHandlers(registry: IChangesetOperationRegistry): IDisposable {
28 > this._registry = registry; agentHostPullRequestOperationProvider.ts
29 > const store = new DisposableStore();
30 > const getSessionState = (sessionKey: string) => this._stateManager.getSessionState(sessionKey);
31 > const onCreated = (event: PullRequestCreatedEvent) => this._onPullRequestCreated(event);
32 > const createPrHandler = this._instantiationService.createInstance(AgentHostPullRequestOperationHandler, false, undefined, getSessionState, onCreated);
33 > const createDraftPrHandler = this._instantiationService.createInstance(AgentHostPullRequestOperationHandler, true, undefined, getSessionState, onCreated);
34 > const createAutoMergePrHandler = this._instantiationService.createInstance(AgentHostPullRequestOperationHandler, false, 'MERGE', getSessionState, onCreated);
35 > const createAutoSquashPrHandler = this._instantiationService.createInstance(AgentHostPullRequestOperationHandler, false, 'SQUASH', getSessionState, onCreated);
36 > const createAutoRebasePrHandler = this._instantiationService.createInstance(AgentHostPullRequestOperationHandler, false, 'REBASE', getSessionState, onCreated);
37 > store.add(registry.registerChangesetOperationHandler(AgentHostPullRequestOperationHandler.OPERATION_CREATE_PR, createPrHandler));
38 > store.add(registry.registerChangesetOperationHandler(AgentHostPullRequestOperationHandler.OPERATION_CREATE_DRAFT_PR, createDraftPrHandler));
39 > store.add(registry.registerChangesetOperationHandler(AgentHostPullRequestOperationHandler.OPERATION_CREATE_PR_AUTO_MERGE, createAutoMergePrHandler));
40 > store.add(registry.registerChangesetOperationHandler(AgentHostPullRequestOperationHandler.OPERATION_CREATE_PR_AUTO_SQUASH, createAutoSquashPrHandler));
41 > store.add(registry.registerChangesetOperationHandler(AgentHostPullRequestOperationHandler.OPERATION_CREATE_PR_AUTO_REBASE, createAutoRebasePrHandler));
42 > store.add({ dispose: () => { this._registry = undefined; } });
43 > return store;
44 > }
45
46 getOperations({ sessionKey, gitState, gitHubState }: IChangesetOperationContext): ChangesetOperation[] | undefined {
src/vs/platform/agentHost/node/agentHostReviewService.ts 14 introduced LOC · 2 ranges

Open complete file

43
44 constructor(
45 > @IAgentHostStateManager private readonly _stateManager: AgentHostStateManager, agentHostReviewService.ts
46 > @IAgentHostGitService private readonly _gitService: IAgentHostGitService,
47 > @ISessionDataService private readonly _sessionDataService: ISessionDataService,
48 > @ILogService private readonly _logService: ILogService,
49 > ) {
50 > super();
51 >
52 > // When a session's data directory is about to be deleted, delete the
53 > // reviewed ref we created for it. The working directory needed to
54 > // resolve the repository root is supplied by the event (resolved from
55 > // live session state) so we don't persist our own copy.
56 > this._register(this._sessionDataService.onWillDeleteSessionData(e => {
57 e.waitUntil(this.disposeSessionData(e.session.toString()));
59 > }
60
61 async setReviewState(channel: ProtocolURI, resources: readonly ProtocolURI[], reviewed: boolean): Promise<void> {
src/vs/platform/agentHost/node/agentHostChangesetService.ts 13 introduced LOC · 1 range

Open complete file

158
159 constructor(
160 > @IAgentHostStateManager private readonly _stateManager: AgentHostStateManager, agentHostChangesetService.ts
161 > @ILogService private readonly _logService: ILogService,
162 > @ISessionDataService private readonly _sessionDataService: ISessionDataService,
163 > @IAgentHostGitService private readonly _gitService: IAgentHostGitService,
164 > @IAgentHostCheckpointService private readonly _checkpointService: IAgentHostCheckpointService,
165 > @IAgentConfigurationService private readonly _configurationService: IAgentConfigurationService,
166 > @IAgentHostChangesetOperationService private readonly _changesetOperationService: IAgentHostChangesetOperationService,
167 > @IAgentHostChangesetSubscriptionService private readonly _changesetSubscriptions: IAgentHostChangesetSubscriptionService,
168 > @IAgentHostReviewService private readonly _reviewService: IAgentHostReviewService,
169 > ) {
170 > super();
171 > this._diffComputeService = this._register(new NodeWorkerDiffComputeService(this._logService));
172 > }
173
174 /**
src/vs/platform/agentHost/node/agentHostDiscardChangesOperationProvider.ts 12 introduced LOC · 2 ranges

Open complete file

16
17 constructor(
18 > @IAgentHostStateManager private readonly _stateManager: AgentHostStateManager, agentHostDiscardChangesOperationProvider.ts
19 > @IInstantiationService private readonly _instantiationService: IInstantiationService,
20 > ) {
21 > super();
22 > }
23
24 registerHandlers(registry: IChangesetOperationRegistry): IDisposable {
25 > const store = new DisposableStore(); agentHostDiscardChangesOperationProvider.ts
26 > const getSessionState = (sessionKey: string) => this._stateManager.getSessionState(sessionKey);
27 > const handler = this._instantiationService.createInstance(AgentHostDiscardChangesOperationHandler, getSessionState);
28 > store.add(registry.registerChangesetOperationHandler(AgentHostDiscardChangesOperationHandler.OPERATION_DISCARD_CHANGES, handler));
29 >
30 > return store;
31 > }
32
33 getOperations({ changesetKind, gitState }: IChangesetOperationContext): ChangesetOperation[] {
src/vs/platform/agentHost/node/diffComputeService.ts 9 introduced LOC · 4 ranges

Open complete file

25
26 constructor(
27 > @ILogService private readonly _logService: ILogService, diffComputeService.ts
28 > ) {
29 > super();
30 > }
31
32 async computeDiffCounts(original: string, modified: string, timeoutMs: number = DEFAULT_DIFF_TIMEOUT_MS): Promise<IDiffCountResult> {
82
83 override dispose(): void {
84 > if (this._worker) { diffComputeService.ts
85 this._worker.terminate();
86 this._worker = undefined;
87 }
88 > for (const [, handler] of this._pending) { diffComputeService.ts
89 handler.reject(new Error('DiffComputeService disposed'));
90 }
91 > this._pending.clear(); diffComputeService.ts
92 > super.dispose();
93 > }
94 }
src/vs/platform/agentHost/node/agentHostCommitOperationProvider.ts 8 introduced LOC · 1 range

Open complete file

24
25 registerHandlers(registry: IChangesetOperationRegistry): IDisposable {
26 > this._registry = registry; agentHostCommitOperationProvider.ts
27 > const store = new DisposableStore();
28 > const getSessionState = (sessionKey: string) => this._stateManager.getSessionState(sessionKey);
29 > const handler = this._instantiationService.createInstance(AgentHostCommitOperationHandler, getSessionState, (sessionKey: string) => this._onCommitted(sessionKey));
30 > store.add(registry.registerChangesetOperationHandler(AgentHostCommitOperationHandler.OPERATION_COMMIT, handler));
31 > store.add({ dispose: () => { this._registry = undefined; } });
32 > return store;
33 > }
34
35 getOperations({ changesetKind, gitHubState, gitState }: IChangesetOperationContext): ChangesetOperation[] {
src/vs/platform/agentHost/node/agentHostSyncOperationProvider.ts 8 introduced LOC · 1 range

Open complete file

24
25 registerHandlers(registry: IChangesetOperationRegistry): IDisposable {
26 > this._registry = registry; agentHostSyncOperationProvider.ts
27 > const store = new DisposableStore();
28 > const getSessionState = (sessionKey: string) => this._stateManager.getSessionState(sessionKey);
29 > const handler = this._instantiationService.createInstance(AgentHostSyncOperationHandler, getSessionState, (sessionKey: string) => this._onSynced(sessionKey));
30 > store.add(registry.registerChangesetOperationHandler(AgentHostSyncOperationHandler.OPERATION_SYNC, handler));
31 > store.add({ dispose: () => { this._registry = undefined; } });
32 > return store;
33 > }
34
35 getOperations({ sessionKey, gitState }: IChangesetOperationContext): ChangesetOperation[] | undefined {
src/vs/platform/agentHost/common/state/sessionState.ts 7 introduced LOC · 1 range

Open complete file

1345 */
1346 export function hostBuildInfoFromProduct(productService: IProductService): IHostBuildInfo {
1347 > return { sessionState.ts
1348 > version: productService.version,
1349 > commit: productService.commit,
1350 > date: productService.date,
1351 > quality: productService.quality,
1352 > };
1353 > }
1354
1355 /**
src/vs/platform/agentHost/node/agentHostSyncOperationHandler.ts 5 introduced LOC · 1 range

Open complete file

20
21 constructor(
22 > private readonly _getSessionState: (sessionKey: string) => SessionState | undefined, agentHostSyncOperationHandler.ts
23 > private readonly _onSynced: (sessionKey: string) => Promise<void>,
24 > @IAgentHostGitService private readonly _gitService: IAgentHostGitService,
25 > @ILogService private readonly _logService: ILogService,
26 > ) { }
27
28 async invoke(params: InvokeChangesetOperationParams, token: CancellationToken): Promise<InvokeChangesetOperationResult> {
src/vs/platform/agentHost/node/agentHostAuthenticationService.ts 2 introduced LOC · 1 range

Open complete file

18
19 constructor(
20 > private readonly _logService: ILogService, agentHostAuthenticationService.ts
21 > ) { }
22
23 async authenticate(params: AuthenticateParams, providers: Iterable<IAgent>): Promise<AuthenticateResult> {
src/vs/platform/agentHost/common/agentHostSchema.ts 1 introduced LOC · 1 range

Open complete file

589 return TelemetryLevel.ERROR;
590 case TelemetryConfiguration.ON:
591 > return TelemetryLevel.USAGE; agentHostSchema.ts
592 default:
593 return undefined;