dsh-opencode-go 0.1.21 → 0.1.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.en.md +128 -167
  2. package/README.md +126 -158
  3. package/THIRD_PARTY_NOTICES.md +3 -1
  4. package/docs/development.md +56 -6
  5. package/docs/fork-review-2026-09-25.md +191 -0
  6. package/docs/independent-package.md +2 -2
  7. package/docs/verification.md +154 -0
  8. package/lib/build-info.json +8 -1
  9. package/lib/client.js +412 -262
  10. package/lib/index.js +6763 -428
  11. package/lib/types/account-manager.d.ts +23 -0
  12. package/lib/types/account-operations.d.ts +31 -0
  13. package/lib/types/account-policy.d.ts +16 -0
  14. package/lib/types/account-recovery.d.ts +2 -0
  15. package/lib/types/account-selection.d.ts +30 -0
  16. package/lib/types/account-service.d.ts +12 -0
  17. package/lib/types/accounts-contract.d.ts +38 -0
  18. package/lib/types/accounts.d.ts +5 -0
  19. package/lib/types/adapter.d.ts +30 -10
  20. package/lib/types/call-trace.d.ts +54 -0
  21. package/lib/types/catalog-manager.d.ts +20 -0
  22. package/lib/types/catalog.d.ts +5 -3
  23. package/lib/types/client/accounts-controller.d.ts +6 -17
  24. package/lib/types/client/host-compat.d.ts +7 -0
  25. package/lib/types/client/locales.d.ts +9 -0
  26. package/lib/types/client/section-controller.d.ts +11 -46
  27. package/lib/types/client/staged-form.d.ts +1 -3
  28. package/lib/types/client/usage.d.ts +1 -1
  29. package/lib/types/config-contract.d.ts +69 -0
  30. package/lib/types/config.d.ts +12 -53
  31. package/lib/types/conversion/context.d.ts +5 -1
  32. package/lib/types/conversion/image-pool.d.ts +24 -0
  33. package/lib/types/conversion/replay.d.ts +1 -1
  34. package/lib/types/conversion/stream.d.ts +1 -1
  35. package/lib/types/gateway-diagnostics.d.ts +22 -0
  36. package/lib/types/gateway-error.d.ts +2 -0
  37. package/lib/types/host-settings.d.ts +11 -0
  38. package/lib/types/index.d.ts +1 -1
  39. package/lib/types/model-metadata.d.ts +3 -1
  40. package/lib/types/models-contract.d.ts +7 -0
  41. package/lib/types/protocol-contract.d.ts +5 -0
  42. package/lib/types/protocol-policy.d.ts +4 -0
  43. package/lib/types/reasoning.d.ts +36 -6
  44. package/lib/types/request-control.d.ts +2 -0
  45. package/lib/types/sdk-types.d.ts +1568 -0
  46. package/lib/types/settings-bridge.d.ts +22 -0
  47. package/lib/vendor-licenses.txt +103 -0
  48. package/package.json +6 -2
