@openrouter/ai-sdk-provider 1.2.8 → 1.3.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.
@@ -91,7 +91,7 @@ type OpenRouterUsageAccounting = {
91
91
  };
92
92
  totalTokens: number;
93
93
  cost?: number;
94
- costDetails: {
94
+ costDetails?: {
95
95
  upstreamInferenceCost: number;
96
96
  };
97
97
  };
@@ -224,6 +224,19 @@ type OpenRouterChatSettings = {
224
224
  */
225
225
  search_prompt?: string;
226
226
  };
227
+ /**
228
+ * Debug options for troubleshooting API requests.
229
+ * Only works with streaming requests.
230
+ * @see https://openrouter.ai/docs/api-reference/debugging
231
+ */
232
+ debug?: {
233
+ /**
234
+ * When true, echoes back the request body that was sent to the upstream provider.
235
+ * The debug data will be returned as the first chunk in the stream with a `debug.echo_upstream_body` field.
236
+ * Sensitive data like user IDs and base64 content will be redacted.
237
+ */
238
+ echo_upstream_body?: boolean;
239
+ };
227
240
  /**
228
241
  * Provider routing preferences to control request routing behavior
229
242
  */
@@ -259,7 +272,7 @@ type OpenRouterChatSettings = {
259
272
  /**
260
273
  * Sort providers by price, throughput, or latency
261
274
  */
262
- sort?: models.Sort;
275
+ sort?: models.ProviderSort;
263
276
  /**
264
277
  * Maximum pricing you want to pay for this request
265
278
  */
@@ -91,7 +91,7 @@ type OpenRouterUsageAccounting = {
91
91
  };
92
92
  totalTokens: number;
93
93
  cost?: number;
94
- costDetails: {
94
+ costDetails?: {
95
95
  upstreamInferenceCost: number;
96
96
  };
97
97
  };
@@ -224,6 +224,19 @@ type OpenRouterChatSettings = {
224
224
  */
225
225
  search_prompt?: string;
226
226
  };
227
+ /**
228
+ * Debug options for troubleshooting API requests.
229
+ * Only works with streaming requests.
230
+ * @see https://openrouter.ai/docs/api-reference/debugging
231
+ */
232
+ debug?: {
233
+ /**
234
+ * When true, echoes back the request body that was sent to the upstream provider.
235
+ * The debug data will be returned as the first chunk in the stream with a `debug.echo_upstream_body` field.
236
+ * Sensitive data like user IDs and base64 content will be redacted.
237
+ */
238
+ echo_upstream_body?: boolean;
239
+ };
227
240
  /**
228
241
  * Provider routing preferences to control request routing behavior
229
242
  */
@@ -259,7 +272,7 @@ type OpenRouterChatSettings = {
259
272
  /**
260
273
  * Sort providers by price, throughput, or latency
261
274
  */
262
- sort?: models.Sort;
275
+ sort?: models.ProviderSort;
263
276
  /**
264
277
  * Maximum pricing you want to pay for this request
265
278
  */
@@ -984,7 +984,7 @@ var OpenRouterProviderMetadataSchema = import_v43.z.object({
984
984
  cost: import_v43.z.number().optional(),
985
985
  costDetails: import_v43.z.object({
986
986
  upstreamInferenceCost: import_v43.z.number()
987
- }).passthrough()
987
+ }).passthrough().optional()
988
988
  }).passthrough()
989
989
  }).passthrough();
