@openrouter/ai-sdk-provider 2.8.0 → 2.9.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 +25 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +25 -24
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +19 -0
- package/dist/internal/index.d.ts +19 -0
- package/dist/internal/index.js +24 -23
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +24 -23
- package/dist/internal/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -219,6 +219,25 @@ type OpenRouterChatSettings = {
|
|
|
219
219
|
*/
|
|
220
220
|
echo_upstream_body?: boolean;
|
|
221
221
|
};
|
|
222
|
+
/**
|
|
223
|
+
* Structured-output options forwarded to OpenRouter's
|
|
224
|
+
* `response_format.json_schema` payload.
|
|
225
|
+
*
|
|
226
|
+
* Use this to opt out of strict mode for models whose providers don't
|
|
227
|
+
* advertise support for it (e.g. open-source models routed through
|
|
228
|
+
* non-OpenAI-compatible providers). When `strict` is left unset, the
|
|
229
|
+
* SDK defaults to `true` for backward compatibility.
|
|
230
|
+
*
|
|
231
|
+
* Only applies when a `responseFormat` with a `schema` is provided on
|
|
232
|
+
* the call site. Has no effect for `json_object` or text responses.
|
|
233
|
+
*/
|
|
234
|
+
structuredOutputs?: {
|
|
235
|
+
/**
|
|
236
|
+
* Whether to set `response_format.json_schema.strict` on the outbound
|
|
237
|
+
* request. Defaults to `true` when omitted.
|
|
238
|
+
*/
|
|
239
|
+
strict?: boolean;
|
|
240
|
+
};
|
|
222
241
|
/**
|
|
223
242
|
* Provider routing preferences to control request routing behavior
|
|
224
243
|
*/
|
package/dist/internal/index.d.ts
CHANGED
|
@@ -219,6 +219,25 @@ type OpenRouterChatSettings = {
|
|
|
219
219
|
*/
|
|
220
220
|
echo_upstream_body?: boolean;
|
|
221
221
|
};
|
|
222
|
+
/**
|
|
223
|
+
* Structured-output options forwarded to OpenRouter's
|
|
224
|
+
* `response_format.json_schema` payload.
|
|
225
|
+
*
|
|
226
|
+
* Use this to opt out of strict mode for models whose providers don't
|
|
227
|
+
* advertise support for it (e.g. open-source models routed through
|
|
228
|
+
* non-OpenAI-compatible providers). When `strict` is left unset, the
|
|
229
|
+
* SDK defaults to `true` for backward compatibility.
|
|
230
|
+
*
|
|
231
|
+
* Only applies when a `responseFormat` with a `schema` is provided on
|
|
232
|
+
* the call site. Has no effect for `json_object` or text responses.
|
|
233
|
+
*/
|
|
234
|
+
structuredOutputs?: {
|
|
235
|
+
/**
|
|
236
|
+
* Whether to set `response_format.json_schema.strict` on the outbound
|
|
237
|
+
* request. Defaults to `true` when omitted.
|
|
238
|
+
*/
|
|
239
|
+
strict?: boolean;
|
|
240
|
+
};
|
|
222
241
|
/**
|
|
223
242
|
* Provider routing preferences to control request routing behavior
|
|
224
243
|
*/
|
package/dist/internal/index.js
CHANGED
|
@@ -2980,9 +2980,9 @@ function convertToOpenRouterChatMessages(prompt) {
|
|
|
2980
2980
|
const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
|
|
2981
2981
|
const messageReasoningDetails = parsedProviderOptions.success ? (_e = (_d = parsedProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details : void 0;
|
|
2982
2982
|
const messageAnnotations = parsedProviderOptions.success ? (_g = (_f = parsedProviderOptions.data) == null ? void 0 : _f.openrouter) == null ? void 0 : _g.annotations : void 0;
|
|
2983
|
-
const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails)
|
|
2983
|
+
const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) ? messageReasoningDetails : findFirstReasoningDetails(content);
|
|
2984
2984
|
let finalReasoningDetails;
|
|
2985
|
-
if (candidateReasoningDetails
|
|
2985
|
+
if (candidateReasoningDetails) {
|
|
2986
2986
|
const validDetails = candidateReasoningDetails.filter((detail) => {
|
|
2987
2987
|
var _a17;
|
|
2988
2988
|
if (detail.type !== "reasoning.text" /* Text */) {
|
|
@@ -3008,9 +3008,9 @@ function convertToOpenRouterChatMessages(prompt) {
|
|
|
3008
3008
|
uniqueDetails.push(detail);
|
|
3009
3009
|
}
|
|
3010
3010
|
}
|
|
3011
|
-
finalReasoningDetails = uniqueDetails
|
|
3011
|
+
finalReasoningDetails = uniqueDetails;
|
|
3012
3012
|
}
|
|
3013
|
-
const effectiveReasoning = reasoning && finalReasoningDetails ? reasoning : void 0;
|
|
3013
|
+
const effectiveReasoning = reasoning && finalReasoningDetails && finalReasoningDetails.length > 0 ? reasoning : void 0;
|
|
3014
3014
|
messages.push({
|
|
3015
3015
|
role: "assistant",
|
|
3016
3016
|
content: text,
|
|
@@ -3454,7 +3454,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3454
3454
|
this.supportedUrls = {
|
|
3455
3455
|
"image/*": [
|
|
3456
3456
|
/^data:image\/[a-zA-Z]+;base64,/,
|
|
3457
|
-
/^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)
|
|
3457
|
+
/^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)(?:[?#].*)?$/i
|
|
3458
3458
|
],
|
|
3459
3459
|
// 'text/*': [/^data:text\//, /^https?:\/\/.+$/],
|
|
3460
3460
|
"application/*": [/^data:application\//, /^https?:\/\/.+$/]
|
|
@@ -3477,7 +3477,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3477
3477
|
tools,
|
|
3478
3478
|
toolChoice
|
|
3479
3479
|
}) {
|
|
3480
|
-
var _a16, _b16;
|
|
3480
|
+
var _a16, _b16, _c, _d;
|
|
3481
3481
|
const baseArgs = __spreadValues(__spreadValues({
|
|
3482
3482
|
// model id:
|
|
3483
3483
|
model: this.modelId,
|
|
@@ -3500,8 +3500,8 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3500
3500
|
type: "json_schema",
|
|
3501
3501
|
json_schema: __spreadValues({
|
|
3502
3502
|
schema: responseFormat.schema,
|
|
3503
|
-
strict: true,
|
|
3504
|
-
name: (
|
|
3503
|
+
strict: (_b16 = (_a16 = this.settings.structuredOutputs) == null ? void 0 : _a16.strict) != null ? _b16 : true,
|
|
3504
|
+
name: (_c = responseFormat.name) != null ? _c : "response"
|
|
3505
3505
|
}, responseFormat.description && {
|
|
3506
3506
|
description: responseFormat.description
|
|
3507
3507
|
})
|
|
@@ -3527,7 +3527,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3527
3527
|
const mappedTools = [];
|
|
3528
3528
|
for (const tool of tools) {
|
|
3529
3529
|
if (tool.type === "function") {
|
|
3530
|
-
const openrouterOptions = (
|
|
3530
|
+
const openrouterOptions = (_d = tool.providerOptions) == null ? void 0 : _d.openrouter;
|
|
3531
3531
|
const eagerInputStreaming = openrouterOptions == null ? void 0 : openrouterOptions.eager_input_streaming;
|
|
3532
3532
|
mappedTools.push(__spreadValues({
|
|
3533
3533
|
type: "function",
|
|
@@ -3937,15 +3937,17 @@ var OpenRouterChatLanguageModel = class {
|
|
|
3937
3937
|
controller.enqueue({
|
|
3938
3938
|
type: "reasoning-end",
|
|
3939
3939
|
id: reasoningId || generateId(),
|
|
3940
|
-
//
|
|
3941
|
-
// the reasoning part's providerMetadata with the correct
|
|
3942
|
-
// The signature typically arrives in the last
|
|
3940
|
+
// Always include accumulated reasoning_details so the AI SDK can
|
|
3941
|
+
// update the reasoning part's providerMetadata with the correct
|
|
3942
|
+
// signature. The signature typically arrives in the last delta,
|
|
3943
3943
|
// but reasoning-start only carries the first delta's metadata.
|
|
3944
|
-
|
|
3944
|
+
// An empty array is intentional — it signals the provider produced
|
|
3945
|
+
// no reasoning tokens this turn (e.g. DeepSeek V4).
|
|
3946
|
+
providerMetadata: {
|
|
3945
3947
|
openrouter: {
|
|
3946
3948
|
reasoning_details: accumulatedReasoningDetails
|
|
3947
3949
|
}
|
|
3948
|
-
}
|
|
3950
|
+
}
|
|
3949
3951
|
});
|
|
3950
3952
|
reasoningStarted = false;
|
|
3951
3953
|
}
|
|
@@ -4094,7 +4096,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
4094
4096
|
id: toolCall.id,
|
|
4095
4097
|
delta: (_s = toolCallDelta.function.arguments) != null ? _s : ""
|
|
4096
4098
|
});
|
|
4097
|
-
if (((_t = toolCall.function) == null ? void 0 : _t.name) != null && ((_u = toolCall.function) == null ? void 0 : _u.arguments) != null && isParsableJson(toolCall.function.arguments)) {
|
|
4099
|
+
if (!toolCall.sent && ((_t = toolCall.function) == null ? void 0 : _t.name) != null && ((_u = toolCall.function) == null ? void 0 : _u.arguments) != null && isParsableJson(toolCall.function.arguments)) {
|
|
4098
4100
|
controller.enqueue({
|
|
4099
4101
|
type: "tool-input-end",
|
|
4100
4102
|
id: toolCall.id
|
|
@@ -4180,13 +4182,14 @@ var OpenRouterChatLanguageModel = class {
|
|
|
4180
4182
|
controller.enqueue({
|
|
4181
4183
|
type: "reasoning-end",
|
|
4182
4184
|
id: reasoningId || generateId(),
|
|
4183
|
-
//
|
|
4184
|
-
// the reasoning part's providerMetadata
|
|
4185
|
-
|
|
4185
|
+
// Always include accumulated reasoning_details so the AI SDK can
|
|
4186
|
+
// update the reasoning part's providerMetadata. An empty array is
|
|
4187
|
+
// intentional — it signals the provider produced no reasoning tokens.
|
|
4188
|
+
providerMetadata: {
|
|
4186
4189
|
openrouter: {
|
|
4187
4190
|
reasoning_details: accumulatedReasoningDetails
|
|
4188
4191
|
}
|
|
4189
|
-
}
|
|
4192
|
+
}
|
|
4190
4193
|
});
|
|
4191
4194
|
}
|
|
4192
4195
|
if (textStarted) {
|
|
@@ -4201,9 +4204,7 @@ var OpenRouterChatLanguageModel = class {
|
|
|
4201
4204
|
if (provider !== void 0) {
|
|
4202
4205
|
openrouterMetadata.provider = provider;
|
|
4203
4206
|
}
|
|
4204
|
-
|
|
4205
|
-
openrouterMetadata.reasoning_details = accumulatedReasoningDetails;
|
|
4206
|
-
}
|
|
4207
|
+
openrouterMetadata.reasoning_details = accumulatedReasoningDetails;
|
|
4207
4208
|
if (accumulatedFileAnnotations.length > 0) {
|
|
4208
4209
|
openrouterMetadata.annotations = accumulatedFileAnnotations;
|
|
4209
4210
|
}
|
|
@@ -4401,7 +4402,7 @@ var OpenRouterCompletionLanguageModel = class {
|
|
|
4401
4402
|
this.supportedUrls = {
|
|
4402
4403
|
"image/*": [
|
|
4403
4404
|
/^data:image\/[a-zA-Z]+;base64,/,
|
|
4404
|
-
/^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)
|
|
4405
|
+
/^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)(?:[?#].*)?$/i
|
|
4405
4406
|
],
|
|
4406
4407
|
"text/*": [/^data:text\//, /^https?:\/\/.+$/],
|
|
4407
4408
|
"application/*": [/^data:application\//, /^https?:\/\/.+$/]
|