@openrouter/ai-sdk-provider 2.0.4 → 2.1.1

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.
@@ -4,6 +4,9 @@ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
4
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
6
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __typeError = (msg) => {
8
+ throw TypeError(msg);
9
+ };
7
10
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
11
  var __spreadValues = (a, b) => {
9
12
  for (var prop in b || (b = {}))
@@ -29,6 +32,9 @@ var __objRest = (source, exclude) => {
29
32
  }
30
33
  return target;
31
34
  };
35
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
36
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
37
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
32
38
 
33
39
  // node_modules/.pnpm/@ai-sdk+provider@3.0.0/node_modules/@ai-sdk/provider/dist/index.mjs
34
40
  var marker = "vercel.ai.error";
@@ -2281,6 +2287,54 @@ function createFinishReason(unified, raw) {
2281
2287
  return { unified, raw };
2282
2288
  }
2283
2289
 
2290
+ // src/utils/reasoning-details-duplicate-tracker.ts
2291
+ var _seenKeys;
2292
+ var ReasoningDetailsDuplicateTracker = class {
2293
+ constructor() {
2294
+ __privateAdd(this, _seenKeys, /* @__PURE__ */ new Set());
2295
+ }
2296
+ /**
2297
+ * Attempts to track a detail.
2298
+ * Returns true if this is a NEW detail (not seen before and has valid key),
2299
+ * false if it was skipped (no valid key) or already seen (duplicate).
2300
+ */
2301
+ upsert(detail) {
2302
+ const key = this.getCanonicalKey(detail);
2303
+ if (key === null) {
2304
+ return false;
2305
+ }
2306
+ if (__privateGet(this, _seenKeys).has(key)) {
2307
+ return false;
2308
+ }
2309
+ __privateGet(this, _seenKeys).add(key);
2310
+ return true;
2311
+ }
2312
+ getCanonicalKey(detail) {
2313
+ switch (detail.type) {
2314
+ case "reasoning.summary" /* Summary */:
2315
+ return detail.summary;
2316
+ case "reasoning.encrypted" /* Encrypted */:
2317
+ if (detail.id) {
2318
+ return detail.id;
2319
+ }
2320
+ return detail.data;
2321
+ case "reasoning.text" /* Text */: {
2322
+ if (detail.text) {
2323
+ return detail.text;
2324
+ }
2325
+ if (detail.signature) {
2326
+ return detail.signature;
2327
+ }
2328
+ return null;
2329
+ }
2330
+ default: {
2331
+ return null;
2332
+ }
2333
+ }
2334
+ }
2335
+ };
2336
+ _seenKeys = new WeakMap();
2337
+
2284
2338
  // src/types/openrouter-chat-completions-input.ts
