claudeAgent.ts ×7

Frontier kind: Code frontier

unlabeled · c_498874eb969d

192 tests · 53876 LOC · 346 files · introduces 0 tests · 68 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
7 ranges68 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
4916 ranges53876 lines · 346 files · Browse complete extent
All tests (intent)
192 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: 68 introduced LOC across 7 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/claude/claudeAgent.ts 68 introduced LOC · 7 ranges

Open complete file

441
442 constructor(
443 > @ILogService private readonly _logService: ILogService, claudeAgent.ts
444 > @ICopilotApiService private readonly _copilotApiService: ICopilotApiService,
445 > @IClaudeProxyService private readonly _claudeProxyService: IClaudeProxyService,
446 > @IClaudeAgentSdkService private readonly _sdkService: IClaudeAgentSdkService,
447 > @IAgentHostStateManager private readonly _stateManager: AgentHostStateManager,
448 > @IAgentHostGitService private readonly _gitService: IAgentHostGitService,
449 > @IAgentConfigurationService private readonly _configurationService: IAgentConfigurationService,
450 > @IAgentHostGitHubEndpointService private readonly _gitHubEndpointService: IAgentHostGitHubEndpointService,
451 > @IInstantiationService private readonly _instantiationService: IInstantiationService,
452 > @IAgentPluginManager private readonly _pluginManager: IAgentPluginManager,
453 > @IProductService private readonly _productService: IProductService,
454 > @INativeEnvironmentService private readonly _environmentService: INativeEnvironmentService,
455 > ) {
456 > super();
457 > this._metadataStore = _instantiationService.createInstance(ClaudeSessionMetadataStore, this.id);
458 > // CAPI reports each request's billed credits via the proxy (the SDK
459 > // strips `copilot_usage` from its `result`). Route every report to
460 > // the originating session by the session id the proxy decoded from
461 > // the Bearer token, so the session can surface real per-turn credits.
462 > this._register(this._claudeProxyService.onDidReportCredits(e => {
463 this._findSessionBySdkId(e.sessionId)?.recordTurnCredits(e.totalNanoAiu);
464 > })); claudeAgent.ts
465 >
466 > // Phase 19: resolve the transport mode now and re-resolve reactively.
467 > // A flip only affects sessions materialized afterwards; in-flight
468 > // subprocesses keep their original transport. When native, kick off an
469 > // initial model refresh since no GitHub auth (which would otherwise
470 > // trigger it) is required.
471 > this._transportMode = this._resolveTransportMode();
472 > this._register(this._configurationService.onDidRootConfigChange(() => {
473 const next = this._resolveTransportMode();
474 if (next !== this._transportMode) {
492 }
493 }
494 > })); claudeAgent.ts
495 > if (this._transportMode === 'native') {
496 // Only native bootstraps its model list here. Proxy mode fetches
497 // models from CAPI, which needs the GitHub token — so its first
504 queueMicrotask(() => { void this._startModelRefresh(); });
505 }
506 > } claudeAgent.ts
507
508 private _resolveTransportMode(): 'proxy' | 'native' {
509 > // Defaults to proxied when the `claudeUseCopilotProxy` root value is unset. claudeAgent.ts
510 > const useProxy = this._configurationService.getRootValue(agentHostCustomizationConfigSchema, AgentHostConfigKey.ClaudeUseCopilotProxy) ?? true;
511 > return useProxy ? 'proxy' : 'native';
512 > }
513
514 // #region Descriptor + auth
2254
2255 override dispose(): void {
2256 > // Phase 6+ INVARIANT: SDK Query subprocesses (owned by individual claudeAgent.ts
2257 > // ClaudeAgentSession wrappers) MUST die BEFORE the proxy handle
2258 > // is disposed. After proxy disposal the proxy may rebind on a
2259 > // different port and a still-running subprocess would silently
2260 > // lose its endpoint. See `IClaudeProxyHandle` doc in
2261 > // `claudeProxyService.ts`.
2262 > //
2263 > // Step 1: abort every provisional AbortController. These are
2264 > // the same controllers wired into `Options.abortController` at
2265 > // materialize time (sdk.d.ts:982), so any in-flight
2266 > // `await sdk.startup()` will reject and any sequencer-queued
2267 > // `_materializeProvisional` continuation will trip its
2268 > // post-startup or post-customization-write abort gates,
2269 > // disposing the WarmQuery without ever reaching
2270 > // `_sessions.set(...)`. Without this step, dispose during a
2271 > // concurrent first `sendMessage` could orphan a WarmQuery
2272 > // subprocess. (Copilot reviewer: dispose lifecycle.)
2273 > //
2274 > // Step 2: `super.dispose()` synchronously disposes the
2275 > // `_sessions` DisposableMap, firing each session wrapper's
2276 > // `dispose()` (which interrupts/asyncDisposes its WarmQuery).
2277 > //
2278 > // Step 3: only then release the proxy handle, preserving the
2279 > // wrapper-before-proxy ordering invariant. This is locked by
2280 > // test "dispose disposes the proxy handle and is idempotent".
2281 > for (const entry of this._sessions.values()) {
2282 for (const chat of entry.allChatSessions()) {
2283 if (!chat.isPipelineReady) {
2286 }
2287 }
2288 > super.dispose(); claudeAgent.ts
2289 > this._proxyHandle?.dispose();
2290 > this._proxyHandle = undefined;
2291 > this._githubToken = undefined;
2292 > this._models.set([], undefined);
2293 > }
2294 }
2295