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