@opencode/ai 2.0.18 → 2.0.20
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 +24 -12
- package/dist/cache-policy.js +7 -0
- package/dist/experimental/evaluation.d.ts +7 -0
- package/dist/experimental/evaluation.js +2 -0
- package/dist/experimental/system-one.js +10 -7
- package/dist/generation.d.ts +1 -1
- package/dist/generation.js +23 -18
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/llm.d.ts +1 -1
- package/dist/promise.d.ts +3 -3
- package/dist/promise.js +4 -3
- package/dist/protocols/alibaba-chat.d.ts +8 -2
- package/dist/protocols/alibaba-responses.d.ts +14 -14
- package/dist/protocols/anthropic-messages.js +2 -15
- package/dist/protocols/bedrock-converse.d.ts +1 -1
- package/dist/protocols/bedrock-converse.js +38 -12
- package/dist/protocols/deepgram-speech.js +9 -7
- package/dist/protocols/deepgram-transcription.js +4 -10
- package/dist/protocols/elevenlabs-transcription.d.ts +28 -0
- package/dist/protocols/elevenlabs-transcription.js +137 -0
- package/dist/protocols/gemini.js +1 -10
- package/dist/protocols/google-speech.js +9 -2
- package/dist/protocols/google-transcription.js +4 -0
- package/dist/protocols/google-video.js +11 -2
- package/dist/protocols/meta-messages.d.ts +5 -1
- package/dist/protocols/meta-messages.js +11 -4
- package/dist/protocols/meta-responses.d.ts +16 -16
- package/dist/protocols/mistral-chat.d.ts +6 -0
- package/dist/protocols/mistral-chat.js +8 -5
- package/dist/protocols/open-responses.d.ts +31 -31
- package/dist/protocols/openai-chat.d.ts +53 -10
- package/dist/protocols/openai-chat.js +21 -8
- package/dist/protocols/openai-compatible-chat.d.ts +7 -2
- package/dist/protocols/openai-compatible-responses.d.ts +2 -2
- package/dist/protocols/openai-responses.d.ts +22 -22
- package/dist/protocols/openai-speech.js +6 -1
- package/dist/protocols/openai-transcription.js +1 -1
- package/dist/protocols/runway-video.js +2 -1
- package/dist/protocols/utils/claude-model.d.ts +8 -0
- package/dist/protocols/utils/claude-model.js +15 -0
- package/dist/protocols/utils/gemini-generate-content.d.ts +6 -0
- package/dist/protocols/utils/gemini-generate-content.js +33 -0
- package/dist/protocols/utils/media-input.d.ts +4 -3
- package/dist/protocols/utils/media-input.js +5 -4
- package/dist/protocols/utils/speaker-turns.d.ts +3 -0
- package/dist/protocols/utils/speaker-turns.js +9 -0
- package/dist/protocols/utils/speech-stream.d.ts +1 -0
- package/dist/protocols/utils/speech-stream.js +1 -0
- package/dist/protocols/utils/tool-stream.d.ts +4 -3
- package/dist/protocols/utils/tool-stream.js +1 -1
- package/dist/protocols/xai-responses.d.ts +14 -14
- package/dist/protocols/xai-video.js +7 -1
- package/dist/protocols/zai-chat.d.ts +8 -2
- package/dist/provider-error.d.ts +6 -0
- package/dist/provider-error.js +65 -2
- package/dist/providers/alibaba.d.ts +9 -4
- package/dist/providers/amazon-bedrock-mantle.d.ts +9 -4
- package/dist/providers/anthropic-compatible.js +3 -2
- package/dist/providers/azure.d.ts +11 -6
- package/dist/providers/baseten.d.ts +14 -4
- package/dist/providers/cerebras.d.ts +14 -4
- package/dist/providers/cloudflare-ai-gateway.d.ts +18 -8
- package/dist/providers/cloudflare-workers-ai.d.ts +14 -4
- package/dist/providers/deepinfra.d.ts +14 -4
- package/dist/providers/deepseek.d.ts +14 -4
- package/dist/providers/elevenlabs.d.ts +5 -0
- package/dist/providers/elevenlabs.js +4 -0
- package/dist/providers/fireworks.d.ts +14 -4
- package/dist/providers/google-vertex-chat.d.ts +7 -2
- package/dist/providers/google-vertex-responses.d.ts +2 -2
- package/dist/providers/groq.d.ts +15 -4
- package/dist/providers/meta.d.ts +14 -5
- package/dist/providers/minimax.d.ts +9 -4
- package/dist/providers/moonshot.d.ts +9 -4
- package/dist/providers/openai-compatible-responses.d.ts +2 -2
- package/dist/providers/openai-compatible.d.ts +7 -2
- package/dist/providers/openai.d.ts +9 -4
- package/dist/providers/openrouter.d.ts +27 -6
- package/dist/providers/togetherai.d.ts +14 -4
- package/dist/providers/xai.d.ts +7 -2
- package/dist/providers/xai.js +3 -3
- package/dist/providers/zai-coding-plan.d.ts +9 -4
- package/dist/providers/zai.d.ts +7 -2
- package/dist/route/client.d.ts +1 -1
- package/dist/route/executor.js +12 -8
- package/dist/route/media-protocol.d.ts +13 -3
- package/dist/route/media-protocol.js +16 -6
- package/dist/route/media.js +18 -4
- package/dist/schema/events.d.ts +30 -30
- package/dist/testing.d.ts +8 -8
- package/dist/transcription.d.ts +1 -1
- package/dist/transcription.js +1 -1
- package/package.json +3 -3
|
@@ -629,21 +629,10 @@ export declare const decodeChannelEvent: (frame: string) => Effect.Effect<{
|
|
|
629
629
|
readonly [x: string]: unknown;
|
|
630
630
|
readonly type: string;
|
|
631
631
|
readonly status?: unknown;
|
|
632
|
-
readonly code?: unknown;
|
|
633
632
|
readonly message?: unknown;
|
|
633
|
+
readonly code?: unknown;
|
|
634
634
|
readonly text?: string | undefined;
|
|
635
635
|
readonly error?: unknown;
|
|
636
|
-
readonly item?: {
|
|
637
|
-
readonly [x: string]: unknown;
|
|
638
|
-
readonly type: string;
|
|
639
|
-
readonly id?: string | undefined;
|
|
640
|
-
readonly name?: string | undefined;
|
|
641
|
-
readonly namespace?: string | undefined;
|
|
642
|
-
readonly arguments?: string | undefined;
|
|
643
|
-
readonly encrypted_content?: string | null | undefined;
|
|
644
|
-
readonly call_id?: string | undefined;
|
|
645
|
-
} | null | undefined;
|
|
646
|
-
readonly delta?: string | undefined;
|
|
647
636
|
readonly response?: {
|
|
648
637
|
readonly [x: string]: unknown;
|
|
649
638
|
readonly id?: string | undefined;
|
|
@@ -675,6 +664,17 @@ export declare const decodeChannelEvent: (frame: string) => Effect.Effect<{
|
|
|
675
664
|
readonly reason?: string | undefined;
|
|
676
665
|
} | null | undefined;
|
|
677
666
|
} | undefined;
|
|
667
|
+
readonly item?: {
|
|
668
|
+
readonly [x: string]: unknown;
|
|
669
|
+
readonly type: string;
|
|
670
|
+
readonly id?: string | undefined;
|
|
671
|
+
readonly name?: string | undefined;
|
|
672
|
+
readonly namespace?: string | undefined;
|
|
673
|
+
readonly arguments?: string | undefined;
|
|
674
|
+
readonly encrypted_content?: string | null | undefined;
|
|
675
|
+
readonly call_id?: string | undefined;
|
|
676
|
+
} | null | undefined;
|
|
677
|
+
readonly delta?: string | undefined;
|
|
678
678
|
readonly arguments?: string | undefined;
|
|
679
679
|
readonly item_id?: string | undefined;
|
|
680
680
|
readonly output_index?: number | undefined;
|
|
@@ -896,8 +896,8 @@ export declare const fromRequest: (request: LLMRequest<import("../schema/options
|
|
|
896
896
|
} | {
|
|
897
897
|
readonly type: "input_file";
|
|
898
898
|
readonly filename: string;
|
|
899
|
-
readonly file_data?: string | undefined;
|
|
900
899
|
readonly detail?: string | undefined;
|
|
900
|
+
readonly file_data?: string | undefined;
|
|
901
901
|
readonly file_url?: string | undefined;
|
|
902
902
|
} | {
|
|
903
903
|
readonly type: "input_text";
|
|
@@ -933,8 +933,8 @@ export declare const fromRequest: (request: LLMRequest<import("../schema/options
|
|
|
933
933
|
} | {
|
|
934
934
|
readonly type: "input_file";
|
|
935
935
|
readonly filename: string;
|
|
936
|
-
readonly file_data?: string | undefined;
|
|
937
936
|
readonly detail?: string | undefined;
|
|
937
|
+
readonly file_data?: string | undefined;
|
|
938
938
|
readonly file_url?: string | undefined;
|
|
939
939
|
} | {
|
|
940
940
|
readonly type: "input_text";
|
|
@@ -1169,8 +1169,8 @@ export declare const step: (state: ParserState, event: NormalizedEvent) => AIErr
|
|
|
1169
1169
|
} | {
|
|
1170
1170
|
readonly id: string;
|
|
1171
1171
|
readonly type: "tool-error";
|
|
1172
|
-
readonly name: string;
|
|
1173
1172
|
readonly message: string;
|
|
1173
|
+
readonly name: string;
|
|
1174
1174
|
readonly error?: unknown;
|
|
1175
1175
|
readonly providerMetadata?: {
|
|
1176
1176
|
readonly [x: string]: {
|
|
@@ -1293,8 +1293,8 @@ export declare const protocol: Protocol<{
|
|
|
1293
1293
|
} | {
|
|
1294
1294
|
readonly type: "input_file";
|
|
1295
1295
|
readonly filename: string;
|
|
1296
|
-
readonly file_data?: string | undefined;
|
|
1297
1296
|
readonly detail?: string | undefined;
|
|
1297
|
+
readonly file_data?: string | undefined;
|
|
1298
1298
|
readonly file_url?: string | undefined;
|
|
1299
1299
|
} | {
|
|
1300
1300
|
readonly type: "input_text";
|
|
@@ -1330,8 +1330,8 @@ export declare const protocol: Protocol<{
|
|
|
1330
1330
|
} | {
|
|
1331
1331
|
readonly type: "input_file";
|
|
1332
1332
|
readonly filename: string;
|
|
1333
|
-
readonly file_data?: string | undefined;
|
|
1334
1333
|
readonly detail?: string | undefined;
|
|
1334
|
+
readonly file_data?: string | undefined;
|
|
1335
1335
|
readonly file_url?: string | undefined;
|
|
1336
1336
|
} | {
|
|
1337
1337
|
readonly type: "input_text";
|
|
@@ -1395,21 +1395,10 @@ export declare const protocol: Protocol<{
|
|
|
1395
1395
|
readonly [x: string]: unknown;
|
|
1396
1396
|
readonly type: string;
|
|
1397
1397
|
readonly status?: unknown;
|
|
1398
|
-
readonly code?: unknown;
|
|
1399
1398
|
readonly message?: unknown;
|
|
1399
|
+
readonly code?: unknown;
|
|
1400
1400
|
readonly text?: string | undefined;
|
|
1401
1401
|
readonly error?: unknown;
|
|
1402
|
-
readonly item?: {
|
|
1403
|
-
readonly [x: string]: unknown;
|
|
1404
|
-
readonly type: string;
|
|
1405
|
-
readonly id?: string | undefined;
|
|
1406
|
-
readonly name?: string | undefined;
|
|
1407
|
-
readonly namespace?: string | undefined;
|
|
1408
|
-
readonly arguments?: string | undefined;
|
|
1409
|
-
readonly encrypted_content?: string | null | undefined;
|
|
1410
|
-
readonly call_id?: string | undefined;
|
|
1411
|
-
} | null | undefined;
|
|
1412
|
-
readonly delta?: string | undefined;
|
|
1413
1402
|
readonly response?: {
|
|
1414
1403
|
readonly [x: string]: unknown;
|
|
1415
1404
|
readonly id?: string | undefined;
|
|
@@ -1441,6 +1430,17 @@ export declare const protocol: Protocol<{
|
|
|
1441
1430
|
readonly reason?: string | undefined;
|
|
1442
1431
|
} | null | undefined;
|
|
1443
1432
|
} | undefined;
|
|
1433
|
+
readonly item?: {
|
|
1434
|
+
readonly [x: string]: unknown;
|
|
1435
|
+
readonly type: string;
|
|
1436
|
+
readonly id?: string | undefined;
|
|
1437
|
+
readonly name?: string | undefined;
|
|
1438
|
+
readonly namespace?: string | undefined;
|
|
1439
|
+
readonly arguments?: string | undefined;
|
|
1440
|
+
readonly encrypted_content?: string | null | undefined;
|
|
1441
|
+
readonly call_id?: string | undefined;
|
|
1442
|
+
} | null | undefined;
|
|
1443
|
+
readonly delta?: string | undefined;
|
|
1444
1444
|
readonly arguments?: string | undefined;
|
|
1445
1445
|
readonly item_id?: string | undefined;
|
|
1446
1446
|
readonly output_index?: number | undefined;
|
|
@@ -1514,8 +1514,8 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
1514
1514
|
} | {
|
|
1515
1515
|
readonly type: "input_file";
|
|
1516
1516
|
readonly filename: string;
|
|
1517
|
-
readonly file_data?: string | undefined;
|
|
1518
1517
|
readonly detail?: string | undefined;
|
|
1518
|
+
readonly file_data?: string | undefined;
|
|
1519
1519
|
readonly file_url?: string | undefined;
|
|
1520
1520
|
} | {
|
|
1521
1521
|
readonly type: "input_text";
|
|
@@ -1551,8 +1551,8 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
1551
1551
|
} | {
|
|
1552
1552
|
readonly type: "input_file";
|
|
1553
1553
|
readonly filename: string;
|
|
1554
|
-
readonly file_data?: string | undefined;
|
|
1555
1554
|
readonly detail?: string | undefined;
|
|
1555
|
+
readonly file_data?: string | undefined;
|
|
1556
1556
|
readonly file_url?: string | undefined;
|
|
1557
1557
|
} | {
|
|
1558
1558
|
readonly type: "input_text";
|
|
@@ -12,6 +12,11 @@ declare const OpenAIChatCacheControl: Schema.Struct<{
|
|
|
12
12
|
readonly type: Schema.Literal<"ephemeral">;
|
|
13
13
|
readonly ttl: Schema.optional<Schema.String>;
|
|
14
14
|
}>;
|
|
15
|
+
declare const ExtraContent: Schema.Struct<{
|
|
16
|
+
readonly google: Schema.Struct<{
|
|
17
|
+
readonly thought_signature: Schema.String;
|
|
18
|
+
}>;
|
|
19
|
+
}>;
|
|
15
20
|
declare const ReasoningDetail: Schema.Union<readonly [Schema.StructWithRest<Schema.Struct<{
|
|
16
21
|
readonly id: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
17
22
|
readonly format: Schema.optional<Schema.String>;
|
|
@@ -97,6 +102,11 @@ export declare const bodyFields: {
|
|
|
97
102
|
readonly name: Schema.String;
|
|
98
103
|
readonly arguments: Schema.String;
|
|
99
104
|
}>;
|
|
105
|
+
readonly extra_content: Schema.optional<Schema.Struct<{
|
|
106
|
+
readonly google: Schema.Struct<{
|
|
107
|
+
readonly thought_signature: Schema.String;
|
|
108
|
+
}>;
|
|
109
|
+
}>>;
|
|
100
110
|
}>>>;
|
|
101
111
|
readonly reasoning_content: Schema.optional<Schema.String>;
|
|
102
112
|
readonly reasoning: Schema.optional<Schema.String>;
|
|
@@ -205,6 +215,11 @@ declare const OpenAIChatBody: Schema.Struct<{
|
|
|
205
215
|
readonly name: Schema.String;
|
|
206
216
|
readonly arguments: Schema.String;
|
|
207
217
|
}>;
|
|
218
|
+
readonly extra_content: Schema.optional<Schema.Struct<{
|
|
219
|
+
readonly google: Schema.Struct<{
|
|
220
|
+
readonly thought_signature: Schema.String;
|
|
221
|
+
}>;
|
|
222
|
+
}>>;
|
|
208
223
|
}>>>;
|
|
209
224
|
readonly reasoning_content: Schema.optional<Schema.String>;
|
|
210
225
|
readonly reasoning: Schema.optional<Schema.String>;
|
|
@@ -276,6 +291,7 @@ export declare const OpenAIChatEvent: Schema.StructWithRest<Schema.Struct<{
|
|
|
276
291
|
readonly name: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
277
292
|
readonly arguments: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
278
293
|
}>>>;
|
|
294
|
+
readonly extra_content: Schema.optional<Schema.NullOr<Schema.Unknown>>;
|
|
279
295
|
}>>>>;
|
|
280
296
|
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>>>;
|
|
281
297
|
readonly finish_reason: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
@@ -323,6 +339,7 @@ interface PendingToolDelta {
|
|
|
323
339
|
readonly id?: string;
|
|
324
340
|
readonly name?: string;
|
|
325
341
|
readonly input: string;
|
|
342
|
+
readonly extraContent?: Schema.Schema.Type<typeof ExtraContent>;
|
|
326
343
|
}
|
|
327
344
|
export interface ParserState {
|
|
328
345
|
readonly providerMetadataKey: string;
|
|
@@ -418,12 +435,17 @@ export declare const fromRequest: (request: LLMRequest<import("../schema/options
|
|
|
418
435
|
readonly ttl?: string | undefined;
|
|
419
436
|
} | undefined;
|
|
420
437
|
readonly tool_calls?: readonly {
|
|
421
|
-
readonly id: string;
|
|
422
|
-
readonly type: "function";
|
|
423
438
|
readonly function: {
|
|
424
439
|
readonly name: string;
|
|
425
440
|
readonly arguments: string;
|
|
426
441
|
};
|
|
442
|
+
readonly id: string;
|
|
443
|
+
readonly type: "function";
|
|
444
|
+
readonly extra_content?: {
|
|
445
|
+
readonly google: {
|
|
446
|
+
readonly thought_signature: string;
|
|
447
|
+
};
|
|
448
|
+
} | undefined;
|
|
427
449
|
}[] | undefined;
|
|
428
450
|
readonly reasoning_details?: unknown;
|
|
429
451
|
} | {
|
|
@@ -527,12 +549,17 @@ export declare const fromRequest: (request: LLMRequest<import("../schema/options
|
|
|
527
549
|
readonly ttl?: string | undefined;
|
|
528
550
|
} | undefined;
|
|
529
551
|
readonly tool_calls?: readonly {
|
|
530
|
-
readonly id: string;
|
|
531
|
-
readonly type: "function";
|
|
532
552
|
readonly function: {
|
|
533
553
|
readonly name: string;
|
|
534
554
|
readonly arguments: string;
|
|
535
555
|
};
|
|
556
|
+
readonly id: string;
|
|
557
|
+
readonly type: "function";
|
|
558
|
+
readonly extra_content?: {
|
|
559
|
+
readonly google: {
|
|
560
|
+
readonly thought_signature: string;
|
|
561
|
+
};
|
|
562
|
+
} | undefined;
|
|
536
563
|
}[] | undefined;
|
|
537
564
|
readonly reasoning_details?: unknown;
|
|
538
565
|
} | {
|
|
@@ -629,12 +656,17 @@ export declare const protocol: Protocol<{
|
|
|
629
656
|
readonly ttl?: string | undefined;
|
|
630
657
|
} | undefined;
|
|
631
658
|
readonly tool_calls?: readonly {
|
|
632
|
-
readonly id: string;
|
|
633
|
-
readonly type: "function";
|
|
634
659
|
readonly function: {
|
|
635
660
|
readonly name: string;
|
|
636
661
|
readonly arguments: string;
|
|
637
662
|
};
|
|
663
|
+
readonly id: string;
|
|
664
|
+
readonly type: "function";
|
|
665
|
+
readonly extra_content?: {
|
|
666
|
+
readonly google: {
|
|
667
|
+
readonly thought_signature: string;
|
|
668
|
+
};
|
|
669
|
+
} | undefined;
|
|
638
670
|
}[] | undefined;
|
|
639
671
|
readonly reasoning_details?: unknown;
|
|
640
672
|
} | {
|
|
@@ -725,6 +757,7 @@ export declare const protocol: Protocol<{
|
|
|
725
757
|
} | null | undefined;
|
|
726
758
|
readonly id?: string | null | undefined;
|
|
727
759
|
readonly index?: number | null | undefined;
|
|
760
|
+
readonly extra_content?: unknown;
|
|
728
761
|
}[] | null | undefined;
|
|
729
762
|
readonly reasoning_details?: unknown;
|
|
730
763
|
} | null | undefined;
|
|
@@ -808,12 +841,17 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
808
841
|
readonly ttl?: string | undefined;
|
|
809
842
|
} | undefined;
|
|
810
843
|
readonly tool_calls?: readonly {
|
|
811
|
-
readonly id: string;
|
|
812
|
-
readonly type: "function";
|
|
813
844
|
readonly function: {
|
|
814
845
|
readonly name: string;
|
|
815
846
|
readonly arguments: string;
|
|
816
847
|
};
|
|
848
|
+
readonly id: string;
|
|
849
|
+
readonly type: "function";
|
|
850
|
+
readonly extra_content?: {
|
|
851
|
+
readonly google: {
|
|
852
|
+
readonly thought_signature: string;
|
|
853
|
+
};
|
|
854
|
+
} | undefined;
|
|
817
855
|
}[] | undefined;
|
|
818
856
|
readonly reasoning_details?: unknown;
|
|
819
857
|
} | {
|
|
@@ -919,12 +957,17 @@ export declare const route: Route<{
|
|
|
919
957
|
readonly ttl?: string | undefined;
|
|
920
958
|
} | undefined;
|
|
921
959
|
readonly tool_calls?: readonly {
|
|
922
|
-
readonly id: string;
|
|
923
|
-
readonly type: "function";
|
|
924
960
|
readonly function: {
|
|
925
961
|
readonly name: string;
|
|
926
962
|
readonly arguments: string;
|
|
927
963
|
};
|
|
964
|
+
readonly id: string;
|
|
965
|
+
readonly type: "function";
|
|
966
|
+
readonly extra_content?: {
|
|
967
|
+
readonly google: {
|
|
968
|
+
readonly thought_signature: string;
|
|
969
|
+
};
|
|
970
|
+
} | undefined;
|
|
928
971
|
}[] | undefined;
|
|
929
972
|
readonly reasoning_details?: unknown;
|
|
930
973
|
} | {
|
|
@@ -41,6 +41,13 @@ const OpenAIChatTool = Schema.Struct({
|
|
|
41
41
|
}),
|
|
42
42
|
cache_control: Schema.optional(OpenAIChatCacheControl),
|
|
43
43
|
});
|
|
44
|
+
// Gemini's OpenAI-compatible surface carries thought signatures in tool call
|
|
45
|
+
// `extra_content` and rejects replayed parallel calls without them:
|
|
46
|
+
// https://ai.google.dev/gemini-api/docs/thinking#signatures
|
|
47
|
+
const ExtraContent = Schema.Struct({
|
|
48
|
+
google: Schema.Struct({ thought_signature: Schema.String }),
|
|
49
|
+
});
|
|
50
|
+
const decodeExtraContent = (value) => Option.getOrUndefined(Schema.decodeUnknownOption(ExtraContent)(value));
|
|
44
51
|
const OpenAIChatAssistantToolCall = Schema.Struct({
|
|
45
52
|
id: Schema.String,
|
|
46
53
|
type: Schema.tag("function"),
|
|
@@ -48,6 +55,7 @@ const OpenAIChatAssistantToolCall = Schema.Struct({
|
|
|
48
55
|
name: Schema.String,
|
|
49
56
|
arguments: Schema.String,
|
|
50
57
|
}),
|
|
58
|
+
extra_content: Schema.optional(ExtraContent),
|
|
51
59
|
});
|
|
52
60
|
// `reasoning_details` carries two dialects. OpenRouter's `reasoning.*` entries
|
|
53
61
|
// must be replayed unmodified (`index` included), so they keep every field they
|
|
@@ -75,11 +83,6 @@ const ReasoningDetail = Schema.Union([
|
|
|
75
83
|
]);
|
|
76
84
|
const decodeReasoningDetail = Schema.decodeUnknownOption(ReasoningDetail);
|
|
77
85
|
const knownReasoningDetails = (details) => details.flatMap((detail) => Option.toArray(decodeReasoningDetail(detail)));
|
|
78
|
-
// Intentionally omit Gemini's provider-specific `extra_content.google.thought_signature`
|
|
79
|
-
// extension until direct Google OpenAI-compatible routing is supported here:
|
|
80
|
-
// https://github.com/vercel/ai/issues/11590
|
|
81
|
-
// https://github.com/vercel/ai/pull/11745
|
|
82
|
-
// https://ai.google.dev/gemini-api/docs/thought-signatures#openai
|
|
83
86
|
const OpenAIChatUserContent = Schema.Union([
|
|
84
87
|
Schema.Struct({
|
|
85
88
|
type: Schema.Literal("text"),
|
|
@@ -180,6 +183,7 @@ const OpenAIChatToolCallDelta = Schema.Struct({
|
|
|
180
183
|
index: optionalNull(Schema.Number),
|
|
181
184
|
id: optionalNull(Schema.String),
|
|
182
185
|
function: optionalNull(OpenAIChatToolCallDeltaFunction),
|
|
186
|
+
extra_content: optionalNull(Schema.Unknown),
|
|
183
187
|
});
|
|
184
188
|
const OpenAIChatDelta = Schema.StructWithRest(Schema.Struct({
|
|
185
189
|
content: optionalNull(Schema.String),
|
|
@@ -231,6 +235,7 @@ const lowerToolCall = (part, options) => ({
|
|
|
231
235
|
name: part.name,
|
|
232
236
|
arguments: ProviderShared.encodeJson(part.input === undefined ? {} : part.input),
|
|
233
237
|
},
|
|
238
|
+
extra_content: decodeExtraContent(part.providerMetadata?.[options.providerMetadataKey]?.extraContent),
|
|
234
239
|
});
|
|
235
240
|
const lowerMedia = Effect.fn("OpenAIChat.lowerMedia")(function* (part) {
|
|
236
241
|
// Chat Completions accepts PDFs, and no other documents, as inline `file` parts; file URLs are not supported.
|
|
@@ -566,7 +571,9 @@ const detectSupportsStore = (provider, baseURL) => {
|
|
|
566
571
|
const isVercelAiGateway = p === "vercel-ai-gateway" || url.includes("ai-gateway.vercel.sh") || url.includes("vercel.sh");
|
|
567
572
|
const isAntLing = p === "ant-ling" || url.includes("api.ant-ling.com");
|
|
568
573
|
const isOpencode = p === "opencode" || url.includes("opencode.ai");
|
|
569
|
-
const
|
|
574
|
+
const isGemini = url.includes("generativelanguage.googleapis.com");
|
|
575
|
+
const isNonStandard = isGemini ||
|
|
576
|
+
isNvidia ||
|
|
570
577
|
isCerebras ||
|
|
571
578
|
isXai ||
|
|
572
579
|
isTogether ||
|
|
@@ -908,12 +915,13 @@ const step = (state, event) => Effect.gen(function* () {
|
|
|
908
915
|
const id = current?.id ?? pending?.id ?? (tool.id || undefined);
|
|
909
916
|
const name = current?.name ?? pending?.name ?? (tool.function?.name || undefined);
|
|
910
917
|
const text = `${pending?.input ?? ""}${tool.function?.arguments ?? ""}`;
|
|
918
|
+
const extraContent = pending?.extraContent ?? decodeExtraContent(tool.extra_content);
|
|
911
919
|
latestToolIndex = index;
|
|
912
920
|
nextToolIndex = Math.max(nextToolIndex, index + 1);
|
|
913
921
|
if (!current && (!id || !name)) {
|
|
914
922
|
pendingTools = {
|
|
915
923
|
...pendingTools,
|
|
916
|
-
[index]: { id: id || undefined, name: name || undefined, input: text },
|
|
924
|
+
[index]: { id: id || undefined, name: name || undefined, input: text, extraContent },
|
|
917
925
|
};
|
|
918
926
|
continue;
|
|
919
927
|
}
|
|
@@ -921,7 +929,12 @@ const step = (state, event) => Effect.gen(function* () {
|
|
|
921
929
|
pendingTools = { ...pendingTools };
|
|
922
930
|
delete pendingTools[index];
|
|
923
931
|
}
|
|
924
|
-
const result = ToolStream.appendOrStart(ADAPTER, tools, index, {
|
|
932
|
+
const result = ToolStream.appendOrStart(ADAPTER, tools, index, {
|
|
933
|
+
id: id || undefined,
|
|
934
|
+
name: name || undefined,
|
|
935
|
+
text,
|
|
936
|
+
providerMetadata: extraContent && { [state.providerMetadataKey]: { extraContent } },
|
|
937
|
+
}, "OpenAI Chat tool call delta is missing id or name");
|
|
925
938
|
if (ToolStream.isError(result))
|
|
926
939
|
return yield* new AIError({
|
|
927
940
|
reason: AIErrorReason.make({
|
|
@@ -63,12 +63,17 @@ export declare const route: Route<{
|
|
|
63
63
|
readonly ttl?: string | undefined;
|
|
64
64
|
} | undefined;
|
|
65
65
|
readonly tool_calls?: readonly {
|
|
66
|
-
readonly id: string;
|
|
67
|
-
readonly type: "function";
|
|
68
66
|
readonly function: {
|
|
69
67
|
readonly name: string;
|
|
70
68
|
readonly arguments: string;
|
|
71
69
|
};
|
|
70
|
+
readonly id: string;
|
|
71
|
+
readonly type: "function";
|
|
72
|
+
readonly extra_content?: {
|
|
73
|
+
readonly google: {
|
|
74
|
+
readonly thought_signature: string;
|
|
75
|
+
};
|
|
76
|
+
} | undefined;
|
|
72
77
|
}[] | undefined;
|
|
73
78
|
readonly reasoning_details?: unknown;
|
|
74
79
|
} | {
|
|
@@ -72,8 +72,8 @@ export declare const route: Route<{
|
|
|
72
72
|
} | {
|
|
73
73
|
readonly type: "input_file";
|
|
74
74
|
readonly filename: string;
|
|
75
|
-
readonly file_data?: string | undefined;
|
|
76
75
|
readonly detail?: string | undefined;
|
|
76
|
+
readonly file_data?: string | undefined;
|
|
77
77
|
readonly file_url?: string | undefined;
|
|
78
78
|
} | {
|
|
79
79
|
readonly type: "input_text";
|
|
@@ -109,8 +109,8 @@ export declare const route: Route<{
|
|
|
109
109
|
} | {
|
|
110
110
|
readonly type: "input_file";
|
|
111
111
|
readonly filename: string;
|
|
112
|
-
readonly file_data?: string | undefined;
|
|
113
112
|
readonly detail?: string | undefined;
|
|
113
|
+
readonly file_data?: string | undefined;
|
|
114
114
|
readonly file_url?: string | undefined;
|
|
115
115
|
} | {
|
|
116
116
|
readonly type: "input_text";
|
|
@@ -291,8 +291,8 @@ export declare const protocol: Protocol<{
|
|
|
291
291
|
} | {
|
|
292
292
|
readonly type: "input_file";
|
|
293
293
|
readonly filename: string;
|
|
294
|
-
readonly file_data?: string | undefined;
|
|
295
294
|
readonly detail?: string | undefined;
|
|
295
|
+
readonly file_data?: string | undefined;
|
|
296
296
|
readonly file_url?: string | undefined;
|
|
297
297
|
} | {
|
|
298
298
|
readonly type: "input_text";
|
|
@@ -328,8 +328,8 @@ export declare const protocol: Protocol<{
|
|
|
328
328
|
} | {
|
|
329
329
|
readonly type: "input_file";
|
|
330
330
|
readonly filename: string;
|
|
331
|
-
readonly file_data?: string | undefined;
|
|
332
331
|
readonly detail?: string | undefined;
|
|
332
|
+
readonly file_data?: string | undefined;
|
|
333
333
|
readonly file_url?: string | undefined;
|
|
334
334
|
} | {
|
|
335
335
|
readonly type: "input_text";
|
|
@@ -450,21 +450,10 @@ export declare const protocol: Protocol<{
|
|
|
450
450
|
readonly [x: string]: unknown;
|
|
451
451
|
readonly type: string;
|
|
452
452
|
readonly status?: unknown;
|
|
453
|
-
readonly code?: unknown;
|
|
454
453
|
readonly message?: unknown;
|
|
454
|
+
readonly code?: unknown;
|
|
455
455
|
readonly text?: string | undefined;
|
|
456
456
|
readonly error?: unknown;
|
|
457
|
-
readonly item?: {
|
|
458
|
-
readonly [x: string]: unknown;
|
|
459
|
-
readonly type: string;
|
|
460
|
-
readonly id?: string | undefined;
|
|
461
|
-
readonly name?: string | undefined;
|
|
462
|
-
readonly namespace?: string | undefined;
|
|
463
|
-
readonly arguments?: string | undefined;
|
|
464
|
-
readonly encrypted_content?: string | null | undefined;
|
|
465
|
-
readonly call_id?: string | undefined;
|
|
466
|
-
} | null | undefined;
|
|
467
|
-
readonly delta?: string | undefined;
|
|
468
457
|
readonly response?: {
|
|
469
458
|
readonly [x: string]: unknown;
|
|
470
459
|
readonly id?: string | undefined;
|
|
@@ -496,6 +485,17 @@ export declare const protocol: Protocol<{
|
|
|
496
485
|
readonly reason?: string | undefined;
|
|
497
486
|
} | null | undefined;
|
|
498
487
|
} | undefined;
|
|
488
|
+
readonly item?: {
|
|
489
|
+
readonly [x: string]: unknown;
|
|
490
|
+
readonly type: string;
|
|
491
|
+
readonly id?: string | undefined;
|
|
492
|
+
readonly name?: string | undefined;
|
|
493
|
+
readonly namespace?: string | undefined;
|
|
494
|
+
readonly arguments?: string | undefined;
|
|
495
|
+
readonly encrypted_content?: string | null | undefined;
|
|
496
|
+
readonly call_id?: string | undefined;
|
|
497
|
+
} | null | undefined;
|
|
498
|
+
readonly delta?: string | undefined;
|
|
499
499
|
readonly arguments?: string | undefined;
|
|
500
500
|
readonly item_id?: string | undefined;
|
|
501
501
|
readonly output_index?: number | undefined;
|
|
@@ -574,8 +574,8 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
574
574
|
} | {
|
|
575
575
|
readonly type: "input_file";
|
|
576
576
|
readonly filename: string;
|
|
577
|
-
readonly file_data?: string | undefined;
|
|
578
577
|
readonly detail?: string | undefined;
|
|
578
|
+
readonly file_data?: string | undefined;
|
|
579
579
|
readonly file_url?: string | undefined;
|
|
580
580
|
} | {
|
|
581
581
|
readonly type: "input_text";
|
|
@@ -611,8 +611,8 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
611
611
|
} | {
|
|
612
612
|
readonly type: "input_file";
|
|
613
613
|
readonly filename: string;
|
|
614
|
-
readonly file_data?: string | undefined;
|
|
615
614
|
readonly detail?: string | undefined;
|
|
615
|
+
readonly file_data?: string | undefined;
|
|
616
616
|
readonly file_url?: string | undefined;
|
|
617
617
|
} | {
|
|
618
618
|
readonly type: "input_text";
|
|
@@ -802,8 +802,8 @@ export declare const channelTransport: (options: import("./open-responses-channe
|
|
|
802
802
|
} | {
|
|
803
803
|
readonly type: "input_file";
|
|
804
804
|
readonly filename: string;
|
|
805
|
-
readonly file_data?: string | undefined;
|
|
806
805
|
readonly detail?: string | undefined;
|
|
806
|
+
readonly file_data?: string | undefined;
|
|
807
807
|
readonly file_url?: string | undefined;
|
|
808
808
|
} | {
|
|
809
809
|
readonly type: "input_text";
|
|
@@ -839,8 +839,8 @@ export declare const channelTransport: (options: import("./open-responses-channe
|
|
|
839
839
|
} | {
|
|
840
840
|
readonly type: "input_file";
|
|
841
841
|
readonly filename: string;
|
|
842
|
-
readonly file_data?: string | undefined;
|
|
843
842
|
readonly detail?: string | undefined;
|
|
843
|
+
readonly file_data?: string | undefined;
|
|
844
844
|
readonly file_url?: string | undefined;
|
|
845
845
|
} | {
|
|
846
846
|
readonly type: "input_text";
|
|
@@ -1030,8 +1030,8 @@ export declare const transport: import("../route/transport/index.js").Transport<
|
|
|
1030
1030
|
} | {
|
|
1031
1031
|
readonly type: "input_file";
|
|
1032
1032
|
readonly filename: string;
|
|
1033
|
-
readonly file_data?: string | undefined;
|
|
1034
1033
|
readonly detail?: string | undefined;
|
|
1034
|
+
readonly file_data?: string | undefined;
|
|
1035
1035
|
readonly file_url?: string | undefined;
|
|
1036
1036
|
} | {
|
|
1037
1037
|
readonly type: "input_text";
|
|
@@ -1067,8 +1067,8 @@ export declare const transport: import("../route/transport/index.js").Transport<
|
|
|
1067
1067
|
} | {
|
|
1068
1068
|
readonly type: "input_file";
|
|
1069
1069
|
readonly filename: string;
|
|
1070
|
-
readonly file_data?: string | undefined;
|
|
1071
1070
|
readonly detail?: string | undefined;
|
|
1071
|
+
readonly file_data?: string | undefined;
|
|
1072
1072
|
readonly file_url?: string | undefined;
|
|
1073
1073
|
} | {
|
|
1074
1074
|
readonly type: "input_text";
|
|
@@ -1258,8 +1258,8 @@ export declare const route: Route<{
|
|
|
1258
1258
|
} | {
|
|
1259
1259
|
readonly type: "input_file";
|
|
1260
1260
|
readonly filename: string;
|
|
1261
|
-
readonly file_data?: string | undefined;
|
|
1262
1261
|
readonly detail?: string | undefined;
|
|
1262
|
+
readonly file_data?: string | undefined;
|
|
1263
1263
|
readonly file_url?: string | undefined;
|
|
1264
1264
|
} | {
|
|
1265
1265
|
readonly type: "input_text";
|
|
@@ -1295,8 +1295,8 @@ export declare const route: Route<{
|
|
|
1295
1295
|
} | {
|
|
1296
1296
|
readonly type: "input_file";
|
|
1297
1297
|
readonly filename: string;
|
|
1298
|
-
readonly file_data?: string | undefined;
|
|
1299
1298
|
readonly detail?: string | undefined;
|
|
1299
|
+
readonly file_data?: string | undefined;
|
|
1300
1300
|
readonly file_url?: string | undefined;
|
|
1301
1301
|
} | {
|
|
1302
1302
|
readonly type: "input_text";
|
|
@@ -30,10 +30,13 @@ const decodeEvent = route.decodeFrame(SpeechStreamEvent);
|
|
|
30
30
|
// ---------------------------------------------------------------------------
|
|
31
31
|
// `sse` is not supported for `tts-1` or `tts-1-hd`; those models stream the raw audio body instead.
|
|
32
32
|
const supportsSse = (model) => !/^tts-1(-hd)?(-|$)/.test(model);
|
|
33
|
+
const FORMATS = new Set(["mp3", "opus", "aac", "flac", "wav", "pcm"]);
|
|
33
34
|
const fromRequest = Effect.fn("OpenAISpeech.fromRequest")(function* (request) {
|
|
34
35
|
// Not in `unsupported`: that list would also reject `timestamps: false`, which asks for nothing.
|
|
35
36
|
if (request.timestamps === true)
|
|
36
37
|
return yield* route.unsupported("media.timestamps", `${route.name} does not return timestamps`);
|
|
38
|
+
if (request.format !== undefined && !FORMATS.has(request.format))
|
|
39
|
+
return yield* route.unsupported("media.format", `${route.name} supports the mp3, opus, aac, flac, wav, and pcm formats, not "${request.format}"`);
|
|
37
40
|
return MediaProtocol.json(mergeJsonRecords({
|
|
38
41
|
model: request.model.id,
|
|
39
42
|
input: request.text,
|
|
@@ -73,7 +76,9 @@ const onEvent = Effect.fn("OpenAISpeech.onEvent")(function* (state, frame) {
|
|
|
73
76
|
const finish = (state, context) => {
|
|
74
77
|
if (isSse(context.body) && !state.done)
|
|
75
78
|
return Effect.fail(route.incomplete());
|
|
76
|
-
|
|
79
|
+
// The sent body reflects `providerOptions` and `http.body` overrides of `format`.
|
|
80
|
+
const sent = context.body.type === "json" ? context.body.value.response_format : undefined;
|
|
81
|
+
const format = typeof sent === "string" ? sent : "mp3";
|
|
77
82
|
return SpeechStream.finish(route, state, {
|
|
78
83
|
...(format === "pcm" ? SpeechStream.pcm("pcm_s16le", PCM_SAMPLE_RATE) : SpeechStream.container(format)),
|
|
79
84
|
usage: state.usage,
|
|
@@ -118,7 +118,7 @@ const fromRequest = Effect.fn("OpenAITranscription.fromRequest")(function* (requ
|
|
|
118
118
|
}, {
|
|
119
119
|
overlay: mergeJsonRecords(request.providerOptions, request.http?.body),
|
|
120
120
|
reserved: RESERVED_FORM_FIELDS,
|
|
121
|
-
repeatArrays:
|
|
121
|
+
repeatArrays: "key[]",
|
|
122
122
|
});
|
|
123
123
|
return MediaProtocol.multipart(form);
|
|
124
124
|
});
|
|
@@ -89,7 +89,8 @@ const decodeResult = Effect.fn("RunwayVideo.decodeResult")(function* (response,
|
|
|
89
89
|
// Runway failure codes are dotted paths; every moderation outcome carries a SAFETY segment.
|
|
90
90
|
if (code !== undefined && /(^|\.)SAFETY(\.|$)/.test(code))
|
|
91
91
|
return yield* output.contentPolicy(message);
|
|
92
|
-
|
|
92
|
+
// ASSET.INVALID rejects the caller's input media; Runway documents it as not retryable.
|
|
93
|
+
return yield* output.ended("failed", message, code !== undefined && /^ASSET\.INVALID(\.|$)/.test(code) ? "InvalidRequest" : "ProviderInternal");
|
|
93
94
|
}
|
|
94
95
|
if (status === "cancelled")
|
|
95
96
|
return yield* output.ended("cancelled", `${route.name} task ${context.token.taskID} was cancelled`);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LLMRequest } from "../../schema/index.js";
|
|
2
|
+
export declare const THINKING_BINDING_BETA = "thinking-binding-controls-2026-08-01";
|
|
3
|
+
export declare const claudeVersion: (id: string) => {
|
|
4
|
+
family: string;
|
|
5
|
+
major: number;
|
|
6
|
+
minor: number;
|
|
7
|
+
} | undefined;
|
|
8
|
+
export declare const supportsThinkingBlockBinding: (model: LLMRequest["model"]) => boolean;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const THINKING_BINDING_BETA = "thinking-binding-controls-2026-08-01";
|
|
2
|
+
// Accept gateway namespaces and Vertex suffixes without treating a snapshot date as a minor version.
|
|
3
|
+
export const claudeVersion = (id) => {
|
|
4
|
+
const match = /(?:^|[./])claude-(?<family>[a-z]+)-(?<major>\d+)(?:[.-](?<minor>\d{1,2}))?(?:$|[-:@])/.exec(id.toLowerCase())?.groups;
|
|
5
|
+
if (!match)
|
|
6
|
+
return undefined;
|
|
7
|
+
return { family: match.family, major: Number(match.major), minor: Number(match.minor ?? 0) };
|
|
8
|
+
};
|
|
9
|
+
export const supportsThinkingBlockBinding = (model) => {
|
|
10
|
+
const override = model.compatibility?.supportsThinkingBlockBinding;
|
|
11
|
+
if (override !== undefined)
|
|
12
|
+
return override;
|
|
13
|
+
const version = claudeVersion(model.id);
|
|
14
|
+
return version !== undefined && (version.major > 5 || (version.major === 5 && version.minor >= 1));
|
|
15
|
+
};
|
|
@@ -47,6 +47,12 @@ export interface Metadata {
|
|
|
47
47
|
}
|
|
48
48
|
export declare const track: <State extends Metadata>(state: State, chunk: Chunk) => State;
|
|
49
49
|
export declare const blocked: (name: string, chunk: Chunk, frame: string) => AIError | undefined;
|
|
50
|
+
/** Finish reasons for which Gemini stops output on safety or policy grounds. */
|
|
51
|
+
export declare const contentFiltered: (finishReason: string | undefined) => boolean;
|
|
52
|
+
/** Callers check that the response produced no output: a policy stop after output is a partial result instead. */
|
|
53
|
+
export declare const withheld: (name: string, chunk: Chunk, frame: string) => AIError | undefined;
|
|
54
|
+
/** Any finish reason other than `STOP` means the output may be cut short, so it is surfaced rather than dropped. */
|
|
55
|
+
export declare const notices: (name: string, state: Metadata) => ReadonlyArray<Media.Notice> | undefined;
|
|
50
56
|
export declare const usage: (usage: UsageMetadata | undefined) => MediaUsage | undefined;
|
|
51
57
|
export declare const providerMetadata: (state: Metadata) => ProviderMetadata;
|
|
52
58
|
export declare const path: (model: string, mode: MediaProtocol.Mode) => string;
|