@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.
@@ -2945,9 +2945,9 @@ function convertToOpenRouterChatMessages(prompt) {
2945
2945
  const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
2946
2946
  const messageReasoningDetails = parsedProviderOptions.success ? (_e = (_d = parsedProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details : void 0;
2947
2947
  const messageAnnotations = parsedProviderOptions.success ? (_g = (_f = parsedProviderOptions.data) == null ? void 0 : _f.openrouter) == null ? void 0 : _g.annotations : void 0;
2948
- const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : findFirstReasoningDetails(content);
2948
+ const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) ? messageReasoningDetails : findFirstReasoningDetails(content);
2949
2949
  let finalReasoningDetails;
2950
- if (candidateReasoningDetails && candidateReasoningDetails.length > 0) {
2950
+ if (candidateReasoningDetails) {
2951
2951
  const validDetails = candidateReasoningDetails.filter((detail) => {
2952
2952
  var _a17;
2953
2953
  if (detail.type !== "reasoning.text" /* Text */) {
@@ -2973,9 +2973,9 @@ function convertToOpenRouterChatMessages(prompt) {
2973
2973
  uniqueDetails.push(detail);
2974
2974
  }
2975
2975
  }
2976
- finalReasoningDetails = uniqueDetails.length > 0 ? uniqueDetails : void 0;
2976
+ finalReasoningDetails = uniqueDetails;
2977
2977
  }
2978
- const effectiveReasoning = reasoning && finalReasoningDetails ? reasoning : void 0;
2978
+ const effectiveReasoning = reasoning && finalReasoningDetails && finalReasoningDetails.length > 0 ? reasoning : void 0;
2979
2979
  messages.push({
2980
2980
  role: "assistant",
2981
2981
  content: text,
@@ -3419,7 +3419,7 @@ var OpenRouterChatLanguageModel = class {
3419
3419
  this.supportedUrls = {
3420
3420
  "image/*": [
3421
3421
  /^data:image\/[a-zA-Z]+;base64,/,
3422
- /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
3422
+ /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)(?:[?#].*)?$/i
3423
3423
  ],
3424
3424
  // 'text/*': [/^data:text\//, /^https?:\/\/.+$/],
3425
3425
  "application/*": [/^data:application\//, /^https?:\/\/.+$/]
@@ -3442,7 +3442,7 @@ var OpenRouterChatLanguageModel = class {
3442
3442
  tools,
3443
3443
  toolChoice
3444
3444
  }) {
3445
- var _a16, _b16;
3445
+ var _a16, _b16, _c, _d;
3446
3446
  const baseArgs = __spreadValues(__spreadValues({
3447
3447
  // model id:
3448
3448
  model: this.modelId,
@@ -3465,8 +3465,8 @@ var OpenRouterChatLanguageModel = class {
3465
3465
  type: "json_schema",
3466
3466
  json_schema: __spreadValues({
3467
3467
  schema: responseFormat.schema,
3468
- strict: true,
3469
- name: (_a16 = responseFormat.name) != null ? _a16 : "response"
3468
+ strict: (_b16 = (_a16 = this.settings.structuredOutputs) == null ? void 0 : _a16.strict) != null ? _b16 : true,
3469
+ name: (_c = responseFormat.name) != null ? _c : "response"
3470
3470
  }, responseFormat.description && {
3471
3471
  description: responseFormat.description
3472
3472
  })
@@ -3492,7 +3492,7 @@ var OpenRouterChatLanguageModel = class {
3492
3492
  const mappedTools = [];
3493
3493
  for (const tool of tools) {
3494
3494
  if (tool.type === "function") {
3495
- const openrouterOptions = (_b16 = tool.providerOptions) == null ? void 0 : _b16.openrouter;
3495
+ const openrouterOptions = (_d = tool.providerOptions) == null ? void 0 : _d.openrouter;
3496
3496
  const eagerInputStreaming = openrouterOptions == null ? void 0 : openrouterOptions.eager_input_streaming;
3497
3497
  mappedTools.push(__spreadValues({
3498
3498
  type: "function",
@@ -3902,15 +3902,17 @@ var OpenRouterChatLanguageModel = class {
3902
3902
  controller.enqueue({
3903
3903
  type: "reasoning-end",
3904
3904
  id: reasoningId || generateId(),
3905
- // Include accumulated reasoning_details so the AI SDK can update
3906
- // the reasoning part's providerMetadata with the correct signature.
3907
- // The signature typically arrives in the last reasoning delta,
3905
+ // Always include accumulated reasoning_details so the AI SDK can
3906
+ // update the reasoning part's providerMetadata with the correct
3907
+ // signature. The signature typically arrives in the last delta,
3908
3908
  // but reasoning-start only carries the first delta's metadata.
3909
- providerMetadata: accumulatedReasoningDetails.length > 0 ? {
3909
+ // An empty array is intentional — it signals the provider produced
3910
+ // no reasoning tokens this turn (e.g. DeepSeek V4).
3911
+ providerMetadata: {
3910
3912
  openrouter: {
3911
3913
  reasoning_details: accumulatedReasoningDetails
3912
3914
  }
3913
- } : void 0
3915
+ }
3914
3916
  });
3915
3917
  reasoningStarted = false;
3916
3918
  }
@@ -4059,7 +4061,7 @@ var OpenRouterChatLanguageModel = class {
4059
4061
  id: toolCall.id,
4060
4062
  delta: (_s = toolCallDelta.function.arguments) != null ? _s : ""
4061
4063
  });
4062
- if (((_t = toolCall.function) == null ? void 0 : _t.name) != null && ((_u = toolCall.function) == null ? void 0 : _u.arguments) != null && isParsableJson(toolCall.function.arguments)) {
4064
+ 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)) {
4063
4065
  controller.enqueue({
4064
4066
  type: "tool-input-end",
4065
4067
  id: toolCall.id
@@ -4145,13 +4147,14 @@ var OpenRouterChatLanguageModel = class {
4145
4147
  controller.enqueue({
4146
4148
  type: "reasoning-end",
4147
4149
  id: reasoningId || generateId(),
4148
- // Include accumulated reasoning_details so the AI SDK can update
4149
- // the reasoning part's providerMetadata with the correct signature.
4150
- providerMetadata: accumulatedReasoningDetails.length > 0 ? {
4150
+ // Always include accumulated reasoning_details so the AI SDK can
4151
+ // update the reasoning part's providerMetadata. An empty array is
4152
+ // intentional it signals the provider produced no reasoning tokens.
4153
+ providerMetadata: {
4151
4154
  openrouter: {
4152
4155
  reasoning_details: accumulatedReasoningDetails
4153
4156
  }
4154
- } : void 0
4157
+ }
4155
4158
  });
4156
4159
  }
4157
4160
  if (textStarted) {
@@ -4166,9 +4169,7 @@ var OpenRouterChatLanguageModel = class {
4166
4169
  if (provider !== void 0) {
4167
4170
  openrouterMetadata.provider = provider;
4168
4171
  }
4169
- if (accumulatedReasoningDetails.length > 0) {
4170
- openrouterMetadata.reasoning_details = accumulatedReasoningDetails;
4171
- }
4172
+ openrouterMetadata.reasoning_details = accumulatedReasoningDetails;
4172
4173
  if (accumulatedFileAnnotations.length > 0) {
4173
4174
  openrouterMetadata.annotations = accumulatedFileAnnotations;
4174
4175
  }
@@ -4366,7 +4367,7 @@ var OpenRouterCompletionLanguageModel = class {
4366
4367
  this.supportedUrls = {
4367
4368
  "image/*": [
4368
4369
  /^data:image\/[a-zA-Z]+;base64,/,
4369
- /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i
4370
+ /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)(?:[?#].*)?$/i
4370
4371
  ],
4371
4372
  "text/*": [/^data:text\//, /^https?:\/\/.+$/],
4372
4373
  "application/*": [/^data:application\//, /^https?:\/\/.+$/]