llm-provider.wit

  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}