@opencode/ai 2.0.23 → 2.0.25
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.
- package/README.md +1 -1
- package/dist/cache-policy.js +12 -9
- package/dist/protocols/alibaba-messages.d.ts +3 -0
- package/dist/protocols/alibaba-responses.d.ts +3 -0
- package/dist/protocols/anthropic-messages.d.ts +8 -5
- package/dist/protocols/anthropic-messages.js +19 -16
- package/dist/protocols/bedrock-converse.js +3 -1
- package/dist/protocols/google-interactions.d.ts +1 -1
- package/dist/protocols/meta-messages.d.ts +4 -1
- package/dist/protocols/meta-responses.d.ts +3 -0
- package/dist/protocols/open-responses.d.ts +18 -12
- package/dist/protocols/open-responses.js +7 -5
- package/dist/protocols/openai-responses.d.ts +3 -0
- package/dist/protocols/utils/bedrock-auth.js +2 -1
- package/dist/protocols/utils/gateway-protocol.d.ts +17 -0
- package/dist/protocols/utils/gateway-protocol.js +57 -0
- package/dist/protocols/utils/openai-options.d.ts +1 -1
- package/dist/protocols/utils/openai-options.js +2 -1
- package/dist/protocols/utils/tool-stream.d.ts +1 -1
- package/dist/protocols/utils/tool-stream.js +5 -5
- package/dist/protocols/xai-responses.d.ts +3 -0
- package/dist/protocols/zai-messages.d.ts +3 -0
- package/dist/providers/amazon-bedrock-mantle.d.ts +1 -1
- package/dist/providers/amazon-bedrock-mantle.js +4 -3
- package/dist/providers/anthropic-compatible.d.ts +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/cloudflare-ai-gateway.d.ts +2 -2
- package/dist/providers/google-vertex-messages.d.ts +1 -1
- package/dist/providers/google-vertex-messages.js +1 -0
- package/dist/providers/google-vertex.js +1 -1
- package/dist/providers/google.d.ts +4 -4
- package/dist/providers/meta.d.ts +1 -1
- package/dist/providers/minimax.d.ts +1 -1
- package/dist/providers/moonshot.d.ts +1 -1
- package/dist/providers/vercel-ai-gateway/chat.d.ts +2 -0
- package/dist/providers/vercel-ai-gateway/chat.js +1 -0
- package/dist/providers/vercel-ai-gateway/messages.d.ts +2 -0
- package/dist/providers/vercel-ai-gateway/messages.js +1 -0
- package/dist/providers/vercel-ai-gateway/responses.d.ts +2 -0
- package/dist/providers/vercel-ai-gateway/responses.js +1 -0
- package/dist/providers/vercel-ai-gateway.d.ts +91 -9
- package/dist/providers/vercel-ai-gateway.js +161 -21
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1283,7 +1283,7 @@ const gateway = CloudflareAIGateway.configure({
|
|
|
1283
1283
|
}).model("workers-ai/@cf/meta/llama-3.1-8b-instruct")
|
|
1284
1284
|
```
|
|
1285
1285
|
|
|
1286
|
-
Included LLM providers: OpenAI, Anthropic, Google (Gemini), Google Vertex, Amazon Bedrock, Azure OpenAI, Baseten, Cerebras, Cohere, Cloudflare AI Gateway, Cloudflare Workers AI, DeepInfra, DeepSeek, Fireworks, Groq, Mistral, OpenRouter, TogetherAI, and xAI. Z.ai currently exposes image generation. Generic Chat Completions, Responses, and Anthropic Messages-compatible entrypoints support custom endpoints.
|
|
1286
|
+
Included LLM providers: OpenAI, Anthropic, Google (Gemini), Google Vertex, Amazon Bedrock, Azure OpenAI, Baseten, Cerebras, Cohere, Cloudflare AI Gateway, Cloudflare Workers AI, DeepInfra, DeepSeek, Fireworks, Groq, Mistral, OpenRouter, TogetherAI, Vercel AI Gateway, and xAI. Z.ai currently exposes image generation. Generic Chat Completions, Responses, and Anthropic Messages-compatible entrypoints support custom endpoints.
|
|
1287
1287
|
|
|
1288
1288
|
Each named provider owns its module, endpoint, authentication, and route setup. Providers with the same wire format compose the shared protocol directly:
|
|
1289
1289
|
|
package/dist/cache-policy.js
CHANGED
|
@@ -46,21 +46,22 @@ const RESPECTS_INLINE_HINTS = new Set([
|
|
|
46
46
|
"meta-messages",
|
|
47
47
|
"minimax-messages",
|
|
48
48
|
"moonshot-messages",
|
|
49
|
+
"vercel-ai-gateway-messages",
|
|
49
50
|
"zai-coding-messages",
|
|
50
51
|
"bedrock-converse",
|
|
51
52
|
"openrouter",
|
|
52
53
|
"digitalocean",
|
|
53
54
|
]);
|
|
54
|
-
// OpenRouter upstreams other than Anthropic and Alibaba Qwen cache without breakpoints.
|
|
55
|
-
// breakpoint, so a conversation-tail breakpoint writes a new cache every step and costs
|
|
56
|
-
// breakpoints on tool definitions and caches tools with the system prompt.
|
|
55
|
+
// OpenRouter and Vercel AI Gateway upstreams other than Anthropic and Alibaba Qwen cache without breakpoints.
|
|
56
|
+
// Gemini uses only the last breakpoint, so a conversation-tail breakpoint writes a new cache every step and costs
|
|
57
|
+
// more than none. Qwen ignores breakpoints on tool definitions and caches tools with the system prompt.
|
|
57
58
|
const QWEN = { system: true, messages: { tail: 1 } };
|
|
58
|
-
const
|
|
59
|
+
const gatewayPolicy = (modelID) => {
|
|
59
60
|
// `~anthropic/claude-sonnet-latest` style IDs are OpenRouter aliases for the latest model in a family.
|
|
60
61
|
const id = modelID.replace(/^~/, "");
|
|
61
62
|
if (id.startsWith("anthropic/"))
|
|
62
63
|
return AUTO;
|
|
63
|
-
if (id.startsWith("qwen/"))
|
|
64
|
+
if (id.startsWith("qwen/") || id.startsWith("alibaba/qwen"))
|
|
64
65
|
return QWEN;
|
|
65
66
|
return NONE;
|
|
66
67
|
};
|
|
@@ -142,11 +143,13 @@ const countHints = (request) => countToolHints(request.tools) +
|
|
|
142
143
|
request.messages.reduce((count, message) => count +
|
|
143
144
|
message.content.reduce((contentCount, part) => contentCount + ("cache" in part && part.cache !== undefined ? 1 : 0), 0), 0);
|
|
144
145
|
export const applyCachePolicy = (request) => {
|
|
145
|
-
|
|
146
|
+
const route = request.model.route.id;
|
|
147
|
+
if (!RESPECTS_INLINE_HINTS.has(route))
|
|
146
148
|
return request;
|
|
147
|
-
const policy =
|
|
148
|
-
|
|
149
|
-
|
|
149
|
+
const policy = (route === "openrouter" || route === "vercel-ai-gateway-messages") &&
|
|
150
|
+
(request.cache === undefined || request.cache === "auto")
|
|
151
|
+
? gatewayPolicy(request.model.id)
|
|
152
|
+
: route === "alibaba-chat" && (request.cache === undefined || request.cache === "auto")
|
|
150
153
|
? request.model.id.toLowerCase().startsWith("qwen")
|
|
151
154
|
? QWEN
|
|
152
155
|
: NONE
|
|
@@ -272,8 +272,10 @@ export declare const protocol: Protocol<{
|
|
|
272
272
|
readonly top_k?: number | undefined;
|
|
273
273
|
readonly stop_sequences?: readonly string[] | undefined;
|
|
274
274
|
}, string, {
|
|
275
|
+
readonly [x: string]: unknown;
|
|
275
276
|
readonly type: string;
|
|
276
277
|
readonly message?: {
|
|
278
|
+
readonly [x: string]: unknown;
|
|
277
279
|
readonly usage?: {
|
|
278
280
|
readonly [x: string]: unknown;
|
|
279
281
|
readonly input_tokens?: number | null | undefined;
|
|
@@ -306,6 +308,7 @@ export declare const protocol: Protocol<{
|
|
|
306
308
|
} | undefined;
|
|
307
309
|
} | undefined;
|
|
308
310
|
readonly error?: {
|
|
311
|
+
readonly [x: string]: unknown;
|
|
309
312
|
readonly type?: string | undefined;
|
|
310
313
|
readonly message?: string | undefined;
|
|
311
314
|
} | undefined;
|
|
@@ -213,13 +213,16 @@ export declare const protocol: Protocol<{
|
|
|
213
213
|
}[] | undefined;
|
|
214
214
|
readonly error?: unknown;
|
|
215
215
|
readonly usage?: {
|
|
216
|
+
readonly [x: string]: unknown;
|
|
216
217
|
readonly input_tokens?: number | undefined;
|
|
217
218
|
readonly output_tokens?: number | undefined;
|
|
218
219
|
readonly output_tokens_details?: {
|
|
220
|
+
readonly [x: string]: unknown;
|
|
219
221
|
readonly reasoning_tokens?: number | undefined;
|
|
220
222
|
} | null | undefined;
|
|
221
223
|
readonly total_tokens?: number | undefined;
|
|
222
224
|
readonly input_tokens_details?: {
|
|
225
|
+
readonly [x: string]: unknown;
|
|
223
226
|
readonly cached_tokens?: number | undefined;
|
|
224
227
|
readonly cache_write_tokens?: number | undefined;
|
|
225
228
|
} | null | undefined;
|
|
@@ -58,7 +58,7 @@ declare const Thinking: Schema.Union<readonly [Schema.decodeTo<Schema.Struct<{
|
|
|
58
58
|
}>>;
|
|
59
59
|
readonly type: Schema.tag<"adaptive">;
|
|
60
60
|
}>, Schema.Struct<{
|
|
61
|
-
readonly type: Schema.
|
|
61
|
+
readonly type: Schema.Literals<readonly ["disabled", "between_tools"]>;
|
|
62
62
|
}>]>;
|
|
63
63
|
declare const Options: Schema.Struct<{
|
|
64
64
|
/** Advanced in-band compaction. The caller owns checkpoint persistence and recovery. */
|
|
@@ -101,7 +101,7 @@ declare const Options: Schema.Struct<{
|
|
|
101
101
|
}>>;
|
|
102
102
|
readonly type: Schema.tag<"adaptive">;
|
|
103
103
|
}>, Schema.Struct<{
|
|
104
|
-
readonly type: Schema.
|
|
104
|
+
readonly type: Schema.Literals<readonly ["disabled", "between_tools"]>;
|
|
105
105
|
}>]>>;
|
|
106
106
|
readonly effort: Schema.optional<Schema.String>;
|
|
107
107
|
readonly service_tier: Schema.optional<Schema.declare<import("../schema/options.js").OpenString<"auto" | "standard_only">, import("../schema/options.js").OpenString<"auto" | "standard_only">>>;
|
|
@@ -382,7 +382,7 @@ export declare const AnthropicMessagesBody: Schema.Struct<{
|
|
|
382
382
|
}>>;
|
|
383
383
|
readonly type: Schema.tag<"adaptive">;
|
|
384
384
|
}>, Schema.Struct<{
|
|
385
|
-
readonly type: Schema.
|
|
385
|
+
readonly type: Schema.Literals<readonly ["disabled", "between_tools"]>;
|
|
386
386
|
}>]>>;
|
|
387
387
|
output_config: Schema.optional<Schema.Struct<{
|
|
388
388
|
readonly effort: Schema.optional<Schema.String>;
|
|
@@ -638,7 +638,7 @@ export declare const protocol: Protocol<{
|
|
|
638
638
|
readonly prefix_mismatch_behavior?: import("../schema/options.js").OpenString<"error" | "drop_block"> | undefined;
|
|
639
639
|
} | undefined;
|
|
640
640
|
} | {
|
|
641
|
-
readonly type: "disabled";
|
|
641
|
+
readonly type: "disabled" | "between_tools";
|
|
642
642
|
} | undefined;
|
|
643
643
|
readonly service_tier?: import("../schema/options.js").OpenString<"auto" | "standard_only"> | undefined;
|
|
644
644
|
readonly container?: string | {
|
|
@@ -684,8 +684,10 @@ export declare const protocol: Protocol<{
|
|
|
684
684
|
readonly top_k?: number | undefined;
|
|
685
685
|
readonly stop_sequences?: readonly string[] | undefined;
|
|
686
686
|
}, string, {
|
|
687
|
+
readonly [x: string]: unknown;
|
|
687
688
|
readonly type: string;
|
|
688
689
|
readonly message?: {
|
|
690
|
+
readonly [x: string]: unknown;
|
|
689
691
|
readonly usage?: {
|
|
690
692
|
readonly [x: string]: unknown;
|
|
691
693
|
readonly input_tokens?: number | null | undefined;
|
|
@@ -718,6 +720,7 @@ export declare const protocol: Protocol<{
|
|
|
718
720
|
} | undefined;
|
|
719
721
|
} | undefined;
|
|
720
722
|
readonly error?: {
|
|
723
|
+
readonly [x: string]: unknown;
|
|
721
724
|
readonly type?: string | undefined;
|
|
722
725
|
readonly message?: string | undefined;
|
|
723
726
|
} | undefined;
|
|
@@ -995,7 +998,7 @@ export declare const route: Route<{
|
|
|
995
998
|
readonly prefix_mismatch_behavior?: import("../schema/options.js").OpenString<"error" | "drop_block"> | undefined;
|
|
996
999
|
} | undefined;
|
|
997
1000
|
} | {
|
|
998
|
-
readonly type: "disabled";
|
|
1001
|
+
readonly type: "disabled" | "between_tools";
|
|
999
1002
|
} | undefined;
|
|
1000
1003
|
readonly service_tier?: import("../schema/options.js").OpenString<"auto" | "standard_only"> | undefined;
|
|
1001
1004
|
readonly container?: string | {
|
|
@@ -223,7 +223,7 @@ const AnthropicThinkingEnabled = Schema.Struct({
|
|
|
223
223
|
...AnthropicThinkingFields,
|
|
224
224
|
});
|
|
225
225
|
const AnthropicThinkingAdaptive = Schema.Struct({ type: Schema.tag("adaptive"), ...AnthropicThinkingFields });
|
|
226
|
-
const AnthropicThinkingDisabled = Schema.Struct({ type: Schema.
|
|
226
|
+
const AnthropicThinkingDisabled = Schema.Struct({ type: Schema.Literals(["disabled", "between_tools"]) });
|
|
227
227
|
const AnthropicThinking = Schema.Union([AnthropicThinkingEnabled, AnthropicThinkingAdaptive, AnthropicThinkingDisabled]);
|
|
228
228
|
// SDK OutputConfig:2684 {effort?: "low"|"medium"|"high"|"xhigh"|"max"|null, format?: JSONOutputFormat:2399}
|
|
229
229
|
const AnthropicJsonOutputFormat = Schema.Struct({
|
|
@@ -332,7 +332,7 @@ const AnthropicUsage = Schema.StructWithRest(Schema.Struct({
|
|
|
332
332
|
...AnthropicIterationUsage.schema.fields,
|
|
333
333
|
iterations: Schema.optional(Schema.Array(AnthropicIterationUsage)),
|
|
334
334
|
}), [JsonObject]);
|
|
335
|
-
const AnthropicStreamBlock = Schema.Struct({
|
|
335
|
+
const AnthropicStreamBlock = Schema.StructWithRest(Schema.Struct({
|
|
336
336
|
type: Schema.String,
|
|
337
337
|
id: Schema.optional(Schema.String),
|
|
338
338
|
name: Schema.optional(Schema.String),
|
|
@@ -348,9 +348,9 @@ const AnthropicStreamBlock = Schema.Struct({
|
|
|
348
348
|
// server_tool_use id in `tool_use_id`.
|
|
349
349
|
tool_use_id: Schema.optional(Schema.String),
|
|
350
350
|
content: Schema.optional(Schema.Unknown),
|
|
351
|
-
});
|
|
351
|
+
}), [JsonObject]);
|
|
352
352
|
const decodeAnthropicStreamBlock = Schema.decodeUnknownOption(AnthropicStreamBlock);
|
|
353
|
-
const AnthropicStreamDelta = Schema.Struct({
|
|
353
|
+
const AnthropicStreamDelta = Schema.StructWithRest(Schema.Struct({
|
|
354
354
|
content: optionalNull(Schema.String),
|
|
355
355
|
type: Schema.optional(Schema.String),
|
|
356
356
|
text: Schema.optional(Schema.String),
|
|
@@ -359,13 +359,13 @@ const AnthropicStreamDelta = Schema.Struct({
|
|
|
359
359
|
signature: Schema.optional(Schema.String),
|
|
360
360
|
stop_reason: optionalNull(Schema.String),
|
|
361
361
|
stop_sequence: optionalNull(Schema.String),
|
|
362
|
-
stop_details: optionalNull(Schema.Struct({ category: optionalNull(Schema.String), explanation: optionalNull(Schema.String) })),
|
|
363
|
-
});
|
|
362
|
+
stop_details: optionalNull(Schema.StructWithRest(Schema.Struct({ category: optionalNull(Schema.String), explanation: optionalNull(Schema.String) }), [JsonObject])),
|
|
363
|
+
}), [JsonObject]);
|
|
364
364
|
const decodeAnthropicStreamDelta = Schema.decodeUnknownOption(AnthropicStreamDelta);
|
|
365
|
-
const AnthropicEvent = Schema.Struct({
|
|
365
|
+
const AnthropicEvent = Schema.StructWithRest(Schema.Struct({
|
|
366
366
|
type: Schema.String,
|
|
367
367
|
index: Schema.optional(Schema.Number),
|
|
368
|
-
message: Schema.optional(Schema.Struct({ usage: Schema.optional(AnthropicUsage) })),
|
|
368
|
+
message: Schema.optional(Schema.StructWithRest(Schema.Struct({ usage: Schema.optional(AnthropicUsage) }), [JsonObject])),
|
|
369
369
|
content_block: Schema.optional(Schema.Unknown),
|
|
370
370
|
delta: Schema.optional(Schema.Unknown),
|
|
371
371
|
usage: Schema.optional(AnthropicUsage),
|
|
@@ -373,8 +373,8 @@ const AnthropicEvent = Schema.Struct({
|
|
|
373
373
|
// OpenAI-compatible proxies and gateway translations occasionally drop one
|
|
374
374
|
// or the other; mark them optional so a partial payload still parses and
|
|
375
375
|
// the parser can fall back to whichever field is populated.
|
|
376
|
-
error: Schema.optional(Schema.Struct({ type: Schema.optional(Schema.String), message: Schema.optional(Schema.String) })),
|
|
377
|
-
});
|
|
376
|
+
error: Schema.optional(Schema.StructWithRest(Schema.Struct({ type: Schema.optional(Schema.String), message: Schema.optional(Schema.String) }), [JsonObject])),
|
|
377
|
+
}), [JsonObject]);
|
|
378
378
|
const invalid = ProviderShared.invalidRequest;
|
|
379
379
|
// =============================================================================
|
|
380
380
|
// Request Lowering
|
|
@@ -855,12 +855,15 @@ const lowerMessages = Effect.fnUntraced(function* (request, breakpoints) {
|
|
|
855
855
|
// TODO: Move per-model capability heuristics (`supportsEffortUpdates`, `supportsNativeSystemUpdates`,
|
|
856
856
|
// `supportsThinkingBlockBinding`) into explicit model/provider `compatibility` metadata so the protocol
|
|
857
857
|
// only reads `request.model.compatibility`.
|
|
858
|
+
const isThinkingOff = Schema.is(AnthropicThinkingDisabled);
|
|
858
859
|
// Per-turn effort started with Claude Opus 5 and every Claude 5.1 model; later versions of any family inherit it.
|
|
859
|
-
const supportsEffortUpdates = (
|
|
860
|
-
|
|
860
|
+
const supportsEffortUpdates = (request) => {
|
|
861
|
+
if (isThinkingOff(request.providerOptions?.thinking))
|
|
862
|
+
return false;
|
|
863
|
+
const override = request.model.compatibility?.supportsEffortUpdates;
|
|
861
864
|
if (override !== undefined)
|
|
862
865
|
return override;
|
|
863
|
-
const version = claudeVersion(model.id);
|
|
866
|
+
const version = claudeVersion(request.model.id);
|
|
864
867
|
if (version === undefined)
|
|
865
868
|
return false;
|
|
866
869
|
if (version.family === "opus" && version.major >= 5)
|
|
@@ -868,7 +871,7 @@ const supportsEffortUpdates = (model) => {
|
|
|
868
871
|
return version.major > 5 || (version.major === 5 && version.minor >= 1);
|
|
869
872
|
};
|
|
870
873
|
const applyThinkingBindingDefault = (model, thinking) => {
|
|
871
|
-
if (thinking
|
|
874
|
+
if (isThinkingOff(thinking))
|
|
872
875
|
return thinking;
|
|
873
876
|
if (!supportsThinkingBlockBinding(model))
|
|
874
877
|
return thinking;
|
|
@@ -1390,7 +1393,7 @@ export const protocol = Protocol.make({
|
|
|
1390
1393
|
}),
|
|
1391
1394
|
step,
|
|
1392
1395
|
},
|
|
1393
|
-
supportsEffortUpdates
|
|
1396
|
+
supportsEffortUpdates,
|
|
1394
1397
|
});
|
|
1395
1398
|
export const transport = () => {
|
|
1396
1399
|
const http = HttpTransport.httpJson({ framing });
|
|
@@ -1430,7 +1433,7 @@ function requiredBetaHeaders(body) {
|
|
|
1430
1433
|
if (body.messages.some((message) => message.role === "system" && message.output_config !== undefined))
|
|
1431
1434
|
betas.push("mid-conversation-output-config-2026-07-01");
|
|
1432
1435
|
const thinking = body.thinking;
|
|
1433
|
-
if (thinking && thinking
|
|
1436
|
+
if (thinking && !isThinkingOff(thinking) && thinking.block_binding)
|
|
1434
1437
|
betas.push(THINKING_BINDING_BETA);
|
|
1435
1438
|
return betas;
|
|
1436
1439
|
}
|
|
@@ -382,7 +382,9 @@ const decodeOptions = ProviderShared.validateWith(Schema.decodeUnknownEffect(Opt
|
|
|
382
382
|
// Claude on Bedrock requires the thinking budget below `maxTokens`, with a minimum of 1,024.
|
|
383
383
|
const MIN_THINKING_BUDGET = 1_024;
|
|
384
384
|
const isThinkingDisabled = Schema.is(Schema.Struct({
|
|
385
|
-
additionalModelRequestFields: Schema.Struct({
|
|
385
|
+
additionalModelRequestFields: Schema.Struct({
|
|
386
|
+
thinking: Schema.Struct({ type: Schema.Literals(["disabled", "between_tools"]) }),
|
|
387
|
+
}),
|
|
386
388
|
}));
|
|
387
389
|
// Claude 5.1+ binds each thinking signature to the prefix above it. Ask Bedrock to drop the affected blocks instead of
|
|
388
390
|
// failing when that prefix changes. `http.body` overlays this field by field, so callers can still override it.
|
|
@@ -9,7 +9,7 @@ declare const Options: Schema.Struct<{
|
|
|
9
9
|
readonly store: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.Boolean>, never>>;
|
|
10
10
|
readonly thinkingLevel: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<import("../schema/options.js").OpenString<"minimal" | "low" | "medium" | "high">, import("../schema/options.js").OpenString<"minimal" | "low" | "medium" | "high">>>, never>>;
|
|
11
11
|
readonly thinkingSummaries: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<import("../schema/options.js").OpenString<"auto" | "none">, import("../schema/options.js").OpenString<"auto" | "none">>>, never>>;
|
|
12
|
-
readonly serviceTier: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<import("../schema/options.js").OpenString<"standard" | "flex" | "priority">, import("../schema/options.js").OpenString<"standard" | "flex" | "priority">>>, never>>;
|
|
12
|
+
readonly serviceTier: Schema.optionalKey<Schema.middlewareDecoding<Schema.UndefinedOr<Schema.declare<import("../schema/options.js").OpenString<"standard" | "flex" | "priority" | "deferred">, import("../schema/options.js").OpenString<"standard" | "flex" | "priority" | "deferred">>>, never>>;
|
|
13
13
|
}>;
|
|
14
14
|
export type OptionsInput = typeof Options.Encoded;
|
|
15
15
|
export type ProviderOptionsInput = OptionsInput;
|
|
@@ -236,7 +236,7 @@ export declare const protocol: Protocol<{
|
|
|
236
236
|
readonly prefix_mismatch_behavior?: import("../schema/options.js").OpenString<"error" | "drop_block"> | undefined;
|
|
237
237
|
} | undefined;
|
|
238
238
|
} | {
|
|
239
|
-
readonly type: "disabled";
|
|
239
|
+
readonly type: "disabled" | "between_tools";
|
|
240
240
|
} | undefined;
|
|
241
241
|
readonly service_tier?: import("../schema/options.js").OpenString<"auto" | "standard_only"> | undefined;
|
|
242
242
|
readonly container?: string | {
|
|
@@ -282,8 +282,10 @@ export declare const protocol: Protocol<{
|
|
|
282
282
|
readonly top_k?: number | undefined;
|
|
283
283
|
readonly stop_sequences?: readonly string[] | undefined;
|
|
284
284
|
}, string, {
|
|
285
|
+
readonly [x: string]: unknown;
|
|
285
286
|
readonly type: string;
|
|
286
287
|
readonly message?: {
|
|
288
|
+
readonly [x: string]: unknown;
|
|
287
289
|
readonly usage?: {
|
|
288
290
|
readonly [x: string]: unknown;
|
|
289
291
|
readonly input_tokens?: number | null | undefined;
|
|
@@ -316,6 +318,7 @@ export declare const protocol: Protocol<{
|
|
|
316
318
|
} | undefined;
|
|
317
319
|
} | undefined;
|
|
318
320
|
readonly error?: {
|
|
321
|
+
readonly [x: string]: unknown;
|
|
319
322
|
readonly type?: string | undefined;
|
|
320
323
|
readonly message?: string | undefined;
|
|
321
324
|
} | undefined;
|
|
@@ -224,13 +224,16 @@ export declare const protocol: Protocol<{
|
|
|
224
224
|
}[] | undefined;
|
|
225
225
|
readonly error?: unknown;
|
|
226
226
|
readonly usage?: {
|
|
227
|
+
readonly [x: string]: unknown;
|
|
227
228
|
readonly input_tokens?: number | undefined;
|
|
228
229
|
readonly output_tokens?: number | undefined;
|
|
229
230
|
readonly output_tokens_details?: {
|
|
231
|
+
readonly [x: string]: unknown;
|
|
230
232
|
readonly reasoning_tokens?: number | undefined;
|
|
231
233
|
} | null | undefined;
|
|
232
234
|
readonly total_tokens?: number | undefined;
|
|
233
235
|
readonly input_tokens_details?: {
|
|
236
|
+
readonly [x: string]: unknown;
|
|
234
237
|
readonly cached_tokens?: number | undefined;
|
|
235
238
|
readonly cache_write_tokens?: number | undefined;
|
|
236
239
|
} | null | undefined;
|
|
@@ -559,18 +559,18 @@ export declare const OpenResponsesBody: Schema.Struct<{
|
|
|
559
559
|
readonly frequency_penalty: Schema.optional<Schema.Number>;
|
|
560
560
|
}>;
|
|
561
561
|
export type OpenResponsesBody = Schema.Schema.Type<typeof OpenResponsesBody>;
|
|
562
|
-
export declare const OpenResponsesUsage: Schema.Struct<{
|
|
562
|
+
export declare const OpenResponsesUsage: Schema.StructWithRest<Schema.Struct<{
|
|
563
563
|
readonly input_tokens: Schema.optional<Schema.Number>;
|
|
564
|
-
readonly input_tokens_details: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
564
|
+
readonly input_tokens_details: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
|
|
565
565
|
readonly cached_tokens: Schema.optional<Schema.Number>;
|
|
566
566
|
readonly cache_write_tokens: Schema.optional<Schema.Number>;
|
|
567
|
-
}>>>;
|
|
567
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
|
|
568
568
|
readonly output_tokens: Schema.optional<Schema.Number>;
|
|
569
|
-
readonly output_tokens_details: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
569
|
+
readonly output_tokens_details: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
|
|
570
570
|
readonly reasoning_tokens: Schema.optional<Schema.Number>;
|
|
571
|
-
}>>>;
|
|
571
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
|
|
572
572
|
readonly total_tokens: Schema.optional<Schema.Number>;
|
|
573
|
-
}>;
|
|
573
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>;
|
|
574
574
|
type OpenResponsesUsage = Schema.Schema.Type<typeof OpenResponsesUsage>;
|
|
575
575
|
export declare const StreamItem: Schema.StructWithRest<Schema.Struct<{
|
|
576
576
|
readonly type: Schema.String;
|
|
@@ -617,18 +617,18 @@ export declare const Event: Schema.StructWithRest<Schema.Struct<{
|
|
|
617
617
|
readonly arguments: Schema.optional<Schema.String>;
|
|
618
618
|
readonly encrypted_content: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
619
619
|
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
|
|
620
|
-
readonly usage: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
620
|
+
readonly usage: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
|
|
621
621
|
readonly input_tokens: Schema.optional<Schema.Number>;
|
|
622
|
-
readonly input_tokens_details: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
622
|
+
readonly input_tokens_details: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
|
|
623
623
|
readonly cached_tokens: Schema.optional<Schema.Number>;
|
|
624
624
|
readonly cache_write_tokens: Schema.optional<Schema.Number>;
|
|
625
|
-
}>>>;
|
|
625
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
|
|
626
626
|
readonly output_tokens: Schema.optional<Schema.Number>;
|
|
627
|
-
readonly output_tokens_details: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
627
|
+
readonly output_tokens_details: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
|
|
628
628
|
readonly reasoning_tokens: Schema.optional<Schema.Number>;
|
|
629
|
-
}>>>;
|
|
629
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
|
|
630
630
|
readonly total_tokens: Schema.optional<Schema.Number>;
|
|
631
|
-
}>>>;
|
|
631
|
+
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
|
|
632
632
|
readonly error: Schema.optional<Schema.Unknown>;
|
|
633
633
|
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>;
|
|
634
634
|
readonly code: Schema.optional<Schema.Unknown>;
|
|
@@ -669,13 +669,16 @@ export declare const decodeChannelEvent: (frame: string) => Effect.Effect<{
|
|
|
669
669
|
}[] | undefined;
|
|
670
670
|
readonly error?: unknown;
|
|
671
671
|
readonly usage?: {
|
|
672
|
+
readonly [x: string]: unknown;
|
|
672
673
|
readonly input_tokens?: number | undefined;
|
|
673
674
|
readonly output_tokens?: number | undefined;
|
|
674
675
|
readonly output_tokens_details?: {
|
|
676
|
+
readonly [x: string]: unknown;
|
|
675
677
|
readonly reasoning_tokens?: number | undefined;
|
|
676
678
|
} | null | undefined;
|
|
677
679
|
readonly total_tokens?: number | undefined;
|
|
678
680
|
readonly input_tokens_details?: {
|
|
681
|
+
readonly [x: string]: unknown;
|
|
679
682
|
readonly cached_tokens?: number | undefined;
|
|
680
683
|
readonly cache_write_tokens?: number | undefined;
|
|
681
684
|
} | null | undefined;
|
|
@@ -1721,13 +1724,16 @@ export declare const protocol: Protocol<{
|
|
|
1721
1724
|
}[] | undefined;
|
|
1722
1725
|
readonly error?: unknown;
|
|
1723
1726
|
readonly usage?: {
|
|
1727
|
+
readonly [x: string]: unknown;
|
|
1724
1728
|
readonly input_tokens?: number | undefined;
|
|
1725
1729
|
readonly output_tokens?: number | undefined;
|
|
1726
1730
|
readonly output_tokens_details?: {
|
|
1731
|
+
readonly [x: string]: unknown;
|
|
1727
1732
|
readonly reasoning_tokens?: number | undefined;
|
|
1728
1733
|
} | null | undefined;
|
|
1729
1734
|
readonly total_tokens?: number | undefined;
|
|
1730
1735
|
readonly input_tokens_details?: {
|
|
1736
|
+
readonly [x: string]: unknown;
|
|
1731
1737
|
readonly cached_tokens?: number | undefined;
|
|
1732
1738
|
readonly cache_write_tokens?: number | undefined;
|
|
1733
1739
|
} | null | undefined;
|
|
@@ -221,16 +221,16 @@ export const OpenResponsesBody = Schema.Struct({
|
|
|
221
221
|
...coreFields,
|
|
222
222
|
stream: Schema.Literal(true),
|
|
223
223
|
});
|
|
224
|
-
export const OpenResponsesUsage = Schema.Struct({
|
|
224
|
+
export const OpenResponsesUsage = Schema.StructWithRest(Schema.Struct({
|
|
225
225
|
input_tokens: Schema.optional(Schema.Number),
|
|
226
|
-
input_tokens_details: optionalNull(Schema.Struct({
|
|
226
|
+
input_tokens_details: optionalNull(Schema.StructWithRest(Schema.Struct({
|
|
227
227
|
cached_tokens: Schema.optional(Schema.Number),
|
|
228
228
|
cache_write_tokens: Schema.optional(Schema.Number),
|
|
229
|
-
})),
|
|
229
|
+
}), [JsonObject])),
|
|
230
230
|
output_tokens: Schema.optional(Schema.Number),
|
|
231
|
-
output_tokens_details: optionalNull(Schema.Struct({ reasoning_tokens: Schema.optional(Schema.Number) })),
|
|
231
|
+
output_tokens_details: optionalNull(Schema.StructWithRest(Schema.Struct({ reasoning_tokens: Schema.optional(Schema.Number) }), [JsonObject])),
|
|
232
232
|
total_tokens: Schema.optional(Schema.Number),
|
|
233
|
-
});
|
|
233
|
+
}), [JsonObject]);
|
|
234
234
|
// The spec requires `id` on every output item, but some gateways drop it from
|
|
235
235
|
// later item events (Bedrock Mantle renames it to `item_id` on
|
|
236
236
|
// `output_item.done` and `response.completed.output`). Decode it as optional
|
|
@@ -336,6 +336,8 @@ const lowerReasoning = (part, providerMetadataKey) => {
|
|
|
336
336
|
const encryptedContent = typeof metadata.reasoningEncryptedContent === "string" || metadata.reasoningEncryptedContent === null
|
|
337
337
|
? metadata.reasoningEncryptedContent
|
|
338
338
|
: undefined;
|
|
339
|
+
if (part.text.length === 0 && !encryptedContent)
|
|
340
|
+
return undefined;
|
|
339
341
|
return {
|
|
340
342
|
type: "reasoning",
|
|
341
343
|
...(id === undefined ? {} : { id }),
|
|
@@ -429,13 +429,16 @@ export declare const protocol: Protocol<{
|
|
|
429
429
|
}[] | undefined;
|
|
430
430
|
readonly error?: unknown;
|
|
431
431
|
readonly usage?: {
|
|
432
|
+
readonly [x: string]: unknown;
|
|
432
433
|
readonly input_tokens?: number | undefined;
|
|
433
434
|
readonly output_tokens?: number | undefined;
|
|
434
435
|
readonly output_tokens_details?: {
|
|
436
|
+
readonly [x: string]: unknown;
|
|
435
437
|
readonly reasoning_tokens?: number | undefined;
|
|
436
438
|
} | null | undefined;
|
|
437
439
|
readonly total_tokens?: number | undefined;
|
|
438
440
|
readonly input_tokens_details?: {
|
|
441
|
+
readonly [x: string]: unknown;
|
|
439
442
|
readonly cached_tokens?: number | undefined;
|
|
440
443
|
readonly cache_write_tokens?: number | undefined;
|
|
441
444
|
} | null | undefined;
|
|
@@ -15,7 +15,8 @@ import { ProviderShared } from "../shared.js";
|
|
|
15
15
|
export const defaultChain = (options) => Effect.tryPromise({
|
|
16
16
|
try: async () => {
|
|
17
17
|
const { fromNodeProviderChain } = await import("@aws-sdk/credential-providers");
|
|
18
|
-
|
|
18
|
+
// ignoreCache re-reads shared config and SSO token files, so `aws sso login` takes effect without a restart.
|
|
19
|
+
const identity = await fromNodeProviderChain({ ignoreCache: true, profile: options.profile })();
|
|
19
20
|
return {
|
|
20
21
|
region: options.region,
|
|
21
22
|
accessKeyId: identity.accessKeyId,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { Protocol } from "../../route/protocol.js";
|
|
3
|
+
import { type AIError, type LLMRequest } from "../../schema/index.js";
|
|
4
|
+
interface ParserState<Inner> {
|
|
5
|
+
readonly inner: Inner;
|
|
6
|
+
readonly gateway?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export declare function gatewayProtocol<Body, Event, State>(protocol: Protocol<Body, string, Event, State>, input: {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly prepare: (request: LLMRequest) => Effect.Effect<{
|
|
11
|
+
readonly request: LLMRequest;
|
|
12
|
+
readonly body: Record<string, unknown>;
|
|
13
|
+
}, AIError>;
|
|
14
|
+
}): Protocol<{
|
|
15
|
+
readonly [x: string]: unknown;
|
|
16
|
+
}, string, Event, ParserState<State>>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Effect, Option, Schema } from "effect";
|
|
2
|
+
import { Protocol } from "../../route/protocol.js";
|
|
3
|
+
import { LLMEvent, mergeJsonRecords } from "../../schema/index.js";
|
|
4
|
+
import { JsonObject, lenient } from "../shared.js";
|
|
5
|
+
const GatewayHolder = Schema.Struct({
|
|
6
|
+
provider_metadata: lenient(Schema.Struct({
|
|
7
|
+
gateway: lenient(JsonObject),
|
|
8
|
+
})),
|
|
9
|
+
});
|
|
10
|
+
const GatewayEvent = Schema.Struct({
|
|
11
|
+
...GatewayHolder.fields,
|
|
12
|
+
response: lenient(GatewayHolder),
|
|
13
|
+
choices: lenient(Schema.Array(Schema.Struct({
|
|
14
|
+
delta: lenient(GatewayHolder),
|
|
15
|
+
}))),
|
|
16
|
+
});
|
|
17
|
+
const decodeGatewayEvent = Schema.decodeUnknownOption(GatewayEvent);
|
|
18
|
+
function attachGatewayMetadata(events, gateway) {
|
|
19
|
+
if (!gateway || !events.some(LLMEvent.is.finish))
|
|
20
|
+
return events;
|
|
21
|
+
return events.map((event) => LLMEvent.is.finish(event) ? { ...event, providerMetadata: { ...event.providerMetadata, gateway } } : event);
|
|
22
|
+
}
|
|
23
|
+
export function gatewayProtocol(protocol, input) {
|
|
24
|
+
const initial = (request) => ({
|
|
25
|
+
inner: protocol.stream.initial(request),
|
|
26
|
+
});
|
|
27
|
+
const onHalt = protocol.stream.onHalt;
|
|
28
|
+
return Protocol.make({
|
|
29
|
+
id: input.id,
|
|
30
|
+
body: {
|
|
31
|
+
schema: JsonObject,
|
|
32
|
+
from: Effect.fnUntraced(function* (request) {
|
|
33
|
+
const prepared = yield* input.prepare(request);
|
|
34
|
+
const body = yield* protocol.body.from(prepared.request);
|
|
35
|
+
return { ...body, ...prepared.body };
|
|
36
|
+
}),
|
|
37
|
+
},
|
|
38
|
+
supportsEffortUpdates: protocol.supportsEffortUpdates,
|
|
39
|
+
sanitizer: protocol.sanitizer,
|
|
40
|
+
stream: {
|
|
41
|
+
event: protocol.stream.event,
|
|
42
|
+
initial,
|
|
43
|
+
step: Effect.fnUntraced(function* (state, event) {
|
|
44
|
+
const decoded = Option.getOrUndefined(decodeGatewayEvent(event));
|
|
45
|
+
const gateway = decoded
|
|
46
|
+
? mergeJsonRecords(state.gateway, decoded.provider_metadata?.gateway, decoded.response?.provider_metadata?.gateway, ...(decoded.choices ?? []).map((choice) => choice.delta?.provider_metadata?.gateway))
|
|
47
|
+
: state.gateway;
|
|
48
|
+
const [inner, events] = yield* protocol.stream.step(state.inner, event);
|
|
49
|
+
return [{ inner, gateway }, attachGatewayMetadata(events, gateway)];
|
|
50
|
+
}),
|
|
51
|
+
terminal: protocol.stream.terminal,
|
|
52
|
+
onHalt: onHalt
|
|
53
|
+
? (state) => onHalt(state.inner).pipe(Effect.map((events) => attachGatewayMetadata(events, state.gateway)))
|
|
54
|
+
: undefined,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -5,7 +5,7 @@ export declare const OpenAITextVerbosities: readonly ["low", "medium", "high"];
|
|
|
5
5
|
export type OpenAITextVerbosity = OpenResponsesOptions.TextVerbosity;
|
|
6
6
|
export declare const OpenAIResponseIncludables: readonly ["file_search_call.results", "web_search_call.results", "web_search_call.action.sources", "message.input_image.image_url", "computer_call_output.output.image_url", "code_interpreter_call.outputs", "reasoning.encrypted_content", "message.output_text.logprobs"];
|
|
7
7
|
export type OpenAIResponseIncludable = OpenResponsesOptions.ResponseIncludable;
|
|
8
|
-
export declare const OpenAIServiceTiers: readonly ["auto", "default", "flex", "priority", "scale"];
|
|
8
|
+
export declare const OpenAIServiceTiers: readonly ["auto", "default", "flex", "priority", "scale", "fast", "ultrafast"];
|
|
9
9
|
export type OpenAIServiceTier = (typeof OpenAIServiceTiers)[number] | (string & {});
|
|
10
10
|
export declare const OpenAIReasoningEffort: import("effect/Schema").declare<OpenResponsesOptions.ReasoningEffort, OpenResponsesOptions.ReasoningEffort>;
|
|
11
11
|
export declare const OpenAITextVerbosity: import("effect/Schema").declare<OpenResponsesOptions.TextVerbosity, OpenResponsesOptions.TextVerbosity>;
|
|
@@ -4,7 +4,8 @@ export const OpenAITextVerbosities = OpenResponsesOptions.TextVerbosities;
|
|
|
4
4
|
// Mirrors OpenAI's `ResponseIncludable` union from the official SDK. Keep this
|
|
5
5
|
// in lockstep with `openai-node/src/resources/responses/responses.ts`.
|
|
6
6
|
export const OpenAIResponseIncludables = OpenResponsesOptions.ResponseIncludables;
|
|
7
|
-
|
|
7
|
+
// Mirrors OpenAI's `ServiceTier` union from the official SDK.
|
|
8
|
+
export const OpenAIServiceTiers = [...OpenResponsesOptions.ServiceTiers, "scale", "fast", "ultrafast"];
|
|
8
9
|
export const OpenAIReasoningEffort = OpenResponsesOptions.ReasoningEffort;
|
|
9
10
|
export const OpenAITextVerbosity = OpenResponsesOptions.TextVerbosity;
|
|
10
11
|
export const OpenAIResponseIncludable = OpenResponsesOptions.ResponseIncludableSchema;
|
|
@@ -67,7 +67,7 @@ export declare const append: <K extends StreamKey>(tools: State<K>, key: K, text
|
|
|
67
67
|
export declare const appendExisting: <K extends StreamKey>(route: string, tools: State<K>, key: K, text: string, missingToolMessage: string) => AppendOutcome<K> | AIError;
|
|
68
68
|
/**
|
|
69
69
|
* Finalize one pending tool call: parse the accumulated raw JSON, remove it
|
|
70
|
-
* from state, and
|
|
70
|
+
* from state, and reject malformed local arguments without repairing them.
|
|
71
71
|
* Missing keys are a no-op because some providers emit stop events for
|
|
72
72
|
* non-tool content blocks.
|
|
73
73
|
*/
|
|
@@ -37,16 +37,16 @@ const inputDelta = (tool, text) => {
|
|
|
37
37
|
};
|
|
38
38
|
const toolCall = (route, tool, inputOverride) => {
|
|
39
39
|
const raw = inputOverride ?? tool.input;
|
|
40
|
-
return parseToolInput(route, tool.name, raw).pipe(Effect.
|
|
41
|
-
? Effect.fail(error)
|
|
42
|
-
: Effect.succeed(Option.getOrElse(Option.map(parsePartialInput(raw), (input) => input ?? {}), () => ({})))), Effect.map((input) => LLMEvent.toolCall({
|
|
40
|
+
return parseToolInput(route, tool.name, raw).pipe(Effect.map((input) => LLMEvent.toolCall({
|
|
43
41
|
id: tool.id,
|
|
44
42
|
name: tool.name,
|
|
45
43
|
namespace: tool.namespace,
|
|
46
44
|
input,
|
|
47
45
|
providerExecuted: tool.providerExecuted ? true : undefined,
|
|
48
46
|
providerMetadata: tool.providerMetadata,
|
|
49
|
-
})))
|
|
47
|
+
})), Effect.catch((error) => tool.providerExecuted
|
|
48
|
+
? Effect.fail(error)
|
|
49
|
+
: Effect.succeed(LLMEvent.toolInputError({ id: tool.id, name: tool.name, namespace: tool.namespace, raw }))));
|
|
50
50
|
};
|
|
51
51
|
const finishEvents = (tool, event) => [
|
|
52
52
|
LLMEvent.toolInputEnd({
|
|
@@ -121,7 +121,7 @@ export const append = (tools, key, text) => {
|
|
|
121
121
|
export const appendExisting = (route, tools, key, text, missingToolMessage) => append(tools, key, text) ?? eventError(route, missingToolMessage);
|
|
122
122
|
/**
|
|
123
123
|
* Finalize one pending tool call: parse the accumulated raw JSON, remove it
|
|
124
|
-
* from state, and
|
|
124
|
+
* from state, and reject malformed local arguments without repairing them.
|
|
125
125
|
* Missing keys are a no-op because some providers emit stop events for
|
|
126
126
|
* non-tool content blocks.
|
|
127
127
|
*/
|
|
@@ -200,13 +200,16 @@ export declare const protocol: Protocol<{
|
|
|
200
200
|
}[] | undefined;
|
|
201
201
|
readonly error?: unknown;
|
|
202
202
|
readonly usage?: {
|
|
203
|
+
readonly [x: string]: unknown;
|
|
203
204
|
readonly input_tokens?: number | undefined;
|
|
204
205
|
readonly output_tokens?: number | undefined;
|
|
205
206
|
readonly output_tokens_details?: {
|
|
207
|
+
readonly [x: string]: unknown;
|
|
206
208
|
readonly reasoning_tokens?: number | undefined;
|
|
207
209
|
} | null | undefined;
|
|
208
210
|
readonly total_tokens?: number | undefined;
|
|
209
211
|
readonly input_tokens_details?: {
|
|
212
|
+
readonly [x: string]: unknown;
|
|
210
213
|
readonly cached_tokens?: number | undefined;
|
|
211
214
|
readonly cache_write_tokens?: number | undefined;
|
|
212
215
|
} | null | undefined;
|