1
>
/*---------------------------------------------------------------------------------------------
agentHostByokLm.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 { CancellationToken } from '../../../base/common/cancellation.js';
7
>
import { Event } from '../../../base/common/event.js';
8
>
import { createDecorator } from '../../instantiation/common/instantiation.js';
9
>
10
>
/**
11
>
* Serializable bridge contract between the node agent host (where the
12
>
* {@link IByokLmProxyService} OpenAI-compatible proxy runs) and the renderer
13
>
* (which owns the extension-provided BYOK language models via the LM API).
14
>
*
15
>
* These shapes are deliberately wire-friendly (plain JSON, no `VSBuffer`,
16
>
* `URI`, or `workbench/contrib/chat` types) so they survive both the local
17
>
* utility-process IPC channel and the remote JSON-RPC transport without a
18
>
* translation step. The node side converts OpenAI Chat Completions wire
19
>
* payloads to/from these; the renderer side converts these to/from the VS Code
20
>
* LM API (`ILanguageModelsService`).
21
>
*/
22
>
23
>
/** A single tool/function call requested by the assistant. */
24
>
export interface IByokLmToolCall {
25
>
/** Stable id correlating the call with its later `tool` result message. */
26
>
readonly id: string;
27
>
/** Tool/function name. */
28
>
readonly name: string;
29
>
/** JSON-encoded arguments object. */
30
>
readonly argumentsJson: string;
31
>
}
32
>
33
>
/** A tool/function the model may call. */
34
>
export interface IByokLmTool {
35
>
readonly name: string;
36
>
readonly description?: string;
37
>
/** JSON schema for the tool parameters. */
38
>
readonly parametersSchema?: object;
39
>
}
40
>
41
>
/** One chat message in a BYOK request. */
42
>
export interface IByokLmChatMessage {
43
>
readonly role: 'system' | 'user' | 'assistant' | 'tool';
44
>
/** Flattened text content. Empty string when the message carries only tool calls/results. */
45
>
readonly content: string;
46
>
/** Present on `assistant` messages that requested tool calls. */
47
>
readonly toolCalls?: IByokLmToolCall[];
48
>
/** Present on `tool` messages: the {@link IByokLmToolCall.id} this result answers. */
49
>
readonly toolCallId?: string;
50
>
}
51
>
52
>
/** A chat request forwarded from the proxy to the renderer LM API. */
53
>
export interface IByokLmChatRequest {
54
>
/** Provider/vendor name (the LM API vendor that registered the model). */
55
>
readonly vendor: string;
56
>
/** Provider-local model id (the wire id the runtime sent on the OpenAI request). */
57
>
readonly modelId: string;
58
>
readonly messages: IByokLmChatMessage[];
59
>
readonly tools?: IByokLmTool[];
60
>
/** Opaque per-request model options forwarded to the LM provider. */
61
>
readonly modelOptions?: Record<string, unknown>;
62
>
}
63
>
64
>
/** The (buffered) completion produced by the renderer LM API. */
65
>
export interface IByokLmChatResult {
66
>
/** Concatenated assistant text. */
67
>
readonly content: string;
68
>
/** Tool calls the assistant requested, if any. */
69
>
readonly toolCalls?: IByokLmToolCall[];
70
>
/** Best-effort token usage, when the provider reports it. */
71
>
readonly usage?: {
72
>
readonly promptTokens?: number;
73
>
readonly completionTokens?: number;
74
>
};
75
>
/** Set when the LM call failed; `content` is then empty. */
76
>
readonly error?: string;
77
>
}
78
>
79
>
/**
80
>
* Metadata for a renderer BYOK model, enumerated over the bridge so the node
81
>
* agent host can advertise it to the SDK runtime without any host-side config.
82
>
*/
83
>
export interface IByokLmModelInfo {
84
>
/** Provider/vendor name (the LM API vendor that registered the model). */
85
>
readonly vendor: string;
86
>
/** Provider-local model id. */
87
>
readonly id: string;
88
>
/** Display name, when the provider supplies one. */
89
>
readonly name?: string;
90
>
/**
91
>
* The identifier the model is registered under in the renderer's LM service —
92
>
* i.e. `toModelIdentifier(vendor, group, id)` in `extHostLanguageModels`
93
>
* (`<vendor>/<group>/<id>` when the user configured a provider group in
94
>
* `chatLanguageModels.json`, else `<vendor>/<id>`).
95
>
*/
96
>
readonly modelIdentifier?: string;
97
>
/** Maximum context window tokens (prompt + output), when known. */
98
>
readonly maxContextWindowTokens?: number;
99
>
/** Whether the model accepts image inputs, when known. */
100
>
readonly supportsVision?: boolean;
101
>
}
102
>
103
>
export const IAgentHostByokLmHandler = createDecorator<IAgentHostByokLmHandler>('agentHostByokLmHandler');
104
>
105
>
/**
106
>
* Renderer-side handler that services {@link IByokLmChatRequest}s by calling
107
>
* the VS Code Language Model API. Implemented in the workbench (where
108
>
* `ILanguageModelsService` lives) and reached from the node agent host over
109
>
* the reverse bridge.
110
>
*/
111
>
export interface IAgentHostByokLmHandler {
112
>
readonly _serviceBrand: undefined;
113
>
114
>
/**
115
>
* Fires when the renderer's set of BYOK models changes, so the node agent
116
>
* host can re-enumerate them for the model picker. Optional: test fakes may
117
>
* omit it.
118
>
*/
119
>
readonly onDidChangeModels?: Event<void>;
120
>
121
>
/**
122
>
* Run a BYOK chat completion against the extension-registered model that
123
>
* matches `request.vendor` + `request.modelId`. Rejects (or resolves with
124
>
* {@link IByokLmChatResult.error}) when no such model is available.
125
>
*/
126
>
chat(request: IByokLmChatRequest, token: CancellationToken): Promise<IByokLmChatResult>;
127
>
128
>
/**
129
>
* Enumerate the renderer's BYOK models (vendor `isBYOK`, excluding
130
>
* session-scoped agent-host copies) so the node agent host can synthesize
131
>
* provider/model config for the SDK runtime.
132
>
*/
133
>
listModels(token: CancellationToken): Promise<IByokLmModelInfo[]>;
134
>
}
135
>
136
>
/**
137
>
* Node-side connection to a single renderer's {@link IAgentHostByokLmHandler}.
138
>
* Mirrors `IRemoteFilesystemConnection` for the reverse FS bridge. The renderer
139
>
* pushes its models over {@link onDidChangeModels}; `chat` stays a round-trip.
140
>
*/
141
>
export interface IByokLmBridgeConnection {
142
>
chat(request: IByokLmChatRequest): Promise<IByokLmChatResult>;
143
>
/** Emits the renderer's current BYOK model snapshot on subscribe and on every change. */
144
>
readonly onDidChangeModels: Event<IByokLmModelInfo[]>;
145
>
}