@opencode/ai 2.0.20 → 2.0.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.
- package/dist/cache-policy.js +22 -3
- package/dist/llm.d.ts +4 -0
- package/dist/promise.d.ts +8 -0
- package/dist/protocols/alibaba-chat.d.ts +20 -10
- package/dist/protocols/alibaba-chat.js +2 -1
- package/dist/protocols/anthropic-messages.js +14 -12
- package/dist/protocols/bedrock-converse.js +30 -1
- package/dist/protocols/open-responses.d.ts +4 -0
- package/dist/protocols/openai-chat.d.ts +122 -71
- package/dist/protocols/openai-chat.js +40 -37
- package/dist/protocols/openai-compatible-chat.d.ts +16 -10
- package/dist/protocols/openai-responses.js +4 -3
- package/dist/protocols/utils/cache.d.ts +5 -0
- package/dist/protocols/utils/cache.js +9 -1
- package/dist/protocols/utils/tool-stream.d.ts +12 -0
- package/dist/protocols/zai-chat.d.ts +20 -10
- package/dist/protocols/zai-chat.js +6 -3
- package/dist/provider-error.js +24 -6
- package/dist/providers/alibaba.d.ts +16 -10
- package/dist/providers/amazon-bedrock-mantle.d.ts +16 -10
- package/dist/providers/azure.d.ts +16 -10
- package/dist/providers/baseten.d.ts +32 -20
- package/dist/providers/cerebras.d.ts +32 -20
- package/dist/providers/cloudflare-ai-gateway.d.ts +32 -20
- package/dist/providers/cloudflare-ai-gateway.js +43 -35
- package/dist/providers/cloudflare-workers-ai.d.ts +32 -20
- package/dist/providers/deepinfra.d.ts +32 -20
- package/dist/providers/deepseek.d.ts +32 -20
- package/dist/providers/digitalocean.d.ts +469 -0
- package/dist/providers/digitalocean.js +53 -0
- package/dist/providers/fireworks.d.ts +32 -20
- package/dist/providers/google-vertex-chat.d.ts +16 -10
- package/dist/providers/google-vertex-messages.js +1 -1
- package/dist/providers/groq.d.ts +36 -20
- package/dist/providers/groq.js +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.js +1 -0
- package/dist/providers/meta.d.ts +16 -10
- package/dist/providers/minimax.d.ts +16 -10
- package/dist/providers/moonshot.d.ts +16 -10
- package/dist/providers/openai-compatible.d.ts +16 -10
- package/dist/providers/openai.d.ts +16 -10
- package/dist/providers/openrouter.d.ts +68 -40
- package/dist/providers/openrouter.js +1 -13
- package/dist/providers/togetherai.d.ts +32 -20
- package/dist/providers/xai.d.ts +16 -10
- package/dist/providers/zai-coding-plan.d.ts +16 -10
- package/dist/providers/zai.d.ts +16 -10
- package/dist/route/client.d.ts +4 -0
- package/dist/route/executor.js +13 -6
- package/dist/route/transport/http.d.ts +2 -1
- package/dist/route/transport/http.js +28 -6
- package/dist/schema/events.d.ts +176 -0
- package/dist/schema/events.js +4 -0
- package/dist/schema/options.d.ts +11 -0
- package/dist/schema/options.js +15 -2
- package/dist/testing.d.ts +32 -0
- package/dist/tool-history.js +17 -3
- package/package.json +3 -3
|
@@ -12,6 +12,7 @@ declare const OpenAIChatCacheControl: Schema.Struct<{
|
|
|
12
12
|
readonly type: Schema.Literal<"ephemeral">;
|
|
13
13
|
readonly ttl: Schema.optional<Schema.String>;
|
|
14
14
|
}>;
|
|
15
|
+
type OpenAIChatCacheControl = Schema.Schema.Type<typeof OpenAIChatCacheControl>;
|
|
15
16
|
declare const ExtraContent: Schema.Struct<{
|
|
16
17
|
readonly google: Schema.Struct<{
|
|
17
18
|
readonly thought_signature: Schema.String;
|
|
@@ -94,7 +95,14 @@ export declare const bodyFields: {
|
|
|
94
95
|
}>]>>]>;
|
|
95
96
|
}>, Schema.StructWithRest<Schema.Struct<{
|
|
96
97
|
readonly role: Schema.Literal<"assistant">;
|
|
97
|
-
readonly content: Schema.NullOr<Schema.String
|
|
98
|
+
readonly content: Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Array<Schema.Struct<{
|
|
99
|
+
readonly type: Schema.Literal<"text">;
|
|
100
|
+
readonly text: Schema.String;
|
|
101
|
+
readonly cache_control: Schema.optional<Schema.Struct<{
|
|
102
|
+
readonly type: Schema.Literal<"ephemeral">;
|
|
103
|
+
readonly ttl: Schema.optional<Schema.String>;
|
|
104
|
+
}>>;
|
|
105
|
+
}>>]>>;
|
|
98
106
|
readonly tool_calls: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
99
107
|
readonly id: Schema.String;
|
|
100
108
|
readonly type: Schema.tag<"function">;
|
|
@@ -112,18 +120,17 @@ export declare const bodyFields: {
|
|
|
112
120
|
readonly reasoning: Schema.optional<Schema.String>;
|
|
113
121
|
readonly reasoning_text: Schema.optional<Schema.String>;
|
|
114
122
|
readonly reasoning_details: Schema.optional<Schema.Unknown>;
|
|
115
|
-
readonly cache_control: Schema.optional<Schema.Struct<{
|
|
116
|
-
readonly type: Schema.Literal<"ephemeral">;
|
|
117
|
-
readonly ttl: Schema.optional<Schema.String>;
|
|
118
|
-
}>>;
|
|
119
123
|
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>, Schema.Struct<{
|
|
120
124
|
readonly role: Schema.Literal<"tool">;
|
|
121
125
|
readonly tool_call_id: Schema.String;
|
|
122
|
-
readonly content: Schema.String
|
|
123
|
-
|
|
124
|
-
readonly
|
|
125
|
-
readonly
|
|
126
|
-
|
|
126
|
+
readonly content: Schema.Union<readonly [Schema.String, Schema.$Array<Schema.Struct<{
|
|
127
|
+
readonly type: Schema.Literal<"text">;
|
|
128
|
+
readonly text: Schema.String;
|
|
129
|
+
readonly cache_control: Schema.optional<Schema.Struct<{
|
|
130
|
+
readonly type: Schema.Literal<"ephemeral">;
|
|
131
|
+
readonly ttl: Schema.optional<Schema.String>;
|
|
132
|
+
}>>;
|
|
133
|
+
}>>]>;
|
|
127
134
|
}>]>>;
|
|
128
135
|
tools: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
129
136
|
readonly type: Schema.tag<"function">;
|
|
@@ -207,7 +214,14 @@ declare const OpenAIChatBody: Schema.Struct<{
|
|
|
207
214
|
}>]>>]>;
|
|
208
215
|
}>, Schema.StructWithRest<Schema.Struct<{
|
|
209
216
|
readonly role: Schema.Literal<"assistant">;
|
|
210
|
-
readonly content: Schema.NullOr<Schema.String
|
|
217
|
+
readonly content: Schema.NullOr<Schema.Union<readonly [Schema.String, Schema.$Array<Schema.Struct<{
|
|
218
|
+
readonly type: Schema.Literal<"text">;
|
|
219
|
+
readonly text: Schema.String;
|
|
220
|
+
readonly cache_control: Schema.optional<Schema.Struct<{
|
|
221
|
+
readonly type: Schema.Literal<"ephemeral">;
|
|
222
|
+
readonly ttl: Schema.optional<Schema.String>;
|
|
223
|
+
}>>;
|
|
224
|
+
}>>]>>;
|
|
211
225
|
readonly tool_calls: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
212
226
|
readonly id: Schema.String;
|
|
213
227
|
readonly type: Schema.tag<"function">;
|
|
@@ -225,18 +239,17 @@ declare const OpenAIChatBody: Schema.Struct<{
|
|
|
225
239
|
readonly reasoning: Schema.optional<Schema.String>;
|
|
226
240
|
readonly reasoning_text: Schema.optional<Schema.String>;
|
|
227
241
|
readonly reasoning_details: Schema.optional<Schema.Unknown>;
|
|
228
|
-
readonly cache_control: Schema.optional<Schema.Struct<{
|
|
229
|
-
readonly type: Schema.Literal<"ephemeral">;
|
|
230
|
-
readonly ttl: Schema.optional<Schema.String>;
|
|
231
|
-
}>>;
|
|
232
242
|
}>, readonly [Schema.$Record<Schema.String, Schema.Unknown>]>, Schema.Struct<{
|
|
233
243
|
readonly role: Schema.Literal<"tool">;
|
|
234
244
|
readonly tool_call_id: Schema.String;
|
|
235
|
-
readonly content: Schema.String
|
|
236
|
-
|
|
237
|
-
readonly
|
|
238
|
-
readonly
|
|
239
|
-
|
|
245
|
+
readonly content: Schema.Union<readonly [Schema.String, Schema.$Array<Schema.Struct<{
|
|
246
|
+
readonly type: Schema.Literal<"text">;
|
|
247
|
+
readonly text: Schema.String;
|
|
248
|
+
readonly cache_control: Schema.optional<Schema.Struct<{
|
|
249
|
+
readonly type: Schema.Literal<"ephemeral">;
|
|
250
|
+
readonly ttl: Schema.optional<Schema.String>;
|
|
251
|
+
}>>;
|
|
252
|
+
}>>]>;
|
|
240
253
|
}>]>>;
|
|
241
254
|
tools: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
242
255
|
readonly type: Schema.tag<"function">;
|
|
@@ -302,6 +315,8 @@ export declare const OpenAIChatEvent: Schema.StructWithRest<Schema.Struct<{
|
|
|
302
315
|
readonly total_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
303
316
|
readonly cached_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
304
317
|
readonly prompt_cache_hit_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
318
|
+
readonly cache_read_input_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
319
|
+
readonly cache_created_input_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
305
320
|
readonly prompt_tokens_details: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
|
|
306
321
|
readonly cached_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
307
322
|
readonly cache_write_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
@@ -319,6 +334,8 @@ export declare const OpenAIChatEvent: Schema.StructWithRest<Schema.Struct<{
|
|
|
319
334
|
readonly total_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
320
335
|
readonly cached_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
321
336
|
readonly prompt_cache_hit_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
337
|
+
readonly cache_read_input_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
338
|
+
readonly cache_created_input_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
322
339
|
readonly prompt_tokens_details: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
|
|
323
340
|
readonly cached_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
324
341
|
readonly cache_write_tokens: Schema.optional<Schema.NullOr<Schema.Number>>;
|
|
@@ -360,7 +377,7 @@ export interface ParserState {
|
|
|
360
377
|
readonly requireFinishReason: boolean;
|
|
361
378
|
}
|
|
362
379
|
interface LoweringOptions {
|
|
363
|
-
readonly cacheControl?: (cache: CacheHint | undefined) =>
|
|
380
|
+
readonly cacheControl?: (cache: CacheHint | undefined) => OpenAIChatCacheControl | undefined;
|
|
364
381
|
readonly toolCallID?: (id: string) => string;
|
|
365
382
|
}
|
|
366
383
|
export declare const fromRequest: (request: LLMRequest<import("../schema/options.js").LanguageModel<{
|
|
@@ -425,15 +442,18 @@ export declare const fromRequest: (request: LLMRequest<import("../schema/options
|
|
|
425
442
|
})[];
|
|
426
443
|
} | {
|
|
427
444
|
readonly [x: string]: unknown;
|
|
428
|
-
readonly content: string |
|
|
445
|
+
readonly content: string | readonly {
|
|
446
|
+
readonly type: "text";
|
|
447
|
+
readonly text: string;
|
|
448
|
+
readonly cache_control?: {
|
|
449
|
+
readonly type: "ephemeral";
|
|
450
|
+
readonly ttl?: string | undefined;
|
|
451
|
+
} | undefined;
|
|
452
|
+
}[] | null;
|
|
429
453
|
readonly role: "assistant";
|
|
430
454
|
readonly reasoning?: string | undefined;
|
|
431
455
|
readonly reasoning_content?: string | undefined;
|
|
432
456
|
readonly reasoning_text?: string | undefined;
|
|
433
|
-
readonly cache_control?: {
|
|
434
|
-
readonly type: "ephemeral";
|
|
435
|
-
readonly ttl?: string | undefined;
|
|
436
|
-
} | undefined;
|
|
437
457
|
readonly tool_calls?: readonly {
|
|
438
458
|
readonly function: {
|
|
439
459
|
readonly name: string;
|
|
@@ -449,13 +469,16 @@ export declare const fromRequest: (request: LLMRequest<import("../schema/options
|
|
|
449
469
|
}[] | undefined;
|
|
450
470
|
readonly reasoning_details?: unknown;
|
|
451
471
|
} | {
|
|
452
|
-
readonly content: string;
|
|
453
472
|
readonly role: "tool";
|
|
454
473
|
readonly tool_call_id: string;
|
|
455
|
-
readonly
|
|
456
|
-
readonly type: "
|
|
457
|
-
readonly
|
|
458
|
-
|
|
474
|
+
readonly content: string | readonly {
|
|
475
|
+
readonly type: "text";
|
|
476
|
+
readonly text: string;
|
|
477
|
+
readonly cache_control?: {
|
|
478
|
+
readonly type: "ephemeral";
|
|
479
|
+
readonly ttl?: string | undefined;
|
|
480
|
+
} | undefined;
|
|
481
|
+
}[];
|
|
459
482
|
})[];
|
|
460
483
|
tools: {
|
|
461
484
|
readonly function: {
|
|
@@ -539,15 +562,18 @@ export declare const fromRequest: (request: LLMRequest<import("../schema/options
|
|
|
539
562
|
})[];
|
|
540
563
|
} | {
|
|
541
564
|
readonly [x: string]: unknown;
|
|
542
|
-
readonly content: string |
|
|
565
|
+
readonly content: string | readonly {
|
|
566
|
+
readonly type: "text";
|
|
567
|
+
readonly text: string;
|
|
568
|
+
readonly cache_control?: {
|
|
569
|
+
readonly type: "ephemeral";
|
|
570
|
+
readonly ttl?: string | undefined;
|
|
571
|
+
} | undefined;
|
|
572
|
+
}[] | null;
|
|
543
573
|
readonly role: "assistant";
|
|
544
574
|
readonly reasoning?: string | undefined;
|
|
545
575
|
readonly reasoning_content?: string | undefined;
|
|
546
576
|
readonly reasoning_text?: string | undefined;
|
|
547
|
-
readonly cache_control?: {
|
|
548
|
-
readonly type: "ephemeral";
|
|
549
|
-
readonly ttl?: string | undefined;
|
|
550
|
-
} | undefined;
|
|
551
577
|
readonly tool_calls?: readonly {
|
|
552
578
|
readonly function: {
|
|
553
579
|
readonly name: string;
|
|
@@ -563,13 +589,16 @@ export declare const fromRequest: (request: LLMRequest<import("../schema/options
|
|
|
563
589
|
}[] | undefined;
|
|
564
590
|
readonly reasoning_details?: unknown;
|
|
565
591
|
} | {
|
|
566
|
-
readonly content: string;
|
|
567
592
|
readonly role: "tool";
|
|
568
593
|
readonly tool_call_id: string;
|
|
569
|
-
readonly
|
|
570
|
-
readonly type: "
|
|
571
|
-
readonly
|
|
572
|
-
|
|
594
|
+
readonly content: string | readonly {
|
|
595
|
+
readonly type: "text";
|
|
596
|
+
readonly text: string;
|
|
597
|
+
readonly cache_control?: {
|
|
598
|
+
readonly type: "ephemeral";
|
|
599
|
+
readonly ttl?: string | undefined;
|
|
600
|
+
} | undefined;
|
|
601
|
+
}[];
|
|
573
602
|
})[];
|
|
574
603
|
tools: {
|
|
575
604
|
readonly function: {
|
|
@@ -646,15 +675,18 @@ export declare const protocol: Protocol<{
|
|
|
646
675
|
})[];
|
|
647
676
|
} | {
|
|
648
677
|
readonly [x: string]: unknown;
|
|
649
|
-
readonly content: string |
|
|
678
|
+
readonly content: string | readonly {
|
|
679
|
+
readonly type: "text";
|
|
680
|
+
readonly text: string;
|
|
681
|
+
readonly cache_control?: {
|
|
682
|
+
readonly type: "ephemeral";
|
|
683
|
+
readonly ttl?: string | undefined;
|
|
684
|
+
} | undefined;
|
|
685
|
+
}[] | null;
|
|
650
686
|
readonly role: "assistant";
|
|
651
687
|
readonly reasoning?: string | undefined;
|
|
652
688
|
readonly reasoning_content?: string | undefined;
|
|
653
689
|
readonly reasoning_text?: string | undefined;
|
|
654
|
-
readonly cache_control?: {
|
|
655
|
-
readonly type: "ephemeral";
|
|
656
|
-
readonly ttl?: string | undefined;
|
|
657
|
-
} | undefined;
|
|
658
690
|
readonly tool_calls?: readonly {
|
|
659
691
|
readonly function: {
|
|
660
692
|
readonly name: string;
|
|
@@ -670,13 +702,16 @@ export declare const protocol: Protocol<{
|
|
|
670
702
|
}[] | undefined;
|
|
671
703
|
readonly reasoning_details?: unknown;
|
|
672
704
|
} | {
|
|
673
|
-
readonly content: string;
|
|
674
705
|
readonly role: "tool";
|
|
675
706
|
readonly tool_call_id: string;
|
|
676
|
-
readonly
|
|
677
|
-
readonly type: "
|
|
678
|
-
readonly
|
|
679
|
-
|
|
707
|
+
readonly content: string | readonly {
|
|
708
|
+
readonly type: "text";
|
|
709
|
+
readonly text: string;
|
|
710
|
+
readonly cache_control?: {
|
|
711
|
+
readonly type: "ephemeral";
|
|
712
|
+
readonly ttl?: string | undefined;
|
|
713
|
+
} | undefined;
|
|
714
|
+
}[];
|
|
680
715
|
})[];
|
|
681
716
|
readonly stream: true;
|
|
682
717
|
readonly max_completion_tokens?: number | undefined;
|
|
@@ -724,6 +759,7 @@ export declare const protocol: Protocol<{
|
|
|
724
759
|
} | null | undefined;
|
|
725
760
|
readonly usage?: {
|
|
726
761
|
readonly [x: string]: unknown;
|
|
762
|
+
readonly cache_read_input_tokens?: number | null | undefined;
|
|
727
763
|
readonly cached_tokens?: number | null | undefined;
|
|
728
764
|
readonly prompt_tokens?: number | null | undefined;
|
|
729
765
|
readonly completion_tokens?: number | null | undefined;
|
|
@@ -734,6 +770,7 @@ export declare const protocol: Protocol<{
|
|
|
734
770
|
readonly cache_write_tokens?: number | null | undefined;
|
|
735
771
|
} | null | undefined;
|
|
736
772
|
readonly prompt_cache_hit_tokens?: number | null | undefined;
|
|
773
|
+
readonly cache_created_input_tokens?: number | null | undefined;
|
|
737
774
|
readonly completion_tokens_details?: {
|
|
738
775
|
readonly [x: string]: unknown;
|
|
739
776
|
readonly reasoning_tokens?: number | null | undefined;
|
|
@@ -763,6 +800,7 @@ export declare const protocol: Protocol<{
|
|
|
763
800
|
} | null | undefined;
|
|
764
801
|
readonly usage?: {
|
|
765
802
|
readonly [x: string]: unknown;
|
|
803
|
+
readonly cache_read_input_tokens?: number | null | undefined;
|
|
766
804
|
readonly cached_tokens?: number | null | undefined;
|
|
767
805
|
readonly prompt_tokens?: number | null | undefined;
|
|
768
806
|
readonly completion_tokens?: number | null | undefined;
|
|
@@ -773,6 +811,7 @@ export declare const protocol: Protocol<{
|
|
|
773
811
|
readonly cache_write_tokens?: number | null | undefined;
|
|
774
812
|
} | null | undefined;
|
|
775
813
|
readonly prompt_cache_hit_tokens?: number | null | undefined;
|
|
814
|
+
readonly cache_created_input_tokens?: number | null | undefined;
|
|
776
815
|
readonly completion_tokens_details?: {
|
|
777
816
|
readonly [x: string]: unknown;
|
|
778
817
|
readonly reasoning_tokens?: number | null | undefined;
|
|
@@ -831,15 +870,18 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
831
870
|
})[];
|
|
832
871
|
} | {
|
|
833
872
|
readonly [x: string]: unknown;
|
|
834
|
-
readonly content: string |
|
|
873
|
+
readonly content: string | readonly {
|
|
874
|
+
readonly type: "text";
|
|
875
|
+
readonly text: string;
|
|
876
|
+
readonly cache_control?: {
|
|
877
|
+
readonly type: "ephemeral";
|
|
878
|
+
readonly ttl?: string | undefined;
|
|
879
|
+
} | undefined;
|
|
880
|
+
}[] | null;
|
|
835
881
|
readonly role: "assistant";
|
|
836
882
|
readonly reasoning?: string | undefined;
|
|
837
883
|
readonly reasoning_content?: string | undefined;
|
|
838
884
|
readonly reasoning_text?: string | undefined;
|
|
839
|
-
readonly cache_control?: {
|
|
840
|
-
readonly type: "ephemeral";
|
|
841
|
-
readonly ttl?: string | undefined;
|
|
842
|
-
} | undefined;
|
|
843
885
|
readonly tool_calls?: readonly {
|
|
844
886
|
readonly function: {
|
|
845
887
|
readonly name: string;
|
|
@@ -855,13 +897,16 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
855
897
|
}[] | undefined;
|
|
856
898
|
readonly reasoning_details?: unknown;
|
|
857
899
|
} | {
|
|
858
|
-
readonly content: string;
|
|
859
900
|
readonly role: "tool";
|
|
860
901
|
readonly tool_call_id: string;
|
|
861
|
-
readonly
|
|
862
|
-
readonly type: "
|
|
863
|
-
readonly
|
|
864
|
-
|
|
902
|
+
readonly content: string | readonly {
|
|
903
|
+
readonly type: "text";
|
|
904
|
+
readonly text: string;
|
|
905
|
+
readonly cache_control?: {
|
|
906
|
+
readonly type: "ephemeral";
|
|
907
|
+
readonly ttl?: string | undefined;
|
|
908
|
+
} | undefined;
|
|
909
|
+
}[];
|
|
865
910
|
})[];
|
|
866
911
|
readonly stream: true;
|
|
867
912
|
readonly max_completion_tokens?: number | undefined;
|
|
@@ -947,15 +992,18 @@ export declare const route: Route<{
|
|
|
947
992
|
})[];
|
|
948
993
|
} | {
|
|
949
994
|
readonly [x: string]: unknown;
|
|
950
|
-
readonly content: string |
|
|
995
|
+
readonly content: string | readonly {
|
|
996
|
+
readonly type: "text";
|
|
997
|
+
readonly text: string;
|
|
998
|
+
readonly cache_control?: {
|
|
999
|
+
readonly type: "ephemeral";
|
|
1000
|
+
readonly ttl?: string | undefined;
|
|
1001
|
+
} | undefined;
|
|
1002
|
+
}[] | null;
|
|
951
1003
|
readonly role: "assistant";
|
|
952
1004
|
readonly reasoning?: string | undefined;
|
|
953
1005
|
readonly reasoning_content?: string | undefined;
|
|
954
1006
|
readonly reasoning_text?: string | undefined;
|
|
955
|
-
readonly cache_control?: {
|
|
956
|
-
readonly type: "ephemeral";
|
|
957
|
-
readonly ttl?: string | undefined;
|
|
958
|
-
} | undefined;
|
|
959
1007
|
readonly tool_calls?: readonly {
|
|
960
1008
|
readonly function: {
|
|
961
1009
|
readonly name: string;
|
|
@@ -971,13 +1019,16 @@ export declare const route: Route<{
|
|
|
971
1019
|
}[] | undefined;
|
|
972
1020
|
readonly reasoning_details?: unknown;
|
|
973
1021
|
} | {
|
|
974
|
-
readonly content: string;
|
|
975
1022
|
readonly role: "tool";
|
|
976
1023
|
readonly tool_call_id: string;
|
|
977
|
-
readonly
|
|
978
|
-
readonly type: "
|
|
979
|
-
readonly
|
|
980
|
-
|
|
1024
|
+
readonly content: string | readonly {
|
|
1025
|
+
readonly type: "text";
|
|
1026
|
+
readonly text: string;
|
|
1027
|
+
readonly cache_control?: {
|
|
1028
|
+
readonly type: "ephemeral";
|
|
1029
|
+
readonly ttl?: string | undefined;
|
|
1030
|
+
} | undefined;
|
|
1031
|
+
}[];
|
|
981
1032
|
})[];
|
|
982
1033
|
readonly stream: true;
|
|
983
1034
|
readonly max_completion_tokens?: number | undefined;
|
|
@@ -83,12 +83,13 @@ const ReasoningDetail = Schema.Union([
|
|
|
83
83
|
]);
|
|
84
84
|
const decodeReasoningDetail = Schema.decodeUnknownOption(ReasoningDetail);
|
|
85
85
|
const knownReasoningDetails = (details) => details.flatMap((detail) => Option.toArray(decodeReasoningDetail(detail)));
|
|
86
|
+
const OpenAIChatTextContent = Schema.Struct({
|
|
87
|
+
type: Schema.Literal("text"),
|
|
88
|
+
text: Schema.String,
|
|
89
|
+
cache_control: Schema.optional(OpenAIChatCacheControl),
|
|
90
|
+
});
|
|
86
91
|
const OpenAIChatUserContent = Schema.Union([
|
|
87
|
-
|
|
88
|
-
type: Schema.Literal("text"),
|
|
89
|
-
text: Schema.String,
|
|
90
|
-
cache_control: Schema.optional(OpenAIChatCacheControl),
|
|
91
|
-
}),
|
|
92
|
+
OpenAIChatTextContent,
|
|
92
93
|
Schema.Struct({
|
|
93
94
|
type: Schema.Literal("image_url"),
|
|
94
95
|
image_url: Schema.Struct({ url: Schema.String }),
|
|
@@ -109,19 +110,17 @@ const OpenAIChatMessage = Schema.Union([
|
|
|
109
110
|
}),
|
|
110
111
|
Schema.StructWithRest(Schema.Struct({
|
|
111
112
|
role: Schema.Literal("assistant"),
|
|
112
|
-
content: Schema.NullOr(Schema.String),
|
|
113
|
+
content: Schema.NullOr(Schema.Union([Schema.String, Schema.Array(OpenAIChatTextContent)])),
|
|
113
114
|
tool_calls: optionalArray(OpenAIChatAssistantToolCall),
|
|
114
115
|
reasoning_content: Schema.optional(Schema.String),
|
|
115
116
|
reasoning: Schema.optional(Schema.String),
|
|
116
117
|
reasoning_text: Schema.optional(Schema.String),
|
|
117
118
|
reasoning_details: Schema.optional(Schema.Unknown),
|
|
118
|
-
cache_control: Schema.optional(OpenAIChatCacheControl),
|
|
119
119
|
}), [Schema.Record(Schema.String, Schema.Unknown)]),
|
|
120
120
|
Schema.Struct({
|
|
121
121
|
role: Schema.Literal("tool"),
|
|
122
122
|
tool_call_id: Schema.String,
|
|
123
|
-
content: Schema.String,
|
|
124
|
-
cache_control: Schema.optional(OpenAIChatCacheControl),
|
|
123
|
+
content: Schema.Union([Schema.String, Schema.Array(OpenAIChatTextContent)]),
|
|
125
124
|
}),
|
|
126
125
|
]).pipe(Schema.toTaggedUnion("role"));
|
|
127
126
|
const OpenAIChatToolChoice = Schema.Union([
|
|
@@ -162,9 +161,11 @@ const OpenAIChatUsage = Schema.StructWithRest(Schema.Struct({
|
|
|
162
161
|
prompt_tokens: optionalNull(Schema.Number),
|
|
163
162
|
completion_tokens: optionalNull(Schema.Number),
|
|
164
163
|
total_tokens: optionalNull(Schema.Number),
|
|
165
|
-
//
|
|
164
|
+
// Provider-specific cache accounting fields.
|
|
166
165
|
cached_tokens: optionalNull(Schema.Number),
|
|
167
166
|
prompt_cache_hit_tokens: optionalNull(Schema.Number),
|
|
167
|
+
cache_read_input_tokens: optionalNull(Schema.Number),
|
|
168
|
+
cache_created_input_tokens: optionalNull(Schema.Number),
|
|
168
169
|
prompt_tokens_details: optionalNull(Schema.StructWithRest(Schema.Struct({
|
|
169
170
|
cached_tokens: optionalNull(Schema.Number),
|
|
170
171
|
cache_write_tokens: optionalNull(Schema.Number),
|
|
@@ -305,7 +306,7 @@ const lowerAssistantMessage = Effect.fn("OpenAIChat.lowerAssistantMessage")(func
|
|
|
305
306
|
if (!ProviderShared.supportsContent(part, ["text", "reasoning", "tool-call"]))
|
|
306
307
|
return yield* ProviderShared.unsupportedContent("OpenAI Chat", "assistant", ["text", "reasoning", "tool-call"]);
|
|
307
308
|
if (part.type === "text") {
|
|
308
|
-
content.push(part);
|
|
309
|
+
content.push({ type: "text", text: part.text, cache_control: options.cacheControl?.(part.cache) });
|
|
309
310
|
continue;
|
|
310
311
|
}
|
|
311
312
|
if (part.type === "reasoning") {
|
|
@@ -347,14 +348,17 @@ const lowerAssistantMessage = Effect.fn("OpenAIChat.lowerAssistantMessage")(func
|
|
|
347
348
|
return nativeReasoning ?? (requireReasoning ? "" : undefined);
|
|
348
349
|
return text;
|
|
349
350
|
})();
|
|
350
|
-
const cached = message.content.findLast((part) => "cache" in part && part.cache !== undefined);
|
|
351
|
-
const cacheControl = options.cacheControl?.(cached && "cache" in cached ? cached.cache : undefined);
|
|
352
351
|
const result = {
|
|
353
352
|
role: "assistant",
|
|
354
|
-
content:
|
|
353
|
+
content: (() => {
|
|
354
|
+
if (content.some((part) => part.cache_control !== undefined))
|
|
355
|
+
return content;
|
|
356
|
+
if (content.length === 0 && toolCalls.length > 0)
|
|
357
|
+
return null;
|
|
358
|
+
return content.map((part) => part.text).join("");
|
|
359
|
+
})(),
|
|
355
360
|
...(toolCalls.length > 0 ? { tool_calls: toolCalls } : {}),
|
|
356
361
|
...(details !== undefined ? { reasoning_details: details } : {}),
|
|
357
|
-
...(cacheControl !== undefined ? { cache_control: cacheControl } : {}),
|
|
358
362
|
};
|
|
359
363
|
if (field === undefined || reasoningText === undefined)
|
|
360
364
|
return result;
|
|
@@ -367,27 +371,23 @@ const lowerToolMessages = Effect.fn("OpenAIChat.lowerToolMessages")(function* (m
|
|
|
367
371
|
if (!ProviderShared.supportsContent(part, ["tool-result"]))
|
|
368
372
|
return yield* ProviderShared.unsupportedContent("OpenAI Chat", "tool", ["tool-result"]);
|
|
369
373
|
if (part.result.type !== "content") {
|
|
370
|
-
messages.push(
|
|
371
|
-
role: "tool",
|
|
372
|
-
tool_call_id: options.toolCallID?.(part.id) ?? part.id,
|
|
373
|
-
content: ProviderShared.toolResultText(part),
|
|
374
|
-
cache_control: options.cacheControl?.(part.cache),
|
|
375
|
-
});
|
|
374
|
+
messages.push(toolMessage(options.toolCallID?.(part.id) ?? part.id, ProviderShared.toolResultText(part), options.cacheControl?.(part.cache)));
|
|
376
375
|
continue;
|
|
377
376
|
}
|
|
378
377
|
const content = part.result.value;
|
|
379
378
|
const text = content.filter((item) => item.type === "text").map((item) => item.text);
|
|
380
|
-
messages.push(
|
|
381
|
-
role: "tool",
|
|
382
|
-
tool_call_id: options.toolCallID?.(part.id) ?? part.id,
|
|
383
|
-
content: text.join("\n"),
|
|
384
|
-
cache_control: options.cacheControl?.(part.cache),
|
|
385
|
-
});
|
|
379
|
+
messages.push(toolMessage(options.toolCallID?.(part.id) ?? part.id, text.join("\n"), options.cacheControl?.(part.cache)));
|
|
386
380
|
const files = content.filter((item) => item.type === "file");
|
|
387
381
|
attachments.push(...(yield* Effect.forEach(files, (item) => lowerMedia(ProviderShared.toolFileMedia(item)))));
|
|
388
382
|
}
|
|
389
383
|
return { messages, attachments };
|
|
390
384
|
});
|
|
385
|
+
// Chat cache breakpoints belong on text content parts, not on the message itself.
|
|
386
|
+
const toolMessage = (toolCallID, text, cacheControl) => ({
|
|
387
|
+
role: "tool",
|
|
388
|
+
tool_call_id: toolCallID,
|
|
389
|
+
content: cacheControl === undefined ? text : [{ type: "text", text, cache_control: cacheControl }],
|
|
390
|
+
});
|
|
391
391
|
const lowerMessage = Effect.fn("OpenAIChat.lowerMessage")(function* (message, reasoningField, requireReasoning, options) {
|
|
392
392
|
if (message.role === "user")
|
|
393
393
|
return [yield* lowerUserMessage(message, options)];
|
|
@@ -452,24 +452,25 @@ const lowerMessages = Effect.fn("OpenAIChat.lowerMessages")(function* (request,
|
|
|
452
452
|
bridgeTools();
|
|
453
453
|
if (message.role === "system") {
|
|
454
454
|
const part = yield* ProviderShared.wrappedSystemUpdate("OpenAI Chat", message);
|
|
455
|
+
const cacheControl = options.cacheControl?.(part.cache);
|
|
455
456
|
if (pendingAttachments.length > 0) {
|
|
456
457
|
messages.push({
|
|
457
458
|
role: "user",
|
|
458
459
|
content: [
|
|
459
460
|
...pendingAttachments.splice(0),
|
|
460
|
-
{ type: "text", text: part.text, cache_control:
|
|
461
|
+
{ type: "text", text: part.text, cache_control: cacheControl },
|
|
461
462
|
],
|
|
462
463
|
});
|
|
463
464
|
continue;
|
|
464
465
|
}
|
|
465
466
|
const previous = messages.at(-1);
|
|
466
467
|
if (previous?.role === "user" && typeof previous.content === "string")
|
|
467
|
-
messages[messages.length - 1] =
|
|
468
|
+
messages[messages.length - 1] = cacheControl
|
|
468
469
|
? {
|
|
469
470
|
role: "user",
|
|
470
471
|
content: [
|
|
471
472
|
{ type: "text", text: previous.content },
|
|
472
|
-
{ type: "text", text: part.text, cache_control:
|
|
473
|
+
{ type: "text", text: part.text, cache_control: cacheControl },
|
|
473
474
|
],
|
|
474
475
|
}
|
|
475
476
|
: { role: "user", content: `${previous.content}\n${part.text}` };
|
|
@@ -478,14 +479,14 @@ const lowerMessages = Effect.fn("OpenAIChat.lowerMessages")(function* (request,
|
|
|
478
479
|
role: "user",
|
|
479
480
|
content: [
|
|
480
481
|
...previous.content,
|
|
481
|
-
{ type: "text", text: part.text, cache_control:
|
|
482
|
+
{ type: "text", text: part.text, cache_control: cacheControl },
|
|
482
483
|
],
|
|
483
484
|
};
|
|
484
485
|
else
|
|
485
|
-
messages.push(
|
|
486
|
+
messages.push(cacheControl
|
|
486
487
|
? {
|
|
487
488
|
role: "user",
|
|
488
|
-
content: [{ type: "text", text: part.text, cache_control:
|
|
489
|
+
content: [{ type: "text", text: part.text, cache_control: cacheControl }],
|
|
489
490
|
}
|
|
490
491
|
: { role: "user", content: part.text });
|
|
491
492
|
continue;
|
|
@@ -720,17 +721,19 @@ const mapFinishReason = Effect.fn("OpenAIChat.mapFinishReason")(function* (event
|
|
|
720
721
|
// satisfied on both sides.
|
|
721
722
|
// Providers differ on cache-hit location: OpenAI uses
|
|
722
723
|
// `prompt_tokens_details.cached_tokens`, DeepSeek uses
|
|
723
|
-
// `prompt_cache_hit_tokens`,
|
|
724
|
+
// `prompt_cache_hit_tokens`, Zai uses top-level `cached_tokens`, and
|
|
725
|
+
// DigitalOcean uses top-level `cache_read_input_tokens` / `cache_created_input_tokens`.
|
|
724
726
|
const mapUsage = (usage, providerMetadataKey) => {
|
|
725
727
|
if (!usage)
|
|
726
728
|
return undefined;
|
|
727
729
|
const input = usage.prompt_tokens ?? undefined;
|
|
728
730
|
const output = usage.completion_tokens ?? undefined;
|
|
729
|
-
const cached =
|
|
731
|
+
const cached = usage.prompt_tokens_details?.cached_tokens ??
|
|
730
732
|
usage.prompt_cache_hit_tokens ??
|
|
731
733
|
usage.cached_tokens ??
|
|
732
|
-
|
|
733
|
-
|
|
734
|
+
usage.cache_read_input_tokens ??
|
|
735
|
+
undefined;
|
|
736
|
+
const cacheWrite = usage.prompt_tokens_details?.cache_write_tokens ?? usage.cache_created_input_tokens ?? undefined;
|
|
734
737
|
const reasoning = usage.completion_tokens_details?.reasoning_tokens ?? undefined;
|
|
735
738
|
const nonCached = ProviderShared.subtractTokens(input, ProviderShared.sumTokens(cached, cacheWrite));
|
|
736
739
|
return new Usage({
|
|
@@ -53,15 +53,18 @@ export declare const route: Route<{
|
|
|
53
53
|
})[];
|
|
54
54
|
} | {
|
|
55
55
|
readonly [x: string]: unknown;
|
|
56
|
-
readonly content: string |
|
|
56
|
+
readonly content: string | readonly {
|
|
57
|
+
readonly type: "text";
|
|
58
|
+
readonly text: string;
|
|
59
|
+
readonly cache_control?: {
|
|
60
|
+
readonly type: "ephemeral";
|
|
61
|
+
readonly ttl?: string | undefined;
|
|
62
|
+
} | undefined;
|
|
63
|
+
}[] | null;
|
|
57
64
|
readonly role: "assistant";
|
|
58
65
|
readonly reasoning?: string | undefined;
|
|
59
66
|
readonly reasoning_content?: string | undefined;
|
|
60
67
|
readonly reasoning_text?: string | undefined;
|
|
61
|
-
readonly cache_control?: {
|
|
62
|
-
readonly type: "ephemeral";
|
|
63
|
-
readonly ttl?: string | undefined;
|
|
64
|
-
} | undefined;
|
|
65
68
|
readonly tool_calls?: readonly {
|
|
66
69
|
readonly function: {
|
|
67
70
|
readonly name: string;
|
|
@@ -77,13 +80,16 @@ export declare const route: Route<{
|
|
|
77
80
|
}[] | undefined;
|
|
78
81
|
readonly reasoning_details?: unknown;
|
|
79
82
|
} | {
|
|
80
|
-
readonly content: string;
|
|
81
83
|
readonly role: "tool";
|
|
82
84
|
readonly tool_call_id: string;
|
|
83
|
-
readonly
|
|
84
|
-
readonly type: "
|
|
85
|
-
readonly
|
|
86
|
-
|
|
85
|
+
readonly content: string | readonly {
|
|
86
|
+
readonly type: "text";
|
|
87
|
+
readonly text: string;
|
|
88
|
+
readonly cache_control?: {
|
|
89
|
+
readonly type: "ephemeral";
|
|
90
|
+
readonly ttl?: string | undefined;
|
|
91
|
+
} | undefined;
|
|
92
|
+
}[];
|
|
87
93
|
})[];
|
|
88
94
|
readonly stream: true;
|
|
89
95
|
readonly max_completion_tokens?: number | undefined;
|
|
@@ -111,8 +111,8 @@ const adapter = {
|
|
|
111
111
|
name: NAME,
|
|
112
112
|
restoreHostedToolItem: (item) => (Schema.is(OpenAIResponsesHostedToolItem)(item) ? item : undefined),
|
|
113
113
|
};
|
|
114
|
-
// GPT-6
|
|
115
|
-
//
|
|
114
|
+
// GPT-6 and later default to `configuration_update` support, except in `reasoning.mode: "pro"`
|
|
115
|
+
// or alongside automatic `context_management` compaction.
|
|
116
116
|
const supportsEffortUpdates = (request) => {
|
|
117
117
|
if (request.providerOptions?.contextManagement !== undefined)
|
|
118
118
|
return false;
|
|
@@ -121,7 +121,8 @@ const supportsEffortUpdates = (request) => {
|
|
|
121
121
|
const override = request.model.compatibility?.supportsEffortUpdates;
|
|
122
122
|
if (override !== undefined)
|
|
123
123
|
return override;
|
|
124
|
-
|
|
124
|
+
const match = /(?:^|\/)gpt-(\d+)(?:\.\d+)?(?:-|$)/i.exec(request.model.id);
|
|
125
|
+
return match !== null && Number(match[1]) >= 6;
|
|
125
126
|
};
|
|
126
127
|
const nativeImageToolInput = (tool) => {
|
|
127
128
|
const native = tool.native?.openai;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import type { CacheHint } from "../../schema/index.js";
|
|
1
2
|
export interface Breakpoints {
|
|
2
3
|
remaining: number;
|
|
3
4
|
dropped: number;
|
|
4
5
|
}
|
|
5
6
|
export declare const newBreakpoints: (cap: number) => Breakpoints;
|
|
6
7
|
export declare const ttlBucket: (ttlSeconds: number | undefined) => "1h" | undefined;
|
|
8
|
+
export declare const cacheControl: () => (cache: CacheHint | undefined) => {
|
|
9
|
+
type: "ephemeral";
|
|
10
|
+
ttl: "1h" | undefined;
|
|
11
|
+
} | undefined;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
// Shared counter and TTL mapping for provider cache-marker lowering.
|
|
2
1
|
export const newBreakpoints = (cap) => ({ remaining: cap, dropped: 0 });
|
|
3
2
|
// Requests of at least one hour use the explicit `"1h"` bucket; shorter
|
|
4
3
|
// requests omit the wire TTL and use the provider default.
|
|
5
4
|
export const ttlBucket = (ttlSeconds) => ttlSeconds !== undefined && ttlSeconds >= 3600 ? "1h" : undefined;
|
|
5
|
+
export const cacheControl = () => {
|
|
6
|
+
const breakpoints = newBreakpoints(4);
|
|
7
|
+
return (cache) => {
|
|
8
|
+
if (cache === undefined || breakpoints.remaining === 0)
|
|
9
|
+
return undefined;
|
|
10
|
+
breakpoints.remaining -= 1;
|
|
11
|
+
return { type: "ephemeral", ttl: ttlBucket(cache.ttlSeconds) };
|
|
12
|
+
};
|
|
13
|
+
};
|