agentHostChannel.ts ×20

Frontier kind: Code frontier

unlabeled · c_f9605a80879a

3 tests · 7952 LOC · 38 files · introduces 0 tests · 124 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
20 ranges124 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1260 ranges7952 lines · 38 files · Browse complete extent
All tests (intent)
3 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.

Introduced files, introduced tests, and structurally relevant concept specializationagentHostChannel.ts ×1 · 6 introduced LOCagentHostChannel.ts ×1agentHostChannel.ts ×4 · 7 introduced LOCagentHostChannel.ts ×4agentHostChannel.ts ×11 · 44 introduced LOCagentHostChannel.ts ×11agentHostChannel.ts ×4 · 14 introduced LOCagentHostChannel.ts ×4log.ts ×72 · 446 introduced LOClog.ts ×72contextkey.ts ×1 · 2 introduced LOCcontextkey.ts ×1contextkey.ts ×3 · 7 introduced LOCcontextkey.ts ×3contextkey.ts ×1 · 3 introduced LOCcontextkey.ts ×1contextkey.ts ×1 · 2 introduced LOCcontextkey.ts ×1contextkey.ts ×1 · 3 introduced LOCcontextkey.ts ×1contextkey.ts ×1 · 2 introduced LOCcontextkey.ts ×1contextkey.ts ×2 · 3 introduced LOCcontextkey.ts ×2contextkey.ts ×1 · 2 introduced LOCcontextkey.ts ×1contextkey.ts ×2 · 3 introduced LOCcontextkey.ts ×2contextkey.ts ×2 · 3 introduced LOCcontextkey.ts ×2contextkey.ts ×1 · 2 introduced LOCcontextkey.ts ×1contextkey.ts ×1 · 4 introduced LOCcontextkey.ts ×1contextkey.ts ×201 · 796 introduced LOCcontextkey.ts ×201hash.ts ×17 · 74 introduced LOChash.ts ×17resources.ts ×23 · 253 introduced LOCresources.ts ×23network.ts ×20 · 292 introduced LOCnetwork.ts ×20extpath.ts ×17 · 91 introduced LOCextpath.ts ×17strings.ts ×101 · 542 introduced LOCstrings.ts ×101cancellation.ts ×18 · 90 introduced LOCcancellation.ts ×18event.ts ×93 · 864 introduced LOCevent.ts ×93buffer.ts ×42 · 483 introduced LOCbuffer.ts ×42scanner.ts ×13 · 13 introduced LOCscanner.ts ×13scanner.ts ×3 · 3 introduced LOCscanner.ts ×3scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×36 · 181 introduced LOCscanner.ts ×36utils.ts ×3 · 9 introduced LOCutils.ts ×3nls.ts ×1 · 1 introduced LOCnls.ts ×1errorMessage.ts ×6 · 29 introduced LOCerrorMessage.ts ×6linkedList.ts ×13 · 44 introduced LOClinkedList.ts ×13nls.ts ×6 · 13 introduced LOCnls.ts ×6instantiation.ts ×5 · 111 introduced LOCinstantiation.ts ×5lifecycle.ts ×2 · 4 introduced LOClifecycle.ts ×2lifecycle.ts ×4 · 8 introduced LOClifecycle.ts ×4lifecycle.ts ×6 · 16 introduced LOClifecycle.ts ×6lazy.ts ×1 · 2 introduced LOClazy.ts ×1lazy.ts ×3 · 37 introduced LOClazy.ts ×3lifecycle.ts ×1 · 2 introduced LOClifecycle.ts ×1lifecycle.ts ×1 · 2 introduced LOClifecycle.ts ×1uint.ts ×2 · 43 introduced LOCuint.ts ×2lifecycle.ts ×1 · 3 introduced LOClifecycle.ts ×1map.ts ×97 · 3334 introduced LOCmap.ts ×97src/vs/base/common/arrays.ts · 949 LOCcommon/arrays.tssrc/vs/base/common/arraysFind.ts · 226 LOCcommon/arraysFind.tssrc/vs/base/common/assert.ts · 91 LOCcommon/assert.tssrc/vs/base/common/buffer.ts · 499 LOCcommon/buffer.tssrc/vs/base/common/cache.ts · 153 LOCcommon/cache.tssrc/vs/base/common/cancellation.ts · 206 LOCcommon/cancellation.tssrc/vs/base/common/charCode.ts · 450 LOCcommon/charCode.tssrc/vs/base/common/collections.ts · 176 LOCcommon/collections.tssrc/vs/base/common/errorMessage.ts · 113 LOCcommon/errorMessage.tssrc/vs/base/common/errors.ts · 357 LOCcommon/errors.tssrc/vs/base/common/event.ts · 1964 LOCcommon/event.tssrc/vs/base/common/extpath.ts · 433 LOCcommon/extpath.tssrc/vs/base/common/functional.ts · 32 LOCcommon/functional.tssrc/vs/base/common/hash.ts · 324 LOCcommon/hash.tssrc/vs/base/common/iterator.ts · 194 LOCcommon/iterator.tssrc/vs/base/common/lazy.ts · 57 LOCcommon/lazy.tssrc/vs/base/common/lifecycle.ts · 974 LOCcommon/lifecycle.tssrc/vs/base/common/linkedList.ts · 151 LOCcommon/linkedList.tssrc/vs/base/common/map.ts · 1016 LOCcommon/map.tssrc/vs/base/common/marshallingIds.ts · 33 LOCcommon/marshallingIds.tssrc/vs/base/common/network.ts · 440 LOCcommon/network.tssrc/vs/base/common/path.ts · 1589 LOCcommon/path.tssrc/vs/base/common/platform.ts · 281 LOCcommon/platform.tssrc/vs/base/common/process.ts · 76 LOCcommon/process.tssrc/vs/base/common/resources.ts · 444 LOCcommon/resources.tssrc/vs/base/common/stopwatch.ts · 41 LOCcommon/stopwatch.tssrc/vs/base/common/stream.ts · 790 LOCcommon/stream.tssrc/vs/base/common/strings.ts · 1413 LOCcommon/strings.tssrc/vs/base/common/types.ts · 410 LOCcommon/types.tssrc/vs/base/common/uint.ts · 59 LOCcommon/uint.tssrc/vs/base/common/uri.ts · 754 LOCcommon/uri.tssrc/vs/base/test/common/utils.ts · 107 LOCcommon/utils.tssrc/vs/nls.ts · 244 LOCvs/nls.tssrc/vs/platform/contextkey/common/contextkey.ts · 2183 LOCcommon/contextkey.tssrc/vs/platform/contextkey/common/scanner.ts · 384 LOCcommon/scanner.tssrc/vs/platform/instantiation/common/instantiation.ts · 130 LOCcommon/instantiation.tssrc/vs/platform/log/common/log.ts · 926 LOCcommon/log.tssrc/vs/server/node/agentHostChannel.ts · 304 LOCnode/agentHostChannel.tsagentHostChannel.test|title=AgentHostChannel closes upstream when renderer client disconnects|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/server/test/node/agentHostChannel.test|title=AgentHostChannel closes upstream when renderer client disconnects|occurrence=1agentHostChannel.test|ti…agentHostChannel.test|title=AgentHostChannel routes frames between renderer and upstream per context|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/server/test/node/agentHostChannel.test|title=AgentHostChannel routes frames between renderer and upstream per context|occurrence=1agentHostChannel.test|ti…agentHostChannel.test|title=UnavailableAgentHostChannel rejects connect without reporting an unknown IPC channel|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/server/test/node/agentHostChannel.test|title=UnavailableAgentHostChannel rejects connect without reporting an unknown IPC channel|occurrence=1agentHostChannel.test|ti…Focused concept · agentHostChannel.ts ×20 · 124 introduced LOCagentHostChannel.ts ×20

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: 124 introduced LOC across 20 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/server/node/agentHostChannel.ts 124 introduced LOC · 20 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- agentHostChannel.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > // Server-side IPC channel that proxies the agent host protocol from a
7 > // renderer to the agent host process running on the server. For each
8 > // renderer client (identified by IPC context) the channel opens its own
9 > // AHP-over-WebSocket connection upstream and pipes raw JSON frames.
10 > //
11 > // The renderer-side counterpart is `AgentHostIpcChannelTransport` in
12 > // `src/vs/platform/agentHost/browser/`. Together they reuse the existing
13 > // `RemoteAgentHostProtocolClient` over IPC instead of a raw WebSocket.
14 >
15 > import { Emitter, Event } from '../../base/common/event.js';
16 > import { Disposable, IDisposable } from '../../base/common/lifecycle.js';
17 > import { connectionTokenQueryName } from '../../base/common/network.js';
18 > import { IPCServer, IServerChannel } from '../../base/parts/ipc/common/ipc.js';
19 > import { ILogService } from '../../platform/log/common/log.js';
20 > import type * as wsTypes from 'ws';
21 > import type * as netTypes from 'net';
22 >
23 > const agentHostProxyUnavailableMessage = 'Agent host proxy is not available because no upstream agent host endpoint was configured.';
24 >
25 > /**
26 > * Endpoint description for the upstream agent host. One of `port` or
27 > * `socketPath` must be set, matching how `setWebSocketConfig` is called
28 > * for `NodeAgentHostStarter`.
29 > */
30 > export interface IAgentHostUpstreamEndpoint {
31 > readonly host?: string;
32 > readonly port?: string;
33 > readonly socketPath?: string;
34 > readonly connectionToken?: string;
35 > }
36 >
37 > /**
38 > * Lazy-loaded `ws` module. Imported once on first connection so renderers
39 > * that never touch the agent host don't pay the cost.
40 > */
41 > let _wsModule: typeof wsTypes | undefined;
42 async function loadWs(): Promise<typeof wsTypes> {
43 return _wsModule ??= await import('ws');
44 }
46 > let _netModule: typeof netTypes | undefined;
47 async function loadNet(): Promise<typeof netTypes> {
48 return _netModule ??= await import('net');
49 }
51 > /**
52 > * One upstream connection to the agent host, owned by a single renderer
53 > * client. The default implementation wraps a `ws.WebSocket`; tests inject
54 > * a custom factory via {@link AgentHostChannel.upstreamFactory}.
55 > */
56 > export interface IUpstreamConnection extends IDisposable {
57 > readonly onFrame: Event<string>;
58 > readonly onClose: Event<void>;
59 > connect(): Promise<void>;
60 > send(frame: string): void;
61 > }
62 >
63 > export type UpstreamConnectionFactory = (endpoint: IAgentHostUpstreamEndpoint) => IUpstreamConnection;
64 >
65 > /**
66 > * IPC channel registered when the remote server has no agent host upstream.
67 > * Keeping the channel present lets renderers fail explicitly without making
68 > * the IPC layer report `Unknown channel: agentHostProxy`.
69 > */
70 > export class UnavailableAgentHostChannel<TContext> implements IServerChannel<TContext> {
71 >
72 > listen<T>(_ctx: TContext, event: string): Event<T> {
73 switch (event) {
74 case 'frame':
78 throw new Error(`Invalid listen: ${event}`);
79 }
81 > call<T>(_ctx: TContext, command: string): Promise<T> {
82 switch (command) {
83 case 'connect':
89 return Promise.reject(new Error(`Invalid call: ${command}`));
90 }
92 >
93 > /**
94 > * Default upstream factory: opens an AHP WebSocket to the local agent host.
95 > */
96 > const defaultUpstreamFactory = (logService: ILogService): UpstreamConnectionFactory =>
97 (endpoint) => new WebSocketUpstreamConnection(endpoint, logService);
99 > class WebSocketUpstreamConnection extends Disposable implements IUpstreamConnection {
100 > private readonly _onFrame = this._register(new Emitter<string>());
101 > readonly onFrame: Event<string> = this._onFrame.event;
102 >
103 > private readonly _onClose = this._register(new Emitter<void>());
104 > readonly onClose: Event<void> = this._onClose.event;
105 >
106 > private _ws: wsTypes.WebSocket | undefined;
107 > private _connectPromise: Promise<void> | undefined;
108 > private _closeFired = false;
109 >
110 > constructor(
111 private readonly _endpoint: IAgentHostUpstreamEndpoint,
112 private readonly _logService: ILogService,
114 super();
115 }
117 > connect(): Promise<void> {
118 if (this._store.isDisposed) {
119 return Promise.reject(new Error('UpstreamConnection is disposed'));
121 return this._connectPromise ??= this._doConnect();
122 }
124 > private async _doConnect(): Promise<void> {
125 const ws = await loadWs();
126 const url = this._buildUrl();
171 });
172 }
174 > send(frame: string): void {
175 const ws = this._ws;
176 if (!ws || ws.readyState !== ws.OPEN) {
181 ws.send(frame);
182 }
184 > override dispose(): void {
185 this._ws?.close();
186 this._fireClose();
187 super.dispose();
188 }
190 > private _fireClose(): void {
191 if (this._closeFired) {
192 return;
195 this._onClose.fire();
196 }
198 > private _buildUrl(): string {
199 const host = this._endpoint.host ?? 'localhost';
200 const port = this._endpoint.port ?? '0';
205 return url;
206 }
208 > private async _buildWsOptions(): Promise<wsTypes.ClientOptions | undefined> {
209 if (!this._endpoint.socketPath) {
210 return undefined;
217 return { createConnection } satisfies wsTypes.ClientOptions;
218 }
220 >
221 > /**
222 > * IPC channel that proxies the agent host protocol. One channel instance
223 > * serves all renderer clients; per-context state is tracked in `_perCtx`.
224 > */
225 > export class AgentHostChannel<TContext> extends Disposable implements IServerChannel<TContext> {
226 >
227 > private readonly _perCtx = new Map<TContext, IUpstreamConnection>();
228 > private readonly _upstreamFactory: UpstreamConnectionFactory;
229 >
230 > constructor(
231 ipcServer: IPCServer<TContext>,
232 private readonly _endpoint: IAgentHostUpstreamEndpoint,
238 this._register(ipcServer.onDidRemoveConnection(c => this._disposeCtx(c.ctx as unknown as TContext)));
239 }
241 > listen<T>(ctx: TContext, event: string): Event<T> {
242 const conn = this._getOrCreate(ctx);
243 switch (event) {
247 throw new Error(`Invalid listen: ${event}`);
248 }
250 > async call<T>(ctx: TContext, command: string, arg?: unknown): Promise<T> {
251 const conn = this._getOrCreate(ctx);
252 switch (command) {
267 throw new Error(`Invalid call: ${command}`);
268 }
270 > override dispose(): void {
271 for (const conn of this._perCtx.values()) {
272 conn.dispose();
275 super.dispose();
276 }
278 > private _getOrCreate(ctx: TContext): IUpstreamConnection {
279 let conn = this._perCtx.get(ctx);
280 if (!conn) {
294 return conn;
295 }
297 > private _disposeCtx(ctx: TContext): void {
298 const conn = this._perCtx.get(ctx);
299 if (conn) {