990
990
  var OpenRouterProviderOptionsSchema = import_v43.z.object({
@@ -1103,9 +1103,8 @@ function getCacheControl(providerMetadata) {
1103
1103
  return (_c = (_b = (_a15 = openrouter == null ? void 0 : openrouter.cacheControl) != null ? _a15 : openrouter == null ? void 0 : openrouter.cache_control) != null ? _b : anthropic == null ? void 0 : anthropic.cacheControl) != null ? _c : anthropic == null ? void 0 : anthropic.cache_control;
1104
1104
  }
1105
1105
  function convertToOpenRouterChatMessages(prompt) {
1106
- var _a15, _b, _c, _d, _e, _f;
1106
+ var _a15, _b, _c, _d, _e, _f, _g, _h;
1107
1107
  const messages = [];
1108
- const accumulatedReasoningDetails = [];
1109
1108
  for (const { role, content, providerOptions } of prompt) {
1110
1109
  switch (role) {
1111
1110
  case "system": {
@@ -1135,7 +1134,7 @@ function convertToOpenRouterChatMessages(prompt) {
1135
1134
  const messageCacheControl = getCacheControl(providerOptions);
1136
1135
  const contentParts = content.map(
1137
1136
  (part) => {
1138
- var _a16, _b2, _c2, _d2, _e2, _f2, _g;
1137
+ var _a16, _b2, _c2, _d2, _e2, _f2, _g2;
1139
1138
  const cacheControl = (_a16 = getCacheControl(part.providerOptions)) != null ? _a16 : messageCacheControl;
1140
1139
  switch (part.type) {
1141
1140
  case "text":
@@ -1168,7 +1167,7 @@ function convertToOpenRouterChatMessages(prompt) {
1168
1167
  };
1169
1168
  }
1170
1169
  const fileName = String(
1171
- (_g = (_f2 = (_e2 = (_d2 = part.providerOptions) == null ? void 0 : _d2.openrouter) == null ? void 0 : _e2.filename) != null ? _f2 : part.filename) != null ? _g : ""
1170
+ (_g2 = (_f2 = (_e2 = (_d2 = part.providerOptions) == null ? void 0 : _d2.openrouter) == null ? void 0 : _e2.filename) != null ? _f2 : part.filename) != null ? _g2 : ""
1172
1171
  );
1173
1172
  const fileData = getFileUrl({
1174
1173
  part,
@@ -1215,6 +1214,7 @@ function convertToOpenRouterChatMessages(prompt) {
1215
1214
  let text = "";
1216
1215
  let reasoning = "";
1217
1216
  const toolCalls = [];
1217
+ const accumulatedReasoningDetails = [];
1218
1218
  for (const part of content) {
1219
1219
  switch (part.type) {
1220
1220
  case "text": {
@@ -1240,6 +1240,12 @@ function convertToOpenRouterChatMessages(prompt) {
1240
1240
  }
1241
1241
  case "reasoning": {
1242
1242
  reasoning += part.text;
1243
+ const parsedPartProviderOptions = OpenRouterProviderOptionsSchema.safeParse(part.providerOptions);
1244
+ if (parsedPartProviderOptions.success && ((_e = (_d = parsedPartProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details)) {
1245
+ accumulatedReasoningDetails.push(
1246
+ ...parsedPartProviderOptions.data.openrouter.reasoning_details
1247
+ );
1248
+ }
1243
1249
  break;
1244
1250
  }
1245
1251
  case "file":
@@ -1250,7 +1256,7 @@ function convertToOpenRouterChatMessages(prompt) {
1250
1256
  }
1251
1257
  }
1252
1258
  const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
1253
- const messageReasoningDetails = parsedProviderOptions.success ? (_e = (_d = parsedProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details : void 0;
1259
+ const messageReasoningDetails = parsedProviderOptions.success ? (_g = (_f = parsedProviderOptions.data) == null ? void 0 : _f.openrouter) == null ? void 0 : _g.reasoning_details : void 0;
1254
1260
  const finalReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : accumulatedReasoningDetails.length > 0 ? accumulatedReasoningDetails : void 0;
1255
1261
  messages.push({
1256
1262
  role: "assistant",
@@ -1269,7 +1275,7 @@ function convertToOpenRouterChatMessages(prompt) {
1269
1275
  role: "tool",
1270
1276
  tool_call_id: toolResponse.toolCallId,
1271
1277
  content: content2,
1272
- cache_control: (_f = getCacheControl(providerOptions)) != null ? _f : getCacheControl(toolResponse.providerOptions)
1278
+ cache_control: (_h = getCacheControl(providerOptions)) != null ? _h : getCacheControl(toolResponse.providerOptions)
1273
1279
  });
1274
1280
  }
1275
1281
  break;
@@ -1585,7 +1591,9 @@ var OpenRouterChatLanguageModel = class {
1585
1591
  plugins: this.settings.plugins,
1586
1592
  web_search_options: this.settings.web_search_options,
1587
1593
  // Provider routing settings:
1588
- provider: this.settings.provider
1594
+ provider: this.settings.provider,
1595
+ // Debug settings:
1596
+ debug: this.settings.debug
1589
1597
  }, this.config.extraBody), this.settings.extraBody);
1590
1598
  if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null) {
1591
1599
  return __spreadProps(__spreadValues({}, baseArgs), {
@@ -1620,7 +1628,7 @@ var OpenRouterChatLanguageModel = class {
1620
1628
  return baseArgs;
1621
1629
  }
1622
1630
  async doGenerate(options) {
1623
- var _a15, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
1631
+ var _a15, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
1624
1632
  const providerOptions = options.providerOptions || {};
1625
1633
  const openrouterOptions = providerOptions.openrouter || {};
1626
1634
  const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
@@ -1787,21 +1795,24 @@ var OpenRouterChatLanguageModel = class {
1787
1795
  openrouter: OpenRouterProviderMetadataSchema.parse({
1788
1796
  provider: (_k = response.provider) != null ? _k : "",
1789
1797
  reasoning_details: (_l = choice.message.reasoning_details) != null ? _l : [],
1790
- usage: {
1798
+ usage: __spreadValues(__spreadValues(__spreadValues({
1791
1799
  promptTokens: (_m = usageInfo.inputTokens) != null ? _m : 0,
1792
1800
  completionTokens: (_n = usageInfo.outputTokens) != null ? _n : 0,
1793
1801
  totalTokens: (_o = usageInfo.totalTokens) != null ? _o : 0,
1794
- cost: (_p = response.usage) == null ? void 0 : _p.cost,
1802
+ cost: (_p = response.usage) == null ? void 0 : _p.cost
1803
+ }, ((_r = (_q = response.usage) == null ? void 0 : _q.prompt_tokens_details) == null ? void 0 : _r.cached_tokens) != null ? {
1795
1804
  promptTokensDetails: {
1796
- cachedTokens: (_s = (_r = (_q = response.usage) == null ? void 0 : _q.prompt_tokens_details) == null ? void 0 : _r.cached_tokens) != null ? _s : 0
1797
- },
1805
+ cachedTokens: response.usage.prompt_tokens_details.cached_tokens
1806
+ }
1807
+ } : {}), ((_t = (_s = response.usage) == null ? void 0 : _s.completion_tokens_details) == null ? void 0 : _t.reasoning_tokens) != null ? {
1798
1808
  completionTokensDetails: {
1799
- reasoningTokens: (_v = (_u = (_t = response.usage) == null ? void 0 : _t.completion_tokens_details) == null ? void 0 : _u.reasoning_tokens) != null ? _v : 0
1800
- },
1809
+ reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
1810
+ }
1811
+ } : {}), ((_v = (_u = response.usage) == null ? void 0 : _u.cost_details) == null ? void 0 : _v.upstream_inference_cost) != null ? {
1801
1812
  costDetails: {
1802
- upstreamInferenceCost: (_y = (_x = (_w = response.usage) == null ? void 0 : _w.cost_details) == null ? void 0 : _x.upstream_inference_cost) != null ? _y : 0
1813
+ upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
1803
1814
  }
1804
- }
1815
+ } : {})
1805
1816
  })
1806
1817
  },
1807
1818
  request: { body: args },
@@ -1858,7 +1869,7 @@ var OpenRouterChatLanguageModel = class {
1858
1869
  stream: response.pipeThrough(
1859
1870
  new TransformStream({
1860
1871
  transform(chunk, controller) {
1861
- var _a16, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1872
+ var _a16, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
1862
1873
  if (!chunk.success) {
1863
1874
  finishReason = "error";
1864
1875
  controller.enqueue({ type: "error", error: chunk.error });
@@ -1908,6 +1919,12 @@ var OpenRouterChatLanguageModel = class {
1908
1919
  }
1909
1920
  openrouterUsage.cost = value.usage.cost;
1910
1921
  openrouterUsage.totalTokens = value.usage.total_tokens;
1922
+ const upstreamInferenceCost = (_c = value.usage.cost_details) == null ? void 0 : _c.upstream_inference_cost;
1923
+ if (upstreamInferenceCost != null) {
1924
+ openrouterUsage.costDetails = {
1925
+ upstreamInferenceCost
1926
+ };
1927
+ }
1911
1928
  }
1912
1929
  const choice = value.choices[0];
1913
1930
  if ((choice == null ? void 0 : choice.finish_reason) != null) {
@@ -1917,16 +1934,18 @@ var OpenRouterChatLanguageModel = class {
1917
1934
  return;
1918
1935
  }
1919
1936
  const delta = choice.delta;
1920
- const emitReasoningChunk = (chunkText) => {
1937
+ const emitReasoningChunk = (chunkText, providerMetadata) => {
1921
1938
  if (!reasoningStarted) {
1922
1939
  reasoningId = openrouterResponseId || generateId();
1923
1940
  controller.enqueue({
1941
+ providerMetadata,
1924
1942
  type: "reasoning-start",
1925
1943
  id: reasoningId
1926
1944
  });
1927
1945
  reasoningStarted = true;
1928
1946
  }
1929
1947
  controller.enqueue({
1948
+ providerMetadata,
1930
1949
  type: "reasoning-delta",
1931
1950
  delta: chunkText,
1932
1951
  id: reasoningId || generateId()
@@ -1947,23 +1966,28 @@ var OpenRouterChatLanguageModel = class {
1947
1966
  accumulatedReasoningDetails.push(detail);
1948
1967
  }
1949
1968
  }
1969
+ const reasoningMetadata = {
1970
+ openrouter: {
1971
+ reasoning_details: delta.reasoning_details
1972
+ }
1973
+ };
1950
1974
  for (const detail of delta.reasoning_details) {
1951
1975
  switch (detail.type) {
1952
1976
  case "reasoning.text" /* Text */: {
1953
1977
  if (detail.text) {
1954
- emitReasoningChunk(detail.text);
1978
+ emitReasoningChunk(detail.text, reasoningMetadata);
1955
1979
  }
1956
1980
  break;
1957
1981
  }
1958
1982
  case "reasoning.encrypted" /* Encrypted */: {
1959
1983
  if (detail.data) {
1960
- emitReasoningChunk("[REDACTED]");
1984
+ emitReasoningChunk("[REDACTED]", reasoningMetadata);
1961
1985
  }
1962
1986
  break;
1963
1987
  }
1964
1988
  case "reasoning.summary" /* Summary */: {
1965
1989
  if (detail.summary) {
1966
- emitReasoningChunk(detail.summary);
1990
+ emitReasoningChunk(detail.summary, reasoningMetadata);
1967
1991
  }
1968
1992
  break;
1969
1993
  }
@@ -2018,7 +2042,7 @@ var OpenRouterChatLanguageModel = class {
2018
2042
  }
2019
2043
  if (delta.tool_calls != null) {
2020
2044
  for (const toolCallDelta of delta.tool_calls) {
2021
- const index = (_c = toolCallDelta.index) != null ? _c : toolCalls.length - 1;
2045
+ const index = (_d = toolCallDelta.index) != null ? _d : toolCalls.length - 1;
2022
2046
  if (toolCalls[index] == null) {
2023
2047
  if (toolCallDelta.type !== "function") {
2024
2048
  throw new InvalidResponseDataError({
@@ -2032,7 +2056,7 @@ var OpenRouterChatLanguageModel = class {
2032
2056
  message: `Expected 'id' to be a string.`
2033
2057
  });
2034
2058
  }
2035
- if (((_d = toolCallDelta.function) == null ? void 0 : _d.name) == null) {
2059
+ if (((_e = toolCallDelta.function) == null ? void 0 : _e.name) == null) {
2036
2060
  throw new InvalidResponseDataError({
2037
2061
  data: toolCallDelta,
2038
2062
  message: `Expected 'function.name' to be a string.`
@@ -2043,7 +2067,7 @@ var OpenRouterChatLanguageModel = class {
2043
2067
  type: "function",
2044
2068
  function: {
2045
2069
  name: toolCallDelta.function.name,
2046
- arguments: (_e = toolCallDelta.function.arguments) != null ? _e : ""
2070
+ arguments: (_f = toolCallDelta.function.arguments) != null ? _f : ""
2047
2071
  },
2048
2072
  inputStarted: false,
2049
2073
  sent: false
@@ -2055,7 +2079,7 @@ var OpenRouterChatLanguageModel = class {
2055
2079
  message: `Tool call at index ${index} is missing after creation.`
2056
2080
  });
2057
2081
  }
2058
- if (((_f = toolCall2.function) == null ? void 0 : _f.name) != null && ((_g = toolCall2.function) == null ? void 0 : _g.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
2082
+ if (((_g = toolCall2.function) == null ? void 0 : _g.name) != null && ((_h = toolCall2.function) == null ? void 0 : _h.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
2059
2083
  toolCall2.inputStarted = true;
2060
2084
  controller.enqueue({
2061
2085
  type: "tool-input-start",
@@ -2105,18 +2129,18 @@ var OpenRouterChatLanguageModel = class {
2105
2129
  toolName: toolCall.function.name
2106
2130
  });
2107
2131
  }
2108
- if (((_h = toolCallDelta.function) == null ? void 0 : _h.arguments) != null) {
2109
- toolCall.function.arguments += (_j = (_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null ? _j : "";
2132
+ if (((_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null) {
2133
+ toolCall.function.arguments += (_k = (_j = toolCallDelta.function) == null ? void 0 : _j.arguments) != null ? _k : "";
2110
2134
  }
2111
2135
  controller.enqueue({
2112
2136
  type: "tool-input-delta",
2113
2137
  id: toolCall.id,
2114
- delta: (_k = toolCallDelta.function.arguments) != null ? _k : ""
2138
+ delta: (_l = toolCallDelta.function.arguments) != null ? _l : ""
2115
2139
  });
2116
- if (((_l = toolCall.function) == null ? void 0 : _l.name) != null && ((_m = toolCall.function) == null ? void 0 : _m.arguments) != null && isParsableJson(toolCall.function.arguments)) {
2140
+ if (((_m = toolCall.function) == null ? void 0 : _m.name) != null && ((_n = toolCall.function) == null ? void 0 : _n.arguments) != null && isParsableJson(toolCall.function.arguments)) {
2117
2141
  controller.enqueue({
2118
2142
  type: "tool-call",
2119
- toolCallId: (_n = toolCall.id) != null ? _n : generateId(),
2143
+ toolCallId: (_o = toolCall.id) != null ? _o : generateId(),
2120
2144
  toolName: toolCall.function.name,
2121
2145
  input: toolCall.function.arguments,
2122
2146
  providerMetadata: {
@@ -2332,7 +2356,10 @@ var OpenRouterCompletionChunkSchema = import_v47.z.union([
2332
2356
  reasoning_tokens: import_v47.z.number()
2333
2357
  }).passthrough().nullish(),
2334
2358
  total_tokens: import_v47.z.number(),
2335
- cost: import_v47.z.number().optional()
2359
+ cost: import_v47.z.number().optional(),
2360
+ cost_details: import_v47.z.object({
2361
+ upstream_inference_cost: import_v47.z.number().nullish()
2362
+ }).passthrough().nullish()
2336
2363
  }).passthrough().nullish()
2337
2364
  }).passthrough(),
2338
2365
  OpenRouterErrorResponseSchema
@@ -2505,7 +2532,7 @@ var OpenRouterCompletionLanguageModel = class {
2505
2532
  stream: response.pipeThrough(
2506
2533
  new TransformStream({
2507
2534
  transform(chunk, controller) {
2508
- var _a15, _b;
2535
+ var _a15, _b, _c;
2509
2536
  if (!chunk.success) {
2510
2537
  finishReason = "error";
2511
2538
  controller.enqueue({ type: "error", error: chunk.error });
@@ -2539,6 +2566,12 @@ var OpenRouterCompletionLanguageModel = class {
2539
2566
  }
2540
2567
  openrouterUsage.cost = value.usage.cost;
2541
2568
  openrouterUsage.totalTokens = value.usage.total_tokens;
2569
+ const upstreamInferenceCost = (_c = value.usage.cost_details) == null ? void 0 : _c.upstream_inference_cost;
2570
+ if (upstreamInferenceCost != null) {
2571
+ openrouterUsage.costDetails = {
2572
+ upstreamInferenceCost
2573
+ };
2574
+ }
2542
2575
  }
2543
2576
  const choice = value.choices[0];
2544
2577
  if ((choice == null ? void 0 : choice.finish_reason) != null) {