@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.
@@ -9,6 +9,9 @@ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
9
  var __getProtoOf = Object.getPrototypeOf;
10
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
11
11
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __typeError = (msg) => {
13
+ throw TypeError(msg);
14
+ };
12
15
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
16
  var __spreadValues = (a, b) => {
14
17
  for (var prop in b || (b = {}))
@@ -55,12 +58,17 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
55
58
  mod
56
59
  ));
57
60
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
61
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
62
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
63
+ 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);
58
64
 
59
65
  // src/internal/index.ts
60
66
  var index_exports = {};
61
67
  __export(index_exports, {
62
68
  OpenRouterChatLanguageModel: () => OpenRouterChatLanguageModel,
63
- OpenRouterCompletionLanguageModel: () => OpenRouterCompletionLanguageModel
69
+ OpenRouterCompletionLanguageModel: () => OpenRouterCompletionLanguageModel,
70
+ OpenRouterEmbeddingModel: () => OpenRouterEmbeddingModel,
71
+ OpenRouterImageModel: () => OpenRouterImageModel
64
72
  });
65
73
  module.exports = __toCommonJS(index_exports);
66
74
 
@@ -2313,6 +2321,54 @@ function createFinishReason(unified, raw) {
2313
2321
  return { unified, raw };
2314
2322
  }
2315
2323
 
2324
+ // src/utils/reasoning-details-duplicate-tracker.ts
2325
+ var _seenKeys;
2326
+ var ReasoningDetailsDuplicateTracker = class {
2327
+ constructor() {
2328
+ __privateAdd(this, _seenKeys, /* @__PURE__ */ new Set());
2329
+ }
2330
+ /**
2331
+ * Attempts to track a detail.
2332
+ * Returns true if this is a NEW detail (not seen before and has valid key),
2333
+ * false if it was skipped (no valid key) or already seen (duplicate).
2334
+ */
2335
+ upsert(detail) {
2336
+ const key = this.getCanonicalKey(detail);
2337
+ if (key === null) {
2338
+ return false;
2339
+ }
2340
+ if (__privateGet(this, _seenKeys).has(key)) {
2341
+ return false;
2342
+ }
2343
+ __privateGet(this, _seenKeys).add(key);
2344
+ return true;
2345
+ }
2346
+ getCanonicalKey(detail) {
2347
+ switch (detail.type) {
2348
+ case "reasoning.summary" /* Summary */:
2349
+ return detail.summary;
2350
+ case "reasoning.encrypted" /* Encrypted */:
2351
+ if (detail.id) {
2352
+ return detail.id;
2353
+ }
2354
+ return detail.data;
2355
+ case "reasoning.text" /* Text */: {
2356
+ if (detail.text) {
2357
+ return detail.text;
2358
+ }
2359
+ if (detail.signature) {
2360
+ return detail.signature;
2361
+ }
2362
+ return null;
2363
+ }
2364
+ default: {
2365
+ return null;
2366
+ }
2367
+ }
2368
+ }
2369
+ };
2370
+ _seenKeys = new WeakMap();
2371
+
2316
2372
  // src/types/openrouter-chat-completions-input.ts
