1interface llm-provider {
2 use http-client.{http-request, http-response-with-status};
3
4 /// Information about a language model provider.
5 record provider-info {
6 /// Unique identifier for the provider (e.g. "my-extension.my-provider").
7 id: string,
8 /// Display name for the provider.
9 name: string,
10 /// Path to an SVG icon file relative to the extension root (e.g. "icons/provider.svg").
11 icon: option<string>,
12 }
13
14 /// Capabilities of a language model.
15 record model-capabilities {
16 /// Whether the model supports image inputs.
17 supports-images: bool,
18 /// Whether the model supports tool/function calling.
19 supports-tools: bool,
20 /// Whether the model supports the "auto" tool choice.
21 supports-tool-choice-auto: bool,
22 /// Whether the model supports the "any" tool choice.
23 supports-tool-choice-any: bool,
24 /// Whether the model supports the "none" tool choice.
25 supports-tool-choice-none: bool,
26 /// Whether the model supports extended thinking/reasoning.
27 supports-thinking: bool,
28 /// The format for tool input schemas.
29 tool-input-format: tool-input-format,
30 }
31
32 /// Format for tool input schemas.
33 enum tool-input-format {
34 /// Standard JSON Schema format.
35 json-schema,
36 /// A subset of JSON Schema supported by Google AI.
37 /// See https://ai.google.dev/api/caching#Schema
38 json-schema-subset,
39 /// Simplified schema format for certain providers.
40 simplified,
41 }
42
43 /// Information about a specific model.
44 record model-info {
45 /// Unique identifier for the model.
46 id: string,
47 /// Display name for the model.
48 name: string,
49 /// Maximum input token count.
50 max-token-count: u64,
51 /// Maximum output tokens (optional).
52 max-output-tokens: option<u64>,
53 /// Model capabilities.
54 capabilities: model-capabilities,
55 /// Whether this is the default model for the provider.
56 is-default: bool,
57 /// Whether this is the default fast model.
58 is-default-fast: bool,
59 }
60
61 /// The role of a message participant.
62 enum message-role {
63 /// User message.
64 user,
65 /// Assistant message.
66 assistant,
67 /// System message.
68 system,
69 }
70
71 /// A message in a completion request.
72 record request-message {
73 /// The role of the message sender.
74 role: message-role,
75 /// The content of the message.
76 content: list<message-content>,
77 /// Whether to cache this message for prompt caching.
78 cache: bool,
79 }
80
81 /// Content within a message.
82 variant message-content {
83 /// Plain text content.
84 text(string),
85 /// Image content.
86 image(image-data),
87 /// A tool use request from the assistant.
88 tool-use(tool-use),
89 /// A tool result from the user.
90 tool-result(tool-result),
91 /// Thinking/reasoning content.
92 thinking(thinking-content),
93 /// Redacted/encrypted thinking content.
94 redacted-thinking(string),
95 }
96
97 /// Image data for vision models.
98 record image-data {
99 /// Base64-encoded image data.
100 source: string,
101 /// Image width in pixels (optional).
102 width: option<u32>,
103 /// Image height in pixels (optional).
104 height: option<u32>,
105 }
106
107 /// A tool use request from the model.
108 record tool-use {
109 /// Unique identifier for this tool use.
110 id: string,
111 /// The name of the tool being used.
112 name: string,
113 /// JSON string of the tool input arguments.
114 input: string,
115 /// Whether the input JSON is complete (false while streaming, true when done).
116 is-input-complete: bool,
117 /// Thought signature for providers that support it (e.g., Anthropic).
118 thought-signature: option<string>,
119 }
120
121 /// A tool result to send back to the model.
122 record tool-result {
123 /// The ID of the tool use this is a result for.
124 tool-use-id: string,
125 /// The name of the tool.
126 tool-name: string,
127 /// Whether this result represents an error.
128 is-error: bool,
129 /// The content of the result.
130 content: tool-result-content,
131 }
132
133 /// Content of a tool result.
134 variant tool-result-content {
135 /// Text result.
136 text(string),
137 /// Image result.
138 image(image-data),
139 }
140
141 /// Thinking/reasoning content from models that support extended thinking.
142 record thinking-content {
143 /// The thinking text.
144 text: string,
145 /// Signature for the thinking block (provider-specific).
146 signature: option<string>,
147 }
148
149 /// A tool definition for function calling.
150 record tool-definition {
151 /// The name of the tool.
152 name: string,
153 /// Description of what the tool does.
154 description: string,
155 /// JSON Schema for input parameters.
156 input-schema: string,
157 }
158
159 /// Tool choice preference for the model.
160 enum tool-choice {
161 /// Let the model decide whether to use tools.
162 auto,
163 /// Force the model to use at least one tool.
164 any,
165 /// Prevent the model from using tools.
166 none,
167 }
168
169 /// A completion request to send to the model.
170 record completion-request {
171 /// The messages in the conversation.
172 messages: list<request-message>,
173 /// Available tools for the model to use.
174 tools: list<tool-definition>,
175 /// Tool choice preference.
176 tool-choice: option<tool-choice>,
177 /// Stop sequences to end generation.
178 stop-sequences: list<string>,
179 /// Temperature for sampling (0.0-1.0).
180 temperature: option<f32>,
181 /// Whether thinking/reasoning is allowed.
182 thinking-allowed: bool,
183 /// Maximum tokens to generate.
184 max-tokens: option<u64>,
185 }
186
187 /// Events emitted during completion streaming.
188 variant completion-event {
189 /// Completion has started.
190 started,
191 /// Text content chunk.
192 text(string),
193 /// Thinking/reasoning content chunk.
194 thinking(thinking-content),
195 /// Redacted thinking (encrypted) chunk.
196 redacted-thinking(string),
197 /// Tool use request from the model.
198 tool-use(tool-use),
199 /// JSON parse error when parsing tool input.
200 tool-use-json-parse-error(tool-use-json-parse-error),
201 /// Completion stopped.
202 stop(stop-reason),
203 /// Token usage update.
204 usage(token-usage),
205 /// Reasoning details (provider-specific JSON).
206 reasoning-details(string),
207 }
208
209 /// Error information when tool use JSON parsing fails.
210 record tool-use-json-parse-error {
211 /// The tool use ID.
212 id: string,
213 /// The tool name.
214 tool-name: string,
215 /// The raw input that failed to parse.
216 raw-input: string,
217 /// The parse error message.
218 error: string,
219 }
220
221 /// Reason the completion stopped.
222 enum stop-reason {
223 /// The model finished generating.
224 end-turn,
225 /// Maximum tokens reached.
226 max-tokens,
227 /// The model wants to use a tool.
228 tool-use,
229 /// The model refused to respond.
230 refusal,
231 }
232
233 /// Token usage statistics.
234 record token-usage {
235 /// Number of input tokens used.
236 input-tokens: u64,
237 /// Number of output tokens generated.
238 output-tokens: u64,
239 /// Tokens used for cache creation (if supported).
240 cache-creation-input-tokens: option<u64>,
241 /// Tokens read from cache (if supported).
242 cache-read-input-tokens: option<u64>,
243 }
244
245 /// Cache configuration for prompt caching.
246 record cache-configuration {
247 /// Maximum number of cache anchors.
248 max-cache-anchors: u32,
249 /// Whether caching should be applied to tool definitions.
250 should-cache-tool-definitions: bool,
251 /// Minimum token count for a message to be cached.
252 min-total-token-count: u64,
253 }
254
255 /// Configuration for starting an OAuth web authentication flow.
256 record oauth-web-auth-config {
257 /// The URL to open in the user's browser to start authentication.
258 /// This should include client_id, redirect_uri, scope, state, etc.
259 /// Use `{port}` as a placeholder in the URL - it will be replaced with
260 /// the actual localhost port before opening the browser.
261 /// Example: "https://example.com/oauth?redirect_uri=http://127.0.0.1:{port}/callback"
262 auth-url: string,
263 /// The path to listen on for the OAuth callback (e.g., "/callback").
264 /// A localhost server will be started to receive the redirect.
265 callback-path: string,
266 /// Timeout in seconds to wait for the callback (default: 300 = 5 minutes).
267 timeout-secs: option<u32>,
268 }
269
270 /// Result of an OAuth web authentication flow.
271 record oauth-web-auth-result {
272 /// The full callback URL that was received, including query parameters.
273 /// The extension is responsible for parsing the code, state, etc.
274 callback-url: string,
275 /// The port that was used for the localhost callback server.
276 port: u32,
277 }
278
279 /// Get a stored credential for this provider.
280 get-credential: func(provider-id: string) -> option<string>;
281
282 /// Store a credential for this provider.
283 store-credential: func(provider-id: string, value: string) -> result<_, string>;
284
285 /// Delete a stored credential for this provider.
286 delete-credential: func(provider-id: string) -> result<_, string>;
287
288 /// Read an environment variable.
289 get-env-var: func(name: string) -> option<string>;
290
291 /// Start an OAuth web authentication flow.
292 ///
293 /// This will:
294 /// 1. Start a localhost server to receive the OAuth callback
295 /// 2. Open the auth URL in the user's default browser
296 /// 3. Wait for the callback (up to the timeout)
297 /// 4. Return the callback URL with query parameters
298 ///
299 /// The extension is responsible for:
300 /// - Constructing the auth URL with client_id, redirect_uri, scope, state, etc.
301 /// - Parsing the callback URL to extract the authorization code
302 /// - Exchanging the code for tokens using fetch-fallible from http-client
303 oauth-start-web-auth: func(config: oauth-web-auth-config) -> result<oauth-web-auth-result, string>;
304
305 /// Make an HTTP request for OAuth token exchange.
306 ///
307 /// This is a convenience wrapper around http-client's fetch-fallible for OAuth flows.
308 /// Unlike the standard fetch, this does not treat non-2xx responses as errors,
309 /// allowing proper handling of OAuth error responses.
310 oauth-send-http-request: func(request: http-request) -> result<http-response-with-status, string>;
311
312 /// Open a URL in the user's default browser.
313 ///
314 /// Useful for OAuth flows that need to open a browser but handle the
315 /// callback differently (e.g., polling-based flows).
316 oauth-open-browser: func(url: string) -> result<_, string>;
317
318 /// Provider settings from user configuration.
319 /// Extensions can use this to allow custom API URLs, custom models, etc.
320 record provider-settings {
321 /// Custom API URL override (if configured by the user).
322 api-url: option<string>,
323 /// Custom models configured by the user.
324 available-models: list<custom-model-config>,
325 }
326
327 /// Configuration for a custom model defined by the user.
328 record custom-model-config {
329 /// The model's API identifier.
330 name: string,
331 /// Display name for the UI.
332 display-name: option<string>,
333 /// Maximum input token count.
334 max-tokens: u64,
335 /// Maximum output tokens (optional).
336 max-output-tokens: option<u64>,
337 /// Thinking budget for models that support extended thinking (None = auto).
338 thinking-budget: option<u32>,
339 }
340
341 /// Get provider-specific settings configured by the user.
342 /// Returns settings like custom API URLs and custom model configurations.
343 get-provider-settings: func(provider-id: string) -> option<provider-settings>;
344
345 /// Information needed to display the device flow prompt modal to the user.
346 record device-flow-prompt-info {
347 /// The user code to display (e.g., "ABC-123").
348 user-code: string,
349 /// The URL the user needs to visit to authorize (for the "Connect" button).
350 verification-url: string,
351 /// The headline text for the modal (e.g., "Use GitHub Copilot in Zed.").
352 headline: string,
353 /// A description to show below the headline (e.g., "Using Copilot requires an active subscription on GitHub.").
354 description: string,
355 /// Label for the connect button (e.g., "Connect to GitHub").
356 connect-button-label: string,
357 /// Success headline shown when authorization completes.
358 success-headline: string,
359 /// Success message shown when authorization completes.
360 success-message: string,
361 }
362}