@openrouter/ai-sdk-provider 2.3.2 → 2.4.0
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/index.d.mts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +87 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +87 -16
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +1 -0
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.js +80 -11
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +80 -11
- package/dist/internal/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/internal/index.mjs
CHANGED
|
@@ -2148,11 +2148,13 @@ function isDefinedOrNotNull(value) {
|
|
|
2148
2148
|
var ReasoningFormat = /* @__PURE__ */ ((ReasoningFormat2) => {
|
|
2149
2149
|
ReasoningFormat2["Unknown"] = "unknown";
|
|
2150
2150
|
ReasoningFormat2["OpenAIResponsesV1"] = "openai-responses-v1";
|
|
2151
|
+
ReasoningFormat2["AzureOpenAIResponsesV1"] = "azure-openai-responses-v1";
|
|
2151
2152
|
ReasoningFormat2["XAIResponsesV1"] = "xai-responses-v1";
|
|
2152
2153
|
ReasoningFormat2["AnthropicClaudeV1"] = "anthropic-claude-v1";
|
|
2153
2154
|
ReasoningFormat2["GoogleGeminiV1"] = "google-gemini-v1";
|
|
2154
2155
|
return ReasoningFormat2;
|
|
2155
2156
|
})(ReasoningFormat || {});
|
|
2157
|
+
var DEFAULT_REASONING_FORMAT = "anthropic-claude-v1" /* AnthropicClaudeV1 */;
|
|
2156
2158
|
|
|
2157
2159
|
// src/schemas/reasoning-details.ts
|
|
2158
2160
|
var CommonReasoningDetailSchema = z.object({
|
|
@@ -2305,7 +2307,11 @@ var OpenRouterProviderMetadataSchema = z3.object({
|
|
|
2305
2307
|
}).catchall(z3.any());
|
|
2306
2308
|
var OpenRouterProviderOptionsSchema = z3.object({
|
|
2307
2309
|
openrouter: z3.object({
|
|
2308
|
-
|
|
2310
|
+
// Use ReasoningDetailArraySchema (with unknown fallback) instead of
|
|
2311
|
+
// z.array(ReasoningDetailUnionSchema) so that a single malformed entry
|
|
2312
|
+
// (e.g., a future format not yet in the enum) is individually dropped
|
|
2313
|
+
// rather than causing the entire array to fail parsing.
|
|
2314
|
+
reasoning_details: ReasoningDetailArraySchema.optional(),
|
|
2309
2315
|
annotations: z3.array(FileAnnotationSchema).optional()
|
|
2310
2316
|
}).optional()
|
|
2311
2317
|
}).optional();
|
|
@@ -2376,6 +2382,31 @@ function createFinishReason(unified, raw) {
|
|
|
2376
2382
|
return { unified, raw };
|
|
2377
2383
|
}
|
|
2378
2384
|
|
|
2385
|
+
// src/utils/with-stream-error-handling.ts
|
|
2386
|
+
function withStreamErrorHandling(source, onError) {
|
|
2387
|
+
const reader = source.getReader();
|
|
2388
|
+
return new ReadableStream({
|
|
2389
|
+
async pull(controller) {
|
|
2390
|
+
try {
|
|
2391
|
+
const { done, value } = await reader.read();
|
|
2392
|
+
if (done) {
|
|
2393
|
+
controller.close();
|
|
2394
|
+
} else {
|
|
2395
|
+
controller.enqueue(value);
|
|
2396
|
+
}
|
|
2397
|
+
} catch (err) {
|
|
2398
|
+
onError(err);
|
|
2399
|
+
reader.cancel().catch(() => {
|
|
2400
|
+
});
|
|
2401
|
+
controller.close();
|
|
2402
|
+
}
|
|
2403
|
+
},
|
|
2404
|
+
cancel(reason) {
|
|
2405
|
+
reader.cancel(reason);
|
|
2406
|
+
}
|
|
2407
|
+
});
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2379
2410
|
// src/utils/reasoning-details-duplicate-tracker.ts
|
|
2380
2411
|
var _seenKeys;
|
|
2381
2412
|
var ReasoningDetailsDuplicateTracker = class {
|
|
@@ -2717,8 +2748,24 @@ function convertToOpenRouterChatMessages(prompt) {
|
|
|
2717
2748
|
const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : findFirstReasoningDetails(content);
|
|
2718
2749
|
let finalReasoningDetails;
|
|
2719
2750
|
if (candidateReasoningDetails && candidateReasoningDetails.length > 0) {
|
|
2751
|
+
const validDetails = candidateReasoningDetails.filter((detail) => {
|
|
2752
|
+
var _a17;
|
|
2753
|
+
if (detail.type !== "reasoning.text" /* Text */) {
|
|
2754
|
+
return true;
|
|
2755
|
+
}
|
|
2756
|
+
const format = (_a17 = detail.format) != null ? _a17 : DEFAULT_REASONING_FORMAT;
|
|
2757
|
+
if (format !== "anthropic-claude-v1" /* AnthropicClaudeV1 */) {
|
|
2758
|
+
return true;
|
|
2759
|
+
}
|
|
2760
|
+
return !!detail.signature;
|
|
2761
|
+
});
|
|
2762
|
+
if (validDetails.length < candidateReasoningDetails.length) {
|
|
2763
|
+
console.warn(
|
|
2764
|
+
"[openrouter] Some reasoning_details entries were removed because they were missing signatures. See https://github.com/OpenRouterTeam/ai-sdk-provider/issues/423 for more details."
|
|
2765
|
+
);
|
|
2766
|
+
}
|
|
2720
2767
|
const uniqueDetails = [];
|
|
2721
|
-
for (const detail of
|
|
2768
|
+
for (const detail of validDetails) {
|
|
2722
2769
|
if (reasoningDetailsTracker.upsert(detail)) {
|
|
2723
2770
|
uniqueDetails.push(detail);
|
|
2724
2771
|
}
|
|
@@ -2747,6 +2794,7 @@ function convertToOpenRouterChatMessages(prompt) {
|
|
|
2747
2794
|
role: "tool",
|
|
2748
2795
|
tool_call_id: toolResponse.toolCallId,
|
|
2749
2796
|
content: content2,
|
|
2797
|
+
name: toolResponse.toolName,
|
|
2750
2798
|
cache_control: (_h = getCacheControl(providerOptions)) != null ? _h : getCacheControl(toolResponse.providerOptions)
|
|
2751
2799
|
});
|
|
2752
2800
|
}
|
|
@@ -2888,13 +2936,14 @@ function filenameFromUrl(url) {
|
|
|
2888
2936
|
}
|
|
2889
2937
|
}
|
|
2890
2938
|
function findFirstReasoningDetails(content) {
|
|
2891
|
-
var _a16, _b16, _c;
|
|
2939
|
+
var _a16, _b16, _c, _d;
|
|
2892
2940
|
for (const part of content) {
|
|
2893
2941
|
if (part.type === "tool-call") {
|
|
2894
|
-
const
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2942
|
+
const parsed = OpenRouterProviderOptionsSchema.safeParse(
|
|
2943
|
+
part.providerOptions
|
|
2944
|
+
);
|
|
2945
|
+
if (parsed.success && ((_b16 = (_a16 = parsed.data) == null ? void 0 : _a16.openrouter) == null ? void 0 : _b16.reasoning_details) && parsed.data.openrouter.reasoning_details.length > 0) {
|
|
2946
|
+
return parsed.data.openrouter.reasoning_details;
|
|
2898
2947
|
}
|
|
2899
2948
|
}
|
|
2900
2949
|
}
|
|
@@ -2903,7 +2952,7 @@ function findFirstReasoningDetails(content) {
|
|
|
2903
2952
|
const parsed = OpenRouterProviderOptionsSchema.safeParse(
|
|
2904
2953
|
part.providerOptions
|
|
2905
2954
|
);
|
|
2906
|
-
if (parsed.success && ((
|
|
2955
|
+
if (parsed.success && ((_d = (_c = parsed.data) == null ? void 0 : _c.openrouter) == null ? void 0 : _d.reasoning_details) && parsed.data.openrouter.reasoning_details.length > 0) {
|
|
2907
2956
|
return parsed.data.openrouter.reasoning_details;
|
|
2908
2957
|
}
|
|
2909
2958
|
}
|
|
@@ -3408,7 +3457,8 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3408
3457
|
(d) => d.type === "reasoning.encrypted" /* Encrypted */ && d.data
|
|
3409
3458
|
);
|
|
3410
3459
|
const shouldOverrideFinishReason = hasToolCalls && hasEncryptedReasoning && choice.finish_reason === "stop";
|
|
3411
|
-
const
|
|
3460
|
+
const mappedFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_j = choice.finish_reason) != null ? _j : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
|
|
3461
|
+
const effectiveFinishReason = hasToolCalls && mappedFinishReason.unified === "other" ? createFinishReason("tool-calls", mappedFinishReason.raw) : mappedFinishReason;
|
|
3412
3462
|
return {
|
|
3413
3463
|
content,
|
|
3414
3464
|
finishReason: effectiveFinishReason,
|
|
@@ -3472,6 +3522,10 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3472
3522
|
abortSignal: options.abortSignal,
|
|
3473
3523
|
fetch: this.config.fetch
|
|
3474
3524
|
});
|
|
3525
|
+
let streamError;
|
|
3526
|
+
const safeResponse = withStreamErrorHandling(response, (err) => {
|
|
3527
|
+
streamError = err;
|
|
3528
|
+
});
|
|
3475
3529
|
const toolCalls = [];
|
|
3476
3530
|
let finishReason = createFinishReason("other");
|
|
3477
3531
|
const usage = {
|
|
@@ -3500,7 +3554,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3500
3554
|
let openrouterResponseId;
|
|
3501
3555
|
let provider;
|
|
3502
3556
|
return {
|
|
3503
|
-
stream:
|
|
3557
|
+
stream: safeResponse.pipeThrough(
|
|
3504
3558
|
new TransformStream({
|
|
3505
3559
|
transform(chunk, controller) {
|
|
3506
3560
|
var _a17, _b17, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
|
|
@@ -3822,12 +3876,19 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3822
3876
|
flush(controller) {
|
|
3823
3877
|
var _a17;
|
|
3824
3878
|
const hasToolCalls = toolCalls.length > 0;
|
|
3879
|
+
if (streamError != null) {
|
|
3880
|
+
finishReason = createFinishReason("error");
|
|
3881
|
+
controller.enqueue({ type: "error", error: streamError });
|
|
3882
|
+
}
|
|
3825
3883
|
const hasEncryptedReasoning = accumulatedReasoningDetails.some(
|
|
3826
3884
|
(d) => d.type === "reasoning.encrypted" /* Encrypted */ && d.data
|
|
3827
3885
|
);
|
|
3828
3886
|
if (hasToolCalls && hasEncryptedReasoning && finishReason.unified === "stop") {
|
|
3829
3887
|
finishReason = createFinishReason("tool-calls", finishReason.raw);
|
|
3830
3888
|
}
|
|
3889
|
+
if (hasToolCalls && finishReason.unified === "other") {
|
|
3890
|
+
finishReason = createFinishReason("tool-calls", finishReason.raw);
|
|
3891
|
+
}
|
|
3831
3892
|
if (finishReason.unified === "tool-calls") {
|
|
3832
3893
|
for (const toolCall of toolCalls) {
|
|
3833
3894
|
if (toolCall && !toolCall.sent) {
|
|
@@ -4213,6 +4274,10 @@ var OpenRouterCompletionLanguageModel = class {
|
|
|
4213
4274
|
abortSignal: options.abortSignal,
|
|
4214
4275
|
fetch: this.config.fetch
|
|
4215
4276
|
});
|
|
4277
|
+
let streamError;
|
|
4278
|
+
const safeResponse = withStreamErrorHandling(response, (err) => {
|
|
4279
|
+
streamError = err;
|
|
4280
|
+
});
|
|
4216
4281
|
let finishReason = createFinishReason("other");
|
|
4217
4282
|
const usage = {
|
|
4218
4283
|
inputTokens: {
|
|
@@ -4232,7 +4297,7 @@ var OpenRouterCompletionLanguageModel = class {
|
|
|
4232
4297
|
let provider;
|
|
4233
4298
|
let rawUsage;
|
|
4234
4299
|
return {
|
|
4235
|
-
stream:
|
|
4300
|
+
stream: safeResponse.pipeThrough(
|
|
4236
4301
|
new TransformStream({
|
|
4237
4302
|
transform(chunk, controller) {
|
|
4238
4303
|
var _a16, _b16, _c, _d, _e;
|
|
@@ -4296,6 +4361,10 @@ var OpenRouterCompletionLanguageModel = class {
|
|
|
4296
4361
|
}
|
|
4297
4362
|
},
|
|
4298
4363
|
flush(controller) {
|
|
4364
|
+
if (streamError != null) {
|
|
4365
|
+
finishReason = createFinishReason("error");
|
|
4366
|
+
controller.enqueue({ type: "error", error: streamError });
|
|
4367
|
+
}
|
|
4299
4368
|
usage.raw = rawUsage;
|
|
4300
4369
|
const openrouterMetadata = {
|
|
4301
4370
|
usage: openrouterUsage
|