2317
2373
  var OPENROUTER_AUDIO_FORMATS = [
2318
2374
  "wav",
@@ -2444,6 +2500,7 @@ function getCacheControl(providerMetadata) {
2444
2500
  function convertToOpenRouterChatMessages(prompt) {
2445
2501
  var _a16, _b16, _c, _d, _e, _f, _g, _h;
2446
2502
  const messages = [];
2503
+ const reasoningDetailsTracker = new ReasoningDetailsDuplicateTracker();
2447
2504
  for (const { role, content, providerOptions } of prompt) {
2448
2505
  switch (role) {
2449
2506
  case "system": {
@@ -2586,7 +2643,17 @@ function convertToOpenRouterChatMessages(prompt) {
2586
2643
  const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
2587
2644
  const messageReasoningDetails = parsedProviderOptions.success ? (_e = (_d = parsedProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details : void 0;
2588
2645
  const messageAnnotations = parsedProviderOptions.success ? (_g = (_f = parsedProviderOptions.data) == null ? void 0 : _f.openrouter) == null ? void 0 : _g.annotations : void 0;
2589
- const finalReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : findFirstReasoningDetails(content);
2646
+ const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : findFirstReasoningDetails(content);
2647
+ let finalReasoningDetails;
2648
+ if (candidateReasoningDetails && candidateReasoningDetails.length > 0) {
2649
+ const uniqueDetails = [];
2650
+ for (const detail of candidateReasoningDetails) {
2651
+ if (reasoningDetailsTracker.upsert(detail)) {
2652
+ uniqueDetails.push(detail);
2653
+ }
2654
+ }
2655
+ finalReasoningDetails = uniqueDetails.length > 0 ? uniqueDetails : void 0;
2656
+ }
2590
2657
  messages.push({
2591
2658
  role: "assistant",
2592
2659
  content: text,
@@ -2755,13 +2822,14 @@ var OpenRouterNonStreamChatCompletionResponseSchema = import_v46.z.union([
2755
2822
  annotations: import_v46.z.array(
2756
2823
  import_v46.z.union([
2757
2824
  // URL citation from web search
2825
+ // title, start_index, end_index are optional as some upstream providers may omit them
2758
2826
  import_v46.z.object({
2759
2827
  type: import_v46.z.literal("url_citation"),
2760
2828
  url_citation: import_v46.z.object({
2761
- end_index: import_v46.z.number(),
2762
- start_index: import_v46.z.number(),
2763
- title: import_v46.z.string(),
2764
2829
  url: import_v46.z.string(),
2830
+ title: import_v46.z.string().optional(),
2831
+ start_index: import_v46.z.number().optional(),
2832
+ end_index: import_v46.z.number().optional(),
2765
2833
  content: import_v46.z.string().optional()
2766
2834
  }).passthrough()
2767
2835
  }).passthrough(),
@@ -2838,13 +2906,14 @@ var OpenRouterStreamChatCompletionChunkSchema = import_v46.z.union([
2838
2906
  annotations: import_v46.z.array(
2839
2907
  import_v46.z.union([
2840
2908
  // URL citation from web search
2909
+ // title, start_index, end_index are optional as some upstream providers may omit them
2841
2910
  import_v46.z.object({
2842
2911
  type: import_v46.z.literal("url_citation"),
2843
2912
  url_citation: import_v46.z.object({
2844
- end_index: import_v46.z.number(),
2845
- start_index: import_v46.z.number(),
2846
- title: import_v46.z.string(),
2847
2913
  url: import_v46.z.string(),
2914
+ title: import_v46.z.string().optional(),
2915
+ start_index: import_v46.z.number().optional(),
2916
+ end_index: import_v46.z.number().optional(),
2848
2917
  content: import_v46.z.string().optional()
2849
2918
  }).passthrough()
2850
2919
  }).passthrough(),
@@ -2991,7 +3060,7 @@ var OpenRouterChatLanguageModel = class {
2991
3060
  return baseArgs;
2992
3061
  }
2993
3062
  async doGenerate(options) {
2994
- 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;
3063
+ 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;
2995
3064
  const providerOptions = options.providerOptions || {};
2996
3065
  const openrouterOptions = providerOptions.openrouter || {};
2997
3066
  const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
@@ -3041,7 +3110,8 @@ var OpenRouterChatLanguageModel = class {
3041
3110
  total: (_d = response.usage.completion_tokens) != null ? _d : 0,
3042
3111
  text: void 0,
3043
3112
  reasoning: (_f = (_e = response.usage.completion_tokens_details) == null ? void 0 : _e.reasoning_tokens) != null ? _f : void 0
3044
- }
3113
+ },
3114
+ raw: response.usage
3045
3115
  } : {
3046
3116
  inputTokens: {
3047
3117
  total: 0,
@@ -3053,7 +3123,8 @@ var OpenRouterChatLanguageModel = class {
3053
3123
  total: 0,
3054
3124
  text: void 0,
3055
3125
  reasoning: void 0
3056
- }
3126
+ },
3127
+ raw: void 0
3057
3128
  };
3058
3129
  const reasoningDetails = (_g = choice.message.reasoning_details) != null ? _g : [];
3059
3130
  const reasoning = reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
@@ -3153,17 +3224,19 @@ var OpenRouterChatLanguageModel = class {
3153
3224
  sourceType: "url",
3154
3225
  id: annotation.url_citation.url,
3155
3226
  url: annotation.url_citation.url,
3156
- title: annotation.url_citation.title,
3227
+ title: (_j = annotation.url_citation.title) != null ? _j : "",
3157
3228
  providerMetadata: {
3158
3229
  openrouter: {
3159
- content: annotation.url_citation.content || ""
3230
+ content: (_k = annotation.url_citation.content) != null ? _k : "",
3231
+ startIndex: (_l = annotation.url_citation.start_index) != null ? _l : 0,
3232
+ endIndex: (_m = annotation.url_citation.end_index) != null ? _m : 0
3160
3233
  }
3161
3234
  }
3162
3235
  });
3163
3236
  }
3164
3237
  }
3165
3238
  }
3166
- const fileAnnotations = (_j = choice.message.annotations) == null ? void 0 : _j.filter(
3239
+ const fileAnnotations = (_n = choice.message.annotations) == null ? void 0 : _n.filter(
3167
3240
  (a) => a.type === "file"
3168
3241
  );
3169
3242
  const hasToolCalls = choice.message.tool_calls && choice.message.tool_calls.length > 0;
@@ -3171,7 +3244,7 @@ var OpenRouterChatLanguageModel = class {
3171
3244
  (d) => d.type === "reasoning.encrypted" /* Encrypted */ && d.data
3172
3245
  );
3173
3246
  const shouldOverrideFinishReason = hasToolCalls && hasEncryptedReasoning && choice.finish_reason === "stop";
3174
- const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_k = choice.finish_reason) != null ? _k : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3247
+ const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_o = choice.finish_reason) != null ? _o : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3175
3248
  return {
3176
3249
  content,
3177
3250
  finishReason: effectiveFinishReason,
@@ -3179,23 +3252,22 @@ var OpenRouterChatLanguageModel = class {
3179
3252
  warnings: [],
3180
3253
  providerMetadata: {
3181
3254
  openrouter: OpenRouterProviderMetadataSchema.parse({
3182
- provider: (_l = response.provider) != null ? _l : "",
3183
- reasoning_details: (_m = choice.message.reasoning_details) != null ? _m : [],
3255
+ provider: (_p = response.provider) != null ? _p : "",
3256
+ reasoning_details: (_q = choice.message.reasoning_details) != null ? _q : [],
3184
3257
  annotations: fileAnnotations && fileAnnotations.length > 0 ? fileAnnotations : void 0,
3185
- usage: __spreadValues(__spreadValues(__spreadValues({
3186
- promptTokens: (_n = usageInfo.inputTokens.total) != null ? _n : 0,
3187
- completionTokens: (_o = usageInfo.outputTokens.total) != null ? _o : 0,
3188
- totalTokens: ((_p = usageInfo.inputTokens.total) != null ? _p : 0) + ((_q = usageInfo.outputTokens.total) != null ? _q : 0),
3189
- cost: (_r = response.usage) == null ? void 0 : _r.cost
3190
- }, ((_t = (_s = response.usage) == null ? void 0 : _s.prompt_tokens_details) == null ? void 0 : _t.cached_tokens) != null ? {
3258
+ usage: __spreadValues(__spreadValues(__spreadValues(__spreadValues({
3259
+ promptTokens: (_r = usageInfo.inputTokens.total) != null ? _r : 0,
3260
+ completionTokens: (_s = usageInfo.outputTokens.total) != null ? _s : 0,
3261
+ totalTokens: ((_t = usageInfo.inputTokens.total) != null ? _t : 0) + ((_u = usageInfo.outputTokens.total) != null ? _u : 0)
3262
+ }, ((_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 ? {
3191
3263
  promptTokensDetails: {
3192
3264
  cachedTokens: response.usage.prompt_tokens_details.cached_tokens
3193
3265
  }
3194
- } : {}), ((_v = (_u = response.usage) == null ? void 0 : _u.completion_tokens_details) == null ? void 0 : _v.reasoning_tokens) != null ? {
3266
+ } : {}), ((_z = (_y = response.usage) == null ? void 0 : _y.completion_tokens_details) == null ? void 0 : _z.reasoning_tokens) != null ? {
3195
3267
  completionTokensDetails: {
3196
3268
  reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
3197
3269
  }
3198
- } : {}), ((_x = (_w = response.usage) == null ? void 0 : _w.cost_details) == null ? void 0 : _x.upstream_inference_cost) != null ? {
3270
+ } : {}), ((_B = (_A = response.usage) == null ? void 0 : _A.cost_details) == null ? void 0 : _B.upstream_inference_cost) != null ? {
3199
3271
  costDetails: {
3200
3272
  upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
3201
3273
  }
@@ -3248,9 +3320,11 @@ var OpenRouterChatLanguageModel = class {
3248
3320
  total: void 0,
3249
3321
  text: void 0,
3250
3322
  reasoning: void 0
3251
- }
3323
+ },
3324
+ raw: void 0
3252
3325
  };
3253
3326
  const openrouterUsage = {};
3327
+ let rawUsage;
3254
3328
  const accumulatedReasoningDetails = [];
3255
3329
  let reasoningDetailsAttachedToToolCall = false;
3256
3330
  const accumulatedFileAnnotations = [];
@@ -3264,7 +3338,10 @@ var OpenRouterChatLanguageModel = class {
3264
3338
  stream: response.pipeThrough(
3265
3339
  new TransformStream({
3266
3340
  transform(chunk, controller) {
3267
- var _a17, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
3341
+ var _a17, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
3342
+ if (options.includeRawChunks) {
3343
+ controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
3344
+ }
3268
3345
  if (!chunk.success) {
3269
3346
  finishReason = createFinishReason("error");
3270
3347
  controller.enqueue({ type: "error", error: chunk.error });
@@ -3295,6 +3372,7 @@ var OpenRouterChatLanguageModel = class {
3295
3372
  if (value.usage != null) {
3296
3373
  usage.inputTokens.total = value.usage.prompt_tokens;
3297
3374
  usage.outputTokens.total = value.usage.completion_tokens;
3375
+ rawUsage = value.usage;
3298
3376
  openrouterUsage.promptTokens = value.usage.prompt_tokens;
3299
3377
  if (value.usage.prompt_tokens_details) {
3300
3378
  const cachedInputTokens = (_a17 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a17 : 0;
@@ -3311,7 +3389,9 @@ var OpenRouterChatLanguageModel = class {
3311
3389
  reasoningTokens
3312
3390
  };
3313
3391
  }
3314
- openrouterUsage.cost = value.usage.cost;
3392
+ if (value.usage.cost != null) {
3393
+ openrouterUsage.cost = value.usage.cost;
3394
+ }
3315
3395
  openrouterUsage.totalTokens = value.usage.total_tokens;
3316
3396
  const upstreamInferenceCost = (_c = value.usage.cost_details) == null ? void 0 : _c.upstream_inference_cost;
3317
3397
  if (upstreamInferenceCost != null) {
@@ -3424,10 +3504,12 @@ var OpenRouterChatLanguageModel = class {
3424
3504
  sourceType: "url",
3425
3505
  id: annotation.url_citation.url,
3426
3506
  url: annotation.url_citation.url,
3427
- title: annotation.url_citation.title,
3507
+ title: (_d = annotation.url_citation.title) != null ? _d : "",
3428
3508
  providerMetadata: {
3429
3509
  openrouter: {
3430
- content: annotation.url_citation.content || ""
3510
+ content: (_e = annotation.url_citation.content) != null ? _e : "",
3511
+ startIndex: (_f = annotation.url_citation.start_index) != null ? _f : 0,
3512
+ endIndex: (_g = annotation.url_citation.end_index) != null ? _g : 0
3431
3513
  }
3432
3514
  }
3433
3515
  });
@@ -3443,7 +3525,7 @@ var OpenRouterChatLanguageModel = class {
3443
3525
  }
3444
3526
  if (delta.tool_calls != null) {
3445
3527
  for (const toolCallDelta of delta.tool_calls) {
3446
- const index = (_d = toolCallDelta.index) != null ? _d : toolCalls.length - 1;
3528
+ const index = (_h = toolCallDelta.index) != null ? _h : toolCalls.length - 1;
3447
3529
  if (toolCalls[index] == null) {
3448
3530
  if (toolCallDelta.type !== "function") {
3449
3531
  throw new InvalidResponseDataError({
@@ -3457,7 +3539,7 @@ var OpenRouterChatLanguageModel = class {
3457
3539
  message: `Expected 'id' to be a string.`
3458
3540
  });
3459
3541
  }
3460
- if (((_e = toolCallDelta.function) == null ? void 0 : _e.name) == null) {
3542
+ if (((_i = toolCallDelta.function) == null ? void 0 : _i.name) == null) {
3461
3543
  throw new InvalidResponseDataError({
3462
3544
  data: toolCallDelta,
3463
3545
  message: `Expected 'function.name' to be a string.`
@@ -3468,7 +3550,7 @@ var OpenRouterChatLanguageModel = class {
3468
3550
  type: "function",
3469
3551
  function: {
3470
3552
  name: toolCallDelta.function.name,
3471
- arguments: (_f = toolCallDelta.function.arguments) != null ? _f : ""
3553
+ arguments: (_j = toolCallDelta.function.arguments) != null ? _j : ""
3472
3554
  },
3473
3555
  inputStarted: false,
3474
3556
  sent: false
@@ -3480,7 +3562,7 @@ var OpenRouterChatLanguageModel = class {
3480
3562
  message: `Tool call at index ${index} is missing after creation.`
3481
3563
  });
3482
3564
  }
3483
- if (((_g = toolCall2.function) == null ? void 0 : _g.name) != null && ((_h = toolCall2.function) == null ? void 0 : _h.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
3565
+ if (((_k = toolCall2.function) == null ? void 0 : _k.name) != null && ((_l = toolCall2.function) == null ? void 0 : _l.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
3484
3566
  toolCall2.inputStarted = true;
3485
3567
  controller.enqueue({
3486
3568
  type: "tool-input-start",
@@ -3531,18 +3613,18 @@ var OpenRouterChatLanguageModel = class {
3531
3613
  toolName: toolCall.function.name
3532
3614
  });
3533
3615
  }
3534
- if (((_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null) {
3535
- toolCall.function.arguments += (_k = (_j = toolCallDelta.function) == null ? void 0 : _j.arguments) != null ? _k : "";
3616
+ if (((_m = toolCallDelta.function) == null ? void 0 : _m.arguments) != null) {
3617
+ toolCall.function.arguments += (_o = (_n = toolCallDelta.function) == null ? void 0 : _n.arguments) != null ? _o : "";
3536
3618
  }
3537
3619
  controller.enqueue({
3538
3620
  type: "tool-input-delta",
3539
3621
  id: toolCall.id,
3540
- delta: (_l = toolCallDelta.function.arguments) != null ? _l : ""
3622
+ delta: (_p = toolCallDelta.function.arguments) != null ? _p : ""
3541
3623
  });
3542
- if (((_m = toolCall.function) == null ? void 0 : _m.name) != null && ((_n = toolCall.function) == null ? void 0 : _n.arguments) != null && isParsableJson(toolCall.function.arguments)) {
3624
+ if (((_q = toolCall.function) == null ? void 0 : _q.name) != null && ((_r = toolCall.function) == null ? void 0 : _r.arguments) != null && isParsableJson(toolCall.function.arguments)) {
3543
3625
  controller.enqueue({
3544
3626
  type: "tool-call",
3545
- toolCallId: (_o = toolCall.id) != null ? _o : generateId(),
3627
+ toolCallId: (_s = toolCall.id) != null ? _s : generateId(),
3546
3628
  toolName: toolCall.function.name,
3547
3629
  input: toolCall.function.arguments,
3548
3630
  providerMetadata: !reasoningDetailsAttachedToToolCall ? {
@@ -3619,6 +3701,7 @@ var OpenRouterChatLanguageModel = class {
3619
3701
  if (accumulatedFileAnnotations.length > 0) {
3620
3702
  openrouterMetadata.annotations = accumulatedFileAnnotations;
3621
3703
  }
3704
+ usage.raw = rawUsage;
3622
3705
  controller.enqueue({
3623
3706
  type: "finish",
3624
3707
  finishReason,
@@ -3746,6 +3829,7 @@ var OpenRouterCompletionChunkSchema = import_v47.z.union([
3746
3829
  import_v47.z.object({
3747
3830
  id: import_v47.z.string().optional(),
3748
3831
  model: import_v47.z.string().optional(),
3832
+ provider: import_v47.z.string().optional(),
3749
3833
  choices: import_v47.z.array(
3750
3834
  import_v47.z.object({
3751
3835
  text: import_v47.z.string(),
@@ -3853,7 +3937,7 @@ var OpenRouterCompletionLanguageModel = class {
3853
3937
  }, this.config.extraBody), this.settings.extraBody);
3854
3938
  }
3855
3939
  async doGenerate(options) {
3856
- var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k;
3940
+ 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;
3857
3941
  const providerOptions = options.providerOptions || {};
3858
3942
  const openrouterOptions = providerOptions.openrouter || {};
3859
3943
  const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
@@ -3910,9 +3994,32 @@ var OpenRouterCompletionLanguageModel = class {
3910
3994
  total: (_h = (_g = response.usage) == null ? void 0 : _g.completion_tokens) != null ? _h : 0,
3911
3995
  text: void 0,
3912
3996
  reasoning: (_k = (_j = (_i = response.usage) == null ? void 0 : _i.completion_tokens_details) == null ? void 0 : _j.reasoning_tokens) != null ? _k : void 0
3913
- }
3997
+ },
3998
+ raw: (_l = response.usage) != null ? _l : void 0
3914
3999
  },
3915
4000
  warnings: [],
4001
+ providerMetadata: {
4002
+ openrouter: OpenRouterProviderMetadataSchema.parse({
4003
+ provider: (_m = response.provider) != null ? _m : "",
4004
+ usage: __spreadValues(__spreadValues(__spreadValues(__spreadValues({
4005
+ promptTokens: (_o = (_n = response.usage) == null ? void 0 : _n.prompt_tokens) != null ? _o : 0,
4006
+ completionTokens: (_q = (_p = response.usage) == null ? void 0 : _p.completion_tokens) != null ? _q : 0,
4007
+ 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)
4008
+ }, ((_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 ? {
4009
+ promptTokensDetails: {
4010
+ cachedTokens: response.usage.prompt_tokens_details.cached_tokens
4011
+ }
4012
+ } : {}), ((_z = (_y = response.usage) == null ? void 0 : _y.completion_tokens_details) == null ? void 0 : _z.reasoning_tokens) != null ? {
4013
+ completionTokensDetails: {
4014
+ reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
4015
+ }
4016
+ } : {}), ((_B = (_A = response.usage) == null ? void 0 : _A.cost_details) == null ? void 0 : _B.upstream_inference_cost) != null ? {
4017
+ costDetails: {
4018
+ upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
4019
+ }
4020
+ } : {})
4021
+ })
4022
+ },
3916
4023
  response: {
3917
4024
  headers: responseHeaders
3918
4025
  }
@@ -3952,14 +4059,20 @@ var OpenRouterCompletionLanguageModel = class {
3952
4059
  total: void 0,
3953
4060
  text: void 0,
3954
4061
  reasoning: void 0
3955
- }
4062
+ },
4063
+ raw: void 0
3956
4064
  };
3957
4065
  const openrouterUsage = {};
4066
+ let provider;
4067
+ let rawUsage;
3958
4068
  return {
3959
4069
  stream: response.pipeThrough(
3960
4070
  new TransformStream({
3961
4071
  transform(chunk, controller) {
3962
4072
  var _a16, _b16, _c;
4073
+ if (options.includeRawChunks) {
4074
+ controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
4075
+ }
3963
4076
  if (!chunk.success) {
3964
4077
  finishReason = createFinishReason("error");
3965
4078
  controller.enqueue({ type: "error", error: chunk.error });
@@ -3971,9 +4084,13 @@ var OpenRouterCompletionLanguageModel = class {
3971
4084
  controller.enqueue({ type: "error", error: value.error });
3972
4085
  return;
3973
4086
  }
4087
+ if (value.provider) {
4088
+ provider = value.provider;
4089
+ }
3974
4090
  if (value.usage != null) {
3975
4091
  usage.inputTokens.total = value.usage.prompt_tokens;
3976
4092
  usage.outputTokens.total = value.usage.completion_tokens;
4093
+ rawUsage = value.usage;
3977
4094
  openrouterUsage.promptTokens = value.usage.prompt_tokens;
3978
4095
  if (value.usage.prompt_tokens_details) {
3979
4096
  const cachedInputTokens = (_a16 = value.usage.prompt_tokens_details.cached_tokens) != null ? _a16 : 0;
@@ -3990,7 +4107,9 @@ var OpenRouterCompletionLanguageModel = class {
3990
4107
  reasoningTokens
3991
4108
  };
3992
4109
  }
3993
- openrouterUsage.cost = value.usage.cost;
4110
+ if (value.usage.cost != null) {
4111
+ openrouterUsage.cost = value.usage.cost;
4112
+ }
3994
4113
  openrouterUsage.totalTokens = value.usage.total_tokens;
3995
4114
  const upstreamInferenceCost = (_c = value.usage.cost_details) == null ? void 0 : _c.upstream_inference_cost;
3996
4115
  if (upstreamInferenceCost != null) {
@@ -4012,14 +4131,19 @@ var OpenRouterCompletionLanguageModel = class {
4012
4131
  }
4013
4132
  },
4014
4133
  flush(controller) {
4134
+ usage.raw = rawUsage;
4135
+ const openrouterMetadata = {
4136
+ usage: openrouterUsage
4137
+ };
4138
+ if (provider !== void 0) {
4139
+ openrouterMetadata.provider = provider;
4140
+ }
4015
4141
  controller.enqueue({
4016
4142
  type: "finish",
4017
4143
  finishReason,
4018
4144
  usage,
4019
4145
  providerMetadata: {
4020
- openrouter: {
4021
- usage: openrouterUsage
4022
- }
4146
+ openrouter: openrouterMetadata
4023
4147
  }
4024
4148
  });
4025
4149
  }
@@ -4031,9 +4155,228 @@ var OpenRouterCompletionLanguageModel = class {
4031
4155
  };
4032
4156
  }
4033
4157
  };
4158
+
4159
+ // src/embedding/schemas.ts
4160
+ var import_v48 = require("zod/v4");
4161
+ var openrouterEmbeddingUsageSchema = import_v48.z.object({
4162
+ prompt_tokens: import_v48.z.number(),
4163
+ total_tokens: import_v48.z.number(),
4164
+ cost: import_v48.z.number().optional()
4165
+ });
4166
+ var openrouterEmbeddingDataSchema = import_v48.z.object({
4167
+ object: import_v48.z.literal("embedding"),
4168
+ embedding: import_v48.z.array(import_v48.z.number()),
4169
+ index: import_v48.z.number().optional()
4170
+ });
4171
+ var OpenRouterEmbeddingResponseSchema = import_v48.z.object({
4172
+ id: import_v48.z.string().optional(),
4173
+ object: import_v48.z.literal("list"),
4174
+ data: import_v48.z.array(openrouterEmbeddingDataSchema),
4175
+ model: import_v48.z.string(),
4176
+ provider: import_v48.z.string().optional(),
4177
+ usage: openrouterEmbeddingUsageSchema.optional()
4178
+ });
4179
+
4180
+ // src/embedding/index.ts
4181
+ var OpenRouterEmbeddingModel = class {
4182
+ constructor(modelId, settings, config) {
4183
+ this.specificationVersion = "v3";
4184
+ this.provider = "openrouter";
4185
+ this.maxEmbeddingsPerCall = void 0;
4186
+ this.supportsParallelCalls = true;
4187
+ this.modelId = modelId;
4188
+ this.settings = settings;
4189
+ this.config = config;
4190
+ }
4191
+ async doEmbed(options) {
4192
+ var _a16, _b16, _c, _d, _e, _f;
4193
+ const { values, abortSignal, headers } = options;
4194
+ const args = __spreadValues(__spreadValues({
4195
+ model: this.modelId,
4196
+ input: values,
4197
+ user: this.settings.user,
4198
+ provider: this.settings.provider
4199
+ }, this.config.extraBody), this.settings.extraBody);
4200
+ const { value: responseValue, responseHeaders } = await postJsonToApi({
4201
+ url: this.config.url({
4202
+ path: "/embeddings",
4203
+ modelId: this.modelId
4204
+ }),
4205
+ headers: combineHeaders(this.config.headers(), headers),
4206
+ body: args,
4207
+ failedResponseHandler: openrouterFailedResponseHandler,
4208
+ successfulResponseHandler: createJsonResponseHandler(
4209
+ OpenRouterEmbeddingResponseSchema
4210
+ ),
4211
+ abortSignal,
4212
+ fetch: this.config.fetch
4213
+ });
4214
+ return {
4215
+ embeddings: responseValue.data.map((item) => item.embedding),
4216
+ usage: responseValue.usage ? { tokens: responseValue.usage.prompt_tokens } : void 0,
4217
+ providerMetadata: {
4218
+ openrouter: OpenRouterProviderMetadataSchema.parse({
4219
+ provider: (_a16 = responseValue.provider) != null ? _a16 : "",
4220
+ usage: __spreadValues({
4221
+ promptTokens: (_c = (_b16 = responseValue.usage) == null ? void 0 : _b16.prompt_tokens) != null ? _c : 0,
4222
+ completionTokens: 0,
4223
+ totalTokens: (_e = (_d = responseValue.usage) == null ? void 0 : _d.total_tokens) != null ? _e : 0
4224
+ }, ((_f = responseValue.usage) == null ? void 0 : _f.cost) != null ? { cost: responseValue.usage.cost } : {})
4225
+ })
4226
+ },
4227
+ response: {
4228
+ headers: responseHeaders,
4229
+ body: responseValue
4230
+ },
4231
+ warnings: []
4232
+ };
4233
+ }
4234
+ };
4235
+
4236
+ // src/image/schemas.ts
4237
+ var import_v49 = require("zod/v4");
4238
+ var OpenRouterImageResponseSchema = import_v49.z.object({
4239
+ id: import_v49.z.string().optional(),
4240
+ object: import_v49.z.string().optional(),
4241
+ created: import_v49.z.number().optional(),
4242
+ model: import_v49.z.string(),
4243
+ choices: import_v49.z.array(
4244
+ import_v49.z.object({
4245
+ index: import_v49.z.number(),
4246
+ message: import_v49.z.object({
4247
+ role: import_v49.z.string(),
4248
+ content: import_v49.z.string().nullable().optional(),
4249
+ images: import_v49.z.array(
4250
+ import_v49.z.object({
4251
+ type: import_v49.z.literal("image_url"),
4252
+ image_url: import_v49.z.object({
4253
+ url: import_v49.z.string()
4254
+ })
4255
+ }).passthrough()
4256
+ ).optional()
4257
+ }).passthrough(),
4258
+ finish_reason: import_v49.z.string().nullable().optional()
4259
+ }).passthrough()
4260
+ ),
4261
+ usage: import_v49.z.object({
4262
+ prompt_tokens: import_v49.z.number(),
4263
+ completion_tokens: import_v49.z.number(),
4264
+ total_tokens: import_v49.z.number()
4265
+ }).passthrough().optional()
4266
+ }).passthrough();
4267
+
4268
+ // src/image/index.ts
4269
+ var OpenRouterImageModel = class {
4270
+ constructor(modelId, settings, config) {
4271
+ this.specificationVersion = "v3";
4272
+ this.provider = "openrouter";
4273
+ this.maxImagesPerCall = 1;
4274
+ this.modelId = modelId;
4275
+ this.settings = settings;
4276
+ this.config = config;
4277
+ }
4278
+ async doGenerate(options) {
4279
+ var _a16;
4280
+ const {
4281
+ prompt,
4282
+ n,
4283
+ size,
4284
+ aspectRatio,
4285
+ seed,
4286
+ files,
4287
+ mask,
4288
+ abortSignal,
4289
+ headers,
4290
+ providerOptions
4291
+ } = options;
4292
+ const openrouterOptions = (providerOptions == null ? void 0 : providerOptions.openrouter) || {};
4293
+ const warnings = [];
4294
+ if (files !== void 0 && files.length > 0) {
4295
+ throw new UnsupportedFunctionalityError({
4296
+ functionality: "image editing (files parameter)"
4297
+ });
4298
+ }
4299
+ if (mask !== void 0) {
4300
+ throw new UnsupportedFunctionalityError({
4301
+ functionality: "image inpainting (mask parameter)"
4302
+ });
4303
+ }
4304
+ if (n > 1) {
4305
+ warnings.push({
4306
+ type: "unsupported",
4307
+ feature: "n > 1",
4308
+ details: `OpenRouter image generation returns 1 image per call. Requested ${n} images.`
4309
+ });
4310
+ }
4311
+ if (size !== void 0) {
4312
+ warnings.push({
4313
+ type: "unsupported",
4314
+ feature: "size",
4315
+ details: "Use aspectRatio instead. Size parameter is not supported by OpenRouter image generation."
4316
+ });
4317
+ }
4318
+ const imageConfig = aspectRatio !== void 0 ? { aspect_ratio: aspectRatio } : void 0;
4319
+ const body = __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({
4320
+ model: this.modelId,
4321
+ messages: [
4322
+ {
4323
+ role: "user",
4324
+ content: prompt != null ? prompt : ""
4325
+ }
4326
+ ],
4327
+ modalities: ["image", "text"]
4328
+ }, imageConfig !== void 0 && { image_config: imageConfig }), seed !== void 0 && { seed }), this.settings.user !== void 0 && { user: this.settings.user }), this.settings.provider !== void 0 && {
4329
+ provider: this.settings.provider
4330
+ }), this.config.extraBody), this.settings.extraBody), openrouterOptions);
4331
+ const { value: responseValue, responseHeaders } = await postJsonToApi({
4332
+ url: this.config.url({
4333
+ path: "/chat/completions",
4334
+ modelId: this.modelId
4335
+ }),
4336
+ headers: combineHeaders(this.config.headers(), headers),
4337
+ body,
4338
+ failedResponseHandler: openrouterFailedResponseHandler,
4339
+ successfulResponseHandler: createJsonResponseHandler(
4340
+ OpenRouterImageResponseSchema
4341
+ ),
4342
+ abortSignal,
4343
+ fetch: this.config.fetch
4344
+ });
4345
+ const choice = responseValue.choices[0];
4346
+ if (!choice) {
4347
+ throw new NoContentGeneratedError({
4348
+ message: "No choice in response"
4349
+ });
4350
+ }
4351
+ const images = [];
4352
+ if ((_a16 = choice.message) == null ? void 0 : _a16.images) {
4353
+ for (const image of choice.message.images) {
4354
+ const dataUrl = image.image_url.url;
4355
+ images.push(getBase64FromDataUrl(dataUrl));
4356
+ }
4357
+ }
4358
+ const usage = responseValue.usage ? {
4359
+ inputTokens: responseValue.usage.prompt_tokens,
4360
+ outputTokens: responseValue.usage.completion_tokens,
4361
+ totalTokens: responseValue.usage.total_tokens
4362
+ } : void 0;
4363
+ return {
4364
+ images,
4365
+ warnings,
4366
+ response: {
4367
+ timestamp: /* @__PURE__ */ new Date(),
4368
+ modelId: responseValue.model,
4369
+ headers: responseHeaders
4370
+ },
4371
+ usage
4372
+ };
4373
+ }
4374
+ };
4034
4375
  // Annotate the CommonJS export names for ESM import in node:
4035
4376
  0 && (module.exports = {
4036
4377
  OpenRouterChatLanguageModel,
4037
- OpenRouterCompletionLanguageModel
4378
+ OpenRouterCompletionLanguageModel,
4379
+ OpenRouterEmbeddingModel,
4380
+ OpenRouterImageModel
4038
4381
  });
4039
4382
  //# sourceMappingURL=index.js.map