@openrouter/ai-sdk-provider 1.2.8 → 1.4.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.
package/dist/index.mjs CHANGED
@@ -979,9 +979,23 @@ var openrouterFailedResponseHandler = createJsonErrorResponseHandler({
979
979
 
980
980
  // src/schemas/provider-metadata.ts
981
981
  import { z as z3 } from "zod/v4";
982
+ var FileAnnotationSchema = z3.object({
983
+ type: z3.literal("file"),
984
+ file: z3.object({
985
+ hash: z3.string(),
986
+ name: z3.string(),
987
+ content: z3.array(
988
+ z3.object({
989
+ type: z3.string(),
990
+ text: z3.string().optional()
991
+ }).passthrough()
992
+ ).optional()
993
+ }).passthrough()
994
+ });
982
995
  var OpenRouterProviderMetadataSchema = z3.object({
983
996
  provider: z3.string(),
984
997
  reasoning_details: z3.array(ReasoningDetailUnionSchema).optional(),
998
+ annotations: z3.array(FileAnnotationSchema).optional(),
985
999
  usage: z3.object({
986
1000
  promptTokens: z3.number(),
987
1001
  promptTokensDetails: z3.object({
@@ -995,12 +1009,13 @@ var OpenRouterProviderMetadataSchema = z3.object({
995
1009
  cost: z3.number().optional(),
996
1010
  costDetails: z3.object({
997
1011
  upstreamInferenceCost: z3.number()
998
- }).passthrough()
1012
+ }).passthrough().optional()
999
1013
  }).passthrough()
1000
1014
  }).passthrough();
1001
1015
  var OpenRouterProviderOptionsSchema = z3.object({
1002
1016
  openrouter: z3.object({
1003
- reasoning_details: z3.array(ReasoningDetailUnionSchema).optional()
1017
+ reasoning_details: z3.array(ReasoningDetailUnionSchema).optional(),
1018
+ annotations: z3.array(FileAnnotationSchema).optional()
1004
1019
  }).optional()
1005
1020
  }).optional();
1006
1021
 
@@ -1114,9 +1129,8 @@ function getCacheControl(providerMetadata) {
1114
1129
  return (_c = (_b = (_a15 = openrouter2 == null ? void 0 : openrouter2.cacheControl) != null ? _a15 : openrouter2 == null ? void 0 : openrouter2.cache_control) != null ? _b : anthropic == null ? void 0 : anthropic.cacheControl) != null ? _c : anthropic == null ? void 0 : anthropic.cache_control;
1115
1130
  }
1116
1131
  function convertToOpenRouterChatMessages(prompt) {
1117
- var _a15, _b, _c, _d, _e, _f;
1132
+ var _a15, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1118
1133
  const messages = [];
1119
- const accumulatedReasoningDetails = [];
1120
1134
  for (const { role, content, providerOptions } of prompt) {
1121
1135
  switch (role) {
1122
1136
  case "system": {
@@ -1146,7 +1160,7 @@ function convertToOpenRouterChatMessages(prompt) {
1146
1160
  const messageCacheControl = getCacheControl(providerOptions);
1147
1161
  const contentParts = content.map(
1148
1162
  (part) => {
1149
- var _a16, _b2, _c2, _d2, _e2, _f2, _g;
1163
+ var _a16, _b2, _c2, _d2, _e2, _f2, _g2;
1150
1164
  const cacheControl = (_a16 = getCacheControl(part.providerOptions)) != null ? _a16 : messageCacheControl;
1151
1165
  switch (part.type) {
1152
1166
  case "text":
@@ -1179,7 +1193,7 @@ function convertToOpenRouterChatMessages(prompt) {
1179
1193
  };
1180
1194
  }
1181
1195
  const fileName = String(
1182
- (_g = (_f2 = (_e2 = (_d2 = part.providerOptions) == null ? void 0 : _d2.openrouter) == null ? void 0 : _e2.filename) != null ? _f2 : part.filename) != null ? _g : ""
1196
+ (_g2 = (_f2 = (_e2 = (_d2 = part.providerOptions) == null ? void 0 : _d2.openrouter) == null ? void 0 : _e2.filename) != null ? _f2 : part.filename) != null ? _g2 : ""
1183
1197
  );
1184
1198
  const fileData = getFileUrl({
1185
1199
  part,
@@ -1226,6 +1240,7 @@ function convertToOpenRouterChatMessages(prompt) {
1226
1240
  let text = "";
1227
1241
  let reasoning = "";
1228
1242
  const toolCalls = [];
1243
+ const accumulatedReasoningDetails = [];
1229
1244
  for (const part of content) {
1230
1245
  switch (part.type) {
1231
1246
  case "text": {
@@ -1251,6 +1266,12 @@ function convertToOpenRouterChatMessages(prompt) {
1251
1266
  }
1252
1267
  case "reasoning": {
1253
1268
  reasoning += part.text;
1269
+ const parsedPartProviderOptions = OpenRouterProviderOptionsSchema.safeParse(part.providerOptions);
1270
+ if (parsedPartProviderOptions.success && ((_e = (_d = parsedPartProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details)) {
1271
+ accumulatedReasoningDetails.push(
1272
+ ...parsedPartProviderOptions.data.openrouter.reasoning_details
1273
+ );
1274
+ }
1254
1275
  break;
1255
1276
  }
1256
1277
  case "file":
@@ -1261,7 +1282,8 @@ function convertToOpenRouterChatMessages(prompt) {
1261
1282
  }
1262
1283
  }
1263
1284
  const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
1264
- const messageReasoningDetails = parsedProviderOptions.success ? (_e = (_d = parsedProviderOptions.data) == null ? void 0 : _d.openrouter) == null ? void 0 : _e.reasoning_details : void 0;
1285
+ const messageReasoningDetails = parsedProviderOptions.success ? (_g = (_f = parsedProviderOptions.data) == null ? void 0 : _f.openrouter) == null ? void 0 : _g.reasoning_details : void 0;
1286
+ const messageAnnotations = parsedProviderOptions.success ? (_i = (_h = parsedProviderOptions.data) == null ? void 0 : _h.openrouter) == null ? void 0 : _i.annotations : void 0;
1265
1287
  const finalReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : accumulatedReasoningDetails.length > 0 ? accumulatedReasoningDetails : void 0;
1266
1288
  messages.push({
1267
1289
  role: "assistant",
@@ -1269,6 +1291,7 @@ function convertToOpenRouterChatMessages(prompt) {
1269
1291
  tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
1270
1292
  reasoning: reasoning || void 0,
1271
1293
  reasoning_details: finalReasoningDetails,
1294
+ annotations: messageAnnotations,
1272
1295
  cache_control: getCacheControl(providerOptions)
1273
1296
  });
1274
1297
  break;
@@ -1280,7 +1303,7 @@ function convertToOpenRouterChatMessages(prompt) {
1280
1303
  role: "tool",
1281
1304
  tool_call_id: toolResponse.toolCallId,
1282
1305
  content: content2,
1283
- cache_control: (_f = getCacheControl(providerOptions)) != null ? _f : getCacheControl(toolResponse.providerOptions)
1306
+ cache_control: (_j = getCacheControl(providerOptions)) != null ? _j : getCacheControl(toolResponse.providerOptions)
1284
1307
  });
1285
1308
  }
1286
1309
  break;
@@ -1539,6 +1562,7 @@ var OpenRouterChatLanguageModel = class {
1539
1562
  this.specificationVersion = "v2";
1540
1563
  this.provider = "openrouter";
1541
1564
  this.defaultObjectGenerationMode = "tool";
1565
+ this.supportsImageUrls = true;
1542
1566
  this.supportedUrls = {
1543
1567
  "image/*": [
1544
1568
  /^data:image\/[a-zA-Z]+;base64,/,
@@ -1596,7 +1620,9 @@ var OpenRouterChatLanguageModel = class {
1596
1620
  plugins: this.settings.plugins,
1597
1621
  web_search_options: this.settings.web_search_options,
1598
1622
  // Provider routing settings:
1599
- provider: this.settings.provider
1623
+ provider: this.settings.provider,
1624
+ // Debug settings:
1625
+ debug: this.settings.debug
1600
1626
  }, this.config.extraBody), this.settings.extraBody);
1601
1627
  if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null) {
1602
1628
  return __spreadProps(__spreadValues({}, baseArgs), {
@@ -1631,7 +1657,7 @@ var OpenRouterChatLanguageModel = class {
1631
1657
  return baseArgs;
1632
1658
  }
1633
1659
  async doGenerate(options) {
1634
- 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;
1660
+ var _a15, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
1635
1661
  const providerOptions = options.providerOptions || {};
1636
1662
  const openrouterOptions = providerOptions.openrouter || {};
1637
1663
  const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
@@ -1789,6 +1815,9 @@ var OpenRouterChatLanguageModel = class {
1789
1815
  }
1790
1816
  }
1791
1817
  }
1818
+ const fileAnnotations = (_k = choice.message.annotations) == null ? void 0 : _k.filter(
1819
+ (a) => a.type === "file"
1820
+ );
1792
1821
  return {
1793
1822
  content,
1794
1823
  finishReason: mapOpenRouterFinishReason(choice.finish_reason),
@@ -1796,23 +1825,27 @@ var OpenRouterChatLanguageModel = class {
1796
1825
  warnings: [],
1797
1826
  providerMetadata: {
1798
1827
  openrouter: OpenRouterProviderMetadataSchema.parse({
1799
- provider: (_k = response.provider) != null ? _k : "",
1800
- reasoning_details: (_l = choice.message.reasoning_details) != null ? _l : [],
1801
- usage: {
1802
- promptTokens: (_m = usageInfo.inputTokens) != null ? _m : 0,
1803
- completionTokens: (_n = usageInfo.outputTokens) != null ? _n : 0,
1804
- totalTokens: (_o = usageInfo.totalTokens) != null ? _o : 0,
1805
- cost: (_p = response.usage) == null ? void 0 : _p.cost,
1828
+ provider: (_l = response.provider) != null ? _l : "",
1829
+ reasoning_details: (_m = choice.message.reasoning_details) != null ? _m : [],
1830
+ annotations: fileAnnotations && fileAnnotations.length > 0 ? fileAnnotations : void 0,
1831
+ usage: __spreadValues(__spreadValues(__spreadValues({
1832
+ promptTokens: (_n = usageInfo.inputTokens) != null ? _n : 0,
1833
+ completionTokens: (_o = usageInfo.outputTokens) != null ? _o : 0,
1834
+ totalTokens: (_p = usageInfo.totalTokens) != null ? _p : 0,
1835
+ cost: (_q = response.usage) == null ? void 0 : _q.cost
1836
+ }, ((_s = (_r = response.usage) == null ? void 0 : _r.prompt_tokens_details) == null ? void 0 : _s.cached_tokens) != null ? {
1806
1837
  promptTokensDetails: {
1807
- cachedTokens: (_s = (_r = (_q = response.usage) == null ? void 0 : _q.prompt_tokens_details) == null ? void 0 : _r.cached_tokens) != null ? _s : 0
1808
- },
1838
+ cachedTokens: response.usage.prompt_tokens_details.cached_tokens
1839
+ }
1840
+ } : {}), ((_u = (_t = response.usage) == null ? void 0 : _t.completion_tokens_details) == null ? void 0 : _u.reasoning_tokens) != null ? {
1809
1841
  completionTokensDetails: {
1810
- reasoningTokens: (_v = (_u = (_t = response.usage) == null ? void 0 : _t.completion_tokens_details) == null ? void 0 : _u.reasoning_tokens) != null ? _v : 0
1811
- },
1842
+ reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
1843
+ }
1844
+ } : {}), ((_w = (_v = response.usage) == null ? void 0 : _v.cost_details) == null ? void 0 : _w.upstream_inference_cost) != null ? {
1812
1845
  costDetails: {
1813
- upstreamInferenceCost: (_y = (_x = (_w = response.usage) == null ? void 0 : _w.cost_details) == null ? void 0 : _x.upstream_inference_cost) != null ? _y : 0
1846
+ upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
1814
1847
  }
1815
- }
1848
+ } : {})
1816
1849
  })
1817
1850
  },
1818
1851
  request: { body: args },
@@ -1869,7 +1902,7 @@ var OpenRouterChatLanguageModel = class {
1869
1902
  stream: response.pipeThrough(
1870
1903
  new TransformStream({
1871
1904
  transform(chunk, controller) {
1872
- var _a16, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1905
+ var _a16, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
1873
1906
  if (!chunk.success) {
1874
1907
  finishReason = "error";
1875
1908
  controller.enqueue({ type: "error", error: chunk.error });
@@ -1919,6 +1952,12 @@ var OpenRouterChatLanguageModel = class {
1919
1952
  }
1920
1953
  openrouterUsage.cost = value.usage.cost;
1921
1954
  openrouterUsage.totalTokens = value.usage.total_tokens;
1955
+ const upstreamInferenceCost = (_c = value.usage.cost_details) == null ? void 0 : _c.upstream_inference_cost;
1956
+ if (upstreamInferenceCost != null) {
1957
+ openrouterUsage.costDetails = {
1958
+ upstreamInferenceCost
1959
+ };
1960
+ }
1922
1961
  }
1923
1962
  const choice = value.choices[0];
1924
1963
  if ((choice == null ? void 0 : choice.finish_reason) != null) {
@@ -1928,16 +1967,18 @@ var OpenRouterChatLanguageModel = class {
1928
1967
  return;
1929
1968
  }
1930
1969
  const delta = choice.delta;
1931
- const emitReasoningChunk = (chunkText) => {
1970
+ const emitReasoningChunk = (chunkText, providerMetadata) => {
1932
1971
  if (!reasoningStarted) {
1933
1972
  reasoningId = openrouterResponseId || generateId();
1934
1973
  controller.enqueue({
1974
+ providerMetadata,
1935
1975
  type: "reasoning-start",
1936
1976
  id: reasoningId
1937
1977
  });
1938
1978
  reasoningStarted = true;
1939
1979
  }
1940
1980
  controller.enqueue({
1981
+ providerMetadata,
1941
1982
  type: "reasoning-delta",
1942
1983
  delta: chunkText,
1943
1984
  id: reasoningId || generateId()
@@ -1958,23 +1999,28 @@ var OpenRouterChatLanguageModel = class {
1958
1999
  accumulatedReasoningDetails.push(detail);
1959
2000
  }
1960
2001
  }
2002
+ const reasoningMetadata = {
2003
+ openrouter: {
2004
+ reasoning_details: delta.reasoning_details
2005
+ }
2006
+ };
1961
2007
  for (const detail of delta.reasoning_details) {
1962
2008
  switch (detail.type) {
1963
2009
  case "reasoning.text" /* Text */: {
1964
2010
  if (detail.text) {
1965
- emitReasoningChunk(detail.text);
2011
+ emitReasoningChunk(detail.text, reasoningMetadata);
1966
2012
  }
1967
2013
  break;
1968
2014
  }
1969
2015
  case "reasoning.encrypted" /* Encrypted */: {
1970
2016
  if (detail.data) {
1971
- emitReasoningChunk("[REDACTED]");
2017
+ emitReasoningChunk("[REDACTED]", reasoningMetadata);
1972
2018
  }
1973
2019
  break;
1974
2020
  }
1975
2021
  case "reasoning.summary" /* Summary */: {
1976
2022
  if (detail.summary) {
1977
- emitReasoningChunk(detail.summary);
2023
+ emitReasoningChunk(detail.summary, reasoningMetadata);
1978
2024
  }
1979
2025
  break;
1980
2026
  }
@@ -2029,7 +2075,7 @@ var OpenRouterChatLanguageModel = class {
2029
2075
  }
2030
2076
  if (delta.tool_calls != null) {
2031
2077
  for (const toolCallDelta of delta.tool_calls) {
2032
- const index = (_c = toolCallDelta.index) != null ? _c : toolCalls.length - 1;
2078
+ const index = (_d = toolCallDelta.index) != null ? _d : toolCalls.length - 1;
2033
2079
  if (toolCalls[index] == null) {
2034
2080
  if (toolCallDelta.type !== "function") {
2035
2081
  throw new InvalidResponseDataError({
@@ -2043,7 +2089,7 @@ var OpenRouterChatLanguageModel = class {
2043
2089
  message: `Expected 'id' to be a string.`
2044
2090
  });
2045
2091
  }
2046
- if (((_d = toolCallDelta.function) == null ? void 0 : _d.name) == null) {
2092
+ if (((_e = toolCallDelta.function) == null ? void 0 : _e.name) == null) {
2047
2093
  throw new InvalidResponseDataError({
2048
2094
  data: toolCallDelta,
2049
2095
  message: `Expected 'function.name' to be a string.`
@@ -2054,7 +2100,7 @@ var OpenRouterChatLanguageModel = class {
2054
2100
  type: "function",
2055
2101
  function: {
2056
2102
  name: toolCallDelta.function.name,
2057
- arguments: (_e = toolCallDelta.function.arguments) != null ? _e : ""
2103
+ arguments: (_f = toolCallDelta.function.arguments) != null ? _f : ""
2058
2104
  },
2059
2105
  inputStarted: false,
2060
2106
  sent: false
@@ -2066,7 +2112,7 @@ var OpenRouterChatLanguageModel = class {
2066
2112
  message: `Tool call at index ${index} is missing after creation.`
2067
2113
  });
2068
2114
  }
2069
- if (((_f = toolCall2.function) == null ? void 0 : _f.name) != null && ((_g = toolCall2.function) == null ? void 0 : _g.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
2115
+ if (((_g = toolCall2.function) == null ? void 0 : _g.name) != null && ((_h = toolCall2.function) == null ? void 0 : _h.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
2070
2116
  toolCall2.inputStarted = true;
2071
2117
  controller.enqueue({
2072
2118
  type: "tool-input-start",
@@ -2116,18 +2162,18 @@ var OpenRouterChatLanguageModel = class {
2116
2162
  toolName: toolCall.function.name
2117
2163
  });
2118
2164
  }
2119
- if (((_h = toolCallDelta.function) == null ? void 0 : _h.arguments) != null) {
2120
- toolCall.function.arguments += (_j = (_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null ? _j : "";
2165
+ if (((_i = toolCallDelta.function) == null ? void 0 : _i.arguments) != null) {
2166
+ toolCall.function.arguments += (_k = (_j = toolCallDelta.function) == null ? void 0 : _j.arguments) != null ? _k : "";
2121
2167
  }
2122
2168
  controller.enqueue({
2123
2169
  type: "tool-input-delta",
2124
2170
  id: toolCall.id,
2125
- delta: (_k = toolCallDelta.function.arguments) != null ? _k : ""
2171
+ delta: (_l = toolCallDelta.function.arguments) != null ? _l : ""
2126
2172
  });
2127
- if (((_l = toolCall.function) == null ? void 0 : _l.name) != null && ((_m = toolCall.function) == null ? void 0 : _m.arguments) != null && isParsableJson(toolCall.function.arguments)) {
2173
+ if (((_m = toolCall.function) == null ? void 0 : _m.name) != null && ((_n = toolCall.function) == null ? void 0 : _n.arguments) != null && isParsableJson(toolCall.function.arguments)) {
2128
2174
  controller.enqueue({
2129
2175
  type: "tool-call",
2130
- toolCallId: (_n = toolCall.id) != null ? _n : generateId(),
2176
+ toolCallId: (_o = toolCall.id) != null ? _o : generateId(),
2131
2177
  toolName: toolCall.function.name,
2132
2178
  input: toolCall.function.arguments,
2133
2179
  providerMetadata: {
@@ -2343,7 +2389,10 @@ var OpenRouterCompletionChunkSchema = z8.union([
2343
2389
  reasoning_tokens: z8.number()
2344
2390
  }).passthrough().nullish(),
2345
2391
  total_tokens: z8.number(),
2346
- cost: z8.number().optional()
2392
+ cost: z8.number().optional(),
2393
+ cost_details: z8.object({
2394
+ upstream_inference_cost: z8.number().nullish()
2395
+ }).passthrough().nullish()
2347
2396
  }).passthrough().nullish()
2348
2397
  }).passthrough(),
2349
2398
  OpenRouterErrorResponseSchema
@@ -2354,6 +2403,7 @@ var OpenRouterCompletionLanguageModel = class {
2354
2403
  constructor(modelId, settings, config) {
2355
2404
  this.specificationVersion = "v2";
2356
2405
  this.provider = "openrouter";
2406
+ this.supportsImageUrls = true;
2357
2407
  this.supportedUrls = {
2358
2408
  "image/*": [
2359
2409
  /^data:image\/[a-zA-Z]+;base64,/,
@@ -2516,7 +2566,7 @@ var OpenRouterCompletionLanguageModel = class {
2516
2566
  stream: response.pipeThrough(
2517
2567
  new TransformStream({
2518
2568
  transform(chunk, controller) {
2519
- var _a15, _b;
2569
+ var _a15, _b, _c;
2520
2570
  if (!chunk.success) {
2521
2571
  finishReason = "error";
2522
2572
  controller.enqueue({ type: "error", error: chunk.error });
@@ -2550,6 +2600,12 @@ var OpenRouterCompletionLanguageModel = class {
2550
2600
  }
2551
2601
  openrouterUsage.cost = value.usage.cost;
2552
2602
  openrouterUsage.totalTokens = value.usage.total_tokens;
2603
+ const upstreamInferenceCost = (_c = value.usage.cost_details) == null ? void 0 : _c.upstream_inference_cost;
2604
+ if (upstreamInferenceCost != null) {
2605
+ openrouterUsage.costDetails = {
2606
+ upstreamInferenceCost
2607
+ };
2608
+ }
2553
2609
  }
2554
2610
  const choice = value.choices[0];
2555
2611
  if ((choice == null ? void 0 : choice.finish_reason) != null) {
@@ -2645,7 +2701,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
2645
2701
  }
2646
2702
 
2647
2703
  // src/version.ts
2648
- var VERSION = false ? "0.0.0-test" : "1.2.8";
2704
+ var VERSION = false ? "0.0.0-test" : "1.4.0";
2649
2705
 
2650
2706
  // src/provider.ts
2651
2707
  function createOpenRouter(options = {}) {