2285
2339
  var OPENROUTER_AUDIO_FORMATS = [
2286
2340
  "wav",
@@ -2412,6 +2466,7 @@ function getCacheControl(providerMetadata) {
2412
2466
  function convertToOpenRouterChatMessages(prompt) {
2413
2467
  var _a16, _b16, _c, _d, _e, _f, _g, _h;
2414
2468
  const messages = [];
2469
+ const reasoningDetailsTracker = new ReasoningDetailsDuplicateTracker();
2415
2470
  for (const { role, content, providerOptions } of prompt) {
2416
2471
  switch (role) {
2417
2472
  case "system": {
@@ -2554,7 +2609,17 @@ function convertToOpenRouterChatMessages(prompt) {
2554
2609
  const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
2555
2610
  const messageReasoningDetails = parsedProviderOptions.success ? (_e = (_d = parsedProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details : void 0;
2556
2611
  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);
2612
+ const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : findFirstReasoningDetails(content);
2613
+ let finalReasoningDetails;
2614
+ if (candidateReasoningDetails && candidateReasoningDetails.length > 0) {
2615
+ const uniqueDetails = [];
2616
+ for (const detail of candidateReasoningDetails) {
2617
+ if (reasoningDetailsTracker.upsert(detail)) {
2618
+ uniqueDetails.push(detail);
2619
+ }
2620
+ }
2621
+ finalReasoningDetails = uniqueDetails.length > 0 ? uniqueDetails : void 0;
2622
+ }
2558
2623
  messages.push({
2559
2624
  role: "assistant",
2560
2625
  content: text,
@@ -2723,13 +2788,14 @@ var OpenRouterNonStreamChatCompletionResponseSchema = z7.union([
2723
2788
  annotations: z7.array(
2724
2789
  z7.union([
2725
2790
  // URL citation from web search
2791
+ // title, start_index, end_index are optional as some upstream providers may omit them
2726
2792
  z7.object({
2727
2793
  type: z7.literal("url_citation"),
2728
2794
  url_citation: z7.object({
2729
- end_index: z7.number(),
2730
- start_index: z7.number(),
2731
- title: z7.string(),
2732
2795
  url: z7.string(),
2796
+ title: z7.string().optional(),
2797
+ start_index: z7.number().optional(),
2798
+ end_index: z7.number().optional(),
2733
2799
  content: z7.string().optional()
2734
2800
  }).passthrough()
2735
2801
  }).passthrough(),
@@ -2806,13 +2872,14 @@ var OpenRouterStreamChatCompletionChunkSchema = z7.union([
2806
2872
  annotations: z7.array(
2807
2873
  z7.union([
2808
2874
  // URL citation from web search
2875
+ // title, start_index, end_index are optional as some upstream providers may omit them
2809
2876
  z7.object({
2810
2877
  type: z7.literal("url_citation"),
2811
2878
  url_citation: z7.object({
2812
- end_index: z7.number(),
2813
- start_index: z7.number(),
2814
- title: z7.string(),
2815
2879
  url: z7.string(),
2880
+ title: z7.string().optional(),
2881
+ start_index: z7.number().optional(),
2882
+ end_index: z7.number().optional(),
2816
2883
  content: z7.string().optional()
2817
2884
  }).passthrough()
2818
2885
  }).passthrough(),
@@ -2959,7 +3026,7 @@ var OpenRouterChatLanguageModel = class {
2959
3026
  return baseArgs;
2960
3027
  }
2961
3028
  async doGenerate(options) {
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;
3029
+ 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, _y, _z, _A, _B;
2963
3030
  const providerOptions = options.providerOptions || {};
2964
3031
  const openrouterOptions = providerOptions.openrouter || {};
2965
3032
  const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
@@ -3009,7 +3076,8 @@ var OpenRouterChatLanguageModel = class {
3009
3076
  total: (_d = response.usage.completion_tokens) != null ? _d : 0,
3010
3077
  text: void 0,
3011
3078
  reasoning: (_f = (_e = response.usage.completion_tokens_details) == null ? void 0 : _e.reasoning_tokens) != null ? _f : void 0
3012
- }
3079
+ },
3080
+ raw: response.usage
3013
3081
  } : {
3014
3082
  inputTokens: {
3015
3083
  total: 0,
@@ -3021,7 +3089,8 @@ var OpenRouterChatLanguageModel = class {
3021
3089
  total: 0,
3022
3090
  text: void 0,
3023
3091
  reasoning: void 0
3024
- }
3092
+ },
3093
+ raw: void 0
3025
3094
  };
3026
3095
  const reasoningDetails = (_g = choice.message.reasoning_details) != null ? _g : [];
3027
3096
  const reasoning = reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
@@ -3121,17 +3190,19 @@ var OpenRouterChatLanguageModel = class {
3121
3190
  sourceType: "url",
3122
3191
  id: annotation.url_citation.url,
3123
3192
  url: annotation.url_citation.url,
3124
- title: annotation.url_citation.title,
3193
+ title: (_j = annotation.url_citation.title) != null ? _j : "",
3125
3194
  providerMetadata: {
3126
3195
  openrouter: {
3127
- content: annotation.url_citation.content || ""
3196
+ content: (_k = annotation.url_citation.content) != null ? _k : "",
3197
+ startIndex: (_l = annotation.url_citation.start_index) != null ? _l : 0,
3198
+ endIndex: (_m = annotation.url_citation.end_index) != null ? _m : 0
3128
3199
  }
3129
3200
  }
3130
3201
  });
3131
3202
  }
3132
3203
  }
3133
3204
  }
3134
- const fileAnnotations = (_j = choice.message.annotations) == null ? void 0 : _j.filter(
3205
+ const fileAnnotations = (_n = choice.message.annotations) == null ? void 0 : _n.filter(
3135
3206
  (a) => a.type === "file"
3136
3207
  );
3137
3208
  const hasToolCalls = choice.message.tool_calls && choice.message.tool_calls.length > 0;
@@ -3139,7 +3210,7 @@ var OpenRouterChatLanguageModel = class {
3139
3210
  (d) => d.type === "reasoning.encrypted" /* Encrypted */ && d.data
3140
3211
  );
3141
3212
  const shouldOverrideFinishReason = hasToolCalls && hasEncryptedReasoning && choice.finish_reason === "stop";
3142
- const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_k = choice.finish_reason) != null ? _k : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3213
+ const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_o = choice.finish_reason) != null ? _o : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3143
3214
  return {
3144
3215
  content,
3145
3216
  finishReason: effectiveFinishReason,
@@ -3147,23 +3218,22 @@ var OpenRouterChatLanguageModel = class {
3147
3218
  warnings: [],
3148
3219
  providerMetadata: {
3149
3220
  openrouter: OpenRouterProviderMetadataSchema.parse({
3150
- provider: (_l = response.provider) != null ? _l : "",
3151
- reasoning_details: (_m = choice.message.reasoning_details) != null ? _m : [],
3221
+ provider: (_p = response.provider) != null ? _p : "",
3222
+ reasoning_details: (_q = choice.message.reasoning_details) != null ? _q : [],
3152
3223
  annotations: fileAnnotations && fileAnnotations.length > 0 ? fileAnnotations : void 0,
3153
- usage: __spreadValues(__spreadValues(__spreadValues({
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 ? {
3224
+ usage: __spreadValues(__spreadValues(__spreadValues(__spreadValues({
3225
+ promptTokens: (_r = usageInfo.inputTokens.total) != null ? _r : 0,
3226
+ completionTokens: (_s = usageInfo.outputTokens.total) != null ? _s : 0,
3227
+ totalTokens: ((_t = usageInfo.inputTokens.total) != null ? _t : 0) + ((_u = usageInfo.outputTokens.total) != null ? _u : 0)
3228
+ }, ((_v = response.usage) == null ? void 0 : _v.cost) != null ? { cost: response.usage.cost } : {}), ((_x = (_w = response.usage) == null ? void 0 : _w.prompt_tokens_details) == null ? void 0 : _x.cached_tokens) != null ? {
3159
3229
  promptTokensDetails: {
3160
3230
  cachedTokens: response.usage.prompt_tokens_details.cached_tokens
3161
3231
  }
3162
- } : {}), ((_v = (_u = response.usage) == null ? void 0 : _u.completion_tokens_details) == null ? void 0 : _v.reasoning_tokens) != null ? {
3232
+ } : {}), ((_z = (_y = response.usage) == null ? void 0 : _y.completion_tokens_details) == null ? void 0 : _z.reasoning_tokens) != null ? {
3163
3233
  completionTokensDetails: {
3164
3234
  reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
3165
3235
  }
3166
- } : {}), ((_x = (_w = response.usage) == null ? void 0 : _w.cost_details) == null ? void 0 : _x.upstream_inference_cost) != null ? {
3236
+ } : {}), ((_B = (_A = response.usage) == null ? void 0 : _A.cost_details) == null ? void 0 : _B.upstream_inference_cost) != null ? {
3167
3237
  costDetails: {
3168
3238
  upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
3169
3239
  }
@@ -3216,9 +3286,11 @@ var OpenRouterChatLanguageModel = class {
3216
3286
  total: void 0,
3217
3287
  text: void 0,
3218
3288
  reasoning: void 0
3219
- }
3289
+ },
3290
+ raw: void 0
3220
3291
  };
3221
3292
  const openrouterUsage = {};
3293
+ let rawUsage;
3222
3294
  const accumulatedReasoningDetails = [];
3223
3295
  let reasoningDetailsAttachedToToolCall = false;
3224
3296
  const accumulatedFileAnnotations = [];
@@ -3232,7 +3304,10 @@ var OpenRouterChatLanguageModel = class {
3232
3304
  stream: response.pipeThrough(
3233
3305
  new TransformStream({
3234
3306
  transform(chunk, controller) {
3235
- var _a17, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
3307
+ var _a17, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
3308
+ if (options.includeRawChunks) {
3309
+ controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
3310
+ }
3236
3311
  if (!chunk.success) {
3237
3312
  finishReason = createFinishReason("error");
3238
3313
  controller.enqueue({ type: "error", error: chunk.error });
@@ -3263,6 +3338,7 @@ var OpenRouterChatLanguageModel = class {
3263
3338
  if (value.usage != null) {
3264
3339
  usage.inputTokens.total = value.usage.prompt_tokens;
3265
3340
  usage.outputTokens.total = value.usage.completion_tokens;
3341
+ rawUsage = value.usage;
3266
3342
  openrouterUsage.promptTokens = value.usage.prompt_tokens;
3267
3343
  if (value.usage.prompt_tokens_details) {
3268
3344
  const cachedInputTokens = (_a17 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a17 : 0;
@@ -3279,7 +3355,9 @@ var OpenRouterChatLanguageModel = class {
3279
3355
  reasoningTokens
3280
3356
  };
3281
3357
  }
3282
- openrouterUsage.cost = value.usage.cost;
3358
+ if (value.usage.cost != null) {
3359
+ openrouterUsage.cost = value.usage.cost;
3360
+ }
3283
3361
  openrouterUsage.totalTokens = value.usage.total_tokens;
3284
3362
  const upstreamInferenceCost = (_c = value.usage.cost_details) == null ? void 0 : _c.upstream_inference_cost;
3285
3363
  if (upstreamInferenceCost != null) {
@@ -3392,10 +3470,12 @@ var OpenRouterChatLanguageModel = class {
3392
3470
  sourceType: "url",
3393
3471
  id: annotation.url_citation.url,
3394
3472
  url: annotation.url_citation.url,
3395
- title: annotation.url_citation.title,
3473
+ title: (_d = annotation.url_citation.title) != null ? _d : "",
3396
3474
  providerMetadata: {
3397
3475
  openrouter: {
3398
- content: annotation.url_citation.content || ""
3476
+ content: (_e = annotation.url_citation.content) != null ? _e : "",
3477
+ startIndex: (_f = annotation.url_citation.start_index) != null ? _f : 0,
3478
+ endIndex: (_g = annotation.url_citation.end_index) != null ? _g : 0
3399
3479
  }
3400
3480
  }
3401
3481
  });
@@ -3411,7 +3491,7 @@ var OpenRouterChatLanguageModel = class {
3411
3491
  }
3412
3492
  if (delta.tool_calls != null) {
3413
3493
  for (const toolCallDelta of delta.tool_calls) {
3414
- const index = (_d = toolCallDelta.index) != null ? _d : toolCalls.length - 1;
3494
+ const index = (_h = toolCallDelta.index) != null ? _h : toolCalls.length - 1;
3415
3495
  if (toolCalls[index] == null) {
3416
3496
  if (toolCallDelta.type !== "function") {
3417
3497
  throw new InvalidResponseDataError({
@@ -3425,7 +3505,7 @@ var OpenRouterChatLanguageModel = class {
3425
3505
  message: `Expected 'id' to be a string.`
3426
3506
  });
3427
3507
  }
3428
- if (((_e = toolCallDelta.function) == null ? void 0 : _e.name) == null) {
3508
+ if (((_i = toolCallDelta.function) == null ? void 0 : _i.name) == null) {
3429
3509
  throw new InvalidResponseDataError({
3430
3510
  data: toolCallDelta,
3431
3511
  message: `Expected 'function.name' to be a string.`
@@ -3436,7 +3516,7 @@ var OpenRouterChatLanguageModel = class {
3436
3516
  type: "function",
3437
3517
  function: {
3438
3518
  name: toolCallDelta.function.name,
3439
- arguments: (_f = toolCallDelta.function.arguments) != null ? _f : ""
3519
+ arguments: (_j = toolCallDelta.function.arguments) != null ? _j : ""
3440
3520
  },
3441
3521
  inputStarted: false,
3442
3522
  sent: false
@@ -3448,7 +3528,7 @@ var OpenRouterChatLanguageModel = class {
3448
3528
  message: `Tool call at index ${index} is missing after creation.`
3449
3529
  });
3450
3530
  }
3451
- if (((_g = toolCall2.function) == null ? void 0 : _g.name) != null && ((_h = toolCall2.function) == null ? void 0 : _h.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
3531
+ if (((_k = toolCall2.function) == null ? void 0 : _k.name) != null && ((_l = toolCall2.function) == null ? void 0 : _l.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
3452
3532
  toolCall2.inputStarted = true;
3453
3533
  controller.enqueue({
3454
3534
  type: "tool-input-start",
@@ -3499,18 +3579,18 @@ var OpenRouterChatLanguageModel = class {
3499
3579
  toolName: toolCall.function.name
3500
3580
  });
3501
3581
  }
3502
- if (((_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null) {
3503
- toolCall.function.arguments += (_k = (_j = toolCallDelta.function) == null ? void 0 : _j.arguments) != null ? _k : "";
3582
+ if (((_m = toolCallDelta.function) == null ? void 0 : _m.arguments) != null) {
3583
+ toolCall.function.arguments += (_o = (_n = toolCallDelta.function) == null ? void 0 : _n.arguments) != null ? _o : "";
3504
3584
  }
3505
3585
  controller.enqueue({
3506
3586
  type: "tool-input-delta",
3507
3587
  id: toolCall.id,
3508
- delta: (_l = toolCallDelta.function.arguments) != null ? _l : ""
3588
+ delta: (_p = toolCallDelta.function.arguments) != null ? _p : ""
3509
3589
  });
3510
- if (((_m = toolCall.function) == null ? void 0 : _m.name) != null && ((_n = toolCall.function) == null ? void 0 : _n.arguments) != null && isParsableJson(toolCall.function.arguments)) {
3590
+ if (((_q = toolCall.function) == null ? void 0 : _q.name) != null && ((_r = toolCall.function) == null ? void 0 : _r.arguments) != null && isParsableJson(toolCall.function.arguments)) {
3511
3591
  controller.enqueue({
3512
3592
  type: "tool-call",
3513
- toolCallId: (_o = toolCall.id) != null ? _o : generateId(),
3593
+ toolCallId: (_s = toolCall.id) != null ? _s : generateId(),
3514
3594
  toolName: toolCall.function.name,
3515
3595
  input: toolCall.function.arguments,
3516
3596
  providerMetadata: !reasoningDetailsAttachedToToolCall ? {
@@ -3587,6 +3667,7 @@ var OpenRouterChatLanguageModel = class {
3587
3667
  if (accumulatedFileAnnotations.length > 0) {
3588
3668
  openrouterMetadata.annotations = accumulatedFileAnnotations;
3589
3669
  }
3670
+ usage.raw = rawUsage;
3590
3671
  controller.enqueue({
3591
3672
  type: "finish",
3592
3673
  finishReason,
@@ -3714,6 +3795,7 @@ var OpenRouterCompletionChunkSchema = z8.union([
3714
3795
  z8.object({
3715
3796
  id: z8.string().optional(),
3716
3797
  model: z8.string().optional(),
3798
+ provider: z8.string().optional(),
3717
3799
  choices: z8.array(
3718
3800
  z8.object({
3719
3801
  text: z8.string(),
@@ -3821,7 +3903,7 @@ var OpenRouterCompletionLanguageModel = class {
3821
3903
  }, this.config.extraBody), this.settings.extraBody);
3822
3904
  }
3823
3905
  async doGenerate(options) {
3824
- var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k;
3906
+ 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, _y, _z, _A, _B;
3825
3907
  const providerOptions = options.providerOptions || {};
3826
3908
  const openrouterOptions = providerOptions.openrouter || {};
3827
3909
  const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
@@ -3878,9 +3960,32 @@ var OpenRouterCompletionLanguageModel = class {
3878
3960
  total: (_h = (_g = response.usage) == null ? void 0 : _g.completion_tokens) != null ? _h : 0,
3879
3961
  text: void 0,
3880
3962
  reasoning: (_k = (_j = (_i = response.usage) == null ? void 0 : _i.completion_tokens_details) == null ? void 0 : _j.reasoning_tokens) != null ? _k : void 0
3881
- }
3963
+ },
3964
+ raw: (_l = response.usage) != null ? _l : void 0
3882
3965
  },
3883
3966
  warnings: [],
3967
+ providerMetadata: {
3968
+ openrouter: OpenRouterProviderMetadataSchema.parse({
3969
+ provider: (_m = response.provider) != null ? _m : "",
3970
+ usage: __spreadValues(__spreadValues(__spreadValues(__spreadValues({
3971
+ promptTokens: (_o = (_n = response.usage) == null ? void 0 : _n.prompt_tokens) != null ? _o : 0,
3972
+ completionTokens: (_q = (_p = response.usage) == null ? void 0 : _p.completion_tokens) != null ? _q : 0,
3973
+ totalTokens: ((_s = (_r = response.usage) == null ? void 0 : _r.prompt_tokens) != null ? _s : 0) + ((_u = (_t = response.usage) == null ? void 0 : _t.completion_tokens) != null ? _u : 0)
3974
+ }, ((_v = response.usage) == null ? void 0 : _v.cost) != null ? { cost: response.usage.cost } : {}), ((_x = (_w = response.usage) == null ? void 0 : _w.prompt_tokens_details) == null ? void 0 : _x.cached_tokens) != null ? {
3975
+ promptTokensDetails: {
3976
+ cachedTokens: response.usage.prompt_tokens_details.cached_tokens
3977
+ }
3978
+ } : {}), ((_z = (_y = response.usage) == null ? void 0 : _y.completion_tokens_details) == null ? void 0 : _z.reasoning_tokens) != null ? {
3979
+ completionTokensDetails: {
3980
+ reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
3981
+ }
3982
+ } : {}), ((_B = (_A = response.usage) == null ? void 0 : _A.cost_details) == null ? void 0 : _B.upstream_inference_cost) != null ? {
3983
+ costDetails: {
3984
+ upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
3985
+ }
3986
+ } : {})
3987
+ })
3988
+ },
3884
3989
  response: {
3885
3990
  headers: responseHeaders
3886
3991
  }
@@ -3920,14 +4025,20 @@ var OpenRouterCompletionLanguageModel = class {
3920
4025
  total: void 0,
3921
4026
  text: void 0,
3922
4027
  reasoning: void 0
3923
- }
4028
+ },
4029
+ raw: void 0
3924
4030
  };
3925
4031
  const openrouterUsage = {};
4032
+ let provider;
4033
+ let rawUsage;
3926
4034
  return {
3927
4035
  stream: response.pipeThrough(
3928
4036
  new TransformStream({
3929
4037
  transform(chunk, controller) {
3930
4038
  var _a16, _b16, _c;
4039
+ if (options.includeRawChunks) {
4040
+ controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
4041
+ }
3931
4042
  if (!chunk.success) {
3932
4043
  finishReason = createFinishReason("error");
3933
4044
  controller.enqueue({ type: "error", error: chunk.error });
@@ -3939,9 +4050,13 @@ var OpenRouterCompletionLanguageModel = class {
3939
4050
  controller.enqueue({ type: "error", error: value.error });
3940
4051
  return;
3941
4052
  }
4053
+ if (value.provider) {
4054
+ provider = value.provider;
4055
+ }
3942
4056
  if (value.usage != null) {
3943
4057
  usage.inputTokens.total = value.usage.prompt_tokens;
3944
4058
  usage.outputTokens.total = value.usage.completion_tokens;
4059
+ rawUsage = value.usage;
3945
4060
  openrouterUsage.promptTokens = value.usage.prompt_tokens;
3946
4061
  if (value.usage.prompt_tokens_details) {
3947
4062
  const cachedInputTokens = (_a16 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a16 : 0;
@@ -3958,7 +4073,9 @@ var OpenRouterCompletionLanguageModel = class {
3958
4073
  reasoningTokens
3959
4074
  };
3960
4075
  }
3961
- openrouterUsage.cost = value.usage.cost;
4076
+ if (value.usage.cost != null) {
4077
+ openrouterUsage.cost = value.usage.cost;
4078
+ }
3962
4079
  openrouterUsage.totalTokens = value.usage.total_tokens;
3963
4080
  const upstreamInferenceCost = (_c = value.usage.cost_details) == null ? void 0 : _c.upstream_inference_cost;
3964
4081
  if (upstreamInferenceCost != null) {
@@ -3980,14 +4097,19 @@ var OpenRouterCompletionLanguageModel = class {
3980
4097
  }
3981
4098
  },
3982
4099
  flush(controller) {
4100
+ usage.raw = rawUsage;
4101
+ const openrouterMetadata = {
4102
+ usage: openrouterUsage
4103
+ };
4104
+ if (provider !== void 0) {
4105
+ openrouterMetadata.provider = provider;
4106
+ }
3983
4107
  controller.enqueue({
3984
4108
  type: "finish",
3985
4109
  finishReason,
3986
4110
  usage,
3987
4111
  providerMetadata: {
3988
- openrouter: {
3989
- usage: openrouterUsage
3990
- }
4112
+ openrouter: openrouterMetadata
3991
4113
  }
3992
4114
  });
3993
4115
  }
@@ -3999,8 +4121,227 @@ var OpenRouterCompletionLanguageModel = class {
3999
4121
  };
4000
4122
  }
4001
4123
  };
4124
+
4125
+ // src/embedding/schemas.ts
4126
+ import { z as z9 } from "zod/v4";
4127
+ var openrouterEmbeddingUsageSchema = z9.object({
4128
+ prompt_tokens: z9.number(),
4129
+ total_tokens: z9.number(),
4130
+ cost: z9.number().optional()
4131
+ });
4132
+ var openrouterEmbeddingDataSchema = z9.object({
4133
+ object: z9.literal("embedding"),
4134
+ embedding: z9.array(z9.number()),
4135
+ index: z9.number().optional()
4136
+ });
4137
+ var OpenRouterEmbeddingResponseSchema = z9.object({
4138
+ id: z9.string().optional(),
4139
+ object: z9.literal("list"),
4140
+ data: z9.array(openrouterEmbeddingDataSchema),
4141
+ model: z9.string(),
4142
+ provider: z9.string().optional(),
4143
+ usage: openrouterEmbeddingUsageSchema.optional()
4144
+ });
4145
+
4146
+ // src/embedding/index.ts
4147
+ var OpenRouterEmbeddingModel = class {
4148
+ constructor(modelId, settings, config) {
4149
+ this.specificationVersion = "v3";
4150
+ this.provider = "openrouter";
4151
+ this.maxEmbeddingsPerCall = void 0;
4152
+ this.supportsParallelCalls = true;
4153
+ this.modelId = modelId;
4154
+ this.settings = settings;
4155
+ this.config = config;
4156
+ }
4157
+ async doEmbed(options) {
4158
+ var _a16, _b16, _c, _d, _e, _f;
4159
+ const { values, abortSignal, headers } = options;
4160
+ const args = __spreadValues(__spreadValues({
4161
+ model: this.modelId,
4162
+ input: values,
4163
+ user: this.settings.user,
4164
+ provider: this.settings.provider
4165
+ }, this.config.extraBody), this.settings.extraBody);
4166
+ const { value: responseValue, responseHeaders } = await postJsonToApi({
4167
+ url: this.config.url({
4168
+ path: "/embeddings",
4169
+ modelId: this.modelId
4170
+ }),
4171
+ headers: combineHeaders(this.config.headers(), headers),
4172
+ body: args,
4173
+ failedResponseHandler: openrouterFailedResponseHandler,
4174
+ successfulResponseHandler: createJsonResponseHandler(
4175
+ OpenRouterEmbeddingResponseSchema
4176
+ ),
4177
+ abortSignal,
4178
+ fetch: this.config.fetch
4179
+ });
4180
+ return {
4181
+ embeddings: responseValue.data.map((item) => item.embedding),
4182
+ usage: responseValue.usage ? { tokens: responseValue.usage.prompt_tokens } : void 0,
4183
+ providerMetadata: {
4184
+ openrouter: OpenRouterProviderMetadataSchema.parse({
4185
+ provider: (_a16 = responseValue.provider) != null ? _a16 : "",
4186
+ usage: __spreadValues({
4187
+ promptTokens: (_c = (_b16 = responseValue.usage) == null ? void 0 : _b16.prompt_tokens) != null ? _c : 0,
4188
+ completionTokens: 0,
4189
+ totalTokens: (_e = (_d = responseValue.usage) == null ? void 0 : _d.total_tokens) != null ? _e : 0
4190
+ }, ((_f = responseValue.usage) == null ? void 0 : _f.cost) != null ? { cost: responseValue.usage.cost } : {})
4191
+ })
4192
+ },
4193
+ response: {
4194
+ headers: responseHeaders,
4195
+ body: responseValue
4196
+ },
4197
+ warnings: []
4198
+ };
4199
+ }
4200
+ };
4201
+
4202
+ // src/image/schemas.ts
4203
+ import { z as z10 } from "zod/v4";
4204
+ var OpenRouterImageResponseSchema = z10.object({
4205
+ id: z10.string().optional(),
4206
+ object: z10.string().optional(),
4207
+ created: z10.number().optional(),
4208
+ model: z10.string(),
4209
+ choices: z10.array(
4210
+ z10.object({
4211
+ index: z10.number(),
4212
+ message: z10.object({
4213
+ role: z10.string(),
4214
+ content: z10.string().nullable().optional(),
4215
+ images: z10.array(
4216
+ z10.object({
4217
+ type: z10.literal("image_url"),
4218
+ image_url: z10.object({
4219
+ url: z10.string()
4220
+ })
4221
+ }).passthrough()
4222
+ ).optional()
4223
+ }).passthrough(),
4224
+ finish_reason: z10.string().nullable().optional()
4225
+ }).passthrough()
4226
+ ),
4227
+ usage: z10.object({
4228
+ prompt_tokens: z10.number(),
4229
+ completion_tokens: z10.number(),
4230
+ total_tokens: z10.number()
4231
+ }).passthrough().optional()
4232
+ }).passthrough();
4233
+
4234
+ // src/image/index.ts
4235
+ var OpenRouterImageModel = class {
4236
+ constructor(modelId, settings, config) {
4237
+ this.specificationVersion = "v3";
4238
+ this.provider = "openrouter";
4239
+ this.maxImagesPerCall = 1;
4240
+ this.modelId = modelId;
4241
+ this.settings = settings;
4242
+ this.config = config;
4243
+ }
4244
+ async doGenerate(options) {
4245
+ var _a16;
4246
+ const {
4247
+ prompt,
4248
+ n,
4249
+ size,
4250
+ aspectRatio,
4251
+ seed,
4252
+ files,
4253
+ mask,
4254
+ abortSignal,
4255
+ headers,
4256
+ providerOptions
4257
+ } = options;
4258
+ const openrouterOptions = (providerOptions == null ? void 0 : providerOptions.openrouter) || {};
4259
+ const warnings = [];
4260
+ if (files !== void 0 && files.length > 0) {
4261
+ throw new UnsupportedFunctionalityError({
4262
+ functionality: "image editing (files parameter)"
4263
+ });
4264
+ }
4265
+ if (mask !== void 0) {
4266
+ throw new UnsupportedFunctionalityError({
4267
+ functionality: "image inpainting (mask parameter)"
4268
+ });
4269
+ }
4270
+ if (n > 1) {
4271
+ warnings.push({
4272
+ type: "unsupported",
4273
+ feature: "n > 1",
4274
+ details: `OpenRouter image generation returns 1 image per call. Requested ${n} images.`
4275
+ });
4276
+ }
4277
+ if (size !== void 0) {
4278
+ warnings.push({
4279
+ type: "unsupported",
4280
+ feature: "size",
4281
+ details: "Use aspectRatio instead. Size parameter is not supported by OpenRouter image generation."
4282
+ });
4283
+ }
4284
+ const imageConfig = aspectRatio !== void 0 ? { aspect_ratio: aspectRatio } : void 0;
4285
+ const body = __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
4286
+ model: this.modelId,
4287
+ messages: [
4288
+ {
4289
+ role: "user",
4290
+ content: prompt != null ? prompt : ""
4291
+ }
4292
+ ],
4293
+ modalities: ["image", "text"]
4294
+ }, imageConfig !== void 0 && { image_config: imageConfig }), seed !== void 0 && { seed }), this.settings.user !== void 0 && { user: this.settings.user }), this.settings.provider !== void 0 && {
4295
+ provider: this.settings.provider
4296
+ }), this.config.extraBody), this.settings.extraBody), openrouterOptions);
4297
+ const { value: responseValue, responseHeaders } = await postJsonToApi({
4298
+ url: this.config.url({
4299
+ path: "/chat/completions",
4300
+ modelId: this.modelId
4301
+ }),
4302
+ headers: combineHeaders(this.config.headers(), headers),
4303
+ body,
4304
+ failedResponseHandler: openrouterFailedResponseHandler,
4305
+ successfulResponseHandler: createJsonResponseHandler(
4306
+ OpenRouterImageResponseSchema
4307
+ ),
4308
+ abortSignal,
4309
+ fetch: this.config.fetch
4310
+ });
4311
+ const choice = responseValue.choices[0];
4312
+ if (!choice) {
4313
+ throw new NoContentGeneratedError({
4314
+ message: "No choice in response"
4315
+ });
4316
+ }
4317
+ const images = [];
4318
+ if ((_a16 = choice.message) == null ? void 0 : _a16.images) {
4319
+ for (const image of choice.message.images) {
4320
+ const dataUrl = image.image_url.url;
4321
+ images.push(getBase64FromDataUrl(dataUrl));
4322
+ }
4323
+ }
4324
+ const usage = responseValue.usage ? {
4325
+ inputTokens: responseValue.usage.prompt_tokens,
4326
+ outputTokens: responseValue.usage.completion_tokens,
4327
+ totalTokens: responseValue.usage.total_tokens
4328
+ } : void 0;
4329
+ return {
4330
+ images,
4331
+ warnings,
4332
+ response: {
4333
+ timestamp: /* @__PURE__ */ new Date(),
4334
+ modelId: responseValue.model,
4335
+ headers: responseHeaders
4336
+ },
4337
+ usage
4338
+ };
4339
+ }
4340
+ };
4002
4341
  export {
4003
4342
  OpenRouterChatLanguageModel,
4004
- OpenRouterCompletionLanguageModel
4343
+ OpenRouterCompletionLanguageModel,
4344
+ OpenRouterEmbeddingModel,
4345
+ OpenRouterImageModel
4005
4346
  };
4006
4347
  //# sourceMappingURL=index.mjs.map