byokLmBridgeRegistry.ts ×13

Frontier kind: Code frontier

unlabeled · c_78a43f2de530

441 tests · 4517 LOC · 23 files · introduces 0 tests · 114 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
13 ranges114 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
612 ranges4517 lines · 23 files · Browse complete extent
All tests (intent)
441 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: 114 introduced LOC across 13 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/byokLmBridgeRegistry.ts 114 introduced LOC · 13 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- byokLmBridgeRegistry.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 > import { Disposable, DisposableStore, IDisposable, toDisposable } from '../../../base/common/lifecycle.js';
7 > import { createDecorator } from '../../instantiation/common/instantiation.js';
8 > import { IByokLmBridgeConnection, IByokLmModelInfo } from '../common/agentHostByokLm.js';
9 >
10 > export const IByokLmBridgeRegistry = createDecorator<IByokLmBridgeRegistry>('byokLmBridgeRegistry');
11 >
12 > /**
13 > * Node-side registry of renderer {@link IByokLmBridgeConnection}s keyed by
14 > * client id. Populated by the agent host's connection lifecycle (one entry per
15 > * connected renderer) and consumed by {@link IByokLmProxyService} (inference
16 > * routing) and {@link CopilotAgent} (model catalogue).
17 > *
18 > * **Single serving window, multiple connections.** BYOK is serviced by the
19 > * renderer LM API, whose BYOK models are a property of the user's installed
20 > * extensions, not of a particular window — so every window that registers the
21 > * handler exposes the same set. Both the main workbench and the dedicated Agents
22 > * app register it (each runs a full extension host whose LM API holds the same
23 > * BYOK models), so either can serve. A connection that connects without binding
24 > * the handler never pushes a snapshot and is treated as non-serving. The registry
25 > * therefore does NOT aggregate per-window model sets; it surfaces the models from
26 > * any one *serving* window (preferring one that actually has models) and routes
27 > * inference there, automatically excluding non-serving windows.
28 > *
29 > * **Push, not pull.** Each connection pushes its current model snapshot over
30 > * {@link IByokLmBridgeConnection.onDidChangeModels} (on subscribe and on every
31 > * change); the registry subscribes on {@link register}, caches each snapshot, and
32 > * fires {@link onDidChangeModels} when the serving model set changes. A connection
33 > * becomes "serving" once it pushes its first snapshot (even an empty one).
34 > */
35 > export interface IByokLmBridgeRegistry {
36 > readonly _serviceBrand: undefined;
37 >
38 > /** Register a renderer connection. Disposing the result removes it. */
39 > register(clientId: string, connection: IByokLmBridgeConnection): IDisposable;
40 >
41 > /**
42 > * The serving window's BYOK models, read synchronously from the cache (no
43 > * enumeration). Use this for fast reads driven by {@link onDidChangeModels}.
44 > */
45 > getModels(): readonly IByokLmModelInfo[];
46 >
47 > /**
48 > * A connection that can serve BYOK inference, or `undefined` when none can.
49 > * All serving windows expose the same models, so any one is a valid target.
50 > */
51 > getServingConnection(): IByokLmBridgeConnection | undefined;
52 >
53 > /**
54 > * Subscribe to changes in the set of registered connections (a renderer
55 > * connecting or disconnecting) or in the serving window's pushed models, so
56 > * consumers can re-read {@link getModels}. Disposing the result removes the
57 > * listener.
58 > */
59 > onDidChangeModels(listener: () => void): IDisposable;
60 > }
61 >
62 > /**
63 > * Per-connection registry entry. `models` is `undefined` until the connection
64 > * pushes its first snapshot; a connection with defined `models` is "serving"
65 > * (it pushed, even an empty list). Non-serving windows (those that did not
66 > * register the BYOK handler and therefore never push) keep `models === undefined`.
67 > */
68 > interface IConnectionEntry {
69 > readonly connection: IByokLmBridgeConnection;
70 > models: readonly IByokLmModelInfo[] | undefined;
71 > readonly store: DisposableStore;
72 > }
73 >
74 > export class ByokLmBridgeRegistry implements IByokLmBridgeRegistry {
75
76 declare readonly _serviceBrand: undefined;
78 private readonly _entries = new Map<string, IConnectionEntry>();
79 private readonly _changeListeners = new Set<() => void>();
81 > onDidChangeModels(listener: () => void): IDisposable {
82 this._changeListeners.add(listener);
83 return toDisposable(() => {
85 });
86 }
88 > private _notifyChanged(): void {
89 // Snapshot first: a listener may unsubscribe (mutating the set) while it
90 // is being notified.
93 }
94 }
96 > register(clientId: string, connection: IByokLmBridgeConnection): IDisposable {
97 // Replace any prior entry for the same client id (e.g. a reconnect).
98 this._entries.get(clientId)?.store.dispose();
125 });
126 }
128 > getModels(): readonly IByokLmModelInfo[] {
129 return this._servingEntry()?.models ?? [];
130 }
132 > getServingConnection(): IByokLmBridgeConnection | undefined {
133 return this._servingEntry()?.connection;
134 }
136 > /**
137 > * A serving connection (`models` defined), preferring one whose model set is
138 > * non-empty. All serving windows expose the same models, so any populated one
139 > * is equivalent; the preference matters when a still-starting window pushes an
140 > * empty list first — it must not shadow a peer that already has them. Falls
141 > * back to a serving-but-empty window; non-serving windows are skipped.
142 > */
143 > private _servingEntry(): IConnectionEntry | undefined {
144 let emptyFallback: IConnectionEntry | undefined;
145 for (const entry of this._entries.values()) {
154 return emptyFallback;
155 }
157 >
158 > /** Shallow structural comparison of two model lists (order-sensitive). */
159 function modelsEqual(a: readonly IByokLmModelInfo[], b: readonly IByokLmModelInfo[]): boolean {
160 if (a.length !== b.length) {
166 });
167 }
169 > /**
170 > * No-op {@link IByokLmBridgeRegistry} for agent host entrypoints that do not
171 > * support BYOK — e.g. the remote agent host, where no extension host runs
172 > * alongside the agent host to serve the renderer LM API.
173 > */
174 > export class NullByokLmBridgeRegistry implements IByokLmBridgeRegistry {
175 >
176 > declare readonly _serviceBrand: undefined;
177 >
178 > register(): IDisposable {
179 return Disposable.None;
180 }
182 > getModels(): readonly IByokLmModelInfo[] {
183 return [];
184 }
186 > getServingConnection(): IByokLmBridgeConnection | undefined {
187 return undefined;
188 }
190 > onDidChangeModels(): IDisposable {
191 return Disposable.None;
192 }