@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
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { Protocol } from "../route/protocol.js";
|
|
3
|
+
import { AIError, LLMEvent } from "../schema/index.js";
|
|
4
|
+
import { classifyProviderFailure } from "../provider-error.js";
|
|
5
|
+
import { OpenAIChat } from "./openai-chat.js";
|
|
6
|
+
import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared.js";
|
|
7
|
+
import { cacheControl } from "./utils/cache.js";
|
|
8
|
+
const Parameters = Schema.Struct({
|
|
9
|
+
enableWebSearch: Schema.optional(Schema.String),
|
|
10
|
+
enableWebScraping: Schema.optional(Schema.Boolean),
|
|
11
|
+
enableWebCitations: Schema.optional(Schema.Boolean),
|
|
12
|
+
enableXSearch: Schema.optional(Schema.Boolean),
|
|
13
|
+
stripThinkingResponse: Schema.optional(Schema.Boolean),
|
|
14
|
+
disableThinking: Schema.optional(Schema.Boolean),
|
|
15
|
+
includeVeniceSystemPrompt: Schema.optional(Schema.Boolean),
|
|
16
|
+
characterSlug: Schema.optional(Schema.String),
|
|
17
|
+
includeSearchResultsInStream: Schema.optional(Schema.Boolean),
|
|
18
|
+
returnSearchResultsAsDocuments: Schema.optional(Schema.Boolean),
|
|
19
|
+
});
|
|
20
|
+
const Reasoning = Schema.Struct({
|
|
21
|
+
effort: Schema.optional(Schema.String),
|
|
22
|
+
enabled: Schema.optional(Schema.Boolean),
|
|
23
|
+
summary: Schema.optional(Schema.String),
|
|
24
|
+
});
|
|
25
|
+
const Options = Schema.Struct({
|
|
26
|
+
reasoningEffort: Schema.optional(Schema.String),
|
|
27
|
+
reasoning: Schema.optional(Reasoning),
|
|
28
|
+
veniceParameters: Schema.optional(Parameters),
|
|
29
|
+
promptCacheKey: Schema.optional(Schema.String),
|
|
30
|
+
promptCacheRetention: Schema.optional(Schema.String),
|
|
31
|
+
parallelToolCalls: Schema.optional(Schema.Boolean),
|
|
32
|
+
maxCompletionTokens: Schema.optional(Schema.Number),
|
|
33
|
+
maxTokens: Schema.optional(Schema.Number),
|
|
34
|
+
minP: Schema.optional(Schema.Number),
|
|
35
|
+
repetitionPenalty: Schema.optional(Schema.Number),
|
|
36
|
+
stopTokenIds: Schema.optional(Schema.Array(Schema.Number)),
|
|
37
|
+
logprobs: Schema.optional(Schema.Boolean),
|
|
38
|
+
topLogprobs: Schema.optional(Schema.Number),
|
|
39
|
+
maxTemp: Schema.optional(Schema.Number),
|
|
40
|
+
minTemp: Schema.optional(Schema.Number),
|
|
41
|
+
responseFormat: Schema.optional(JsonObject),
|
|
42
|
+
user: Schema.optional(Schema.String),
|
|
43
|
+
});
|
|
44
|
+
const ToolCall = Schema.Struct({
|
|
45
|
+
...OpenAIChat.OpenAIChatAssistantToolCall.fields,
|
|
46
|
+
thought_signature: Schema.optional(Schema.String),
|
|
47
|
+
});
|
|
48
|
+
const Assistant = Schema.StructWithRest(Schema.Struct({
|
|
49
|
+
...OpenAIChat.OpenAIChatMessage.cases.assistant.schema.fields,
|
|
50
|
+
tool_calls: optionalArray(ToolCall),
|
|
51
|
+
thought_signature: Schema.optional(Schema.String),
|
|
52
|
+
}), [Schema.Record(Schema.String, Schema.Unknown)]);
|
|
53
|
+
const Messages = Schema.Array(Schema.Union([
|
|
54
|
+
OpenAIChat.OpenAIChatMessage.cases.system,
|
|
55
|
+
OpenAIChat.OpenAIChatMessage.cases.user,
|
|
56
|
+
Assistant,
|
|
57
|
+
OpenAIChat.OpenAIChatMessage.cases.tool,
|
|
58
|
+
]));
|
|
59
|
+
const Body = Schema.Struct({
|
|
60
|
+
...OpenAIChat.bodyFields,
|
|
61
|
+
messages: Messages,
|
|
62
|
+
reasoning: Schema.optional(Reasoning),
|
|
63
|
+
venice_parameters: Schema.Record(Schema.String, Schema.Union([Schema.String, Schema.Boolean])),
|
|
64
|
+
prompt_cache_retention: Options.fields.promptCacheRetention,
|
|
65
|
+
parallel_tool_calls: Options.fields.parallelToolCalls,
|
|
66
|
+
min_p: Options.fields.minP,
|
|
67
|
+
top_k: Schema.optional(Schema.Number),
|
|
68
|
+
repetition_penalty: Options.fields.repetitionPenalty,
|
|
69
|
+
stop_token_ids: Options.fields.stopTokenIds,
|
|
70
|
+
logprobs: Options.fields.logprobs,
|
|
71
|
+
top_logprobs: Options.fields.topLogprobs,
|
|
72
|
+
max_temp: Options.fields.maxTemp,
|
|
73
|
+
min_temp: Options.fields.minTemp,
|
|
74
|
+
response_format: Options.fields.responseFormat,
|
|
75
|
+
user: Options.fields.user,
|
|
76
|
+
});
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Streaming schemas and state
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
const ToolDelta = Schema.Struct({
|
|
81
|
+
...OpenAIChat.OpenAIChatToolCallDelta.fields,
|
|
82
|
+
thought_signature: optionalNull(Schema.String),
|
|
83
|
+
});
|
|
84
|
+
const Delta = Schema.StructWithRest(Schema.Struct({
|
|
85
|
+
...OpenAIChat.OpenAIChatDelta.schema.fields,
|
|
86
|
+
tool_calls: optionalNull(Schema.Array(ToolDelta)),
|
|
87
|
+
thought_signature: optionalNull(Schema.String),
|
|
88
|
+
}), [Schema.Record(Schema.String, Schema.Unknown)]);
|
|
89
|
+
const Choice = Schema.StructWithRest(Schema.Struct({ ...OpenAIChat.OpenAIChatChoice.schema.fields, delta: optionalNull(Delta) }), [Schema.Record(Schema.String, Schema.Unknown)]);
|
|
90
|
+
const Usage = Schema.StructWithRest(Schema.Struct({
|
|
91
|
+
...OpenAIChat.OpenAIChatUsage.schema.fields,
|
|
92
|
+
prompt_tokens_details: optionalNull(Schema.StructWithRest(Schema.Struct({
|
|
93
|
+
cached_tokens: optionalNull(Schema.Number),
|
|
94
|
+
cache_write_tokens: optionalNull(Schema.Number),
|
|
95
|
+
cache_creation_input_tokens: optionalNull(Schema.Number),
|
|
96
|
+
}), [Schema.Record(Schema.String, Schema.Unknown)])),
|
|
97
|
+
}), [Schema.Record(Schema.String, Schema.Unknown)]);
|
|
98
|
+
const Event = Schema.StructWithRest(Schema.Struct({
|
|
99
|
+
...OpenAIChat.OpenAIChatEvent.schema.fields,
|
|
100
|
+
choices: optionalNull(Schema.Array(Choice)),
|
|
101
|
+
usage: optionalNull(Usage),
|
|
102
|
+
error: optionalNull(Schema.Union([Schema.String, OpenAIChat.OpenAIChatEvent.schema.fields.error.schema])),
|
|
103
|
+
issues: optionalArray(Schema.Struct({
|
|
104
|
+
message: Schema.String,
|
|
105
|
+
path: Schema.optional(Schema.Array(Schema.Union([Schema.String, Schema.Number]))),
|
|
106
|
+
})),
|
|
107
|
+
}), [Schema.Record(Schema.String, Schema.Unknown)]);
|
|
108
|
+
const MARKER = "__ENCRYPTED_REASONING__";
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
// Request lowering
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
const fromRequest = Effect.fn("VeniceChat.fromRequest")(function* (request) {
|
|
113
|
+
const options = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Options))(request.providerOptions ?? {});
|
|
114
|
+
const body = yield* OpenAIChat.fromRequest(request, {
|
|
115
|
+
cacheControl: cacheControl(),
|
|
116
|
+
assistant: (source, message) => {
|
|
117
|
+
if (message.role !== "assistant")
|
|
118
|
+
return message;
|
|
119
|
+
const parts = source.content.filter((part) => part.type === "text" || part.type === "reasoning" || part.type === "tool-call");
|
|
120
|
+
const calls = source.content.filter((part) => part.type === "tool-call");
|
|
121
|
+
const signature = parts
|
|
122
|
+
.map((part) => part.providerMetadata?.venice?.messageThoughtSignature)
|
|
123
|
+
.find((value) => typeof value === "string");
|
|
124
|
+
const raw = parts
|
|
125
|
+
.map((part) => part.providerMetadata?.venice?.encryptedReasoningContent)
|
|
126
|
+
.find((value) => typeof value === "string");
|
|
127
|
+
return {
|
|
128
|
+
...message,
|
|
129
|
+
...(signature === undefined ? {} : { thought_signature: signature }),
|
|
130
|
+
...(raw === undefined ? {} : { reasoning_content: raw }),
|
|
131
|
+
tool_calls: message.tool_calls?.map((call, index) => {
|
|
132
|
+
const signature = calls[index]?.providerMetadata?.venice?.thoughtSignature;
|
|
133
|
+
return { ...call, ...(typeof signature === "string" ? { thought_signature: signature } : {}) };
|
|
134
|
+
}),
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
return {
|
|
139
|
+
...body,
|
|
140
|
+
max_completion_tokens: options.maxCompletionTokens ?? options.maxTokens ?? request.generation?.maxTokens,
|
|
141
|
+
reasoning_effort: undefined,
|
|
142
|
+
reasoning: options.reasoningEffort === undefined
|
|
143
|
+
? options.reasoning
|
|
144
|
+
: { ...options.reasoning, effort: options.reasoningEffort },
|
|
145
|
+
// Match the previous Venice SDK default, not the gateway's added prompt.
|
|
146
|
+
venice_parameters: Object.fromEntries(Object.entries({
|
|
147
|
+
...options.veniceParameters,
|
|
148
|
+
includeVeniceSystemPrompt: options.veniceParameters?.includeVeniceSystemPrompt ?? false,
|
|
149
|
+
})
|
|
150
|
+
.filter(([, value]) => value !== undefined)
|
|
151
|
+
.map(([key, value]) => [key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`), value])),
|
|
152
|
+
prompt_cache_retention: options.promptCacheRetention,
|
|
153
|
+
parallel_tool_calls: options.parallelToolCalls,
|
|
154
|
+
min_p: options.minP,
|
|
155
|
+
top_k: request.generation?.topK,
|
|
156
|
+
repetition_penalty: options.repetitionPenalty,
|
|
157
|
+
stop_token_ids: options.stopTokenIds,
|
|
158
|
+
logprobs: options.logprobs,
|
|
159
|
+
top_logprobs: options.topLogprobs,
|
|
160
|
+
max_temp: options.maxTemp,
|
|
161
|
+
min_temp: options.minTemp,
|
|
162
|
+
response_format: options.responseFormat,
|
|
163
|
+
user: options.user,
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
// Venice normalization around the shared Chat state machine
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
const step = Effect.fn("VeniceChat.step")(function* (state, event) {
|
|
170
|
+
if (typeof event.error === "string")
|
|
171
|
+
return yield* new AIError({
|
|
172
|
+
reason: classifyProviderFailure({
|
|
173
|
+
message: [
|
|
174
|
+
event.error,
|
|
175
|
+
...(event.issues ?? []).map((issue) => `${issue.path?.length ? `${issue.path.join(".")}: ` : ""}${issue.message}`),
|
|
176
|
+
].join("; "),
|
|
177
|
+
rawBody: ProviderShared.encodeJson(event),
|
|
178
|
+
}),
|
|
179
|
+
});
|
|
180
|
+
const delta = event.choices?.[0]?.delta;
|
|
181
|
+
const scalar = delta?.reasoning_content ?? "";
|
|
182
|
+
const text = state.pending + scalar;
|
|
183
|
+
const marker = text.indexOf(MARKER);
|
|
184
|
+
const pending = marker >= 0 || state.encrypted
|
|
185
|
+
? 0
|
|
186
|
+
: (Array.from({ length: Math.min(text.length, MARKER.length - 1) }, (_, index) => index + 1)
|
|
187
|
+
.filter((length) => text.endsWith(MARKER.slice(0, length)))
|
|
188
|
+
.at(-1) ?? 0);
|
|
189
|
+
const visible = state.encrypted ? "" : marker >= 0 ? text.slice(0, marker) : text.slice(0, text.length - pending);
|
|
190
|
+
const result = yield* OpenAIChat.protocol.stream.step(state.shared, {
|
|
191
|
+
...event,
|
|
192
|
+
error: event.error,
|
|
193
|
+
usage: event.usage
|
|
194
|
+
? {
|
|
195
|
+
...event.usage,
|
|
196
|
+
prompt_tokens_details: event.usage.prompt_tokens_details
|
|
197
|
+
? {
|
|
198
|
+
...event.usage.prompt_tokens_details,
|
|
199
|
+
cache_write_tokens: event.usage.prompt_tokens_details.cache_write_tokens ??
|
|
200
|
+
event.usage.prompt_tokens_details.cache_creation_input_tokens,
|
|
201
|
+
}
|
|
202
|
+
: event.usage.prompt_tokens_details,
|
|
203
|
+
}
|
|
204
|
+
: event.usage,
|
|
205
|
+
choices: event.choices?.map((choice, index) => index === 0 && choice.delta
|
|
206
|
+
? {
|
|
207
|
+
...choice,
|
|
208
|
+
delta: {
|
|
209
|
+
...choice.delta,
|
|
210
|
+
reasoning_content: visible || undefined,
|
|
211
|
+
// Opaque-only scalar reasoning still needs a canonical part for replay.
|
|
212
|
+
reasoning_details: choice.delta.reasoning_details ?? (marker >= 0 ? [] : undefined),
|
|
213
|
+
},
|
|
214
|
+
}
|
|
215
|
+
: choice),
|
|
216
|
+
});
|
|
217
|
+
const tools = { ...state.tools };
|
|
218
|
+
for (const call of delta?.tool_calls ?? []) {
|
|
219
|
+
if (!call.thought_signature)
|
|
220
|
+
continue;
|
|
221
|
+
const index = call.index ?? result[0].latestToolIndex;
|
|
222
|
+
const id = call.id ?? (index === undefined ? undefined : (result[0].tools[index]?.id ?? result[0].pendingTools[index]?.id));
|
|
223
|
+
if (id)
|
|
224
|
+
tools[id] = call.thought_signature;
|
|
225
|
+
}
|
|
226
|
+
return [
|
|
227
|
+
{
|
|
228
|
+
shared: result[0],
|
|
229
|
+
pending: pending ? text.slice(-pending) : "",
|
|
230
|
+
reasoning: state.reasoning + scalar,
|
|
231
|
+
encrypted: state.encrypted || marker >= 0,
|
|
232
|
+
signature: delta?.thought_signature ?? state.signature,
|
|
233
|
+
tools,
|
|
234
|
+
},
|
|
235
|
+
result[1],
|
|
236
|
+
];
|
|
237
|
+
});
|
|
238
|
+
const onHalt = Effect.fn("VeniceChat.onHalt")(function* (state) {
|
|
239
|
+
const events = yield* OpenAIChat.finishEvents(state.shared);
|
|
240
|
+
return events.flatMap((event) => {
|
|
241
|
+
if (event.type !== "reasoning-end" &&
|
|
242
|
+
event.type !== "text-end" &&
|
|
243
|
+
event.type !== "tool-call" &&
|
|
244
|
+
event.type !== "tool-input-end")
|
|
245
|
+
return [event];
|
|
246
|
+
const signature = event.type === "tool-call" || event.type === "tool-input-end" ? state.tools[event.id] : undefined;
|
|
247
|
+
const providerMetadata = {
|
|
248
|
+
...event.providerMetadata,
|
|
249
|
+
venice: {
|
|
250
|
+
...event.providerMetadata?.venice,
|
|
251
|
+
...(state.signature ? { messageThoughtSignature: state.signature } : {}),
|
|
252
|
+
...(signature ? { thoughtSignature: signature } : {}),
|
|
253
|
+
...(event.type === "reasoning-end" && state.encrypted ? { encryptedReasoningContent: state.reasoning } : {}),
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
if (event.type === "reasoning-end" && state.pending)
|
|
257
|
+
return [LLMEvent.reasoningDelta({ id: event.id, text: state.pending }), { ...event, providerMetadata }];
|
|
258
|
+
return [{ ...event, providerMetadata }];
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
export const compatibility = {
|
|
262
|
+
maxTokensField: "max_completion_tokens",
|
|
263
|
+
supportsStore: false,
|
|
264
|
+
supportsPromptCacheKey: true,
|
|
265
|
+
};
|
|
266
|
+
export const protocol = Protocol.make({
|
|
267
|
+
id: "venice-chat",
|
|
268
|
+
body: { schema: Body, from: fromRequest },
|
|
269
|
+
stream: {
|
|
270
|
+
event: Schema.Union([Schema.Literal("[DONE]"), Protocol.jsonEvent(Event)]),
|
|
271
|
+
initial: (request) => ({
|
|
272
|
+
shared: OpenAIChat.protocol.stream.initial(request),
|
|
273
|
+
pending: "",
|
|
274
|
+
reasoning: "",
|
|
275
|
+
encrypted: false,
|
|
276
|
+
tools: {},
|
|
277
|
+
}),
|
|
278
|
+
step: (state, event) => (event === "[DONE]" ? Effect.succeed([state, []]) : step(state, event)),
|
|
279
|
+
terminal: (event) => event === "[DONE]",
|
|
280
|
+
onHalt,
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
export * as VeniceChat from "./venice-chat.js";
|
|
@@ -38,6 +38,15 @@ export declare const protocol: Protocol<{
|
|
|
38
38
|
readonly error?: unknown;
|
|
39
39
|
readonly arguments?: string | undefined;
|
|
40
40
|
readonly server_label?: string | undefined;
|
|
41
|
+
} | {
|
|
42
|
+
readonly type: "configuration_update";
|
|
43
|
+
readonly reasoning: {
|
|
44
|
+
readonly effort: import("../schema/options.js").ReasoningEffort;
|
|
45
|
+
};
|
|
46
|
+
} | {
|
|
47
|
+
readonly [x: string]: unknown;
|
|
48
|
+
readonly type: string;
|
|
49
|
+
readonly id: string;
|
|
41
50
|
} | {
|
|
42
51
|
readonly type: "reasoning";
|
|
43
52
|
readonly summary: readonly {
|
|
@@ -114,21 +123,6 @@ export declare const protocol: Protocol<{
|
|
|
114
123
|
readonly type: "input_video";
|
|
115
124
|
readonly video_url: string;
|
|
116
125
|
})[];
|
|
117
|
-
} | {
|
|
118
|
-
readonly [x: string]: unknown;
|
|
119
|
-
readonly id: string;
|
|
120
|
-
readonly type: "x_search_call";
|
|
121
|
-
readonly status?: string | undefined;
|
|
122
|
-
readonly action?: {
|
|
123
|
-
readonly [x: string]: unknown;
|
|
124
|
-
} | null | undefined;
|
|
125
|
-
} | {
|
|
126
|
-
readonly [x: string]: unknown;
|
|
127
|
-
readonly id: string;
|
|
128
|
-
readonly type: "image_generation_call";
|
|
129
|
-
readonly status?: string | undefined;
|
|
130
|
-
readonly error?: unknown;
|
|
131
|
-
readonly result?: unknown;
|
|
132
126
|
})[];
|
|
133
127
|
readonly model: string;
|
|
134
128
|
readonly stream: true;
|
|
@@ -140,7 +134,10 @@ export declare const protocol: Protocol<{
|
|
|
140
134
|
readonly summary?: "auto" | "concise" | "detailed" | undefined;
|
|
141
135
|
readonly effort?: import("../schema/options.js").ReasoningEffort | undefined;
|
|
142
136
|
} | undefined;
|
|
143
|
-
readonly tools?: readonly {
|
|
137
|
+
readonly tools?: readonly ({
|
|
138
|
+
readonly [x: string]: unknown;
|
|
139
|
+
readonly type: string;
|
|
140
|
+
} | {
|
|
144
141
|
readonly type: "function";
|
|
145
142
|
readonly description: string;
|
|
146
143
|
readonly name: string;
|
|
@@ -148,7 +145,7 @@ export declare const protocol: Protocol<{
|
|
|
148
145
|
readonly [x: string]: unknown;
|
|
149
146
|
};
|
|
150
147
|
readonly strict?: boolean | undefined;
|
|
151
|
-
}[] | undefined;
|
|
148
|
+
})[] | undefined;
|
|
152
149
|
readonly text?: {
|
|
153
150
|
readonly verbosity?: import("./utils/open-responses-options.js").TextVerbosity | undefined;
|
|
154
151
|
} | undefined;
|
|
@@ -168,9 +165,10 @@ export declare const protocol: Protocol<{
|
|
|
168
165
|
readonly top_p?: number | undefined;
|
|
169
166
|
readonly frequency_penalty?: number | undefined;
|
|
170
167
|
readonly presence_penalty?: number | undefined;
|
|
168
|
+
readonly store?: boolean | undefined;
|
|
169
|
+
readonly max_output_tokens?: number | undefined;
|
|
171
170
|
readonly prompt_cache_key?: string | undefined;
|
|
172
171
|
readonly parallel_tool_calls?: boolean | undefined;
|
|
173
|
-
readonly store?: boolean | undefined;
|
|
174
172
|
readonly include?: readonly import("./utils/open-responses-options.js").ResponseIncludable[] | undefined;
|
|
175
173
|
readonly truncation?: "auto" | "disabled" | undefined;
|
|
176
174
|
readonly stream_options?: {
|
|
@@ -178,7 +176,6 @@ export declare const protocol: Protocol<{
|
|
|
178
176
|
} | undefined;
|
|
179
177
|
readonly safety_identifier?: string | undefined;
|
|
180
178
|
readonly top_logprobs?: number | undefined;
|
|
181
|
-
readonly max_output_tokens?: number | undefined;
|
|
182
179
|
readonly max_tool_calls?: number | undefined;
|
|
183
180
|
}, string, {
|
|
184
181
|
readonly [x: string]: unknown;
|
|
@@ -198,8 +195,8 @@ export declare const protocol: Protocol<{
|
|
|
198
195
|
readonly name?: string | undefined;
|
|
199
196
|
readonly namespace?: string | undefined;
|
|
200
197
|
readonly arguments?: string | undefined;
|
|
201
|
-
readonly encrypted_content?: string | null | undefined;
|
|
202
198
|
readonly call_id?: string | undefined;
|
|
199
|
+
readonly encrypted_content?: string | null | undefined;
|
|
203
200
|
}[] | undefined;
|
|
204
201
|
readonly error?: unknown;
|
|
205
202
|
readonly usage?: {
|
|
@@ -226,8 +223,8 @@ export declare const protocol: Protocol<{
|
|
|
226
223
|
readonly name?: string | undefined;
|
|
227
224
|
readonly namespace?: string | undefined;
|
|
228
225
|
readonly arguments?: string | undefined;
|
|
229
|
-
readonly encrypted_content?: string | null | undefined;
|
|
230
226
|
readonly call_id?: string | undefined;
|
|
227
|
+
readonly encrypted_content?: string | null | undefined;
|
|
231
228
|
} | null | undefined;
|
|
232
229
|
readonly delta?: string | undefined;
|
|
233
230
|
readonly arguments?: string | undefined;
|
|
@@ -21,17 +21,11 @@ const XAIResponsesHostedToolItem = Schema.Union([
|
|
|
21
21
|
error: Schema.optional(Schema.Unknown),
|
|
22
22
|
}), [JsonObject]),
|
|
23
23
|
]);
|
|
24
|
-
const XAIResponsesBody = Schema.Struct({
|
|
25
|
-
...OpenResponses.coreFields,
|
|
26
|
-
input: Schema.Array(Schema.Union([OpenResponses.InputItem, XAIResponsesHostedToolItem])),
|
|
27
|
-
stream: Schema.Literal(true),
|
|
28
|
-
});
|
|
29
24
|
const adapter = {
|
|
30
25
|
id: ADAPTER,
|
|
31
26
|
name: NAME,
|
|
32
27
|
restoreHostedToolItem: (item) => (Schema.is(XAIResponsesHostedToolItem)(item) ? item : undefined),
|
|
33
28
|
};
|
|
34
|
-
const decodeBody = ProviderShared.validateWith(Schema.decodeUnknownEffect(XAIResponsesBody));
|
|
35
29
|
const fromRequest = Effect.fn("XAIResponses.fromRequest")(function* (request) {
|
|
36
30
|
if (request.providerOptions?.contextManagement !== undefined)
|
|
37
31
|
return yield* ProviderShared.unsupportedOperation({
|
|
@@ -40,7 +34,7 @@ const fromRequest = Effect.fn("XAIResponses.fromRequest")(function* (request) {
|
|
|
40
34
|
route: request.model.route.id,
|
|
41
35
|
message: "xAI requires explicit compaction through LLMClient.compact; automatic context management is not supported",
|
|
42
36
|
});
|
|
43
|
-
return yield*
|
|
37
|
+
return yield* OpenResponses.fromRequestWithAdapter(request, adapter);
|
|
44
38
|
});
|
|
45
39
|
const HOSTED_TOOLS = {
|
|
46
40
|
web_search_call: { name: "web_search", input: (item) => item.action ?? {} },
|
|
@@ -67,7 +61,7 @@ const step = (state, input) => {
|
|
|
67
61
|
export const protocol = Protocol.make({
|
|
68
62
|
id: ADAPTER,
|
|
69
63
|
body: {
|
|
70
|
-
schema:
|
|
64
|
+
schema: OpenResponses.OpenResponsesBody,
|
|
71
65
|
from: fromRequest,
|
|
72
66
|
},
|
|
73
67
|
stream: {
|
|
@@ -142,9 +142,9 @@ export declare const protocol: Protocol<{
|
|
|
142
142
|
readonly top_p?: number | undefined;
|
|
143
143
|
readonly frequency_penalty?: number | undefined;
|
|
144
144
|
readonly presence_penalty?: number | undefined;
|
|
145
|
+
readonly store?: boolean | undefined;
|
|
145
146
|
readonly prompt_cache_key?: string | undefined;
|
|
146
147
|
readonly reasoning_effort?: import("../schema/options.js").ReasoningEffort | undefined;
|
|
147
|
-
readonly store?: boolean | undefined;
|
|
148
148
|
readonly stream_options?: {
|
|
149
149
|
readonly include_usage: boolean;
|
|
150
150
|
} | undefined;
|
|
@@ -163,16 +163,18 @@ export declare const protocol: Protocol<{
|
|
|
163
163
|
} | null | undefined;
|
|
164
164
|
readonly usage?: {
|
|
165
165
|
readonly [x: string]: unknown;
|
|
166
|
+
readonly cache_read_input_tokens?: number | null | undefined;
|
|
166
167
|
readonly cached_tokens?: number | null | undefined;
|
|
168
|
+
readonly total_tokens?: number | null | undefined;
|
|
167
169
|
readonly prompt_tokens?: number | null | undefined;
|
|
168
170
|
readonly completion_tokens?: number | null | undefined;
|
|
169
|
-
readonly total_tokens?: number | null | undefined;
|
|
170
171
|
readonly prompt_tokens_details?: {
|
|
171
172
|
readonly [x: string]: unknown;
|
|
172
173
|
readonly cached_tokens?: number | null | undefined;
|
|
173
174
|
readonly cache_write_tokens?: number | null | undefined;
|
|
174
175
|
} | null | undefined;
|
|
175
176
|
readonly prompt_cache_hit_tokens?: number | null | undefined;
|
|
177
|
+
readonly cache_created_input_tokens?: number | null | undefined;
|
|
176
178
|
readonly completion_tokens_details?: {
|
|
177
179
|
readonly [x: string]: unknown;
|
|
178
180
|
readonly reasoning_tokens?: number | null | undefined;
|
|
@@ -202,16 +204,18 @@ export declare const protocol: Protocol<{
|
|
|
202
204
|
} | null | undefined;
|
|
203
205
|
readonly usage?: {
|
|
204
206
|
readonly [x: string]: unknown;
|
|
207
|
+
readonly cache_read_input_tokens?: number | null | undefined;
|
|
205
208
|
readonly cached_tokens?: number | null | undefined;
|
|
209
|
+
readonly total_tokens?: number | null | undefined;
|
|
206
210
|
readonly prompt_tokens?: number | null | undefined;
|
|
207
211
|
readonly completion_tokens?: number | null | undefined;
|
|
208
|
-
readonly total_tokens?: number | null | undefined;
|
|
209
212
|
readonly prompt_tokens_details?: {
|
|
210
213
|
readonly [x: string]: unknown;
|
|
211
214
|
readonly cached_tokens?: number | null | undefined;
|
|
212
215
|
readonly cache_write_tokens?: number | null | undefined;
|
|
213
216
|
} | null | undefined;
|
|
214
217
|
readonly prompt_cache_hit_tokens?: number | null | undefined;
|
|
218
|
+
readonly cache_created_input_tokens?: number | null | undefined;
|
|
215
219
|
readonly completion_tokens_details?: {
|
|
216
220
|
readonly [x: string]: unknown;
|
|
217
221
|
readonly reasoning_tokens?: number | null | undefined;
|
|
@@ -19,15 +19,18 @@ const Body = Schema.Struct({
|
|
|
19
19
|
request_id: Options.fields.requestID,
|
|
20
20
|
user_id: Options.fields.userID,
|
|
21
21
|
});
|
|
22
|
+
// Tool streaming was introduced in GLM-4.6; later versions inherit support.
|
|
23
|
+
const supportsToolStreaming = (modelID) => {
|
|
24
|
+
const match = /(?:^|\/)glm-(\d+)(?:\.(\d+))?(?:-|$)/i.exec(modelID);
|
|
25
|
+
return match !== null && (Number(match[1]) > 4 || (Number(match[1]) === 4 && Number(match[2] ?? 0) >= 6));
|
|
26
|
+
};
|
|
22
27
|
const fromRequest = Effect.fn("ZAIChat.fromRequest")(function* (request) {
|
|
23
28
|
const options = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Options))(request.providerOptions ?? {});
|
|
24
29
|
const body = yield* OpenAIChat.protocol.body.from(request);
|
|
25
30
|
return {
|
|
26
31
|
...body,
|
|
27
32
|
thinking: options.thinking,
|
|
28
|
-
|
|
29
|
-
tool_stream: options.toolStream ??
|
|
30
|
-
(body.tools?.length && /^glm-(?:4\.[67]|5(?:[.-]|$))/i.test(request.model.id) ? true : undefined),
|
|
33
|
+
tool_stream: options.toolStream ?? (body.tools?.length && supportsToolStreaming(request.model.id) ? true : undefined),
|
|
31
34
|
do_sample: options.doSample,
|
|
32
35
|
response_format: options.responseFormat,
|
|
33
36
|
request_id: options.requestID,
|
package/dist/provider-error.js
CHANGED
|
@@ -13,18 +13,24 @@ const patterns = [
|
|
|
13
13
|
/tokens in request more than max tokens allowed/i,
|
|
14
14
|
/maximum prompt length is \d+/i,
|
|
15
15
|
/reduce the length of the messages/i,
|
|
16
|
+
// DeepInfra
|
|
17
|
+
/requested input length \d+ exceeds maximum input length/i,
|
|
16
18
|
/maximum context length is \d+ tokens/i,
|
|
17
19
|
/exceeds (?:the )?maximum allowed input length of [\d,]+ tokens?/i,
|
|
18
|
-
|
|
20
|
+
// Novita omits the token counts.
|
|
21
|
+
/input(?: \(\d+ tokens\))? is longer than the model'?s context length/i,
|
|
19
22
|
/exceeds the limit of \d+/i,
|
|
20
23
|
/exceeds the available context size/i,
|
|
21
24
|
/greater than the context length/i,
|
|
25
|
+
// Hugging Face Text Generation Inference, e.g. Together
|
|
26
|
+
/`inputs` tokens \+ `max_new_tokens` must be <= \d+/i,
|
|
22
27
|
/context window exceeds limit/i,
|
|
23
28
|
/exceeded model token limit/i,
|
|
24
29
|
/context[_ ]length[_ ]exceeded/i,
|
|
25
30
|
/context length is only \d+ tokens/i,
|
|
26
31
|
/input length.*exceeds.*context length/i,
|
|
27
|
-
|
|
32
|
+
// Z.ai code 1261 arrives as `Prompt too long` or `Prompt 超长`.
|
|
33
|
+
/prompt (?:too long|超长)/i,
|
|
28
34
|
/too large for model with \d+ maximum context length/i,
|
|
29
35
|
/prompt has [\d,]+ tokens?, but the configured context size is [\d,]+ tokens?/i,
|
|
30
36
|
/model_context_window_exceeded/i,
|
|
@@ -34,7 +40,13 @@ const patterns = [
|
|
|
34
40
|
/request_too_large/i,
|
|
35
41
|
];
|
|
36
42
|
const payloadPatterns = [/request entity too large/i, /payload too large/i, /request too large/i];
|
|
37
|
-
const exclusions = [
|
|
43
|
+
const exclusions = [
|
|
44
|
+
/^(throttling error|service unavailable):/i,
|
|
45
|
+
/rate limit/i,
|
|
46
|
+
/too many requests/i,
|
|
47
|
+
// Cohere reports an output limit above the model maximum as "too many tokens"; compaction cannot fix it.
|
|
48
|
+
/max[_ ]tokens must be less than/i,
|
|
49
|
+
];
|
|
38
50
|
export const isContextOverflow = (message) => !exclusions.some((pattern) => pattern.test(message)) &&
|
|
39
51
|
(patterns.some((pattern) => pattern.test(message)) || /^4(?:00|13)\s*(status code)?\s*\(no body\)/i.test(message));
|
|
40
52
|
export const isPayloadTooLarge = (message) => payloadPatterns.some((pattern) => pattern.test(message));
|
|
@@ -92,7 +104,8 @@ const QUOTA_CODES = new Set([
|
|
|
92
104
|
"creditlimitexceeded",
|
|
93
105
|
]);
|
|
94
106
|
// Google reports an invalid API key as HTTP 400 INVALID_ARGUMENT with this `details[].reason`.
|
|
95
|
-
|
|
107
|
+
// Z.ai's Responses API reports account and plan rejections mid-stream as `permission_denied`.
|
|
108
|
+
const AUTH_CODES = new Set(["authentication_error", "permission_error", "permission_denied", "api_key_invalid"]);
|
|
96
109
|
const SERVER_CODES = new Set([
|
|
97
110
|
"api_error",
|
|
98
111
|
"internal_error",
|
|
@@ -106,6 +119,7 @@ const SERVER_CODES = new Set([
|
|
|
106
119
|
]);
|
|
107
120
|
// `invalid_request` is the Vercel AI Gateway's code for an upstream request rejection.
|
|
108
121
|
const INVALID_REQUEST_CODES = new Set([
|
|
122
|
+
"model_not_found",
|
|
109
123
|
"invalid_prompt",
|
|
110
124
|
"invalid_request",
|
|
111
125
|
"invalid_request_error",
|
|
@@ -125,14 +139,17 @@ const CONTENT_POLICY_CODES = new Set([
|
|
|
125
139
|
// OpenCode Zen replaces upstream codes outside its allow-list but keeps the original
|
|
126
140
|
// as a `[code]` label at the start of the rewritten message.
|
|
127
141
|
const GATEWAY_CODE_LABEL = /^[^:\n]+: \[([A-Za-z0-9_.-]+)\]/;
|
|
142
|
+
// xAI reports an invalid API key as HTTP 400 with the generic `invalid-argument` code.
|
|
143
|
+
const AUTH_TEXT = /incorrect api key provided/i;
|
|
128
144
|
const RATE_LIMIT_TEXT = /rate increased too quickly|rate[-_\s]?limit|too[_\s]?many[_\s]?requests/i;
|
|
129
145
|
// Only consulted on 429, where throttles and account caps share a status.
|
|
130
|
-
|
|
146
|
+
// Z.ai reports balance, plan expiry, plan limits, and plan model access on 429.
|
|
147
|
+
const QUOTA_TEXT = /insufficient[-_\s]?(?:quota|balance)|quota[-_\s]?exceeded|budget exceeded|usage limit|limit exhausted|package has expired|plan does not yet include/i;
|
|
131
148
|
// Policy rejections without a dedicated code, matched against the provider's own
|
|
132
149
|
// explanation only. OpenAI reuses `invalid_prompt` for usage-policy rejections while
|
|
133
150
|
// Bedrock Mantle reuses it for schema validation; Anthropic reports blocked output
|
|
134
151
|
// under `invalid_request_error`.
|
|
135
|
-
const CONTENT_POLICY_TEXT = /violating our usage policy|blocked by content filtering policy|content[-_\s]?policy|rejected as a result of our safety system/i;
|
|
152
|
+
const CONTENT_POLICY_TEXT = /violating our usage policy|blocked by content filtering policy|content[-_\s]?policy|rejected as a result of our safety system|detected potentially unsafe or sensitive content/i;
|
|
136
153
|
const SERVER_ERROR_TEXT = /\b(?:try again|(?:please |you can )?retry (?:the |this |your )?request|try (?:the |this |your )?request again|(?:currently |temporarily )?at capacity|overloaded|temporarily unavailable|service[-_\s]?unavailable|(?:server|internal)[-_\s]?error|server (?:is )?busy|provider returned (?:an )?error|resource[-_\s]?exhausted|upstream (?:connect|connection|request)|request buffer limit while retrying upstream)\b/i;
|
|
137
154
|
const Message = Schema.String.check(Schema.isPattern(/\S/));
|
|
138
155
|
const messageAt = (fields, message) => Schema.Struct(fields).pipe(Schema.decodeTo(Schema.String, {
|
|
@@ -185,7 +202,10 @@ export function classifyProviderFailure(input) {
|
|
|
185
202
|
codes.some((code) => QUOTA_CODES.has(code)) ||
|
|
186
203
|
(input.status === 429 && QUOTA_TEXT.test(text)))
|
|
187
204
|
return new QuotaExceededError(details);
|
|
188
|
-
if (input.status === 401 ||
|
|
205
|
+
if (input.status === 401 ||
|
|
206
|
+
input.status === 403 ||
|
|
207
|
+
codes.some((code) => AUTH_CODES.has(code)) ||
|
|
208
|
+
(input.status === 400 && AUTH_TEXT.test(text)))
|
|
189
209
|
return new AuthenticationError(details);
|
|
190
210
|
if (input.status === 429 ||
|
|
191
211
|
codes.some((code) => code.includes("rate_limit") || code === "too_many_requests" || code === "throttlingexception") ||
|