@openrouter/ai-sdk-provider 1.1.2 → 1.2.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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The [OpenRouter](https://openrouter.ai/) provider for the [Vercel AI SDK](https://sdk.vercel.ai/docs) gives access to over 300 large language models on the OpenRouter chat and completion APIs.
4
4
 
5
- ## Setup
5
+ ## Setup for AI SDK v5
6
6
 
7
7
  ```bash
8
8
  # For pnpm
@@ -15,6 +15,20 @@ npm install @openrouter/ai-sdk-provider
15
15
  yarn add @openrouter/ai-sdk-provider
16
16
  ```
17
17
 
18
+ ## (LEGACY) Setup for AI SDK v4
19
+
20
+ ```bash
21
+ # For pnpm
22
+ pnpm add @openrouter/ai-sdk-provider@ai-sdk-v4
23
+
24
+ # For npm
25
+ npm install @openrouter/ai-sdk-provider@ai-sdk-v4
26
+
27
+ # For yarn
28
+ yarn add @openrouter/ai-sdk-provider@ai-sdk-v4
29
+
30
+ ```
31
+
18
32
  ## Provider Instance
19
33
 
20
34
  You can import the default provider instance `openrouter` from `@openrouter/ai-sdk-provider`:
package/dist/index.js CHANGED
@@ -1007,6 +1007,15 @@ function getFileUrl({
1007
1007
  }
1008
1008
  return stringUrl.startsWith("data:") ? stringUrl : `data:${(_b = part.mediaType) != null ? _b : defaultMediaType};base64,${stringUrl}`;
1009
1009
  }
1010
+ function getMediaType(dataUrl, defaultMediaType) {
1011
+ var _a15;
1012
+ const match = dataUrl.match(/^data:([^;]+)/);
1013
+ return match ? (_a15 = match[1]) != null ? _a15 : defaultMediaType : defaultMediaType;
1014
+ }
1015
+ function getBase64FromDataUrl(dataUrl) {
1016
+ const match = dataUrl.match(/^data:[^;]*;base64,(.+)$/);
1017
+ return match ? match[1] : dataUrl;
1018
+ }
1010
1019
 
1011
1020
  // src/chat/convert-to-openrouter-chat-messages.ts
1012
1021
  function getCacheControl(providerMetadata) {
@@ -1219,126 +1228,144 @@ function getChatCompletionToolChoice(toolChoice) {
1219
1228
  }
1220
1229
 
1221
1230
  // src/chat/schemas.ts
1231
+ var import_v45 = require("zod/v4");
1232
+
1233
+ // src/schemas/image.ts
1222
1234
  var import_v44 = require("zod/v4");
1223
- var OpenRouterChatCompletionBaseResponseSchema = import_v44.z.object({
1224
- id: import_v44.z.string().optional(),
1225
- model: import_v44.z.string().optional(),
1226
- provider: import_v44.z.string().optional(),
1227
- usage: import_v44.z.object({
1228
- prompt_tokens: import_v44.z.number(),
1229
- prompt_tokens_details: import_v44.z.object({
1230
- cached_tokens: import_v44.z.number()
1235
+ var ImageResponseSchema = import_v44.z.object({
1236
+ type: import_v44.z.literal("image_url"),
1237
+ image_url: import_v44.z.object({
1238
+ url: import_v44.z.string()
1239
+ })
1240
+ });
1241
+ var ImageResponseWithUnknownSchema = import_v44.z.union([
1242
+ ImageResponseSchema,
1243
+ import_v44.z.unknown().transform(() => null)
1244
+ ]);
1245
+ var ImageResponseArraySchema = import_v44.z.array(ImageResponseWithUnknownSchema).transform((d) => d.filter((d2) => !!d2));
1246
+
1247
+ // src/chat/schemas.ts
1248
+ var OpenRouterChatCompletionBaseResponseSchema = import_v45.z.object({
1249
+ id: import_v45.z.string().optional(),
1250
+ model: import_v45.z.string().optional(),
1251
+ provider: import_v45.z.string().optional(),
1252
+ usage: import_v45.z.object({
1253
+ prompt_tokens: import_v45.z.number(),
1254
+ prompt_tokens_details: import_v45.z.object({
1255
+ cached_tokens: import_v45.z.number()
1231
1256
  }).nullish(),
1232
- completion_tokens: import_v44.z.number(),
1233
- completion_tokens_details: import_v44.z.object({
1234
- reasoning_tokens: import_v44.z.number()
1257
+ completion_tokens: import_v45.z.number(),
1258
+ completion_tokens_details: import_v45.z.object({
1259
+ reasoning_tokens: import_v45.z.number()
1235
1260
  }).nullish(),
1236
- total_tokens: import_v44.z.number(),
1237
- cost: import_v44.z.number().optional(),
1238
- cost_details: import_v44.z.object({
1239
- upstream_inference_cost: import_v44.z.number().nullish()
1261
+ total_tokens: import_v45.z.number(),
1262
+ cost: import_v45.z.number().optional(),
1263
+ cost_details: import_v45.z.object({
1264
+ upstream_inference_cost: import_v45.z.number().nullish()
1240
1265
  }).nullish()
1241
1266
  }).nullish()
1242
1267
  });
1243
1268
  var OpenRouterNonStreamChatCompletionResponseSchema = OpenRouterChatCompletionBaseResponseSchema.extend({
1244
- choices: import_v44.z.array(
1245
- import_v44.z.object({
1246
- message: import_v44.z.object({
1247
- role: import_v44.z.literal("assistant"),
1248
- content: import_v44.z.string().nullable().optional(),
1249
- reasoning: import_v44.z.string().nullable().optional(),
1269
+ choices: import_v45.z.array(
1270
+ import_v45.z.object({
1271
+ message: import_v45.z.object({
1272
+ role: import_v45.z.literal("assistant"),
1273
+ content: import_v45.z.string().nullable().optional(),
1274
+ reasoning: import_v45.z.string().nullable().optional(),
1250
1275
  reasoning_details: ReasoningDetailArraySchema.nullish(),
1251
- tool_calls: import_v44.z.array(
1252
- import_v44.z.object({
1253
- id: import_v44.z.string().optional().nullable(),
1254
- type: import_v44.z.literal("function"),
1255
- function: import_v44.z.object({
1256
- name: import_v44.z.string(),
1257
- arguments: import_v44.z.string()
1276
+ images: ImageResponseArraySchema.nullish(),
1277
+ tool_calls: import_v45.z.array(
1278
+ import_v45.z.object({
1279
+ id: import_v45.z.string().optional().nullable(),
1280
+ type: import_v45.z.literal("function"),
1281
+ function: import_v45.z.object({
1282
+ name: import_v45.z.string(),
1283
+ arguments: import_v45.z.string()
1258
1284
  })
1259
1285
  })
1260
1286
  ).optional(),
1261
- annotations: import_v44.z.array(
1262
- import_v44.z.object({
1263
- type: import_v44.z.enum(["url_citation"]),
1264
- url_citation: import_v44.z.object({
1265
- end_index: import_v44.z.number(),
1266
- start_index: import_v44.z.number(),
1267
- title: import_v44.z.string(),
1268
- url: import_v44.z.string(),
1269
- content: import_v44.z.string().optional()
1287
+ annotations: import_v45.z.array(
1288
+ import_v45.z.object({
1289
+ type: import_v45.z.enum(["url_citation"]),
1290
+ url_citation: import_v45.z.object({
1291
+ end_index: import_v45.z.number(),
1292
+ start_index: import_v45.z.number(),
1293
+ title: import_v45.z.string(),
1294
+ url: import_v45.z.string(),
1295
+ content: import_v45.z.string().optional()
1270
1296
  })
1271
1297
  })
1272
1298
  ).nullish()
1273
1299
  }),
1274
- index: import_v44.z.number().nullish(),
1275
- logprobs: import_v44.z.object({
1276
- content: import_v44.z.array(
1277
- import_v44.z.object({
1278
- token: import_v44.z.string(),
1279
- logprob: import_v44.z.number(),
1280
- top_logprobs: import_v44.z.array(
1281
- import_v44.z.object({
1282
- token: import_v44.z.string(),
1283
- logprob: import_v44.z.number()
1300
+ index: import_v45.z.number().nullish(),
1301
+ logprobs: import_v45.z.object({
1302
+ content: import_v45.z.array(
1303
+ import_v45.z.object({
1304
+ token: import_v45.z.string(),
1305
+ logprob: import_v45.z.number(),
1306
+ top_logprobs: import_v45.z.array(
1307
+ import_v45.z.object({
1308
+ token: import_v45.z.string(),
1309
+ logprob: import_v45.z.number()
1284
1310
  })
1285
1311
  )
1286
1312
  })
1287
1313
  ).nullable()
1288
1314
  }).nullable().optional(),
1289
- finish_reason: import_v44.z.string().optional().nullable()
1315
+ finish_reason: import_v45.z.string().optional().nullable()
1290
1316
  })
1291
1317
  )
1292
1318
  });
1293
- var OpenRouterStreamChatCompletionChunkSchema = import_v44.z.union([
1319
+ var OpenRouterStreamChatCompletionChunkSchema = import_v45.z.union([
1294
1320
  OpenRouterChatCompletionBaseResponseSchema.extend({
1295
- choices: import_v44.z.array(
1296
- import_v44.z.object({
1297
- delta: import_v44.z.object({
1298
- role: import_v44.z.enum(["assistant"]).optional(),
1299
- content: import_v44.z.string().nullish(),
1300
- reasoning: import_v44.z.string().nullish().optional(),
1321
+ choices: import_v45.z.array(
1322
+ import_v45.z.object({
1323
+ delta: import_v45.z.object({
1324
+ role: import_v45.z.enum(["assistant"]).optional(),
1325
+ content: import_v45.z.string().nullish(),
1326
+ reasoning: import_v45.z.string().nullish().optional(),
1301
1327
  reasoning_details: ReasoningDetailArraySchema.nullish(),
1302
- tool_calls: import_v44.z.array(
1303
- import_v44.z.object({
1304
- index: import_v44.z.number().nullish(),
1305
- id: import_v44.z.string().nullish(),
1306
- type: import_v44.z.literal("function").optional(),
1307
- function: import_v44.z.object({
1308
- name: import_v44.z.string().nullish(),
1309
- arguments: import_v44.z.string().nullish()
1328
+ images: ImageResponseArraySchema.nullish(),
1329
+ tool_calls: import_v45.z.array(
1330
+ import_v45.z.object({
1331
+ index: import_v45.z.number().nullish(),
1332
+ id: import_v45.z.string().nullish(),
1333
+ type: import_v45.z.literal("function").optional(),
1334
+ function: import_v45.z.object({
1335
+ name: import_v45.z.string().nullish(),
1336
+ arguments: import_v45.z.string().nullish()
1310
1337
  })
1311
1338
  })
1312
1339
  ).nullish(),
1313
- annotations: import_v44.z.array(
1314
- import_v44.z.object({
1315
- type: import_v44.z.enum(["url_citation"]),
1316
- url_citation: import_v44.z.object({
1317
- end_index: import_v44.z.number(),
1318
- start_index: import_v44.z.number(),
1319
- title: import_v44.z.string(),
1320
- url: import_v44.z.string(),
1321
- content: import_v44.z.string().optional()
1340
+ annotations: import_v45.z.array(
1341
+ import_v45.z.object({
1342
+ type: import_v45.z.enum(["url_citation"]),
1343
+ url_citation: import_v45.z.object({
1344
+ end_index: import_v45.z.number(),
1345
+ start_index: import_v45.z.number(),
1346
+ title: import_v45.z.string(),
1347
+ url: import_v45.z.string(),
1348
+ content: import_v45.z.string().optional()
1322
1349
  })
1323
1350
  })
1324
1351
  ).nullish()
1325
1352
  }).nullish(),
1326
- logprobs: import_v44.z.object({
1327
- content: import_v44.z.array(
1328
- import_v44.z.object({
1329
- token: import_v44.z.string(),
1330
- logprob: import_v44.z.number(),
1331
- top_logprobs: import_v44.z.array(
1332
- import_v44.z.object({
1333
- token: import_v44.z.string(),
1334
- logprob: import_v44.z.number()
1353
+ logprobs: import_v45.z.object({
1354
+ content: import_v45.z.array(
1355
+ import_v45.z.object({
1356
+ token: import_v45.z.string(),
1357
+ logprob: import_v45.z.number(),
1358
+ top_logprobs: import_v45.z.array(
1359
+ import_v45.z.object({
1360
+ token: import_v45.z.string(),
1361
+ logprob: import_v45.z.number()
1335
1362
  })
1336
1363
  )
1337
1364
  })
1338
1365
  ).nullable()
1339
1366
  }).nullish(),
1340
- finish_reason: import_v44.z.string().nullable().optional(),
1341
- index: import_v44.z.number().nullish()
1367
+ finish_reason: import_v45.z.string().nullable().optional(),
1368
+ index: import_v45.z.number().nullish()
1342
1369
  })
1343
1370
  )
1344
1371
  }),
@@ -1535,6 +1562,15 @@ var OpenRouterChatLanguageModel = class {
1535
1562
  });
1536
1563
  }
1537
1564
  }
1565
+ if (choice.message.images) {
1566
+ for (const image of choice.message.images) {
1567
+ content.push({
1568
+ type: "file",
1569
+ mediaType: getMediaType(image.image_url.url, "image/jpeg"),
1570
+ data: getBase64FromDataUrl(image.image_url.url)
1571
+ });
1572
+ }
1573
+ }
1538
1574
  if (choice.message.annotations) {
1539
1575
  for (const annotation of choice.message.annotations) {
1540
1576
  if (annotation.type === "url_citation") {
@@ -1868,6 +1904,15 @@ var OpenRouterChatLanguageModel = class {
1868
1904
  }
1869
1905
  }
1870
1906
  }
1907
+ if (delta.images != null) {
1908
+ for (const image of delta.images) {
1909
+ controller.enqueue({
1910
+ type: "file",
1911
+ mediaType: getMediaType(image.image_url.url, "image/jpeg"),
1912
+ data: getBase64FromDataUrl(image.image_url.url)
1913
+ });
1914
+ }
1915
+ }
1871
1916
  },
1872
1917
  flush(controller) {
1873
1918
  var _a16;
@@ -2025,36 +2070,36 @@ ${assistantMessage}
2025
2070
  }
2026
2071
 
2027
2072
  // src/completion/schemas.ts
2028
- var import_v45 = require("zod/v4");
2029
- var OpenRouterCompletionChunkSchema = import_v45.z.union([
2030
- import_v45.z.object({
2031
- id: import_v45.z.string().optional(),
2032
- model: import_v45.z.string().optional(),
2033
- choices: import_v45.z.array(
2034
- import_v45.z.object({
2035
- text: import_v45.z.string(),
2036
- reasoning: import_v45.z.string().nullish().optional(),
2073
+ var import_v46 = require("zod/v4");
2074
+ var OpenRouterCompletionChunkSchema = import_v46.z.union([
2075
+ import_v46.z.object({
2076
+ id: import_v46.z.string().optional(),
2077
+ model: import_v46.z.string().optional(),
2078
+ choices: import_v46.z.array(
2079
+ import_v46.z.object({
2080
+ text: import_v46.z.string(),
2081
+ reasoning: import_v46.z.string().nullish().optional(),
2037
2082
  reasoning_details: ReasoningDetailArraySchema.nullish(),
2038
- finish_reason: import_v45.z.string().nullish(),
2039
- index: import_v45.z.number().nullish(),
2040
- logprobs: import_v45.z.object({
2041
- tokens: import_v45.z.array(import_v45.z.string()),
2042
- token_logprobs: import_v45.z.array(import_v45.z.number()),
2043
- top_logprobs: import_v45.z.array(import_v45.z.record(import_v45.z.string(), import_v45.z.number())).nullable()
2083
+ finish_reason: import_v46.z.string().nullish(),
2084
+ index: import_v46.z.number().nullish(),
2085
+ logprobs: import_v46.z.object({
2086
+ tokens: import_v46.z.array(import_v46.z.string()),
2087
+ token_logprobs: import_v46.z.array(import_v46.z.number()),
2088
+ top_logprobs: import_v46.z.array(import_v46.z.record(import_v46.z.string(), import_v46.z.number())).nullable()
2044
2089
  }).nullable().optional()
2045
2090
  })
2046
2091
  ),
2047
- usage: import_v45.z.object({
2048
- prompt_tokens: import_v45.z.number(),
2049
- prompt_tokens_details: import_v45.z.object({
2050
- cached_tokens: import_v45.z.number()
2092
+ usage: import_v46.z.object({
2093
+ prompt_tokens: import_v46.z.number(),
2094
+ prompt_tokens_details: import_v46.z.object({
2095
+ cached_tokens: import_v46.z.number()
2051
2096
  }).nullish(),
2052
- completion_tokens: import_v45.z.number(),
2053
- completion_tokens_details: import_v45.z.object({
2054
- reasoning_tokens: import_v45.z.number()
2097
+ completion_tokens: import_v46.z.number(),
2098
+ completion_tokens_details: import_v46.z.object({
2099
+ reasoning_tokens: import_v46.z.number()
2055
2100
  }).nullish(),
2056
- total_tokens: import_v45.z.number(),
2057
- cost: import_v45.z.number().optional()
2101
+ total_tokens: import_v46.z.number(),
2102
+ cost: import_v46.z.number().optional()
2058
2103
  }).nullish()
2059
2104
  }),
2060
2105
  OpenRouterErrorResponseSchema