@openrouter/ai-sdk-provider 1.2.7 → 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
  */
@@ -904,9 +904,9 @@ var ReasoningFormat = /* @__PURE__ */ ((ReasoningFormat2) => {
904
904
  // src/schemas/reasoning-details.ts
905
905
  var CommonReasoningDetailSchema = import_v4.z.object({
906
906
  id: import_v4.z.string().nullish(),
907
- format: import_v4.z.nativeEnum(ReasoningFormat).nullish(),
907
+ format: import_v4.z.enum(ReasoningFormat).nullish(),
908
908
  index: import_v4.z.number().optional()
909
- }).passthrough();
909
+ }).loose();
910
910
  var ReasoningDetailSummarySchema = import_v4.z.object({
911
911
  type: import_v4.z.literal("reasoning.summary" /* Summary */),
912
912
  summary: import_v4.z.string()
@@ -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()
@@ -1938,6 +1957,8 @@ var OpenRouterChatLanguageModel = class {
1938
1957
  const lastDetail = accumulatedReasoningDetails[accumulatedReasoningDetails.length - 1];
1939
1958
  if ((lastDetail == null ? void 0 : lastDetail.type) === "reasoning.text" /* Text */) {
1940
1959
  lastDetail.text = (lastDetail.text || "") + (detail.text || "");
1960
+ lastDetail.signature = lastDetail.signature || detail.signature;
1961
+ lastDetail.format = lastDetail.format || detail.format;
1941
1962
  } else {
1942
1963
  accumulatedReasoningDetails.push(__spreadValues({}, detail));
1943
1964
  }
@@ -1945,23 +1966,28 @@ var OpenRouterChatLanguageModel = class {
1945
1966
  accumulatedReasoningDetails.push(detail);
1946
1967
  }
1947
1968
  }
1969
+ const reasoningMetadata = {
1970
+ openrouter: {
1971
+ reasoning_details: delta.reasoning_details
1972
+ }
1973
+ };
1948
1974
  for (const detail of delta.reasoning_details) {
1949
1975
  switch (detail.type) {
1950
1976
  case "reasoning.text" /* Text */: {
1951
1977
  if (detail.text) {
1952
- emitReasoningChunk(detail.text);
1978
+ emitReasoningChunk(detail.text, reasoningMetadata);
1953
1979
  }
1954
1980
  break;
1955
1981
  }
1956
1982
  case "reasoning.encrypted" /* Encrypted */: {
1957
1983
  if (detail.data) {
1958
- emitReasoningChunk("[REDACTED]");
1984
+ emitReasoningChunk("[REDACTED]", reasoningMetadata);
1959
1985
  }
1960
1986
  break;
1961
1987
  }
1962
1988
  case "reasoning.summary" /* Summary */: {
1963
1989
  if (detail.summary) {
1964
- emitReasoningChunk(detail.summary);
1990
+ emitReasoningChunk(detail.summary, reasoningMetadata);
1965
1991
  }
1966
1992
  break;
1967
1993
  }
@@ -2016,7 +2042,7 @@ var OpenRouterChatLanguageModel = class {
2016
2042
  }
2017
2043
  if (delta.tool_calls != null) {
2018
2044
  for (const toolCallDelta of delta.tool_calls) {
2019
- const index = (_c = toolCallDelta.index) != null ? _c : toolCalls.length - 1;
2045
+ const index = (_d = toolCallDelta.index) != null ? _d : toolCalls.length - 1;
2020
2046
  if (toolCalls[index] == null) {
2021
2047
  if (toolCallDelta.type !== "function") {
2022
2048
  throw new InvalidResponseDataError({
@@ -2030,7 +2056,7 @@ var OpenRouterChatLanguageModel = class {
2030
2056
  message: `Expected 'id' to be a string.`
2031
2057
  });
2032
2058
  }
2033
- if (((_d = toolCallDelta.function) == null ? void 0 : _d.name) == null) {
2059
+ if (((_e = toolCallDelta.function) == null ? void 0 : _e.name) == null) {
2034
2060
  throw new InvalidResponseDataError({
2035
2061
  data: toolCallDelta,
2036
2062
  message: `Expected 'function.name' to be a string.`
@@ -2041,7 +2067,7 @@ var OpenRouterChatLanguageModel = class {
2041
2067
  type: "function",
2042
2068
  function: {
2043
2069
  name: toolCallDelta.function.name,
2044
- arguments: (_e = toolCallDelta.function.arguments) != null ? _e : ""
2070
+ arguments: (_f = toolCallDelta.function.arguments) != null ? _f : ""
2045
2071
  },
2046
2072
  inputStarted: false,
2047
2073
  sent: false
@@ -2053,7 +2079,7 @@ var OpenRouterChatLanguageModel = class {
2053
2079
  message: `Tool call at index ${index} is missing after creation.`
2054
2080
  });
2055
2081
  }
2056
- 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)) {
2057
2083
  toolCall2.inputStarted = true;
2058
2084
  controller.enqueue({
2059
2085
  type: "tool-input-start",
@@ -2103,18 +2129,18 @@ var OpenRouterChatLanguageModel = class {
2103
2129
  toolName: toolCall.function.name
2104
2130
  });
2105
2131
  }
2106
- if (((_h = toolCallDelta.function) == null ? void 0 : _h.arguments) != null) {
2107
- 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 : "";
2108
2134
  }
2109
2135
  controller.enqueue({
2110
2136
  type: "tool-input-delta",
2111
2137
  id: toolCall.id,
2112
- delta: (_k = toolCallDelta.function.arguments) != null ? _k : ""
2138
+ delta: (_l = toolCallDelta.function.arguments) != null ? _l : ""
2113
2139
  });
2114
- 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)) {
2115
2141
  controller.enqueue({
2116
2142
  type: "tool-call",
2117
- toolCallId: (_n = toolCall.id) != null ? _n : generateId(),
2143
+ toolCallId: (_o = toolCall.id) != null ? _o : generateId(),
2118
2144
  toolName: toolCall.function.name,
2119
2145
  input: toolCall.function.arguments,
2120
2146
  providerMetadata: {
@@ -2330,7 +2356,10 @@ var OpenRouterCompletionChunkSchema = import_v47.z.union([
2330
2356
  reasoning_tokens: import_v47.z.number()
2331
2357
  }).passthrough().nullish(),
2332
2358
  total_tokens: import_v47.z.number(),
2333
- 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()
2334
2363
  }).passthrough().nullish()
2335
2364
  }).passthrough(),
2336
2365
  OpenRouterErrorResponseSchema
@@ -2503,7 +2532,7 @@ var OpenRouterCompletionLanguageModel = class {
2503
2532
  stream: response.pipeThrough(
2504
2533
  new TransformStream({
2505
2534
  transform(chunk, controller) {
2506
- var _a15, _b;
2535
+ var _a15, _b, _c;
2507
2536
  if (!chunk.success) {
2508
2537
  finishReason = "error";
2509
2538
  controller.enqueue({ type: "error", error: chunk.error });
@@ -2537,6 +2566,12 @@ var OpenRouterCompletionLanguageModel = class {
2537
2566
  }
2538
2567
  openrouterUsage.cost = value.usage.cost;
2539
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
+ }
2540
2575
  }
2541
2576
  const choice = value.choices[0];
2542
2577
  if ((choice == null ? void 0 : choice.finish_reason) != null) {