@@ -0,0 +1,1568 @@
1
+ import Anthropic from '@anthropic-ai/sdk';
2
+ import { ResponseCreateParamsStreaming } from 'openai/resources/responses/responses.js';
3
+ import OpenAI from 'openai';
4
+ import { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
5
+
6
+ interface TSchema {
7
+ }
8
+
9
+ type AttributeValue = string | number | boolean | readonly string[] | readonly number[] | readonly boolean[];
10
+ interface SpanAttributes {
11
+ [name: string]: AttributeValue | undefined;
12
+ }
13
+ interface SpanOptions {
14
+ name: string;
15
+ attributes?: SpanAttributes;
16
+ }
17
+ type SpanStatus = {
18
+ status: "ok";
19
+ } | {
20
+ status: "error";
21
+ error?: {
22
+ name: string;
23
+ message: string;
24
+ };
25
+ };
26
+ interface TelemetryContext {
27
+ startSpan<T>(options: SpanOptions, callback: (span: TelemetrySpan) => T | Promise<T>): Promise<T>;
28
+ }
29
+ interface TelemetrySpan extends TelemetryContext {
30
+ addEvent(name: string, attributes?: SpanAttributes): void;
31
+ setAttributes(attributes: SpanAttributes): void;
32
+ setStatus(status: SpanStatus): void;
33
+ }
34
+
35
+ /** Azure models ship without a baseUrl: one resource per user, resolved per request. */
36
+ interface AzureEndpointOptions extends StreamOptions {
37
+ azureApiVersion?: string;
38
+ azureResourceName?: string;
39
+ azureBaseUrl?: string;
40
+ azureDeploymentName?: string;
41
+ }
42
+
43
+ interface AzureOpenAIResponsesOptions extends AzureEndpointOptions {
44
+ reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
45
+ toolChoice?: ResponseCreateParamsStreaming["tool_choice"];
46
+ reasoningSummary?: "auto" | "detailed" | "concise" | null;
47
+ }
48
+
49
+ type BedrockThinkingDisplay = "summarized" | "omitted";
50
+ interface BedrockOptions extends StreamOptions {
51
+ region?: string;
52
+ profile?: string;
53
+ toolChoice?: "auto" | "any" | "none" | {
54
+ type: "tool";
55
+ name: string;
56
+ };
57
+ reasoning?: ThinkingLevel;
58
+ thinkingBudgets?: ThinkingBudgets;
59
+ interleavedThinking?: boolean;
60
+ /**
61
+ * Controls how Claude's thinking content is returned in responses.
62
+ * - "summarized": Thinking blocks contain summarized thinking text (default here).
63
+ * - "omitted": Thinking content is redacted but the signature still travels back
64
+ * for multi-turn continuity, reducing time-to-first-text-token.
65
+ *
66
+ * Note: Anthropic's API default for Claude Opus 4.8 and Mythos Preview is
67
+ * "omitted". We default to "summarized" here to keep behavior consistent with
68
+ * older Claude 4 models. Only applies to Claude models on Bedrock.
69
+ */
70
+ thinkingDisplay?: BedrockThinkingDisplay;
71
+ /** Key-value pairs attached to the inference request for cost allocation tagging.
72
+ * Keys: max 64 chars, no `aws:` prefix. Values: max 256 chars. Max 50 pairs.
73
+ * Tags appear in AWS Cost Explorer split cost allocation data.
74
+ * @see https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_ConverseStream.html */
75
+ requestMetadata?: Record<string, string>;
76
+ /** Bearer token for Bedrock API key authentication.
77
+ * When set, bypasses SigV4 signing and sends Authorization: Bearer <token> instead.
78
+ * Requires `bedrock:CallWithBearerToken` IAM permission on the token's identity.
79
+ * Set via AWS_BEARER_TOKEN_BEDROCK env var or pass directly.
80
+ * @see https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonbedrock.html */
81
+ bearerToken?: string;
82
+ }
83
+
84
+ /**
85
+ * Shared utilities for Google Generative AI and Google Vertex providers.
86
+ */
87
+
88
+ /**
89
+ * Thinking level for Gemini 3 models.
90
+ * Mirrors Google's ThinkingLevel enum values.
91
+ */
92
+ type GoogleApiThinkingLevel = "THINKING_LEVEL_UNSPECIFIED" | "MINIMAL" | "LOW" | "MEDIUM" | "HIGH";
93
+
94
+ interface GoogleOptions extends StreamOptions {
95
+ toolChoice?: "auto" | "none" | "any";
96
+ thinking?: {
97
+ enabled: boolean;
98
+ budgetTokens?: number;
99
+ level?: GoogleApiThinkingLevel;
100
+ };
101
+ }
102
+
103
+ interface GoogleVertexOptions extends StreamOptions {
104
+ toolChoice?: "auto" | "none" | "any";
105
+ thinking?: {
106
+ enabled: boolean;
107
+ budgetTokens?: number;
108
+ level?: GoogleApiThinkingLevel;
109
+ };
110
+ project?: string;
111
+ location?: string;
112
+ }
113
+
114
+ /**
115
+ * Provider-specific options for the Mistral API.
116
+ */
117
+ type MistralReasoningEffort = "none" | "low" | "medium" | "high" | "max";
118
+ interface MistralOptions extends StreamOptions {
119
+ toolChoice?: "auto" | "none" | "any" | "required" | {
120
+ type: "function";
121
+ function: {
122
+ name: string;
123
+ };
124
+ };
125
+ promptMode?: "reasoning";
126
+ reasoningEffort?: MistralReasoningEffort;
127
+ }
128
+
129
+ interface OpenAICodexResponsesOptions extends StreamOptions {
130
+ reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
131
+ reasoningSummary?: "auto" | "concise" | "detailed" | "off" | "on" | null;
132
+ serviceTier?: ResponseCreateParamsStreaming["service_tier"];
133
+ textVerbosity?: "low" | "medium" | "high";
134
+ toolChoice?: "auto" | "none" | "required";
135
+ }
136
+
137
+ interface OpenAICompletionsOptions extends StreamOptions {
138
+ toolChoice?: OpenAI.Chat.Completions.ChatCompletionToolChoiceOption;
139
+ reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
140
+ /** Token budgets per thinking level. Used when `compat.thinkingTokenBudgetField` or `compat.supportsThinkingTokenBudget` is set, or by `{ "$var": "thinking.budget" }`. */
141
+ thinkingBudgets?: ThinkingBudgets;
142
+ }
143
+
144
+ interface OpenAIResponsesOptions extends StreamOptions {
145
+ reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
146
+ reasoningSummary?: "auto" | "detailed" | "concise" | null;
147
+ serviceTier?: ResponseCreateParamsStreaming["service_tier"];
148
+ toolChoice?: ResponseCreateParamsStreaming["tool_choice"];
149
+ }
150
+
151
+ /**
152
+ * pi-messages API implementation.
153
+ *
154
+ * Streams pi's own message protocol directly to a backend: the request is a
155
+ * single POST of `{ model, context, options }` to `<baseUrl>/messages`, the
156
+ * response is an SSE stream of serialized assistant-message events plus a
157
+ * terminal `done`/`error` event. This is the wire protocol spoken by the
158
+ * Radius gateway, but any backend implementing it can be used, e.g. via a
159
+ * models.json custom provider with `"api": "pi-messages"`.
160
+ */
161
+
162
+ interface PiMessagesOptions extends StreamOptions {
163
+ reasoning?: ThinkingLevel;
164
+ toolChoice?: "auto" | "none" | "required" | {
165
+ type: "function";
166
+ function: {
167
+ name: string;
168
+ };
169
+ };
170
+ /** Ask the backend for debug metadata (e.g. routing response headers). */
171
+ debug?: boolean;
172
+ }
173
+
174
+ interface DiagnosticErrorInfo {
175
+ name?: string;
176
+ message: string;
177
+ stack?: string;
178
+ code?: string | number;
179
+ }
180
+ interface AssistantMessageDiagnostic {
181
+ type: string;
182
+ timestamp: number;
183
+ error?: DiagnosticErrorInfo;
184
+ details?: JsonObject;
185
+ }
186
+
187
+ declare class EventStream<T, R = T> implements AsyncIterable<T> {
188
+ private queue;
189
+ private waiting;
190
+ protected done: boolean;
191
+ private finalResultPromise;
192
+ private resolveFinalResult;
193
+ private isComplete;
194
+ private extractResult;
195
+ constructor(isComplete: (event: T) => boolean, extractResult: (event: T) => R);
196
+ push(event: T): void;
197
+ end(result?: R): void;
198
+ [Symbol.asyncIterator](): AsyncIterator<T>;
199
+ result(): Promise<R>;
200
+ }
201
+ /**
202
+ * Event stream of one assistant response. It also times the response: the final message (`done` or `error` event, or
203
+ * the result passed to `end()`) gets `durationMs`, measured with a monotonic clock from the stream's creation, unless
204
+ * the message already has one or its `timestamp` predates the stream. A stream that forwards a response which started
205
+ * elsewhere, such as a deferred result fetched later, therefore leaves it untimed.
206
+ */
207
+ declare class AssistantMessageEventStream extends EventStream<AssistantMessageEvent, AssistantMessage> {
208
+ #private;
209
+ constructor();
210
+ push(event: AssistantMessageEvent): void;
211
+ end(result?: AssistantMessage): void;
212
+ }
213
+
214
+ type KnownApi = "openai-completions" | "mistral-conversations" | "openai-responses" | "azure-openai-responses" | "openai-codex-responses" | "anthropic-messages" | "bedrock-converse-stream" | "google-generative-ai" | "google-vertex" | "pi-messages";
215
+ type Api = KnownApi | (string & {});
216
+ type KnownImageApi = "openrouter-images";
217
+ type ImageApi = KnownImageApi | (string & {});
218
+ type KnownClassifierApi = "typesafe-system-one" | "cloudflare-workers-ai-system-one" | "llama-cpp-classify" | "openai-decisions";
219
+ type ClassifierApi = KnownClassifierApi | (string & {});
220
+ type KnownProvider = "amazon-bedrock" | "ant-ling" | "anthropic" | "google" | "google-vertex" | "openai" | "azure" | "openai-codex" | "radius" | "typesafe" | "nvidia" | "deepseek" | "github-copilot" | "xai" | "groq" | "cerebras" | "openrouter" | "vercel-ai-gateway" | "zai" | "zai-coding-cn" | "mistral" | "minimax" | "minimax-cn" | "moonshotai" | "moonshotai-cn" | "huggingface" | "fireworks" | "together" | "baseten" | "opencode" | "opencode-go" | "kimi-coding" | "meta" | "cloudflare-workers-ai" | "cloudflare-ai-gateway" | "qwen-token-plan" | "qwen-token-plan-cn" | "qwen-token-plan-individual" | "xiaomi" | "xiaomi-token-plan-cn" | "xiaomi-token-plan-ams" | "xiaomi-token-plan-sgp";
221
+ type ProviderId = KnownProvider | string;
222
+ type ToolChoice = "auto" | "none";
223
+ type ThinkingLevel = "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
224
+ type ModelThinkingLevel = "off" | ThinkingLevel;
225
+ type ThinkingLevelMap = Partial<Record<ModelThinkingLevel, string | null>>;
226
+ type SamplingParams = Record<string, unknown>;
227
+ type SamplingParamsByThinkingLevel = Partial<Record<ModelThinkingLevel, SamplingParams>>;
228
+ type ChatTemplateKwargValue = string | number | boolean | null | {
229
+ $var: "thinking.enabled" | "thinking.effort" | "thinking.budget";
230
+ omitWhenOff?: boolean;
231
+ };
232
+ /** Top-level request field used to cap reasoning tokens on OpenAI-compatible servers. */
233
+ type ThinkingTokenBudgetField = "thinking_token_budget" | "thinking_budget" | "thinking_budget_tokens";
234
+ /** Token budgets for each thinking level (token-based providers only) */
235
+ interface ThinkingBudgets {
236
+ minimal?: number;
237
+ low?: number;
238
+ medium?: number;
239
+ high?: number;
240
+ }
241
+ type CacheRetention = "none" | "short" | "long";
242
+ /**
243
+ * Best-effort prompt cache lifetime in seconds for each retention tier a request can ask for.
244
+ * A missing tier means the lifetime is unknown; pi does not warm such caches.
245
+ */
246
+ type ModelPromptCache = Partial<Record<Exclude<CacheRetention, "none">, number>>;
247
+ type Transport = "sse" | "websocket" | "websocket-cached" | "auto";
248
+ /** Provider-scoped environment overrides. Values take precedence over process.env. */
249
+ type ProviderEnv = Record<string, string>;
250
+ type ProviderHeaders = Record<string, string | null>;
251
+ type FetchFunction = typeof globalThis.fetch;
252
+ type SessionAffinityFormat = "openai" | "openai-nosession" | "openrouter";
253
+ interface ProviderResponse {
254
+ status: number;
255
+ headers: Record<string, string>;
256
+ }
257
+ /** Authentication, HTTP transport, and lifecycle callbacks shared by provider requests. */
258
+ interface ProviderRequestOptions<TModel = Model$1<Api>> {
259
+ signal?: AbortSignal;
260
+ /** Explicit parent context for telemetry produced by this logical request. */
261
+ telemetryContext?: TelemetryContext;
262
+ apiKey?: string;
263
+ /**
264
+ * Optional fetch implementation for provider HTTP requests.
265
+ * Defaults to `globalThis.fetch`. Provider adapters that cannot inject a custom implementation may reject it.
266
+ * This does not affect WebSocket transports.
267
+ */
268
+ fetch?: FetchFunction;
269
+ /**
270
+ * Provider-scoped environment values. These take precedence over process.env for
271
+ * provider configuration such as regional settings, endpoint placeholders, and
272
+ * proxy variables.
273
+ */
274
+ env?: ProviderEnv;
275
+ /**
276
+ * Optional callback for inspecting or replacing provider payloads before sending.
277
+ * Return undefined to keep the payload unchanged.
278
+ */
279
+ onPayload?: (payload: unknown, model: TModel) => unknown | undefined | Promise<unknown | undefined>;
280
+ /**
281
+ * Optional callback invoked after an HTTP response is received.
282
+ */
283
+ onResponse?: (response: ProviderResponse, model: TModel) => void | Promise<void>;
284
+ /**
285
+ * Optional custom HTTP headers to include in API requests.
286
+ * Merged with provider defaults; caller values override default headers.
287
+ * On AWS Bedrock these are injected via a Smithy `build`-step middleware so
288
+ * they are covered by SigV4 signing; reserved headers (`x-amz-*`,
289
+ * `authorization`, `host`) are silently ignored to preserve SigV4 / bearer auth.
290
+ * A null value suppresses a provider/API default header with the same name.
291
+ */
292
+ headers?: ProviderHeaders;
293
+ /**
294
+ * HTTP request timeout in milliseconds for providers/SDKs that support it.
295
+ * For example, OpenAI and Anthropic SDK clients default to 10 minutes.
296
+ */
297
+ timeoutMs?: number;
298
+ /**
299
+ * Maximum retry attempts for providers/SDKs that support client-side retries.
300
+ * For example, OpenAI and Anthropic SDK clients default to 2.
301
+ */
302
+ maxRetries?: number;
303
+ /**
304
+ * Maximum delay in milliseconds to wait for a retry when the server requests a long wait.
305
+ * If the server's requested delay exceeds this value, the request fails immediately
306
+ * with an error containing the requested delay, allowing higher-level retry logic
307
+ * to handle it with user visibility.
308
+ * Default: 60000 (60 seconds). Set to 0 to disable the cap.
309
+ */
310
+ maxRetryDelayMs?: number;
311
+ }
312
+ interface StreamOptions extends ProviderRequestOptions<Model$1<Api>> {
313
+ /**
314
+ * Optional callback invoked after an HTTP response is received and before
315
+ * its body stream is consumed.
316
+ */
317
+ onResponse?: (response: ProviderResponse, model: Model$1<Api>) => void | Promise<void>;
318
+ /**
319
+ * Optional observer for each parsed provider stream event before Pi normalization.
320
+ * Event data is adapter-owned and must be treated as read-only.
321
+ * Adapter support is explicit; unsupported adapters do not invoke it.
322
+ */
323
+ onProviderStreamEvent?: (data: unknown, model: Model$1<Api>) => void | Promise<void>;
324
+ temperature?: number;
325
+ /**
326
+ * Arbitrary sampling parameters merged into the request body as-is, after the named request
327
+ * fields, so keys here override them. Lets custom OpenAI-compatible servers (llama.cpp, vLLM,
328
+ * SGLang, ...) receive parameters pi does not model, e.g. `top_p`, `top_k`, `min_p`,
329
+ * `repetition_penalty`. Merged over `Model.samplingParams` per key. Only applied by
330
+ * OpenAI-compatible adapters (completions, responses, Azure responses); other APIs ignore it.
331
+ */
332
+ samplingParams?: SamplingParams;
333
+ maxTokens?: number;
334
+ /**
335
+ * Preferred transport for providers that support multiple transports.
336
+ * Providers that do not support this option ignore it.
337
+ */
338
+ transport?: Transport;
339
+ /**
340
+ * Prompt cache retention preference. Providers map this to their supported values.
341
+ * Default: "short".
342
+ */
343
+ cacheRetention?: CacheRetention;
344
+ /**
345
+ * Optional session identifier for providers that support session-based caching.
346
+ * Providers can use this to enable prompt caching, request routing, or other
347
+ * session-aware features. Ignored by providers that don't support it.
348
+ */
349
+ sessionId?: string;
350
+ /**
351
+ * WebSocket connect timeout in milliseconds for providers that support
352
+ * WebSocket transports. This covers the connection/open handshake only;
353
+ * stream idleness after connection uses timeoutMs.
354
+ */
355
+ websocketConnectTimeoutMs?: number;
356
+ /**
357
+ * Optional metadata to include in API requests.
358
+ * Providers extract the fields they understand and ignore the rest.
359
+ * For example, Anthropic uses `user_id` for abuse tracking and rate limiting.
360
+ */
361
+ metadata?: Record<string, unknown>;
362
+ }
363
+ interface DeferredFetchOptions extends ProviderRequestOptions<Model$1<Api>> {
364
+ /**
365
+ * Maximum provider long-poll duration in milliseconds.
366
+ * Defaults to 0, which performs one status check.
367
+ */
368
+ wait?: number;
369
+ }
370
+ /** Request options for best-effort deferred-response cancellation. */
371
+ type DeferredCancelOptions = ProviderRequestOptions<Model$1<Api>>;
372
+ /**
373
+ * Maps known APIs to their full provider-specific stream option types.
374
+ * Type-only imports from API implementation modules are erased at emit, so
375
+ * this is tree-shake safe.
376
+ */
377
+ interface ApiOptionsMap {
378
+ "anthropic-messages": AnthropicOptions;
379
+ "openai-completions": OpenAICompletionsOptions;
380
+ "openai-responses": OpenAIResponsesOptions;
381
+ "openai-codex-responses": OpenAICodexResponsesOptions;
382
+ "azure-openai-responses": AzureOpenAIResponsesOptions;
383
+ "google-generative-ai": GoogleOptions;
384
+ "google-vertex": GoogleVertexOptions;
385
+ "mistral-conversations": MistralOptions;
386
+ "bedrock-converse-stream": BedrockOptions;
387
+ "pi-messages": PiMessagesOptions;
388
+ }
389
+ /**
390
+ * Full stream options for an API. Known APIs resolve to their concrete option
391
+ * type; custom API strings fall back to the generic shape.
392
+ */
393
+ type ApiStreamOptions<TApi extends Api> = TApi extends keyof ApiOptionsMap ? ApiOptionsMap[TApi] : StreamOptions & Record<string, unknown>;
394
+ interface ClassifierOptions extends ProviderRequestOptions<ClassifierModel<ClassifierApi>> {
395
+ /**
396
+ * Divides the answer logits by this value before they are normalized into probabilities.
397
+ * Values above 1 soften the distribution; values below 1 sharpen it. Must be positive.
398
+ * APIs that cannot apply it ignore it.
399
+ */
400
+ temperature?: number;
401
+ }
402
+ interface ImagesOptions extends ProviderRequestOptions<ImageModel<ImageApi>> {
403
+ /**
404
+ * Optional metadata to include in API requests.
405
+ * Providers extract the fields they understand and ignore the rest.
406
+ */
407
+ metadata?: Record<string, unknown>;
408
+ }
409
+ interface AnthropicAllowedFallbackModel {
410
+ provider: ProviderId;
411
+ model: string;
412
+ cost: ModelCost;
413
+ }
414
+ interface SimpleStreamOptions extends StreamOptions {
415
+ /** Provider-neutral tool selection for simple requests. When omitted, adapters use provider-specific behavior. */
416
+ toolChoice?: ToolChoice;
417
+ reasoning?: ThinkingLevel;
418
+ /** Ask a capable provider to return a durable handle and continue the request asynchronously. */
419
+ deferred?: boolean | {
420
+ window?: "15m" | "1h" | "24h";
421
+ };
422
+ /** Custom token budgets for thinking levels (token-based providers only) */
423
+ thinkingBudgets?: ThinkingBudgets;
424
+ }
425
+ interface TextContent {
426
+ type: "text";
427
+ text: string;
428
+ textSignature?: string;
429
+ }
430
+ interface ThinkingContent {
431
+ type: "thinking";
432
+ thinking: string;
433
+ thinkingSignature?: string;
434
+ /** When true, the thinking content was redacted by safety filters. The opaque
435
+ * encrypted payload is stored in `thinkingSignature` so it can be passed back
436
+ * to the API for multi-turn continuity. */
437
+ redacted?: boolean;
438
+ }
439
+ interface ImageContent {
440
+ type: "image";
441
+ data: string;
442
+ mimeType: string;
443
+ }
444
+ interface ToolCall {
445
+ type: "toolCall";
446
+ id: string;
447
+ name: string;
448
+ arguments: JsonObject;
449
+ thoughtSignature?: string;
450
+ /** OpenAI Responses namespace for calls to dynamically loaded or namespaced tools. */
451
+ namespace?: string;
452
+ }
453
+ interface Usage {
454
+ input: number;
455
+ output: number;
456
+ cacheRead: number;
457
+ cacheWrite: number;
458
+ /** Subset of `cacheWrite` written with 1h retention. Only Anthropic reports this split. */
459
+ cacheWrite1h?: number;
460
+ /**
461
+ * Reasoning/thinking tokens, when the provider reports them. This is a subset of
462
+ * `output`: `output` already includes these tokens. Set to a number (possibly 0) by
463
+ * providers that expose a reasoning breakdown; left undefined by providers that don't.
464
+ */
465
+ reasoning?: number;
466
+ totalTokens: number;
467
+ cost: {
468
+ input: number;
469
+ output: number;
470
+ cacheRead: number;
471
+ cacheWrite: number;
472
+ total: number;
473
+ };
474
+ }
475
+ type StopReason = "pending" | "stop" | "length" | "toolUse" | "error" | "aborted" | "deferred";
476
+ type JsonValue = null | boolean | number | string | readonly JsonValue[] | JsonObject;
477
+ type JsonObject = {
478
+ [key: string]: JsonValue;
479
+ };
480
+ type IsAny<T> = 0 extends 1 & T ? true : false;
481
+ type IsExactlyJsonValue<T> = [T] extends [JsonValue] ? ([JsonValue] extends [T] ? true : false) : false;
482
+ type IsJsonProperty<T> = IsAny<T> extends true ? false : unknown extends T ? false : [Exclude<T, undefined>] extends [never] ? true : IsJsonCompatible<Exclude<T, undefined>>;
483
+ type InvalidJsonKeys<T extends object> = {
484
+ [TKey in keyof T]-?: TKey extends string | number ? (IsJsonProperty<T[TKey]> extends true ? never : TKey) : TKey;
485
+ }[keyof T];
486
+ type IsJsonCompatible<T> = IsAny<T> extends true ? false : unknown extends T ? false : IsExactlyJsonValue<T> extends true ? true : T extends null | boolean | number | string ? true : T extends undefined ? false : T extends readonly (infer TItem)[] ? IsJsonCompatible<TItem> : T extends (...args: never[]) => unknown ? false : T extends object ? [InvalidJsonKeys<T>] extends [never] ? true : false : false;
487
+ /** The JSON representation of a typed in-memory value. Optional object properties remain optional. */
488
+ type JsonRepresentation<T> = IsAny<T> extends true ? JsonValue : unknown extends T ? JsonValue : [T] extends [JsonValue] ? T : T extends readonly unknown[] ? {
489
+ [TKey in keyof T]: JsonRepresentation<Exclude<T[TKey], undefined>>;
490
+ } : T extends object ? {
491
+ [TKey in keyof T]: JsonRepresentation<Exclude<T[TKey], undefined>>;
492
+ } : never;
493
+ interface DeferredHandle {
494
+ provider: string;
495
+ modelId: string;
496
+ api: string;
497
+ /** Provider token, such as a response id or batch id plus row id. */
498
+ id: string;
499
+ expiresAt?: number;
500
+ pollAfterMs?: number;
501
+ /** Provider conversion data required to reconstruct the final assistant message. */
502
+ data?: JsonValue;
503
+ }
504
+ /**
505
+ * System instructions and tool declarations at one point in the transcript.
506
+ *
507
+ * The leading system message is the system prompt. Later system messages change it:
508
+ * `content` adds instructions from that point on, `sections` replace or remove named
509
+ * prompt sections, and `toolsAdded`/`toolsRemoved` change the tool set. Replaying
510
+ * every system message in order yields the current prompt and tools. Providers that
511
+ * accept system messages mid-conversation send each one in place; other providers
512
+ * rebuild the leading system message from the replayed state.
513
+ */
514
+ interface SystemMessage {
515
+ role: "system";
516
+ /** Instruction text. On the leading message this is the base prompt; later, additional instructions. */
517
+ content: string | TextContent[];
518
+ /**
519
+ * Named, ordered prompt sections rendered verbatim after `content`. The leading message
520
+ * declares them; later messages replace sections by name, and `null` removes one. Keep
521
+ * each section self-delimiting (a tag, a heading) so the model can relate an update to
522
+ * the original. Avoid integer-like names; JSON objects reorder those.
523
+ */
524
+ sections?: Record<string, string | null>;
525
+ /** Complete definitions of tools that become available at this point. */
526
+ toolsAdded?: Tool[];
527
+ /** Tools that stop being available at this point. */
528
+ toolsRemoved?: ToolReference[];
529
+ timestamp: number;
530
+ }
531
+ interface UserMessage {
532
+ role: "user";
533
+ content: string | (TextContent | ImageContent)[];
534
+ timestamp: number;
535
+ }
536
+ interface AssistantMessage {
537
+ role: "assistant";
538
+ content: (TextContent | ThinkingContent | ToolCall)[];
539
+ api: Api;
540
+ provider: ProviderId;
541
+ model: string;
542
+ responseModel?: string;
543
+ responseId?: string;
544
+ /** Exact provider-native effort level used for this response. Absent for legacy or unmanaged responses. */
545
+ providerThinkingLevel?: string;
546
+ /** Pi thinking level the agent loop requested for this response. Absent outside the agent loop and for legacy responses. */
547
+ thinkingLevel?: ModelThinkingLevel;
548
+ diagnostics?: AssistantMessageDiagnostic[];
549
+ usage: Usage;
550
+ stopReason: StopReason;
551
+ deferred?: DeferredHandle;
552
+ errorMessage?: string;
553
+ rawStopReason?: string;
554
+ /**
555
+ * Provider indication of whether the model explicitly ended its turn.
556
+ * Preserved for debugging and does not currently affect agent control flow.
557
+ */
558
+ endTurn?: boolean;
559
+ /** Unix timestamp in milliseconds when the request started. */
560
+ timestamp: number;
561
+ /**
562
+ * Milliseconds from `timestamp` until the response ended, measured with a monotonic clock. Set by
563
+ * `AssistantMessageEventStream` on the final message of a response it saw start; absent for legacy messages and
564
+ * for deferred results fetched later.
565
+ */
566
+ durationMs?: number;
567
+ }
568
+ /** A tool call that another tool made while it ran, for example from a codemode script. */
569
+ interface NestedToolCallRecord {
570
+ id: string;
571
+ name: string;
572
+ /** Omitted when over the size limits; `argumentsBytes` then gives their size. */
573
+ arguments?: JsonObject;
574
+ /** UTF-8 size of the arguments as JSON, set when `arguments` is omitted. */
575
+ argumentsBytes?: number;
576
+ /** `unfinished`: the call was still running when the calling tool finished. */
577
+ status: "ok" | "error" | "unfinished";
578
+ durationMs?: number;
579
+ /** Error text, truncated. */
580
+ error?: string;
581
+ }
582
+ /** Bounded record of the nested calls a tool made. Results are not recorded. */
583
+ interface NestedToolCalls {
584
+ calls: NestedToolCallRecord[];
585
+ /** False when calls were dropped, arguments omitted, or calls had not finished. */
586
+ complete: boolean;
587
+ }
588
+ type ToolResultMessage<TDetails = JsonValue> = IsJsonCompatible<TDetails> extends true ? {
589
+ role: "toolResult";
590
+ toolCallId: string;
591
+ toolName: string;
592
+ content: (TextContent | ImageContent)[];
593
+ details?: JsonRepresentation<TDetails>;
594
+ /** Usage from the tool execution itself, if available. Not part of main LLM context accounting. */
595
+ usage?: Usage;
596
+ /** Calls this tool made to other tools. Kept for the session record; not sent to the model. */
597
+ nestedCalls?: NestedToolCalls;
598
+ isError: boolean;
599
+ /** Unix timestamp in milliseconds when the result was created. */
600
+ timestamp: number;
601
+ /** Milliseconds the tool's execution took, measured with a monotonic clock. Absent for legacy results. */
602
+ durationMs?: number;
603
+ } : never;
604
+ type Message = SystemMessage | UserMessage | AssistantMessage | ToolResultMessage;
605
+ type ImagesInputContent = TextContent | ImageContent;
606
+ type ImagesOutputContent = TextContent | ImageContent;
607
+ interface ImagesContext {
608
+ input: ImagesInputContent[];
609
+ }
610
+ type ImagesStopReason = "stop" | "error" | "aborted";
611
+ interface AssistantImages {
612
+ api: ImageApi;
613
+ provider: ProviderId;
614
+ model: string;
615
+ output: ImagesOutputContent[];
616
+ responseId?: string;
617
+ usage?: Usage;
618
+ stopReason: ImagesStopReason;
619
+ errorMessage?: string;
620
+ timestamp: number;
621
+ }
622
+ interface ClassifierChoiceQuestion {
623
+ type: "choice";
624
+ instructions: string;
625
+ criteria: Record<string, string>;
626
+ }
627
+ interface ClassifierScoreQuestion {
628
+ type: "score";
629
+ instructions: string;
630
+ criteria: string[];
631
+ }
632
+ interface ClassifierBoolQuestion {
633
+ type: "bool";
634
+ instructions: string;
635
+ criteria: {
636
+ true: string;
637
+ false: string;
638
+ };
639
+ }
640
+ type ClassifierQuestion = ClassifierChoiceQuestion | ClassifierScoreQuestion | ClassifierBoolQuestion;
641
+ interface ClassifierContext {
642
+ state: JsonObject;
643
+ /**
644
+ * Images judged together with `state`. Only models whose `input` includes `"image"` accept them;
645
+ * other models return an error result.
646
+ */
647
+ images?: ImageContent[];
648
+ questions: Record<string, ClassifierQuestion>;
649
+ }
650
+ interface ClassifierChoiceAnswer {
651
+ type: "choice";
652
+ choice: string;
653
+ probabilities: Record<string, number>;
654
+ confidence: number;
655
+ }
656
+ interface ClassifierScoreAnswer {
657
+ type: "score";
658
+ score: number;
659
+ confidence: number;
660
+ }
661
+ interface ClassifierBoolAnswer {
662
+ type: "bool";
663
+ probability: number;
664
+ }
665
+ type ClassifierAnswer = ClassifierChoiceAnswer | ClassifierScoreAnswer | ClassifierBoolAnswer;
666
+ type ClassifierStopReason = "stop" | "error" | "aborted";
667
+ interface ClassifierResult {
668
+ api: ClassifierApi;
669
+ provider: ProviderId;
670
+ model: string;
671
+ answers: Record<string, ClassifierAnswer>;
672
+ /** Token usage and its cost at the model's catalog price, when the service reports token counts. */
673
+ usage?: Usage;
674
+ stopReason: ClassifierStopReason;
675
+ errorMessage?: string;
676
+ timestamp: number;
677
+ }
678
+
679
+ /** OpenAI grammar variants for constrained sampling. */
680
+ type GrammarFormat = "openai_lark" | "openai_regex";
681
+ type GrammarVariants = Partial<Record<GrammarFormat, string>>;
682
+ /**
683
+ * Optional provider-side constrained sampling configs for a tool.
684
+ *
685
+ * The `json_schema` value roughly maps to the concept of `strict` in APIs which is
686
+ * implemented as json-schema constrained sampling by APIs. Grammar variants let
687
+ * callers provide provider-specific encodings of the same intended language.
688
+ */
689
+ type ConstrainedSamplingConfig = {
690
+ type: "json_schema";
691
+ strict: "prefer" | "require";
692
+ } | {
693
+ type: "grammar";
694
+ variants: GrammarVariants;
695
+ };
696
+ interface Tool<TParameters extends TSchema = TSchema> {
697
+ name: string;
698
+ description: string;
699
+ parameters: TParameters;
700
+ constrainedSampling?: false | ConstrainedSamplingConfig;
701
+ }
702
+ interface ToolReference {
703
+ name: string;
704
+ }
705
+ /**
706
+ * Request input accepted by the public stream entry points (`Models.stream()`,
707
+ * `streamSimple()`, ...). `systemPrompt` and `tools` are shorthand for a leading
708
+ * system message; `normalizeContext()` folds them into one before the request
709
+ * reaches a provider.
710
+ */
711
+ interface Context {
712
+ systemPrompt?: string;
713
+ messages: Message[];
714
+ tools?: Tool[];
715
+ }
716
+ declare const transcriptContextBrand: unique symbol;
717
+ /**
718
+ * Normalized request context passed to providers and API implementations. The
719
+ * prompt and tool declarations are carried by the transcript's system messages.
720
+ * Only `normalizeContext()` produces this type, so a raw `Context` cannot reach
721
+ * provider code by accident.
722
+ */
723
+ type TranscriptContext = {
724
+ messages: Message[];
725
+ readonly [transcriptContextBrand]: true;
726
+ };
727
+ /**
728
+ * Event protocol for AssistantMessageEventStream.
729
+ *
730
+ * Successful streams emit `start` before partial updates and terminate with
731
+ * `done`. A stream may terminate directly with `error` when request setup fails
732
+ * before generation starts; after `start`, failures also terminate with `error`.
733
+ * Direct `streamSimple()` calls throw synchronously when request auth is missing.
734
+ * Updates and `done` must never appear before `start`.
735
+ *
736
+ * `partial` is the shared live response-so-far helper, not an event-time
737
+ * snapshot. Text and thinking blocks are empty when their `*_start` event is
738
+ * emitted and grow only through their corresponding `*_delta` events until the
739
+ * authoritative `*_end`. Redacted thinking may be complete at start and emit no
740
+ * deltas. Tool-call arguments at `toolcall_start` are provider-specific;
741
+ * `toolcall_delta` carries subsequent JSON updates.
742
+ */
743
+ type AssistantMessageEvent = {
744
+ type: "start";
745
+ partial: AssistantMessage;
746
+ } | {
747
+ type: "text_start";
748
+ contentIndex: number;
749
+ partial: AssistantMessage;
750
+ } | {
751
+ type: "text_delta";
752
+ contentIndex: number;
753
+ delta: string;
754
+ partial: AssistantMessage;
755
+ } | {
756
+ type: "text_end";
757
+ contentIndex: number;
758
+ content: string;
759
+ partial: AssistantMessage;
760
+ } | {
761
+ type: "thinking_start";
762
+ contentIndex: number;
763
+ partial: AssistantMessage;
764
+ } | {
765
+ type: "thinking_delta";
766
+ contentIndex: number;
767
+ delta: string;
768
+ partial: AssistantMessage;
769
+ } | {
770
+ type: "thinking_end";
771
+ contentIndex: number;
772
+ content: string;
773
+ partial: AssistantMessage;
774
+ } | {
775
+ type: "toolcall_start";
776
+ contentIndex: number;
777
+ partial: AssistantMessage;
778
+ } | {
779
+ type: "toolcall_delta";
780
+ contentIndex: number;
781
+ delta: string;
782
+ partial: AssistantMessage;
783
+ } | {
784
+ type: "toolcall_end";
785
+ contentIndex: number;
786
+ toolCall: ToolCall;
787
+ partial: AssistantMessage;
788
+ } | {
789
+ type: "done";
790
+ reason: Extract<StopReason, "stop" | "length" | "toolUse" | "deferred">;
791
+ message: AssistantMessage;
792
+ } | {
793
+ type: "error";
794
+ reason: Extract<StopReason, "aborted" | "error">;
795
+ error: AssistantMessage;
796
+ };
797
+ /**
798
+ * Compatibility settings for OpenAI-compatible completions APIs.
799
+ * Use this to override URL-based auto-detection for custom providers.
800
+ */
801
+ interface OpenAICompletionsCompat {
802
+ /** Whether the provider supports the `store` field. Default: auto-detected from URL. */
803
+ supportsStore?: boolean;
804
+ /** Whether the provider supports the `developer` role (vs `system`). Default: auto-detected from URL. */
805
+ supportsDeveloperRole?: boolean;
806
+ /** Whether the provider supports `reasoning_effort`. Default: auto-detected from URL. */
807
+ supportsReasoningEffort?: boolean;
808
+ /** Whether the provider supports `stream_options: { include_usage: true }` for token usage in streaming responses. Default: true. */
809
+ supportsUsageInStreaming?: boolean;
810
+ /** Whether streamed responses include `finish_reason`. When false, pi infers `stop` or `toolUse` when the stream ends. Default: true. */
811
+ supportsFinishReason?: boolean;
812
+ /** Which field to use for max tokens. Default: auto-detected from URL. */
813
+ maxTokensField?: "max_completion_tokens" | "max_tokens";
814
+ /** Whether tool results require the `name` field. Default: auto-detected from URL. */
815
+ requiresToolResultName?: boolean;
816
+ /** Whether a user message after tool results requires an assistant message in between. Default: auto-detected from URL. */
817
+ requiresAssistantAfterToolResult?: boolean;
818
+ /** Whether thinking blocks must be converted to text blocks with <thinking> delimiters. Default: auto-detected from URL. */
819
+ requiresThinkingAsText?: boolean;
820
+ /** Whether all replayed assistant messages must include an empty reasoning_content field when reasoning is enabled. Default: auto-detected from URL. */
821
+ requiresReasoningContentOnAssistantMessages?: boolean;
822
+ /** Format for reasoning/thinking parameter. "openai" uses reasoning_effort, "openrouter" uses reasoning: { effort }, "deepseek" uses thinking: { type } plus reasoning_effort when supported, "together" uses reasoning: { enabled } plus reasoning_effort when supported, "baseten" uses configurable chat_template_args plus reasoning_effort when supported, "zai" uses thinking: { type }, "qwen" uses top-level enable_thinking: boolean, "qwen-chat-template" uses chat_template_kwargs.enable_thinking and preserve_thinking, "chat-template" uses configurable chat_template_kwargs, "string-thinking" uses top-level thinking: string, and "ant-ling" uses reasoning: { effort } only when the mapped effort is non-null. Default: "openai". */
823
+ thinkingFormat?: "openai" | "openrouter" | "deepseek" | "together" | "baseten" | "zai" | "qwen" | "chat-template" | "qwen-chat-template" | "string-thinking" | "ant-ling";
824
+ /** Kwargs to send as `chat_template_kwargs` when `thinkingFormat` is `chat-template`. Use `{ "$var": "thinking.enabled" }`, `{ "$var": "thinking.effort" }`, or `{ "$var": "thinking.budget" }` for pi-controlled thinking values. */
825
+ chatTemplateKwargs?: Record<string, ChatTemplateKwargValue>;
826
+ /** Arguments to send as `chat_template_args` when `thinkingFormat` is `baseten`. Use `{ "$var": "thinking.enabled" }`, `{ "$var": "thinking.effort" }`, or `{ "$var": "thinking.budget" }` for pi-controlled thinking values. */
827
+ chatTemplateArgs?: Record<string, ChatTemplateKwargValue>;
828
+ /** OpenRouter-compatible routing preferences sent as the `provider` request field. */
829
+ openRouterRouting?: OpenRouterRouting;
830
+ /** Vercel AI Gateway routing preferences. Only used when baseUrl points to Vercel AI Gateway. */
831
+ vercelGatewayRouting?: VercelGatewayRouting;
832
+ /** Whether z.ai supports top-level `tool_stream: true` for streaming tool call deltas. Default: false. */
833
+ zaiToolStream?: boolean;
834
+ /**
835
+ * Top-level request field used to cap reasoning tokens from `thinkingBudgets`.
836
+ * Reasoning and the answer share `max_tokens` on these endpoints, so without a budget a
837
+ * reasoning-heavy turn can consume the whole response and emit no answer.
838
+ * `"thinking_token_budget"` is vLLM, `"thinking_budget"` is Qwen/DashScope/SGLang,
839
+ * `"thinking_budget_tokens"` is llama.cpp. Off by default; not set on the generated catalog.
840
+ */
841
+ thinkingTokenBudgetField?: ThinkingTokenBudgetField;
842
+ /** Alias for `thinkingTokenBudgetField: "thinking_token_budget"` (vLLM). Prefer `thinkingTokenBudgetField`. Default: false. */
843
+ supportsThinkingTokenBudget?: boolean;
844
+ /** Whether the provider supports OpenAI custom tools with Lark/regex grammar formats. When false, grammar-constrained tools fall back to normal function tools. Default: false; the generated model catalog enables it for capable models. */
845
+ supportsOpenAIGrammarTools?: boolean;
846
+ /** Whether the exact model accepts system or developer messages after the conversation has started. When false, later system messages are folded into the leading system message. Default: false; the generated model catalog enables it for verified models. */
847
+ supportsMidConvoSystemMessages?: boolean;
848
+ /** Whether system messages can introduce additional tools mid-conversation. Requires `supportsMidConvoSystemMessages`. Default: false; the generated model catalog enables it for capable models. */
849
+ supportsMidConvoToolAdditions?: boolean;
850
+ /** Whether the provider supports the `strict` field in tool definitions. Default: false; generated capable models enable it explicitly. */
851
+ supportsStrictMode?: boolean;
852
+ /** Cache control convention for prompt caching. "anthropic" applies Anthropic-style `cache_control` markers to the system prompt, last tool definition, and last user, assistant, or tool-result text content. */
853
+ cacheControlFormat?: "anthropic";
854
+ /** Whether to send session-affinity data from `options.sessionId`. Default: true for OpenRouter endpoints, false otherwise. */
855
+ sendSessionAffinityHeaders?: boolean;
856
+ /** Session-affinity header format: `openai` sends `session_id`, `x-client-request-id`, and `x-session-affinity`; `openai-nosession` sends `x-client-request-id` and `x-session-affinity`; `openrouter` sends `x-session-id`. Does not affect the `prompt_cache_key` body param, which is governed by cache retention. Default: auto-detected. */
857
+ sessionAffinityFormat?: SessionAffinityFormat;
858
+ /** Whether the provider supports long prompt cache retention (`prompt_cache_retention: "24h"` or Anthropic-style `cache_control.ttl: "1h"`, depending on format). Default: true. */
859
+ supportsLongCacheRetention?: boolean;
860
+ /**
861
+ * vLLM scheduler priority sent as the top-level `priority` request field (lower values are
862
+ * handled earlier; server default 0). Only meaningful when vLLM runs with
863
+ * `--scheduling-policy priority`; useful for keeping background/batch work from stalling
864
+ * interactive sessions. Off by default; not set on the generated catalog.
865
+ */
866
+ vllmPriority?: number;
867
+ }
868
+ /** Compatibility settings for OpenAI Responses APIs. */
869
+ interface OpenAIResponsesCompat {
870
+ /** Whether the provider supports the `developer` role (vs `system`). Default: true. */
871
+ supportsDeveloperRole?: boolean;
872
+ /** Whether the exact model accepts developer or system messages after the conversation has started. When false, later system messages are folded into the leading system message. Default: false; the generated model catalog enables it for verified models. */
873
+ supportsMidConvoSystemMessages?: boolean;
874
+ /** Session-affinity header format: `openai` sends `session_id` and `x-client-request-id`; `openai-nosession` sends `x-client-request-id`; `openrouter` sends `x-session-id`. Does not affect the `prompt_cache_key` body param, which is governed by cache retention. Default: auto-detected. */
875
+ sessionAffinityFormat?: SessionAffinityFormat;
876
+ /** Whether the provider supports long prompt cache retention. This uses `prompt_cache_options.ttl: "30m"` on GPT-5.6+ and `prompt_cache_retention: "24h"` on earlier models. Default: true. */
877
+ supportsLongCacheRetention?: boolean;
878
+ /** Whether the provider supports strict JSON-schema function tools. Defaults are API-specific; generated OpenAI models enable it explicitly. */
879
+ supportsStrictMode?: boolean;
880
+ /** Whether to emit OpenAI custom tools with Lark/regex grammar formats. When false, grammar-constrained tools fall back to normal function tools. Default: false; the generated model catalog enables it for capable models. */
881
+ supportsOpenAIGrammarTools?: boolean;
882
+ /** Whether the model supports message-anchored `additional_tools` input items. Default: false. */
883
+ supportsAdditionalTools?: boolean;
884
+ /** Whether the model supports client-executed tool search for transcript-anchored additions. Default: false. */
885
+ supportsToolSearch?: boolean;
886
+ /** Whether the model accepts `prompt_cache_options` (OpenAI GPT-5.6+ prompt caching). Older OpenAI models reject the parameter. Default: false. */
887
+ supportsExplicitPromptCacheMode?: boolean;
888
+ /** Whether the provider accepts the `max_output_tokens` parameter. Some Codex-protocol gateways reject it. Default: true. */
889
+ supportsMaxOutputTokens?: boolean;
890
+ }
891
+ /** Compatibility settings for Anthropic Messages-compatible APIs. */
892
+ interface AnthropicMessagesCompat {
893
+ /**
894
+ * Whether the provider accepts per-tool `eager_input_streaming`.
895
+ * When false, the Anthropic provider omits `tools[].eager_input_streaming`
896
+ * and sends the legacy `fine-grained-tool-streaming-2025-05-14` beta header
897
+ * for tool-enabled requests.
898
+ * Default: true.
899
+ */
900
+ supportsEagerToolInputStreaming?: boolean;
901
+ /** Whether the provider supports Anthropic long cache retention (`cache_control.ttl: "1h"`). Default: true. */
902
+ supportsLongCacheRetention?: boolean;
903
+ /**
904
+ * Whether to send the `x-session-affinity` header from `options.sessionId`
905
+ * when caching is enabled. Required for providers like Fireworks that use
906
+ * session affinity for prompt cache routing (requests to the same replica
907
+ * maximize cache hits).
908
+ * Default: false.
909
+ */
910
+ sendSessionAffinityHeaders?: boolean;
911
+ /** Session-affinity format. `"openrouter"` sends `x-session-id`; when unset, sends `x-session-affinity`. */
912
+ sessionAffinityFormat?: "openrouter";
913
+ /**
914
+ * Whether the provider supports Anthropic-style `cache_control` markers on
915
+ * tool definitions. When false, `cache_control` is omitted from tool params.
916
+ * Some Anthropic-compatible providers (e.g., Fireworks) do not support this
917
+ * field on tools and may reject or ignore it.
918
+ * Default: true.
919
+ */
920
+ supportsCacheControlOnTools?: boolean;
921
+ /**
922
+ * Whether the model accepts the Anthropic `temperature` request field.
923
+ * Claude Opus 4.7+ rejects non-default temperature values.
924
+ * Default: true.
925
+ */
926
+ supportsTemperature?: boolean;
927
+ /**
928
+ * Whether to force adaptive thinking (`thinking.type: "adaptive"` plus
929
+ * `output_config.effort`) regardless of the model id. Built-in models that
930
+ * require adaptive thinking set this in generated metadata. Custom
931
+ * Anthropic-compatible providers can set this to `true` for any model whose
932
+ * upstream requires the adaptive format. Set to `false` to
933
+ * opt out on overridden built-in models.
934
+ * Default: false.
935
+ */
936
+ forceAdaptiveThinking?: boolean;
937
+ /** Whether to replay empty thinking signatures as `signature: ""` instead of converting thinking to text. Default: false. */
938
+ allowEmptySignature?: boolean;
939
+ /** Whether the provider supports Anthropic strict tool schemas. Default: false; generated Anthropic models enable it explicitly. */
940
+ supportsStrictTools?: boolean;
941
+ /** Whether the exact model transport supports effort-only system messages and thinking binding controls. Default: false. */
942
+ supportsMidConvoEffort?: boolean;
943
+ /** Whether the exact model accepts system-role messages inside the conversation. When false, later system messages are folded into the top-level system prompt. Default: false. */
944
+ supportsMidConvoSystemMessages?: boolean;
945
+ /** Whether the exact model accepts mid-conversation `tool_addition` blocks with inline tool definitions (`inline-tools-2026-09-15`) and `tool_removal` blocks. Requires `supportsMidConvoSystemMessages`. Default: false. */
946
+ supportsMidConvoToolChanges?: boolean;
947
+ /**
948
+ * Models Anthropic accepts in `fallbacks` for server-side refusal fallback,
949
+ * with local pricing metadata for returned fallback responses. When absent or
950
+ * empty, callers must omit `fallbacks`; Anthropic rejects the field for models
951
+ * with no permitted fallback targets.
952
+ */
953
+ allowedFallbackModels?: AnthropicAllowedFallbackModel[];
954
+ }
955
+ /** Compatibility settings for Amazon Bedrock models. */
956
+ interface BedrockCompat {
957
+ /** Whether the model supports Bedrock strict tool schemas. Default: false. */
958
+ supportsStrictMode?: boolean;
959
+ }
960
+ /** Compatibility settings for the Mistral chat API. */
961
+ interface MistralConversationsCompat {
962
+ /** Whether the exact model accepts system messages after the conversation has started. When false, later system messages are folded into the leading system message. Default: false. */
963
+ supportsMidConvoSystemMessages?: boolean;
964
+ }
965
+ /**
966
+ * OpenRouter provider routing preferences.
967
+ * Controls which upstream providers OpenRouter routes requests to.
968
+ * Sent as the `provider` field in the OpenRouter API request body.
969
+ * @see https://openrouter.ai/docs/guides/routing/provider-selection
970
+ */
971
+ interface OpenRouterRouting {
972
+ /** Whether to allow backup providers to serve requests. Default: true. */
973
+ allow_fallbacks?: boolean;
974
+ /** Whether to filter providers to only those that support all parameters in the request. Default: false. */
975
+ require_parameters?: boolean;
976
+ /** Data collection setting. "allow" (default): allow providers that may store/train on data. "deny": only use providers that don't collect user data. */
977
+ data_collection?: "deny" | "allow";
978
+ /** Whether to restrict routing to only ZDR (Zero Data Retention) endpoints. */
979
+ zdr?: boolean;
980
+ /** Whether to restrict routing to only models that allow text distillation. */
981
+ enforce_distillable_text?: boolean;
982
+ /** An ordered list of provider names/slugs to try in sequence, falling back to the next if unavailable. */
983
+ order?: string[];
984
+ /** List of provider names/slugs to exclusively allow for this request. */
985
+ only?: string[];
986
+ /** List of provider names/slugs to skip for this request. */
987
+ ignore?: string[];
988
+ /** A list of quantization levels to filter providers by (e.g., ["fp16", "bf16", "fp8", "fp6", "int8", "int4", "fp4", "fp32"]). */
989
+ quantizations?: string[];
990
+ /** Sorting strategy. Can be a string (e.g., "price", "throughput", "latency") or an object with `by` and `partition`. */
991
+ sort?: string | {
992
+ /** The sorting metric: "price", "throughput", "latency". */
993
+ by?: string;
994
+ /** Partitioning strategy: "model" (default) or "none". */
995
+ partition?: string | null;
996
+ };
997
+ /** Maximum price per million tokens (USD). */
998
+ max_price?: {
999
+ /** Price per million prompt tokens. */
1000
+ prompt?: number | string;
1001
+ /** Price per million completion tokens. */
1002
+ completion?: number | string;
1003
+ /** Price per image. */
1004
+ image?: number | string;
1005
+ /** Price per audio unit. */
1006
+ audio?: number | string;
1007
+ /** Price per request. */
1008
+ request?: number | string;
1009
+ };
1010
+ /** Preferred minimum throughput (tokens/second). Can be a number (applies to p50) or an object with percentile-specific cutoffs. */
1011
+ preferred_min_throughput?: number | {
1012
+ /** Minimum tokens/second at the 50th percentile. */
1013
+ p50?: number;
1014
+ /** Minimum tokens/second at the 75th percentile. */
1015
+ p75?: number;
1016
+ /** Minimum tokens/second at the 90th percentile. */
1017
+ p90?: number;
1018
+ /** Minimum tokens/second at the 99th percentile. */
1019
+ p99?: number;
1020
+ };
1021
+ /** Preferred maximum latency (seconds). Can be a number (applies to p50) or an object with percentile-specific cutoffs. */
1022
+ preferred_max_latency?: number | {
1023
+ /** Maximum latency in seconds at the 50th percentile. */
1024
+ p50?: number;
1025
+ /** Maximum latency in seconds at the 75th percentile. */
1026
+ p75?: number;
1027
+ /** Maximum latency in seconds at the 90th percentile. */
1028
+ p90?: number;
1029
+ /** Maximum latency in seconds at the 99th percentile. */
1030
+ p99?: number;
1031
+ };
1032
+ }
1033
+ /**
1034
+ * Vercel AI Gateway routing preferences.
1035
+ * Controls which upstream providers the gateway routes requests to.
1036
+ * @see https://vercel.com/docs/ai-gateway/models-and-providers/provider-options
1037
+ */
1038
+ interface VercelGatewayRouting {
1039
+ /** List of provider slugs to exclusively use for this request (e.g., ["bedrock", "anthropic"]). */
1040
+ only?: string[];
1041
+ /** List of provider slugs to try in order (e.g., ["anthropic", "openai"]). */
1042
+ order?: string[];
1043
+ }
1044
+ interface ModelCostRates {
1045
+ input: number;
1046
+ output: number;
1047
+ cacheRead: number;
1048
+ cacheWrite: number;
1049
+ }
1050
+ interface ModelCostTier extends ModelCostRates {
1051
+ /** Use this tier for requests whose total input usage exceeds this token count. */
1052
+ inputTokensAbove: number;
1053
+ }
1054
+ interface ModelCost extends ModelCostRates {
1055
+ /** Request-wide pricing tiers. The highest matching input threshold applies to the full request. */
1056
+ tiers?: ModelCostTier[];
1057
+ }
1058
+ interface ModelImageResizeOptions {
1059
+ maxWidth?: number;
1060
+ maxHeight?: number;
1061
+ /** Maximum base64-encoded payload size in bytes. */
1062
+ maxBytes?: number;
1063
+ jpegQuality?: number;
1064
+ }
1065
+ interface ModelImageInputLimits {
1066
+ /** Cache-safe resize profile applied before a new image enters conversation history. */
1067
+ resize?: ModelImageResizeOptions;
1068
+ /** Maximum images accepted in one provider message. */
1069
+ maxPerMessage?: number;
1070
+ /** Maximum images accepted across one provider request. */
1071
+ maxPerRequest?: number;
1072
+ }
1073
+ interface ModelInputLimits {
1074
+ /** Maximum serialized provider request size in bytes. */
1075
+ maxRequestBytes?: number;
1076
+ images?: ModelImageInputLimits;
1077
+ }
1078
+ /** Fields shared by every catalog entry, regardless of what you can do with it. */
1079
+ interface BaseModel<TApi extends string> {
1080
+ id: string;
1081
+ name: string;
1082
+ api: TApi;
1083
+ provider: ProviderId;
1084
+ baseUrl: string;
1085
+ input: ("text" | "image")[];
1086
+ /** Provider input limits and cache-safe preprocessing metadata. */
1087
+ inputLimits?: ModelInputLimits;
1088
+ cost: ModelCost;
1089
+ headers?: Record<string, string>;
1090
+ }
1091
+ /** Chat model: usable with `stream()` and friends. */
1092
+ interface Model$1<TApi extends Api> extends BaseModel<TApi> {
1093
+ /**
1094
+ * Optional: chat is the default model type, so models without `type` are chat
1095
+ * models. Narrow mixed model lists with `isModelType()` instead of comparing
1096
+ * `type` directly.
1097
+ */
1098
+ type?: "chat";
1099
+ reasoning: boolean;
1100
+ /**
1101
+ * Maps pi thinking levels to provider/model-specific values.
1102
+ * Missing keys use provider defaults. null marks a level as unsupported.
1103
+ */
1104
+ thinkingLevelMap?: ThinkingLevelMap;
1105
+ /** Prompt cache lifetimes per retention tier. Unset when the provider's cache behavior is unknown. */
1106
+ promptCache?: ModelPromptCache;
1107
+ contextWindow: number;
1108
+ maxTokens: number;
1109
+ /** Default sampling parameters for this model. See {@link StreamOptions.samplingParams}; per-request keys override these. */
1110
+ samplingParams?: SamplingParams;
1111
+ /** Sampling parameter overrides selected by the effective pi thinking level. */
1112
+ samplingParamsByThinkingLevel?: SamplingParamsByThinkingLevel;
1113
+ /** Compatibility overrides for OpenAI-compatible APIs. If not set, auto-detected from baseUrl. */
1114
+ compat?: TApi extends "openai-completions" ? OpenAICompletionsCompat : TApi extends "openai-responses" | "azure-openai-responses" | "openai-codex-responses" ? OpenAIResponsesCompat : TApi extends "anthropic-messages" ? AnthropicMessagesCompat : TApi extends "bedrock-converse-stream" ? BedrockCompat : TApi extends "mistral-conversations" ? MistralConversationsCompat : never;
1115
+ }
1116
+ /** Image-generation model: usable with `generateImages()` only. */
1117
+ interface ImageModel<TApi extends ImageApi> extends BaseModel<TApi> {
1118
+ type: "image";
1119
+ /** Output modalities. Always includes `"image"`; `"text"` means the model can also return text blocks. */
1120
+ output: ("text" | "image")[];
1121
+ }
1122
+ /** Structured classifier model: usable with `classify()` only. */
1123
+ interface ClassifierModel<TApi extends ClassifierApi> extends BaseModel<TApi> {
1124
+ type: "classifier";
1125
+ contextWindow: number;
1126
+ }
1127
+ /** Model shape for each model type. */
1128
+ interface ModelTypeMap {
1129
+ chat: Model$1<Api>;
1130
+ image: ImageModel<ImageApi>;
1131
+ classifier: ClassifierModel<ClassifierApi>;
1132
+ }
1133
+ /** What a catalog entry is for. Decides which `Models` operation accepts it. */
1134
+ type ModelType = keyof ModelTypeMap;
1135
+ /** Anything a provider can list. Narrow with `isModelType()`. */
1136
+ type AnyModel = ModelTypeMap[ModelType];
1137
+
1138
+ type AnthropicEffort = "low" | "medium" | "high" | "xhigh" | "max";
1139
+ type AnthropicThinkingDisplay = "summarized" | "omitted";
1140
+ interface AnthropicOptions extends StreamOptions {
1141
+ /**
1142
+ * Enable extended thinking.
1143
+ * For adaptive thinking models: the model decides when/how much to think.
1144
+ * For older models: uses budget-based thinking with thinkingBudgetTokens.
1145
+ * Default: undefined (thinking is omitted unless `streamSimple()` maps
1146
+ * a simple reasoning level to this option, or callers set it explicitly).
1147
+ */
1148
+ thinkingEnabled?: boolean;
1149
+ /**
1150
+ * Token budget for extended thinking (older models only).
1151
+ * Ignored for adaptive thinking models.
1152
+ * Default: 1024 when `thinkingEnabled` is true and no budget is provided.
1153
+ */
1154
+ thinkingBudgetTokens?: number;
1155
+ /**
1156
+ * Effort level for adaptive thinking models.
1157
+ * Controls how much thinking Claude allocates:
1158
+ * - "max": Always thinks with no constraints (Opus 4.6 only)
1159
+ * - "xhigh": Highest reasoning level (Opus 4.7+, Fable 5)
1160
+ * - "high": Always thinks, deep reasoning
1161
+ * - "medium": Moderate thinking, may skip for simple queries
1162
+ * - "low": Minimal thinking, skips for simple tasks
1163
+ * Ignored for older models.
1164
+ * Default: omitted unless `streamSimple()` maps a simple reasoning
1165
+ * level to this option.
1166
+ */
1167
+ effort?: AnthropicEffort;
1168
+ /**
1169
+ * Controls how thinking content is returned in API responses.
1170
+ * - "summarized": Thinking blocks contain summarized thinking text.
1171
+ * - "omitted": Thinking blocks return an empty thinking field; the encrypted
1172
+ * signature still travels back for multi-turn continuity. Use for faster
1173
+ * time-to-first-text-token when your UI does not surface thinking.
1174
+ *
1175
+ * Note: Anthropic's API default for Claude Opus 4.7 and Claude Mythos Preview
1176
+ * is "omitted". We default to "summarized" here to keep behavior consistent
1177
+ * with older Claude 4 models. Set this explicitly to "omitted" to opt in.
1178
+ * Default: "summarized" when thinking is enabled.
1179
+ */
1180
+ thinkingDisplay?: AnthropicThinkingDisplay;
1181
+ /**
1182
+ * Whether to request the interleaved thinking beta header for non-adaptive
1183
+ * thinking models. Adaptive thinking models have interleaved thinking built in,
1184
+ * so the header is skipped for them regardless of this setting.
1185
+ * Default: true.
1186
+ */
1187
+ interleavedThinking?: boolean;
1188
+ /**
1189
+ * Anthropic tool choice behavior. String values map to Anthropic's built-in
1190
+ * choices; `{ type: "tool", name }` forces a specific tool.
1191
+ * Default: omitted (Anthropic default behavior, currently equivalent to auto).
1192
+ */
1193
+ toolChoice?: "auto" | "any" | "none" | {
1194
+ type: "tool";
1195
+ name: string;
1196
+ };
1197
+ /**
1198
+ * Pre-built Anthropic client instance. When provided, skips internal client
1199
+ * construction entirely. Use this to inject alternative SDK clients such as
1200
+ * `AnthropicVertex` that shares the same messaging API.
1201
+ */
1202
+ client?: Anthropic;
1203
+ }
1204
+
1205
+ /**
1206
+ * Request auth for a single model request. If a value cannot be expressed as
1207
+ * `apiKey`, `headers`, or `baseUrl`, it is provider config, not auth.
1208
+ */
1209
+ interface ModelAuth {
1210
+ apiKey?: string;
1211
+ headers?: ProviderHeaders;
1212
+ baseUrl?: string;
1213
+ }
1214
+ /**
1215
+ * Stored api-key credential. `env` holds provider-scoped environment/config
1216
+ * values such as Cloudflare account/gateway ids.
1217
+ */
1218
+ interface ApiKeyCredential {
1219
+ type: "api_key";
1220
+ key?: string;
1221
+ env?: ProviderEnv;
1222
+ }
1223
+ /** OAuth token data returned by extension compatibility flows. */
1224
+ interface OAuthCredentials {
1225
+ refresh: string;
1226
+ access: string;
1227
+ expires: number;
1228
+ [key: string]: unknown;
1229
+ }
1230
+ /** Stored canonical OAuth credential. */
1231
+ interface OAuthCredential extends OAuthCredentials {
1232
+ type: "oauth";
1233
+ }
1234
+ /** One type-tagged credential per provider — the shape of today's auth.json. */
1235
+ type Credential = ApiKeyCredential | OAuthCredential;
1236
+ /** Environment access for auth resolution. Injectable for tests and browsers. */
1237
+ interface AuthContext {
1238
+ env(name: string): Promise<string | undefined>;
1239
+ /** Check whether a file exists. Supports a leading `~`. Always false in browsers. */
1240
+ fileExists(path: string): Promise<boolean>;
1241
+ }
1242
+ /** Result of resolving auth for a model. */
1243
+ interface AuthResult {
1244
+ auth: ModelAuth;
1245
+ /** Provider-scoped environment/config values resolved from credentials and ambient context. */
1246
+ env?: ProviderEnv;
1247
+ /** Human-readable label for status UI: "ANTHROPIC_API_KEY", "OAuth", "~/.aws/credentials". */
1248
+ source?: string;
1249
+ }
1250
+ interface AuthCheck {
1251
+ source?: string;
1252
+ type: "api_key" | "oauth";
1253
+ }
1254
+ /**
1255
+ * Prompt shown to the user during login. `signal` lets the flow cancel a
1256
+ * pending prompt when an out-of-band event resolves the step, e.g. a
1257
+ * `manual_code` prompt raced against a callback server, aborted when the
1258
+ * callback wins.
1259
+ */
1260
+ type AuthPrompt = {
1261
+ signal?: AbortSignal;
1262
+ } & ({
1263
+ type: "text";
1264
+ message: string;
1265
+ placeholder?: string;
1266
+ } | {
1267
+ type: "secret";
1268
+ message: string;
1269
+ placeholder?: string;
1270
+ } | {
1271
+ type: "select";
1272
+ message: string;
1273
+ options: readonly {
1274
+ id: string;
1275
+ label: string;
1276
+ description?: string;
1277
+ }[];
1278
+ } | {
1279
+ type: "manual_code";
1280
+ message: string;
1281
+ placeholder?: string;
1282
+ });
1283
+ interface AuthInfoLink {
1284
+ url: string;
1285
+ label?: string;
1286
+ }
1287
+ type AuthEvent = {
1288
+ type: "info";
1289
+ message: string;
1290
+ links?: readonly AuthInfoLink[];
1291
+ } | {
1292
+ type: "auth_url";
1293
+ url: string;
1294
+ instructions?: string;
1295
+ } | {
1296
+ type: "device_code";
1297
+ userCode: string;
1298
+ verificationUri: string;
1299
+ intervalSeconds?: number;
1300
+ expiresInSeconds?: number;
1301
+ } | {
1302
+ type: "progress";
1303
+ message: string;
1304
+ };
1305
+ /**
1306
+ * Login interaction callbacks serving both api-key and OAuth flows.
1307
+ *
1308
+ * `prompt()` returns the entered/selected string (`select` returns the option
1309
+ * id). Rejects on cancel/abort. `signal` aborts the whole login flow;
1310
+ * per-prompt cancellation uses `AuthPrompt.signal`.
1311
+ */
1312
+ interface AuthInteraction {
1313
+ signal?: AbortSignal;
1314
+ prompt(prompt: AuthPrompt): Promise<string>;
1315
+ notify(event: AuthEvent): void;
1316
+ }
1317
+ /** Normalized interaction passed to provider login implementations. */
1318
+ type ProviderAuthInteraction = AuthInteraction & {
1319
+ signal: AbortSignal;
1320
+ };
1321
+ /**
1322
+ * Api-key auth: stored key/provider env plus ambient sources (env vars, AWS
1323
+ * profiles, ADC files). Ambient-only providers omit `login`.
1324
+ */
1325
+ interface ApiKeyAuth {
1326
+ /** Display name, e.g. "Anthropic API key". */
1327
+ name: string;
1328
+ /** Interactive setup (prompt for key/provider env). Absent = ambient-only. */
1329
+ login?(interaction: ProviderAuthInteraction): Promise<ApiKeyCredential>;
1330
+ /**
1331
+ * Optional side-effect-free availability check. Use this when `resolve()` may
1332
+ * execute commands or perform other request-time work. Missing means Models
1333
+ * checks availability by resolving auth.
1334
+ */
1335
+ check?(input: {
1336
+ ctx: AuthContext;
1337
+ credential?: ApiKeyCredential;
1338
+ signal: AbortSignal;
1339
+ }): Promise<AuthCheck | undefined>;
1340
+ /**
1341
+ * Resolve auth from the stored credential and/or ambient sources, merging
1342
+ * per field (`credential.key ?? env("...")`, `credential.env?.NAME ?? env("...")`).
1343
+ * undefined = not configured. Resolution is provider-scoped; model-specific
1344
+ * endpoint preparation happens after auth has been resolved.
1345
+ */
1346
+ resolve(input: {
1347
+ ctx: AuthContext;
1348
+ credential?: ApiKeyCredential;
1349
+ signal: AbortSignal;
1350
+ }): Promise<AuthResult | undefined>;
1351
+ }
1352
+ /** App-supplied context for `Models.login`. */
1353
+ interface LoginOptions {
1354
+ /**
1355
+ * Returns the stable ID of this app installation, e.g. sent to OpenAI as its
1356
+ * agent host ID. Called only by login flows that need it, so apps can create
1357
+ * the ID on first use and must return the same ID on every later call.
1358
+ */
1359
+ getDeviceId?: () => string;
1360
+ /**
1361
+ * Name this app introduces itself with during login, e.g. OpenAI's agent name hint and
1362
+ * Codex originator. Defaults to pi's own name.
1363
+ */
1364
+ agentName?: string;
1365
+ }
1366
+ /**
1367
+ * OAuth auth. The `refresh`/`toAuth` split lets `Models` own the locked
1368
+ * refresh pattern: `refresh` produces a credential, `toAuth` derives request
1369
+ * auth from whatever credential ends up stored.
1370
+ */
1371
+ interface OAuthAuth {
1372
+ /** Display name, e.g. "Anthropic (Claude Pro/Max)". */
1373
+ name: string;
1374
+ /** Whether access through this auth method is backed by a provider subscription. */
1375
+ isSubscription?: boolean;
1376
+ /** Selector label for the OAuth login option, e.g. "Sign in with SuperGrok or X Premium". */
1377
+ loginLabel?: string;
1378
+ login(interaction: ProviderAuthInteraction, options?: LoginOptions): Promise<OAuthCredential>;
1379
+ /**
1380
+ * Exchange the refresh token. Network call; throws on failure
1381
+ * (invalid_grant etc.). `Models` runs this under the store lock.
1382
+ */
1383
+ refresh(credential: OAuthCredential, signal: AbortSignal): Promise<OAuthCredential>;
1384
+ /**
1385
+ * Side-effect-free derivation of request auth from a valid credential.
1386
+ * Covers per-credential baseUrl (GitHub Copilot). Async so lazy wrappers
1387
+ * can load the implementation on first use.
1388
+ */
1389
+ toAuth(credential: OAuthCredential): Promise<ModelAuth>;
1390
+ }
1391
+ /**
1392
+ * Provider auth. At least one of `apiKey`/`oauth` must be present: even
1393
+ * ambient-credential providers and keyless local servers provide `apiKey`
1394
+ * auth whose `resolve()` reports whether the provider is configured.
1395
+ */
1396
+ interface ProviderAuth {
1397
+ apiKey?: ApiKeyAuth;
1398
+ oauth?: OAuthAuth;
1399
+ }
1400
+
1401
+ interface ModelsStoreEntry {
1402
+ /** Persisted models of every type. */
1403
+ models: readonly AnyModel[];
1404
+ /** Unix timestamp from the remote catalog's Last-Modified header. */
1405
+ lastModified?: number;
1406
+ /** Unix timestamp of the last completed remote check. */
1407
+ checkedAt?: number;
1408
+ /**
1409
+ * Opaque validator from the remote catalog's ETag header, stored verbatim
1410
+ * (quotes included) and echoed back as If-None-Match.
1411
+ */
1412
+ etag?: string;
1413
+ }
1414
+
1415
+ interface ModelsPublication {
1416
+ /** Provider-selected persisted catalog. Omit to leave storage unchanged; null deletes it. */
1417
+ persist?: ModelsStoreEntry | null;
1418
+ /** Optional synchronous update of provider-private in-memory catalog state. */
1419
+ update?: () => void;
1420
+ }
1421
+ interface RefreshModelsContext {
1422
+ /** Effective configured credential. OAuth credentials are refreshed before network access. */
1423
+ credential?: Credential;
1424
+ /** Immutable provider-scoped catalog snapshot captured before this refresh phase. */
1425
+ stored?: Readonly<ModelsStoreEntry>;
1426
+ /**
1427
+ * Generation-checked publication. Persistence policy remains provider-owned;
1428
+ * the update runs synchronously only after the selected persistence mutation.
1429
+ */
1430
+ publish(publication: ModelsPublication): Promise<boolean>;
1431
+ /** False during offline/cache-only initialization. */
1432
+ allowNetwork: boolean;
1433
+ /** Bypass provider freshness checks and fetch immediately when network access is allowed. */
1434
+ force?: boolean;
1435
+ /** Always present, including when the public refresh caller omits its optional signal. */
1436
+ signal: AbortSignal;
1437
+ }
1438
+ /** Any model a provider with chat APIs `TApi` can list. */
1439
+ type ProviderModel<TApi extends Api> = Model$1<TApi> | ImageModel<ImageApi> | ClassifierModel<ClassifierApi>;
1440
+ /**
1441
+ * A provider is the concrete runtime unit. It owns id/name/base metadata,
1442
+ * auth methods, model listing, and the operations its models support
1443
+ * (streaming, image generation, classification).
1444
+ *
1445
+ * `TApi` lets concrete provider factories declare which chat APIs their models
1446
+ * use (e.g. `openaiProvider(): Provider<"openai-responses" | "openai-completions">`),
1447
+ * giving typed chat model lists to direct factory users. Other model types use
1448
+ * their operation-specific API unions. Inside a `Models` collection providers
1449
+ * are held as `Provider<Api>`.
1450
+ */
1451
+ interface Provider<TApi extends Api = Api> {
1452
+ readonly id: string;
1453
+ readonly name: string;
1454
+ readonly baseUrl?: string;
1455
+ readonly headers?: ProviderHeaders;
1456
+ /**
1457
+ * Required: at least one of `apiKey`/`oauth`. Every provider has auth
1458
+ * semantics — even providers with only ambient credentials (env vars, AWS
1459
+ * profiles, ADC files) and keyless local servers provide `apiKey` auth
1460
+ * whose `resolve()` reports whether the provider is configured.
1461
+ * `Models.getAuth()` returns undefined when the provider is unconfigured.
1462
+ */
1463
+ readonly auth: ProviderAuth;
1464
+ /**
1465
+ * Current known chat models, sync. Static providers return their catalog;
1466
+ * dynamic providers return the list as of the last `refreshModels()` (empty
1467
+ * before the first). Must not throw; `Models` treats a throwing
1468
+ * implementation as having no models.
1469
+ */
1470
+ getModels(): readonly Model$1<TApi>[];
1471
+ /**
1472
+ * Current known models of every type, sync, with the same contract as
1473
+ * `getModels()`. Providers with only chat models may omit it; `Models` then
1474
+ * uses `getModels()`. Model ids are unique within each type; one upstream
1475
+ * model may have separate entries for different operations.
1476
+ */
1477
+ getAllModels?(): readonly ProviderModel<TApi>[];
1478
+ /**
1479
+ * Dynamic providers only: restore `context.stored` and optionally fetch a newer list using
1480
+ * the effective credential. Implementations retain their previous list on failure, publish
1481
+ * persistence and synchronous state changes through `context.publish()`, and honor the
1482
+ * shared abort signal for blocking work.
1483
+ */
1484
+ refreshModels?(context: RefreshModelsContext): Promise<void>;
1485
+ /**
1486
+ * Optional provider policy for credential-specific model availability.
1487
+ * `getModels()` remains the complete synchronous chat catalog; `Models.getAvailable()`
1488
+ * applies this filter after confirming that provider auth is configured.
1489
+ */
1490
+ filterModels?(models: readonly Model$1<TApi>[], credential: Credential | undefined): readonly Model$1<TApi>[];
1491
+ /**
1492
+ * Optional credential-specific availability policy across every model type.
1493
+ * Without it, `Models.getAllAvailable()` applies `filterModels` to chat models
1494
+ * and keeps every other model.
1495
+ */
1496
+ filterAllModels?(models: readonly ProviderModel<TApi>[], credential: Credential | undefined): readonly ProviderModel<TApi>[];
1497
+ /** Stream a normalized transcript. `Models` normalizes the caller's `Context` before dispatching here. */
1498
+ stream<T extends TApi>(model: Model$1<T>, context: TranscriptContext, options?: ApiStreamOptions<T>): AssistantMessageEventStream;
1499
+ streamSimple(model: Model$1<TApi>, context: TranscriptContext, options?: SimpleStreamOptions): AssistantMessageEventStream;
1500
+ fetchDeferred?(model: Model$1<TApi>, handle: DeferredHandle, options?: DeferredFetchOptions): AssistantMessageEventStream;
1501
+ cancelDeferred?(model: Model$1<TApi>, handle: DeferredHandle, options?: DeferredCancelOptions): Promise<void>;
1502
+ /** Present when the provider supports dedicated image models. Never rejects. */
1503
+ generateImages?(model: ImageModel<ImageApi>, context: ImagesContext, options?: ImagesOptions): Promise<AssistantImages>;
1504
+ /** Present when the provider supports structured classifier models. Never rejects. */
1505
+ classify?(model: ClassifierModel<ClassifierApi>, context: ClassifierContext, options?: ClassifierOptions): Promise<ClassifierResult>;
1506
+ }
1507
+
1508
+ /** Settings discovery includes lifecycle data that the host's generic model DTO omits. */
1509
+
1510
+ interface GoModel {
1511
+ id: string;
1512
+ name?: string;
1513
+ contextWindow?: number;
1514
+ maxTokens?: number;
1515
+ /** Token budget controls available to this model, including their catalog bounds. */
1516
+ reasoningBudget?: ThinkingBudgetRange;
1517
+ deprecated?: boolean;
1518
+ releaseDate?: string;
1519
+ /** Input modalities models.dev declares, in {@link INPUT_MODALITIES} order. */
1520
+ inputModalities?: readonly InputModality[];
1521
+ /** Advertised by the gateway but lacking a usable protocol and capability configuration. */
1522
+ configurationMissing?: boolean;
1523
+ }
1524
+ interface ThinkingBudgetRange {
1525
+ min: number;
1526
+ max: number;
1527
+ }
1528
+ /**
1529
+ * Input modalities this page can name. models.dev uses these same five tokens, so
1530
+ * an unknown token is dropped rather than rendered as an untranslatable chip.
1531
+ */
1532
+ declare const INPUT_MODALITIES: readonly ["text", "image", "audio", "video", "pdf"];
1533
+ type InputModality = typeof INPUT_MODALITIES[number];
1534
+ /** Last successful check of one catalog source, plus any current refresh failure. */
1535
+ interface GoCatalogSourceStatus {
1536
+ readonly updatedAt?: number;
1537
+ readonly error?: string;
1538
+ readonly warning?: string;
1539
+ }
1540
+ /** A failed refresh retains the Host's usable data with an explicit diagnostic. */
1541
+ interface GoModelCatalog {
1542
+ readonly models: readonly GoModel[];
1543
+ readonly stale: boolean;
1544
+ readonly error?: string;
1545
+ /** Optional for clients reading an older Host response. Timestamps are Unix milliseconds. */
1546
+ readonly sources?: {
1547
+ readonly listing: GoCatalogSourceStatus;
1548
+ readonly metadata: GoCatalogSourceStatus;
1549
+ };
1550
+ }
1551
+ declare module '@deepseek-ai/dsh-typert-protocol' {
1552
+ interface TypertRemoteNamespaceMap {
1553
+ opencodeGoModels: {
1554
+ read(): Promise<RemoteResult<GoModelCatalog>>;
1555
+ };
1556
+ }
1557
+ }
1558
+
1559
+ /** Public SDK types are bundled at build time, alongside the private implementation. */
1560
+
1561
+ /** User controls are independent of the SDK's internal level used to enable a switch. */
1562
+ type Model<TApi extends Api> = Model$1<TApi> & {
1563
+ reasoningControl?: 'toggle' | 'effort' | 'budget';
1564
+ reasoningBudget?: ThinkingBudgetRange;
1565
+ reasoningBudgetPresets?: readonly number[];
1566
+ };
1567
+
1568
+ export type { Api, AssistantMessage, AssistantMessageEvent, Context, ImageContent, Message, Model, ModelCost, ModelThinkingLevel, Provider, TextContent, ThinkingBudgets, ThinkingLevelMap, Tool, ToolCall, Usage };