@opencode/ai 2.0.21 → 2.0.23
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 +61 -1
- package/dist/cache-policy.js +10 -2
- package/dist/llm.d.ts +4 -0
- package/dist/promise.d.ts +8 -0
- package/dist/protocols/alibaba-chat.d.ts +7 -3
- package/dist/protocols/alibaba-chat.js +2 -1
- package/dist/protocols/alibaba-responses.d.ts +16 -12
- package/dist/protocols/alibaba-responses.js +3 -5
- package/dist/protocols/anthropic-messages.js +58 -51
- package/dist/protocols/bedrock-converse.js +33 -4
- package/dist/protocols/cartesia-speech.js +3 -3
- package/dist/protocols/cohere-chat.d.ts +178 -0
- package/dist/protocols/cohere-chat.js +299 -0
- package/dist/protocols/elevenlabs-speech.js +3 -3
- package/dist/protocols/gemini.d.ts +2 -2
- package/dist/protocols/gemini.js +3 -3
- package/dist/protocols/google-interactions.d.ts +236 -0
- package/dist/protocols/google-interactions.js +478 -0
- package/dist/protocols/google-speech.js +1 -1
- package/dist/protocols/google-transcription.js +1 -1
- package/dist/protocols/index.d.ts +2 -0
- package/dist/protocols/index.js +2 -0
- package/dist/protocols/meta-responses.d.ts +31 -58
- package/dist/protocols/meta-responses.js +8 -27
- package/dist/protocols/mistral-chat.d.ts +24 -9
- package/dist/protocols/mistral-chat.js +22 -10
- package/dist/protocols/open-responses.d.ts +410 -91
- package/dist/protocols/open-responses.js +25 -15
- package/dist/protocols/openai-chat.d.ts +409 -5
- package/dist/protocols/openai-chat.js +27 -26
- package/dist/protocols/openai-compatible-chat.d.ts +1 -1
- package/dist/protocols/openai-compatible-responses.d.ts +16 -4
- package/dist/protocols/openai-images.js +2 -2
- package/dist/protocols/openai-responses.d.ts +87 -223
- package/dist/protocols/openai-responses.js +10 -16
- package/dist/protocols/openai-speech.js +1 -1
- package/dist/protocols/openai-transcription.js +1 -1
- package/dist/protocols/shared.js +2 -2
- package/dist/protocols/stability-images.js +1 -1
- package/dist/protocols/utils/bedrock-media.js +2 -2
- package/dist/protocols/utils/cache.d.ts +5 -0
- package/dist/protocols/utils/cache.js +9 -1
- package/dist/protocols/utils/responses-checkpoint.js +2 -2
- package/dist/protocols/utils/responses-hosted-tools.js +1 -1
- package/dist/protocols/utils/tool-stream.d.ts +12 -0
- package/dist/protocols/utils/tool-stream.js +15 -7
- package/dist/protocols/venice-chat.d.ts +280 -0
- package/dist/protocols/venice-chat.js +283 -0
- package/dist/protocols/xai-responses.d.ts +18 -21
- package/dist/protocols/xai-responses.js +2 -8
- package/dist/protocols/zai-chat.d.ts +7 -3
- package/dist/protocols/zai-chat.js +6 -3
- package/dist/provider-error.js +27 -7
- package/dist/providers/alibaba.d.ts +17 -13
- package/dist/providers/amazon-bedrock/mantle/messages.d.ts +2 -0
- package/dist/providers/amazon-bedrock/mantle/messages.js +1 -0
- package/dist/providers/amazon-bedrock-mantle.d.ts +301 -9
- package/dist/providers/amazon-bedrock-mantle.js +28 -3
- package/dist/providers/azure.d.ts +13 -61
- package/dist/providers/baseten.d.ts +2 -2
- package/dist/providers/cerebras.d.ts +2 -2
- package/dist/providers/cloudflare-ai-gateway.d.ts +14 -62
- package/dist/providers/cloudflare-workers-ai.d.ts +2 -2
- package/dist/providers/cohere/chat.d.ts +4 -0
- package/dist/providers/cohere/chat.js +8 -0
- package/dist/providers/cohere.d.ts +395 -0
- package/dist/providers/cohere.js +48 -0
- package/dist/providers/deepinfra.d.ts +2 -2
- package/dist/providers/deepseek.d.ts +2 -2
- package/dist/providers/digitalocean.d.ts +469 -0
- package/dist/providers/digitalocean.js +53 -0
- package/dist/providers/fireworks.d.ts +2 -2
- package/dist/providers/google/interactions.d.ts +7 -0
- package/dist/providers/google/interactions.js +8 -0
- package/dist/providers/google-vertex-chat.d.ts +1 -1
- package/dist/providers/google-vertex-messages.js +1 -1
- package/dist/providers/google-vertex-responses.d.ts +16 -4
- package/dist/providers/google-vertex.d.ts +1 -1
- package/dist/providers/google.d.ts +95 -4
- package/dist/providers/google.js +8 -1
- package/dist/providers/groq.d.ts +8 -4
- package/dist/providers/groq.js +1 -1
- package/dist/providers/index.d.ts +3 -0
- package/dist/providers/index.js +3 -0
- package/dist/providers/meta.d.ts +15 -28
- package/dist/providers/minimax.d.ts +17 -5
- package/dist/providers/mistral.d.ts +10 -4
- package/dist/providers/moonshot.d.ts +17 -5
- package/dist/providers/openai-compatible-responses.d.ts +16 -4
- package/dist/providers/openai-compatible.d.ts +1 -1
- package/dist/providers/openai-options.d.ts +1 -1
- package/dist/providers/openai.d.ts +7 -31
- package/dist/providers/openrouter.d.ts +9 -5
- package/dist/providers/openrouter.js +1 -13
- package/dist/providers/togetherai.d.ts +2 -2
- package/dist/providers/venice.d.ts +183 -0
- package/dist/providers/venice.js +38 -0
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers/zai-coding-plan.d.ts +17 -5
- package/dist/providers/zai.d.ts +1 -1
- package/dist/route/client.d.ts +4 -0
- package/dist/route/client.js +2 -5
- package/dist/route/executor.js +13 -6
- package/dist/route/framing.js +23 -23
- 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
|
@@ -26,11 +26,6 @@ const OpenAIChatCacheControl = Schema.Struct({
|
|
|
26
26
|
type: Schema.Literal("ephemeral"),
|
|
27
27
|
ttl: Schema.optional(Schema.String),
|
|
28
28
|
});
|
|
29
|
-
const OpenAIChatFunction = Schema.Struct({
|
|
30
|
-
name: Schema.String,
|
|
31
|
-
description: Schema.String,
|
|
32
|
-
parameters: JsonObject,
|
|
33
|
-
});
|
|
34
29
|
const OpenAIChatTool = Schema.Struct({
|
|
35
30
|
type: Schema.tag("function"),
|
|
36
31
|
function: Schema.Struct({
|
|
@@ -48,7 +43,7 @@ const ExtraContent = Schema.Struct({
|
|
|
48
43
|
google: Schema.Struct({ thought_signature: Schema.String }),
|
|
49
44
|
});
|
|
50
45
|
const decodeExtraContent = (value) => Option.getOrUndefined(Schema.decodeUnknownOption(ExtraContent)(value));
|
|
51
|
-
const OpenAIChatAssistantToolCall = Schema.Struct({
|
|
46
|
+
export const OpenAIChatAssistantToolCall = Schema.Struct({
|
|
52
47
|
id: Schema.String,
|
|
53
48
|
type: Schema.tag("function"),
|
|
54
49
|
function: Schema.Struct({
|
|
@@ -99,7 +94,7 @@ const OpenAIChatUserContent = Schema.Union([
|
|
|
99
94
|
file: Schema.Struct({ filename: Schema.String, file_data: Schema.String }),
|
|
100
95
|
}),
|
|
101
96
|
]);
|
|
102
|
-
const OpenAIChatMessage = Schema.Union([
|
|
97
|
+
export const OpenAIChatMessage = Schema.Union([
|
|
103
98
|
Schema.Struct({
|
|
104
99
|
role: Schema.Literal("system"),
|
|
105
100
|
content: Schema.Union([Schema.String, Schema.Array(OpenAIChatUserContent)]),
|
|
@@ -157,13 +152,15 @@ const OpenAIChatBody = Schema.Struct(bodyFields);
|
|
|
157
152
|
// The event schema is one decoded SSE `data:` payload. `Framing.sse` splits the
|
|
158
153
|
// byte stream into strings, then `Protocol.jsonEvent` decodes each string into
|
|
159
154
|
// this provider-native event shape.
|
|
160
|
-
const OpenAIChatUsage = Schema.StructWithRest(Schema.Struct({
|
|
155
|
+
export const OpenAIChatUsage = Schema.StructWithRest(Schema.Struct({
|
|
161
156
|
prompt_tokens: optionalNull(Schema.Number),
|
|
162
157
|
completion_tokens: optionalNull(Schema.Number),
|
|
163
158
|
total_tokens: optionalNull(Schema.Number),
|
|
164
|
-
//
|
|
159
|
+
// Provider-specific cache accounting fields.
|
|
165
160
|
cached_tokens: optionalNull(Schema.Number),
|
|
166
161
|
prompt_cache_hit_tokens: optionalNull(Schema.Number),
|
|
162
|
+
cache_read_input_tokens: optionalNull(Schema.Number),
|
|
163
|
+
cache_created_input_tokens: optionalNull(Schema.Number),
|
|
167
164
|
prompt_tokens_details: optionalNull(Schema.StructWithRest(Schema.Struct({
|
|
168
165
|
cached_tokens: optionalNull(Schema.Number),
|
|
169
166
|
cache_write_tokens: optionalNull(Schema.Number),
|
|
@@ -178,13 +175,13 @@ const OpenAIChatToolCallDeltaFunction = Schema.Struct({
|
|
|
178
175
|
name: optionalNull(Schema.String),
|
|
179
176
|
arguments: optionalNull(Schema.String),
|
|
180
177
|
});
|
|
181
|
-
const OpenAIChatToolCallDelta = Schema.Struct({
|
|
178
|
+
export const OpenAIChatToolCallDelta = Schema.Struct({
|
|
182
179
|
index: optionalNull(Schema.Number),
|
|
183
180
|
id: optionalNull(Schema.String),
|
|
184
181
|
function: optionalNull(OpenAIChatToolCallDeltaFunction),
|
|
185
182
|
extra_content: optionalNull(Schema.Unknown),
|
|
186
183
|
});
|
|
187
|
-
const OpenAIChatDelta = Schema.StructWithRest(Schema.Struct({
|
|
184
|
+
export const OpenAIChatDelta = Schema.StructWithRest(Schema.Struct({
|
|
188
185
|
content: optionalNull(Schema.String),
|
|
189
186
|
refusal: optionalNull(Schema.String),
|
|
190
187
|
reasoning_content: optionalNull(Schema.String),
|
|
@@ -193,7 +190,7 @@ const OpenAIChatDelta = Schema.StructWithRest(Schema.Struct({
|
|
|
193
190
|
reasoning_details: optionalNull(Schema.Unknown),
|
|
194
191
|
tool_calls: optionalNull(Schema.Array(OpenAIChatToolCallDelta)),
|
|
195
192
|
}), [Schema.Record(Schema.String, Schema.Unknown)]);
|
|
196
|
-
const OpenAIChatChoice = Schema.StructWithRest(Schema.Struct({
|
|
193
|
+
export const OpenAIChatChoice = Schema.StructWithRest(Schema.Struct({
|
|
197
194
|
delta: optionalNull(OpenAIChatDelta),
|
|
198
195
|
finish_reason: optionalNull(Schema.String),
|
|
199
196
|
native_finish_reason: optionalNull(Schema.String),
|
|
@@ -236,7 +233,7 @@ const lowerToolCall = (part, options) => ({
|
|
|
236
233
|
},
|
|
237
234
|
extra_content: decodeExtraContent(part.providerMetadata?.[options.providerMetadataKey]?.extraContent),
|
|
238
235
|
});
|
|
239
|
-
const lowerMedia = Effect.
|
|
236
|
+
const lowerMedia = Effect.fnUntraced(function* (part) {
|
|
240
237
|
// Chat Completions accepts PDFs, and no other documents, as inline `file` parts; file URLs are not supported.
|
|
241
238
|
if (part.media.mediaType.toLowerCase() === "application/pdf")
|
|
242
239
|
return {
|
|
@@ -276,7 +273,7 @@ const lowerReasoningDetail = (detail) => {
|
|
|
276
273
|
return detail;
|
|
277
274
|
};
|
|
278
275
|
const isKimiDetail = (detail) => detail.type === "summary" || detail.type === "encrypted";
|
|
279
|
-
const lowerUserMessage = Effect.
|
|
276
|
+
const lowerUserMessage = Effect.fnUntraced(function* (message, options) {
|
|
280
277
|
const content = [];
|
|
281
278
|
for (const part of message.content) {
|
|
282
279
|
if (part.type === "text") {
|
|
@@ -296,7 +293,7 @@ const lowerUserMessage = Effect.fn("OpenAIChat.lowerUserMessage")(function* (mes
|
|
|
296
293
|
};
|
|
297
294
|
return { role: "user", content };
|
|
298
295
|
});
|
|
299
|
-
const lowerAssistantMessage = Effect.
|
|
296
|
+
const lowerAssistantMessage = Effect.fnUntraced(function* (message, configuredField, requireReasoning, options) {
|
|
300
297
|
const content = [];
|
|
301
298
|
const reasoning = [];
|
|
302
299
|
const toolCalls = [];
|
|
@@ -362,7 +359,7 @@ const lowerAssistantMessage = Effect.fn("OpenAIChat.lowerAssistantMessage")(func
|
|
|
362
359
|
return result;
|
|
363
360
|
return { ...result, [field]: reasoningText };
|
|
364
361
|
});
|
|
365
|
-
const lowerToolMessages = Effect.
|
|
362
|
+
const lowerToolMessages = Effect.fnUntraced(function* (message, options) {
|
|
366
363
|
const messages = [];
|
|
367
364
|
const attachments = [];
|
|
368
365
|
for (const part of message.content) {
|
|
@@ -386,14 +383,16 @@ const toolMessage = (toolCallID, text, cacheControl) => ({
|
|
|
386
383
|
tool_call_id: toolCallID,
|
|
387
384
|
content: cacheControl === undefined ? text : [{ type: "text", text, cache_control: cacheControl }],
|
|
388
385
|
});
|
|
389
|
-
const lowerMessage = Effect.
|
|
386
|
+
const lowerMessage = Effect.fnUntraced(function* (message, reasoningField, requireReasoning, options) {
|
|
390
387
|
if (message.role === "user")
|
|
391
388
|
return [yield* lowerUserMessage(message, options)];
|
|
392
|
-
if (message.role === "assistant")
|
|
393
|
-
|
|
389
|
+
if (message.role === "assistant") {
|
|
390
|
+
const lowered = yield* lowerAssistantMessage(message, reasoningField, requireReasoning, options);
|
|
391
|
+
return [options.assistant?.(message, lowered) ?? lowered];
|
|
392
|
+
}
|
|
394
393
|
return (yield* lowerToolMessages(message, options)).messages;
|
|
395
394
|
});
|
|
396
|
-
const lowerMessages = Effect.
|
|
395
|
+
const lowerMessages = Effect.fnUntraced(function* (request, options) {
|
|
397
396
|
const system = request.system.length === 0
|
|
398
397
|
? []
|
|
399
398
|
: request.system.some((part) => part.cache !== undefined) && options.cacheControl !== undefined
|
|
@@ -677,7 +676,7 @@ export const fromRequest = Effect.fn("OpenAIChat.fromRequest")(function* (reques
|
|
|
677
676
|
// Streaming parsers are small state machines: every event returns a new state
|
|
678
677
|
// plus the common `LLMEvent`s produced by that event. Tool calls are accumulated
|
|
679
678
|
// because OpenAI streams JSON arguments across multiple deltas.
|
|
680
|
-
const mapFinishReason = Effect.
|
|
679
|
+
const mapFinishReason = Effect.fnUntraced(function* (event, reason) {
|
|
681
680
|
switch (reason) {
|
|
682
681
|
case "error":
|
|
683
682
|
return yield* new AIError({
|
|
@@ -719,17 +718,19 @@ const mapFinishReason = Effect.fn("OpenAIChat.mapFinishReason")(function* (event
|
|
|
719
718
|
// satisfied on both sides.
|
|
720
719
|
// Providers differ on cache-hit location: OpenAI uses
|
|
721
720
|
// `prompt_tokens_details.cached_tokens`, DeepSeek uses
|
|
722
|
-
// `prompt_cache_hit_tokens`,
|
|
721
|
+
// `prompt_cache_hit_tokens`, Zai uses top-level `cached_tokens`, and
|
|
722
|
+
// DigitalOcean uses top-level `cache_read_input_tokens` / `cache_created_input_tokens`.
|
|
723
723
|
const mapUsage = (usage, providerMetadataKey) => {
|
|
724
724
|
if (!usage)
|
|
725
725
|
return undefined;
|
|
726
726
|
const input = usage.prompt_tokens ?? undefined;
|
|
727
727
|
const output = usage.completion_tokens ?? undefined;
|
|
728
|
-
const cached =
|
|
728
|
+
const cached = usage.prompt_tokens_details?.cached_tokens ??
|
|
729
729
|
usage.prompt_cache_hit_tokens ??
|
|
730
730
|
usage.cached_tokens ??
|
|
731
|
-
|
|
732
|
-
|
|
731
|
+
usage.cache_read_input_tokens ??
|
|
732
|
+
undefined;
|
|
733
|
+
const cacheWrite = usage.prompt_tokens_details?.cache_write_tokens ?? usage.cache_created_input_tokens ?? undefined;
|
|
733
734
|
const reasoning = usage.completion_tokens_details?.reasoning_tokens ?? undefined;
|
|
734
735
|
const nonCached = ProviderShared.subtractTokens(input, ProviderShared.sumTokens(cached, cacheWrite));
|
|
735
736
|
return new Usage({
|
|
@@ -982,7 +983,7 @@ const step = (state, event) => Effect.gen(function* () {
|
|
|
982
983
|
events,
|
|
983
984
|
];
|
|
984
985
|
});
|
|
985
|
-
const finishEvents = Effect.
|
|
986
|
+
export const finishEvents = Effect.fnUntraced(function* (state) {
|
|
986
987
|
if (state.finishReason === undefined && state.requireFinishReason)
|
|
987
988
|
return yield* new AIError({
|
|
988
989
|
reason: new InvalidProviderOutputError({
|
|
@@ -121,9 +121,9 @@ export declare const route: Route<{
|
|
|
121
121
|
readonly top_p?: number | undefined;
|
|
122
122
|
readonly frequency_penalty?: number | undefined;
|
|
123
123
|
readonly presence_penalty?: number | undefined;
|
|
124
|
+
readonly store?: boolean | undefined;
|
|
124
125
|
readonly prompt_cache_key?: string | undefined;
|
|
125
126
|
readonly reasoning_effort?: import("../index.js").ReasoningEffort | undefined;
|
|
126
|
-
readonly store?: boolean | undefined;
|
|
127
127
|
readonly stream_options?: {
|
|
128
128
|
readonly include_usage: boolean;
|
|
129
129
|
} | undefined;
|
|
@@ -43,6 +43,15 @@ export declare const route: Route<{
|
|
|
43
43
|
readonly error?: unknown;
|
|
44
44
|
readonly arguments?: string | undefined;
|
|
45
45
|
readonly server_label?: string | undefined;
|
|
46
|
+
} | {
|
|
47
|
+
readonly type: "configuration_update";
|
|
48
|
+
readonly reasoning: {
|
|
49
|
+
readonly effort: import("../index.js").ReasoningEffort;
|
|
50
|
+
};
|
|
51
|
+
} | {
|
|
52
|
+
readonly [x: string]: unknown;
|
|
53
|
+
readonly type: string;
|
|
54
|
+
readonly id: string;
|
|
46
55
|
} | {
|
|
47
56
|
readonly type: "reasoning";
|
|
48
57
|
readonly summary: readonly {
|
|
@@ -130,7 +139,10 @@ export declare const route: Route<{
|
|
|
130
139
|
readonly summary?: "auto" | "concise" | "detailed" | undefined;
|
|
131
140
|
readonly effort?: import("../index.js").ReasoningEffort | undefined;
|
|
132
141
|
} | undefined;
|
|
133
|
-
readonly tools?: readonly {
|
|
142
|
+
readonly tools?: readonly ({
|
|
143
|
+
readonly [x: string]: unknown;
|
|
144
|
+
readonly type: string;
|
|
145
|
+
} | {
|
|
134
146
|
readonly type: "function";
|
|
135
147
|
readonly description: string;
|
|
136
148
|
readonly name: string;
|
|
@@ -138,7 +150,7 @@ export declare const route: Route<{
|
|
|
138
150
|
readonly [x: string]: unknown;
|
|
139
151
|
};
|
|
140
152
|
readonly strict?: boolean | undefined;
|
|
141
|
-
}[] | undefined;
|
|
153
|
+
})[] | undefined;
|
|
142
154
|
readonly text?: {
|
|
143
155
|
readonly verbosity?: import("./utils/open-responses-options.js").TextVerbosity | undefined;
|
|
144
156
|
} | undefined;
|
|
@@ -158,9 +170,10 @@ export declare const route: Route<{
|
|
|
158
170
|
readonly top_p?: number | undefined;
|
|
159
171
|
readonly frequency_penalty?: number | undefined;
|
|
160
172
|
readonly presence_penalty?: number | undefined;
|
|
173
|
+
readonly store?: boolean | undefined;
|
|
174
|
+
readonly max_output_tokens?: number | undefined;
|
|
161
175
|
readonly prompt_cache_key?: string | undefined;
|
|
162
176
|
readonly parallel_tool_calls?: boolean | undefined;
|
|
163
|
-
readonly store?: boolean | undefined;
|
|
164
177
|
readonly include?: readonly import("./utils/open-responses-options.js").ResponseIncludable[] | undefined;
|
|
165
178
|
readonly truncation?: "auto" | "disabled" | undefined;
|
|
166
179
|
readonly stream_options?: {
|
|
@@ -168,7 +181,6 @@ export declare const route: Route<{
|
|
|
168
181
|
} | undefined;
|
|
169
182
|
readonly safety_identifier?: string | undefined;
|
|
170
183
|
readonly top_logprobs?: number | undefined;
|
|
171
|
-
readonly max_output_tokens?: number | undefined;
|
|
172
184
|
readonly max_tool_calls?: number | undefined;
|
|
173
185
|
}, import("../route/transport/http.js").HttpPrepared<string>, import("../route/client.js").CompactionOperations | undefined>;
|
|
174
186
|
export * as OpenAICompatibleResponses from "./openai-compatible-responses.js";
|
|
@@ -126,7 +126,7 @@ const info = (format, size) => {
|
|
|
126
126
|
const eventImage = (frame, label, data, format, size) => MediaInput.decodedAsset((message, cause) => route.frameError(message, frame, cause), label, data, `image/${format}`, {
|
|
127
127
|
info: info(format, size),
|
|
128
128
|
});
|
|
129
|
-
const onEvent = Effect.
|
|
129
|
+
const onEvent = Effect.fnUntraced(function* (state, frame) {
|
|
130
130
|
const event = yield* decodeEvent(frame);
|
|
131
131
|
const format = event.output_format;
|
|
132
132
|
if ("partial_image_index" in event) {
|
|
@@ -146,7 +146,7 @@ const onEvent = Effect.fn("OpenAIImages.onEvent")(function* (state, frame) {
|
|
|
146
146
|
[ImageOutputEvent.make({ index: state.completed, image })],
|
|
147
147
|
];
|
|
148
148
|
});
|
|
149
|
-
const onDocument = Effect.
|
|
149
|
+
const onDocument = Effect.fnUntraced(function* (frame) {
|
|
150
150
|
const invalid = (message, cause) => route.frameError(message, frame.document, cause);
|
|
151
151
|
const decoded = yield* decodeDocument(frame.document).pipe(Effect.mapError((cause) => invalid(`${route.name} returned an invalid response`, cause)));
|
|
152
152
|
const format = decoded.output_format ?? frame.requested ?? "png";
|