@openrouter/ai-sdk-provider 2.0.1 → 2.0.4

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.
@@ -2410,7 +2410,7 @@ function getCacheControl(providerMetadata) {
2410
2410
  return (_c = (_b16 = (_a16 = openrouter == null ? void 0 : openrouter.cacheControl) != null ? _a16 : openrouter == null ? void 0 : openrouter.cache_control) != null ? _b16 : anthropic == null ? void 0 : anthropic.cacheControl) != null ? _c : anthropic == null ? void 0 : anthropic.cache_control;
2411
2411
  }
2412
2412
  function convertToOpenRouterChatMessages(prompt) {
2413
- var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j;
2413
+ var _a16, _b16, _c, _d, _e, _f, _g, _h;
2414
2414
  const messages = [];
2415
2415
  for (const { role, content, providerOptions } of prompt) {
2416
2416
  switch (role) {
@@ -2439,42 +2439,46 @@ function convertToOpenRouterChatMessages(prompt) {
2439
2439
  break;
2440
2440
  }
2441
2441
  const messageCacheControl = getCacheControl(providerOptions);
2442
+ let lastTextPartIndex = -1;
2443
+ for (let i = content.length - 1; i >= 0; i--) {
2444
+ if (((_c = content[i]) == null ? void 0 : _c.type) === "text") {
2445
+ lastTextPartIndex = i;
2446
+ break;
2447
+ }
2448
+ }
2442
2449
  const contentParts = content.map(
2443
- (part) => {
2444
- var _a17, _b17, _c2, _d2, _e2, _f2, _g2;
2445
- const cacheControl = (_a17 = getCacheControl(part.providerOptions)) != null ? _a17 : messageCacheControl;
2450
+ (part, index) => {
2451
+ var _a17, _b17, _c2, _d2, _e2, _f2;
2452
+ const isLastTextPart = part.type === "text" && index === lastTextPartIndex;
2453
+ const partCacheControl = getCacheControl(part.providerOptions);
2454
+ const cacheControl = part.type === "text" ? partCacheControl != null ? partCacheControl : isLastTextPart ? messageCacheControl : void 0 : partCacheControl;
2446
2455
  switch (part.type) {
2447
2456
  case "text":
2448
- return {
2457
+ return __spreadValues({
2449
2458
  type: "text",
2450
- text: part.text,
2451
- // For text parts, only use part-specific cache control
2452
- cache_control: cacheControl
2453
- };
2459
+ text: part.text
2460
+ }, cacheControl && { cache_control: cacheControl });
2454
2461
  case "file": {
2455
- if ((_b17 = part.mediaType) == null ? void 0 : _b17.startsWith("image/")) {
2462
+ if ((_a17 = part.mediaType) == null ? void 0 : _a17.startsWith("image/")) {
2456
2463
  const url = getFileUrl({
2457
2464
  part,
2458
2465
  defaultMediaType: "image/jpeg"
2459
2466
  });
2460
- return {
2467
+ return __spreadValues({
2461
2468
  type: "image_url",
2462
2469
  image_url: {
2463
2470
  url
2464
- },
2465
- // For image parts, use part-specific or message-level cache control
2466
- cache_control: cacheControl
2467
- };
2471
+ }
2472
+ }, cacheControl && { cache_control: cacheControl });
2468
2473
  }
2469
- if ((_c2 = part.mediaType) == null ? void 0 : _c2.startsWith("audio/")) {
2470
- return {
2474
+ if ((_b17 = part.mediaType) == null ? void 0 : _b17.startsWith("audio/")) {
2475
+ return __spreadValues({
2471
2476
  type: "input_audio",
2472
- input_audio: getInputAudioData(part),
2473
- cache_control: cacheControl
2474
- };
2477
+ input_audio: getInputAudioData(part)
2478
+ }, cacheControl && { cache_control: cacheControl });
2475
2479
  }
2476
2480
  const fileName = String(
2477
- (_g2 = (_f2 = (_e2 = (_d2 = part.providerOptions) == null ? void 0 : _d2.openrouter) == null ? void 0 : _e2.filename) != null ? _f2 : part.filename) != null ? _g2 : ""
2481
+ (_f2 = (_e2 = (_d2 = (_c2 = part.providerOptions) == null ? void 0 : _c2.openrouter) == null ? void 0 : _d2.filename) != null ? _e2 : part.filename) != null ? _f2 : ""
2478
2482
  );
2479
2483
  const fileData = getFileUrl({
2480
2484
  part,
@@ -2492,21 +2496,19 @@ function convertToOpenRouterChatMessages(prompt) {
2492
2496
  }
2493
2497
  };
2494
2498
  }
2495
- return {
2499
+ return __spreadValues({
2496
2500
  type: "file",
2497
2501
  file: {
2498
2502
  filename: fileName,
2499
2503
  file_data: fileData
2500
- },
2501
- cache_control: cacheControl
2502
- };
2504
+ }
2505
+ }, cacheControl && { cache_control: cacheControl });
2503
2506
  }
2504
2507
  default: {
2505
- return {
2508
+ return __spreadValues({
2506
2509
  type: "text",
2507
- text: "",
2508
- cache_control: cacheControl
2509
- };
2510
+ text: ""
2511
+ }, cacheControl && { cache_control: cacheControl });
2510
2512
  }
2511
2513
  }
2512
2514
  }
@@ -2521,7 +2523,6 @@ function convertToOpenRouterChatMessages(prompt) {
2521
2523
  let text = "";
2522
2524
  let reasoning = "";
2523
2525
  const toolCalls = [];
2524
- const accumulatedReasoningDetails = [];
2525
2526
  for (const part of content) {
2526
2527
  switch (part.type) {
2527
2528
  case "text": {
@@ -2529,12 +2530,6 @@ function convertToOpenRouterChatMessages(prompt) {
2529
2530
  break;
2530
2531
  }
2531
2532
  case "tool-call": {
2532
- const partReasoningDetails = (_c = part.providerOptions) == null ? void 0 : _c.openrouter;
2533
- if ((partReasoningDetails == null ? void 0 : partReasoningDetails.reasoning_details) && Array.isArray(partReasoningDetails.reasoning_details)) {
2534
- accumulatedReasoningDetails.push(
2535
- ...partReasoningDetails.reasoning_details
2536
- );
2537
- }
2538
2533
  toolCalls.push({
2539
2534
  id: part.toolCallId,
2540
2535
  type: "function",
@@ -2547,12 +2542,6 @@ function convertToOpenRouterChatMessages(prompt) {
2547
2542
  }
2548
2543
  case "reasoning": {
2549
2544
  reasoning += part.text;
2550
- const parsedPartProviderOptions = OpenRouterProviderOptionsSchema.safeParse(part.providerOptions);
2551
- if (parsedPartProviderOptions.success && ((_e = (_d = parsedPartProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details)) {
2552
- accumulatedReasoningDetails.push(
2553
- ...parsedPartProviderOptions.data.openrouter.reasoning_details
2554
- );
2555
- }
2556
2545
  break;
2557
2546
  }
2558
2547
  case "file":
@@ -2563,9 +2552,9 @@ function convertToOpenRouterChatMessages(prompt) {
2563
2552
  }
2564
2553
  }
2565
2554
  const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
2566
- const messageReasoningDetails = parsedProviderOptions.success ? (_g = (_f = parsedProviderOptions.data) == null ? void 0 : _f.openrouter) == null ? void 0 : _g.reasoning_details : void 0;
2567
- const messageAnnotations = parsedProviderOptions.success ? (_i = (_h = parsedProviderOptions.data) == null ? void 0 : _h.openrouter) == null ? void 0 : _i.annotations : void 0;
2568
- const finalReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : accumulatedReasoningDetails.length > 0 ? accumulatedReasoningDetails : void 0;
2555
+ const messageReasoningDetails = parsedProviderOptions.success ? (_e = (_d = parsedProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details : void 0;
2556
+ const messageAnnotations = parsedProviderOptions.success ? (_g = (_f = parsedProviderOptions.data) == null ? void 0 : _f.openrouter) == null ? void 0 : _g.annotations : void 0;
2557
+ const finalReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : findFirstReasoningDetails(content);
2569
2558
  messages.push({
2570
2559
  role: "assistant",
2571
2560
  content: text,
@@ -2587,7 +2576,7 @@ function convertToOpenRouterChatMessages(prompt) {
2587
2576
  role: "tool",
2588
2577
  tool_call_id: toolResponse.toolCallId,
2589
2578
  content: content2,
2590
- cache_control: (_j = getCacheControl(providerOptions)) != null ? _j : getCacheControl(toolResponse.providerOptions)
2579
+ cache_control: (_h = getCacheControl(providerOptions)) != null ? _h : getCacheControl(toolResponse.providerOptions)
2591
2580
  });
2592
2581
  }
2593
2582
  break;
@@ -2613,6 +2602,29 @@ function getToolResultContent(input) {
2613
2602
  return (_a16 = input.output.reason) != null ? _a16 : "Tool execution denied";
2614
2603
  }
2615
2604
  }
2605
+ function findFirstReasoningDetails(content) {
2606
+ var _a16, _b16, _c;
2607
+ for (const part of content) {
2608
+ if (part.type === "tool-call") {
2609
+ const openrouter = (_a16 = part.providerOptions) == null ? void 0 : _a16.openrouter;
2610
+ const details = openrouter == null ? void 0 : openrouter.reasoning_details;
2611
+ if (Array.isArray(details) && details.length > 0) {
2612
+ return details;
2613
+ }
2614
+ }
2615
+ }
2616
+ for (const part of content) {
2617
+ if (part.type === "reasoning") {
2618
+ const parsed = OpenRouterProviderOptionsSchema.safeParse(
2619
+ part.providerOptions
2620
+ );
2621
+ if (parsed.success && ((_c = (_b16 = parsed.data) == null ? void 0 : _b16.openrouter) == null ? void 0 : _c.reasoning_details) && parsed.data.openrouter.reasoning_details.length > 0) {
2622
+ return parsed.data.openrouter.reasoning_details;
2623
+ }
2624
+ }
2625
+ }
2626
+ return void 0;
2627
+ }
2616
2628
 
2617
2629
  // src/chat/get-tool-choice.ts
2618
2630
  import { z as z5 } from "zod/v4";
@@ -2704,7 +2716,7 @@ var OpenRouterNonStreamChatCompletionResponseSchema = z7.union([
2704
2716
  type: z7.literal("function"),
2705
2717
  function: z7.object({
2706
2718
  name: z7.string(),
2707
- arguments: z7.string()
2719
+ arguments: z7.string().optional()
2708
2720
  }).passthrough()
2709
2721
  }).passthrough()
2710
2722
  ).optional(),
@@ -2947,7 +2959,7 @@ var OpenRouterChatLanguageModel = class {
2947
2959
  return baseArgs;
2948
2960
  }
2949
2961
  async doGenerate(options) {
2950
- var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
2962
+ var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
2951
2963
  const providerOptions = options.providerOptions || {};
2952
2964
  const openrouterOptions = providerOptions.openrouter || {};
2953
2965
  const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
@@ -3076,18 +3088,20 @@ var OpenRouterChatLanguageModel = class {
3076
3088
  });
3077
3089
  }
3078
3090
  if (choice.message.tool_calls) {
3091
+ let reasoningDetailsAttachedToToolCall = false;
3079
3092
  for (const toolCall of choice.message.tool_calls) {
3080
3093
  content.push({
3081
3094
  type: "tool-call",
3082
3095
  toolCallId: (_h = toolCall.id) != null ? _h : generateId(),
3083
3096
  toolName: toolCall.function.name,
3084
- input: toolCall.function.arguments,
3085
- providerMetadata: {
3097
+ input: (_i = toolCall.function.arguments) != null ? _i : "{}",
3098
+ providerMetadata: !reasoningDetailsAttachedToToolCall ? {
3086
3099
  openrouter: {
3087
3100
  reasoning_details: reasoningDetails
3088
3101
  }
3089
- }
3102
+ } : void 0
3090
3103
  });
3104
+ reasoningDetailsAttachedToToolCall = true;
3091
3105
  }
3092
3106
  }
3093
3107
  if (choice.message.images) {
@@ -3117,7 +3131,7 @@ var OpenRouterChatLanguageModel = class {
3117
3131
  }
3118
3132
  }
3119
3133
  }
3120
- const fileAnnotations = (_i = choice.message.annotations) == null ? void 0 : _i.filter(
3134
+ const fileAnnotations = (_j = choice.message.annotations) == null ? void 0 : _j.filter(
3121
3135
  (a) => a.type === "file"
3122
3136
  );
3123
3137
  const hasToolCalls = choice.message.tool_calls && choice.message.tool_calls.length > 0;
@@ -3125,7 +3139,7 @@ var OpenRouterChatLanguageModel = class {
3125
3139
  (d) => d.type === "reasoning.encrypted" /* Encrypted */ && d.data
3126
3140
  );
3127
3141
  const shouldOverrideFinishReason = hasToolCalls && hasEncryptedReasoning && choice.finish_reason === "stop";
3128
- const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_j = choice.finish_reason) != null ? _j : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3142
+ const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_k = choice.finish_reason) != null ? _k : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3129
3143
  return {
3130
3144
  content,
3131
3145
  finishReason: effectiveFinishReason,
@@ -3133,23 +3147,23 @@ var OpenRouterChatLanguageModel = class {
3133
3147
  warnings: [],
3134
3148
  providerMetadata: {
3135
3149
  openrouter: OpenRouterProviderMetadataSchema.parse({
3136
- provider: (_k = response.provider) != null ? _k : "",
3137
- reasoning_details: (_l = choice.message.reasoning_details) != null ? _l : [],
3150
+ provider: (_l = response.provider) != null ? _l : "",
3151
+ reasoning_details: (_m = choice.message.reasoning_details) != null ? _m : [],
3138
3152
  annotations: fileAnnotations && fileAnnotations.length > 0 ? fileAnnotations : void 0,
3139
3153
  usage: __spreadValues(__spreadValues(__spreadValues({
3140
- promptTokens: (_m = usageInfo.inputTokens.total) != null ? _m : 0,
3141
- completionTokens: (_n = usageInfo.outputTokens.total) != null ? _n : 0,
3142
- totalTokens: ((_o = usageInfo.inputTokens.total) != null ? _o : 0) + ((_p = usageInfo.outputTokens.total) != null ? _p : 0),
3143
- cost: (_q = response.usage) == null ? void 0 : _q.cost
3144
- }, ((_s = (_r = response.usage) == null ? void 0 : _r.prompt_tokens_details) == null ? void 0 : _s.cached_tokens) != null ? {
3154
+ promptTokens: (_n = usageInfo.inputTokens.total) != null ? _n : 0,
3155
+ completionTokens: (_o = usageInfo.outputTokens.total) != null ? _o : 0,
3156
+ totalTokens: ((_p = usageInfo.inputTokens.total) != null ? _p : 0) + ((_q = usageInfo.outputTokens.total) != null ? _q : 0),
3157
+ cost: (_r = response.usage) == null ? void 0 : _r.cost
3158
+ }, ((_t = (_s = response.usage) == null ? void 0 : _s.prompt_tokens_details) == null ? void 0 : _t.cached_tokens) != null ? {
3145
3159
  promptTokensDetails: {
3146
3160
  cachedTokens: response.usage.prompt_tokens_details.cached_tokens
3147
3161
  }
3148
- } : {}), ((_u = (_t = response.usage) == null ? void 0 : _t.completion_tokens_details) == null ? void 0 : _u.reasoning_tokens) != null ? {
3162
+ } : {}), ((_v = (_u = response.usage) == null ? void 0 : _u.completion_tokens_details) == null ? void 0 : _v.reasoning_tokens) != null ? {
3149
3163
  completionTokensDetails: {
3150
3164
  reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
3151
3165
  }
3152
- } : {}), ((_w = (_v = response.usage) == null ? void 0 : _v.cost_details) == null ? void 0 : _w.upstream_inference_cost) != null ? {
3166
+ } : {}), ((_x = (_w = response.usage) == null ? void 0 : _w.cost_details) == null ? void 0 : _x.upstream_inference_cost) != null ? {
3153
3167
  costDetails: {
3154
3168
  upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
3155
3169
  }
@@ -3206,6 +3220,7 @@ var OpenRouterChatLanguageModel = class {
3206
3220
  };
3207
3221
  const openrouterUsage = {};
3208
3222
  const accumulatedReasoningDetails = [];
3223
+ let reasoningDetailsAttachedToToolCall = false;
3209
3224
  const accumulatedFileAnnotations = [];
3210
3225
  let textStarted = false;
3211
3226
  let reasoningStarted = false;
@@ -3454,12 +3469,13 @@ var OpenRouterChatLanguageModel = class {
3454
3469
  toolCallId: toolCall2.id,
3455
3470
  toolName: toolCall2.function.name,
3456
3471
  input: toolCall2.function.arguments,
3457
- providerMetadata: {
3472
+ providerMetadata: !reasoningDetailsAttachedToToolCall ? {
3458
3473
  openrouter: {
3459
3474
  reasoning_details: accumulatedReasoningDetails
3460
3475
  }
3461
- }
3476
+ } : void 0
3462
3477
  });
3478
+ reasoningDetailsAttachedToToolCall = true;
3463
3479
  toolCall2.sent = true;
3464
3480
  }
3465
3481
  continue;
@@ -3497,12 +3513,13 @@ var OpenRouterChatLanguageModel = class {
3497
3513
  toolCallId: (_o = toolCall.id) != null ? _o : generateId(),
3498
3514
  toolName: toolCall.function.name,
3499
3515
  input: toolCall.function.arguments,
3500
- providerMetadata: {
3516
+ providerMetadata: !reasoningDetailsAttachedToToolCall ? {
3501
3517
  openrouter: {
3502
3518
  reasoning_details: accumulatedReasoningDetails
3503
3519
  }
3504
- }
3520
+ } : void 0
3505
3521
  });
3522
+ reasoningDetailsAttachedToToolCall = true;
3506
3523
  toolCall.sent = true;
3507
3524
  }
3508
3525
  }
@@ -3535,12 +3552,13 @@ var OpenRouterChatLanguageModel = class {
3535
3552
  toolName: toolCall.function.name,
3536
3553
  // Coerce invalid arguments to an empty JSON object
3537
3554
  input: isParsableJson(toolCall.function.arguments) ? toolCall.function.arguments : "{}",
3538
- providerMetadata: {
3555
+ providerMetadata: !reasoningDetailsAttachedToToolCall ? {
3539
3556
  openrouter: {
3540
3557
  reasoning_details: accumulatedReasoningDetails
3541
3558
  }
3542
- }
3559
+ } : void 0
3543
3560
  });
3561
+ reasoningDetailsAttachedToToolCall = true;
3544
3562
  toolCall.sent = true;
3545
3563
  }
3546
3564
  }