@openrouter/ai-sdk-provider 1.2.1 → 1.2.2

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.d.mts CHANGED
@@ -1,5 +1,6 @@
1
- import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, LanguageModelV2CallWarning, LanguageModelV2ResponseMetadata, SharedV2Headers, LanguageModelV2StreamPart } from '@ai-sdk/provider';
1
+ import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, LanguageModelV2CallWarning, LanguageModelV2ResponseMetadata, SharedV2Headers, LanguageModelV2StreamPart, ProviderV2 } from '@ai-sdk/provider';
2
2
  export { LanguageModelV2, LanguageModelV2Prompt } from '@ai-sdk/provider';
3
+ import * as models from '@openrouter/sdk/models';
3
4
  import { z } from 'zod/v4';
4
5
 
5
6
  type OpenRouterChatModelId = string;
@@ -41,18 +42,21 @@ type OpenRouterChatSettings = {
41
42
  */
42
43
  user?: string;
43
44
  /**
44
- * Web search plugin configuration for enabling web search capabilities
45
+ * Plugin configurations for enabling various capabilities
45
46
  */
46
47
  plugins?: Array<{
47
- id: 'web';
48
- /**
49
- * Maximum number of search results to include (default: 5)
50
- */
48
+ id: models.IdWeb;
51
49
  max_results?: number;
52
- /**
53
- * Custom search prompt to guide the search query
54
- */
55
50
  search_prompt?: string;
51
+ engine?: models.Engine;
52
+ } | {
53
+ id: models.IdFileParser;
54
+ max_files?: number;
55
+ pdf?: {
56
+ engine?: models.PdfEngine;
57
+ };
58
+ } | {
59
+ id: models.IdModeration;
56
60
  }>;
57
61
  /**
58
62
  * Built-in web search options for models that support native web search
@@ -86,7 +90,7 @@ type OpenRouterChatSettings = {
86
90
  /**
87
91
  * Control whether to use providers that may store data
88
92
  */
89
- data_collection?: 'allow' | 'deny';
93
+ data_collection?: models.DataCollection;
90
94
  /**
91
95
  * List of provider slugs to allow for this request
92
96
  */
@@ -98,11 +102,11 @@ type OpenRouterChatSettings = {
98
102
  /**
99
103
  * List of quantization levels to filter by (e.g. ["int4", "int8"])
100
104
  */
101
- quantizations?: Array<'int4' | 'int8' | 'fp4' | 'fp6' | 'fp8' | 'fp16' | 'bf16' | 'fp32' | 'unknown'>;
105
+ quantizations?: Array<models.Quantization>;
102
106
  /**
103
107
  * Sort providers by price, throughput, or latency
104
108
  */
105
- sort?: 'price' | 'throughput' | 'latency';
109
+ sort?: models.Sort;
106
110
  /**
107
111
  * Maximum pricing you want to pay for this request
108
112
  */
@@ -322,7 +326,7 @@ declare class OpenRouterCompletionLanguageModel implements LanguageModelV2 {
322
326
  doStream(options: LanguageModelV2CallOptions): Promise<Awaited<ReturnType<LanguageModelV2['doStream']>>>;
323
327
  }
324
328
 
325
- interface OpenRouterProvider extends LanguageModelV2 {
329
+ interface OpenRouterProvider extends ProviderV2 {
326
330
  (modelId: OpenRouterChatModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
327
331
  (modelId: OpenRouterChatModelId, settings?: OpenRouterChatSettings): OpenRouterChatLanguageModel;
328
332
  languageModel(modelId: OpenRouterChatModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, LanguageModelV2CallWarning, LanguageModelV2ResponseMetadata, SharedV2Headers, LanguageModelV2StreamPart } from '@ai-sdk/provider';
1
+ import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, LanguageModelV2CallWarning, LanguageModelV2ResponseMetadata, SharedV2Headers, LanguageModelV2StreamPart, ProviderV2 } from '@ai-sdk/provider';
2
2
  export { LanguageModelV2, LanguageModelV2Prompt } from '@ai-sdk/provider';
3
+ import * as models from '@openrouter/sdk/models';
3
4
  import { z } from 'zod/v4';
4
5
 
5
6
  type OpenRouterChatModelId = string;
@@ -41,18 +42,21 @@ type OpenRouterChatSettings = {
41
42
  */
42
43
  user?: string;
43
44
  /**
44
- * Web search plugin configuration for enabling web search capabilities
45
+ * Plugin configurations for enabling various capabilities
45
46
  */
46
47
  plugins?: Array<{
47
- id: 'web';
48
- /**
49
- * Maximum number of search results to include (default: 5)
50
- */
48
+ id: models.IdWeb;
51
49
  max_results?: number;
52
- /**
53
- * Custom search prompt to guide the search query
54
- */
55
50
  search_prompt?: string;
51
+ engine?: models.Engine;
52
+ } | {
53
+ id: models.IdFileParser;
54
+ max_files?: number;
55
+ pdf?: {
56
+ engine?: models.PdfEngine;
57
+ };
58
+ } | {
59
+ id: models.IdModeration;
56
60
  }>;
57
61
  /**
58
62
  * Built-in web search options for models that support native web search
@@ -86,7 +90,7 @@ type OpenRouterChatSettings = {
86
90
  /**
87
91
  * Control whether to use providers that may store data
88
92
  */
89
- data_collection?: 'allow' | 'deny';
93
+ data_collection?: models.DataCollection;
90
94
  /**
91
95
  * List of provider slugs to allow for this request
92
96
  */
@@ -98,11 +102,11 @@ type OpenRouterChatSettings = {
98
102
  /**
99
103
  * List of quantization levels to filter by (e.g. ["int4", "int8"])
100
104
  */
101
- quantizations?: Array<'int4' | 'int8' | 'fp4' | 'fp6' | 'fp8' | 'fp16' | 'bf16' | 'fp32' | 'unknown'>;
105
+ quantizations?: Array<models.Quantization>;
102
106
  /**
103
107
  * Sort providers by price, throughput, or latency
104
108
  */
105
- sort?: 'price' | 'throughput' | 'latency';
109
+ sort?: models.Sort;
106
110
  /**
107
111
  * Maximum pricing you want to pay for this request
108
112
  */
@@ -322,7 +326,7 @@ declare class OpenRouterCompletionLanguageModel implements LanguageModelV2 {
322
326
  doStream(options: LanguageModelV2CallOptions): Promise<Awaited<ReturnType<LanguageModelV2['doStream']>>>;
323
327
  }
324
328
 
325
- interface OpenRouterProvider extends LanguageModelV2 {
329
+ interface OpenRouterProvider extends ProviderV2 {
326
330
  (modelId: OpenRouterChatModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
327
331
  (modelId: OpenRouterChatModelId, settings?: OpenRouterChatSettings): OpenRouterChatLanguageModel;
328
332
  languageModel(modelId: OpenRouterChatModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
package/dist/index.js CHANGED
@@ -253,6 +253,18 @@ var name9 = "AI_NoContentGeneratedError";
253
253
  var marker10 = `vercel.ai.error.${name9}`;
254
254
  var symbol10 = Symbol.for(marker10);
255
255
  var _a10;
256
+ var NoContentGeneratedError = class extends AISDKError {
257
+ // used in isInstance
258
+ constructor({
259
+ message = "No content generated."
260
+ } = {}) {
261
+ super({ name: name9, message });
262
+ this[_a10] = true;
263
+ }
264
+ static isInstance(error) {
265
+ return AISDKError.hasMarker(error, marker10);
266
+ }
267
+ };
256
268
  _a10 = symbol10;
257
269
  var name10 = "AI_NoSuchModelError";
258
270
  var marker11 = `vercel.ai.error.${name10}`;
@@ -968,12 +980,16 @@ var OutputUnionToReasoningDetailsSchema = import_v4.z.union([
968
980
  delta: import_v4.z.object({
969
981
  reasoning_details: import_v4.z.array(ReasoningDetailsWithUnknownSchema)
970
982
  })
971
- }).transform((data) => data.delta.reasoning_details.filter(isDefinedOrNotNull)),
983
+ }).transform(
984
+ (data) => data.delta.reasoning_details.filter(isDefinedOrNotNull)
985
+ ),
972
986
  import_v4.z.object({
973
987
  message: import_v4.z.object({
974
988
  reasoning_details: import_v4.z.array(ReasoningDetailsWithUnknownSchema)
975
989
  })
976
- }).transform((data) => data.message.reasoning_details.filter(isDefinedOrNotNull)),
990
+ }).transform(
991
+ (data) => data.message.reasoning_details.filter(isDefinedOrNotNull)
992
+ ),
977
993
  import_v4.z.object({
978
994
  text: import_v4.z.string(),
979
995
  reasoning_details: import_v4.z.array(ReasoningDetailsWithUnknownSchema)
@@ -1221,9 +1237,7 @@ function convertToOpenRouterChatMessages(prompt) {
1221
1237
  }
1222
1238
  }
1223
1239
  }
1224
- const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(
1225
- providerOptions
1226
- );
1240
+ const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
1227
1241
  const preservedReasoningDetails = parsedProviderOptions.success ? (_d = (_c = parsedProviderOptions.data) == null ? void 0 : _c.openrouter) == null ? void 0 : _d.reasoning_details : void 0;
1228
1242
  messages.push({
1229
1243
  role: "assistant",
@@ -1286,7 +1300,10 @@ function getChatCompletionToolChoice(toolChoice) {
1286
1300
  }
1287
1301
  default: {
1288
1302
  toolChoice;
1289
- throw new Error(`Invalid tool choice type: ${toolChoice}`);
1303
+ throw new InvalidArgumentError({
1304
+ argument: "toolChoice",
1305
+ message: `Invalid tool choice type: ${JSON.stringify(toolChoice)}`
1306
+ });
1290
1307
  }
1291
1308
  }
1292
1309
  }
@@ -1329,57 +1346,89 @@ var OpenRouterChatCompletionBaseResponseSchema = import_v46.z.object({
1329
1346
  }).nullish()
1330
1347
  }).nullish()
1331
1348
  });
1332
- var OpenRouterNonStreamChatCompletionResponseSchema = OpenRouterChatCompletionBaseResponseSchema.extend({
1333
- choices: import_v46.z.array(
1334
- import_v46.z.object({
1335
- message: import_v46.z.object({
1336
- role: import_v46.z.literal("assistant"),
1337
- content: import_v46.z.string().nullable().optional(),
1338
- reasoning: import_v46.z.string().nullable().optional(),
1339
- reasoning_details: ReasoningDetailArraySchema.nullish(),
1340
- images: ImageResponseArraySchema.nullish(),
1341
- tool_calls: import_v46.z.array(
1342
- import_v46.z.object({
1343
- id: import_v46.z.string().optional().nullable(),
1344
- type: import_v46.z.literal("function"),
1345
- function: import_v46.z.object({
1346
- name: import_v46.z.string(),
1347
- arguments: import_v46.z.string()
1348
- })
1349
- })
1350
- ).optional(),
1351
- annotations: import_v46.z.array(
1352
- import_v46.z.object({
1353
- type: import_v46.z.enum(["url_citation"]),
1354
- url_citation: import_v46.z.object({
1355
- end_index: import_v46.z.number(),
1356
- start_index: import_v46.z.number(),
1357
- title: import_v46.z.string(),
1358
- url: import_v46.z.string(),
1359
- content: import_v46.z.string().optional()
1349
+ var OpenRouterNonStreamChatCompletionResponseSchema = import_v46.z.union([
1350
+ // Success response with choices
1351
+ OpenRouterChatCompletionBaseResponseSchema.extend({
1352
+ choices: import_v46.z.array(
1353
+ import_v46.z.object({
1354
+ message: import_v46.z.object({
1355
+ role: import_v46.z.literal("assistant"),
1356
+ content: import_v46.z.string().nullable().optional(),
1357
+ reasoning: import_v46.z.string().nullable().optional(),
1358
+ reasoning_details: ReasoningDetailArraySchema.nullish(),
1359
+ images: ImageResponseArraySchema.nullish(),
1360
+ tool_calls: import_v46.z.array(
1361
+ import_v46.z.object({
1362
+ id: import_v46.z.string().optional().nullable(),
1363
+ type: import_v46.z.literal("function"),
1364
+ function: import_v46.z.object({
1365
+ name: import_v46.z.string(),
1366
+ arguments: import_v46.z.string()
1367
+ })
1360
1368
  })
1361
- })
1362
- ).nullish()
1363
- }),
1364
- index: import_v46.z.number().nullish(),
1365
- logprobs: import_v46.z.object({
1366
- content: import_v46.z.array(
1367
- import_v46.z.object({
1368
- token: import_v46.z.string(),
1369
- logprob: import_v46.z.number(),
1370
- top_logprobs: import_v46.z.array(
1369
+ ).optional(),
1370
+ annotations: import_v46.z.array(
1371
+ import_v46.z.union([
1372
+ // URL citation from web search
1373
+ import_v46.z.object({
1374
+ type: import_v46.z.literal("url_citation"),
1375
+ url_citation: import_v46.z.object({
1376
+ end_index: import_v46.z.number(),
1377
+ start_index: import_v46.z.number(),
1378
+ title: import_v46.z.string(),
1379
+ url: import_v46.z.string(),
1380
+ content: import_v46.z.string().optional()
1381
+ })
1382
+ }),
1383
+ // File annotation from FileParserPlugin (old format)
1384
+ import_v46.z.object({
1385
+ type: import_v46.z.literal("file_annotation"),
1386
+ file_annotation: import_v46.z.object({
1387
+ file_id: import_v46.z.string(),
1388
+ quote: import_v46.z.string().optional()
1389
+ })
1390
+ }),
1391
+ // File annotation from FileParserPlugin (new format)
1371
1392
  import_v46.z.object({
1372
- token: import_v46.z.string(),
1373
- logprob: import_v46.z.number()
1393
+ type: import_v46.z.literal("file"),
1394
+ file: import_v46.z.object({
1395
+ hash: import_v46.z.string(),
1396
+ name: import_v46.z.string(),
1397
+ content: import_v46.z.array(
1398
+ import_v46.z.object({
1399
+ type: import_v46.z.string(),
1400
+ text: import_v46.z.string()
1401
+ })
1402
+ ).optional()
1403
+ })
1374
1404
  })
1375
- )
1376
- })
1377
- ).nullable()
1378
- }).nullable().optional(),
1379
- finish_reason: import_v46.z.string().optional().nullable()
1380
- })
1381
- )
1382
- });
1405
+ ])
1406
+ ).nullish()
1407
+ }),
1408
+ index: import_v46.z.number().nullish(),
1409
+ logprobs: import_v46.z.object({
1410
+ content: import_v46.z.array(
1411
+ import_v46.z.object({
1412
+ token: import_v46.z.string(),
1413
+ logprob: import_v46.z.number(),
1414
+ top_logprobs: import_v46.z.array(
1415
+ import_v46.z.object({
1416
+ token: import_v46.z.string(),
1417
+ logprob: import_v46.z.number()
1418
+ })
1419
+ )
1420
+ })
1421
+ ).nullable()
1422
+ }).nullable().optional(),
1423
+ finish_reason: import_v46.z.string().optional().nullable()
1424
+ })
1425
+ )
1426
+ }),
1427
+ // Error response (HTTP 200 with error payload)
1428
+ OpenRouterErrorResponseSchema.extend({
1429
+ user_id: import_v46.z.string().optional()
1430
+ })
1431
+ ]);
1383
1432
  var OpenRouterStreamChatCompletionChunkSchema = import_v46.z.union([
1384
1433
  OpenRouterChatCompletionBaseResponseSchema.extend({
1385
1434
  choices: import_v46.z.array(
@@ -1402,16 +1451,41 @@ var OpenRouterStreamChatCompletionChunkSchema = import_v46.z.union([
1402
1451
  })
1403
1452
  ).nullish(),
1404
1453
  annotations: import_v46.z.array(
1405
- import_v46.z.object({
1406
- type: import_v46.z.enum(["url_citation"]),
1407
- url_citation: import_v46.z.object({
1408
- end_index: import_v46.z.number(),
1409
- start_index: import_v46.z.number(),
1410
- title: import_v46.z.string(),
1411
- url: import_v46.z.string(),
1412
- content: import_v46.z.string().optional()
1454
+ import_v46.z.union([
1455
+ // URL citation from web search
1456
+ import_v46.z.object({
1457
+ type: import_v46.z.literal("url_citation"),
1458
+ url_citation: import_v46.z.object({
1459
+ end_index: import_v46.z.number(),
1460
+ start_index: import_v46.z.number(),
1461
+ title: import_v46.z.string(),
1462
+ url: import_v46.z.string(),
1463
+ content: import_v46.z.string().optional()
1464
+ })
1465
+ }),
1466
+ // File annotation from FileParserPlugin (old format)
1467
+ import_v46.z.object({
1468
+ type: import_v46.z.literal("file_annotation"),
1469
+ file_annotation: import_v46.z.object({
1470
+ file_id: import_v46.z.string(),
1471
+ quote: import_v46.z.string().optional()
1472
+ })
1473
+ }),
1474
+ // File annotation from FileParserPlugin (new format)
1475
+ import_v46.z.object({
1476
+ type: import_v46.z.literal("file"),
1477
+ file: import_v46.z.object({
1478
+ hash: import_v46.z.string(),
1479
+ name: import_v46.z.string(),
1480
+ content: import_v46.z.array(
1481
+ import_v46.z.object({
1482
+ type: import_v46.z.string(),
1483
+ text: import_v46.z.string()
1484
+ })
1485
+ ).optional()
1486
+ })
1413
1487
  })
1414
- })
1488
+ ])
1415
1489
  ).nullish()
1416
1490
  }).nullish(),
1417
1491
  logprobs: import_v46.z.object({
@@ -1536,7 +1610,7 @@ var OpenRouterChatLanguageModel = class {
1536
1610
  const providerOptions = options.providerOptions || {};
1537
1611
  const openrouterOptions = providerOptions.openrouter || {};
1538
1612
  const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
1539
- const { value: response, responseHeaders } = await postJsonToApi({
1613
+ const { value: responseValue, responseHeaders } = await postJsonToApi({
1540
1614
  url: this.config.url({
1541
1615
  path: "/chat/completions",
1542
1616
  modelId: this.modelId
@@ -1550,9 +1624,25 @@ var OpenRouterChatLanguageModel = class {
1550
1624
  abortSignal: options.abortSignal,
1551
1625
  fetch: this.config.fetch
1552
1626
  });
1627
+ if ("error" in responseValue) {
1628
+ throw new APICallError({
1629
+ message: responseValue.error.message,
1630
+ url: this.config.url({
1631
+ path: "/chat/completions",
1632
+ modelId: this.modelId
1633
+ }),
1634
+ requestBodyValues: args,
1635
+ statusCode: 200,
1636
+ responseHeaders,
1637
+ data: responseValue.error
1638
+ });
1639
+ }
1640
+ const response = responseValue;
1553
1641
  const choice = response.choices[0];
1554
1642
  if (!choice) {
1555
- throw new Error("No choice in response");
1643
+ throw new NoContentGeneratedError({
1644
+ message: "No choice in response"
1645
+ });
1556
1646
  }
1557
1647
  const usageInfo = response.usage ? {
1558
1648
  inputTokens: (_a15 = response.usage.prompt_tokens) != null ? _a15 : 0,
@@ -1912,7 +2002,10 @@ var OpenRouterChatLanguageModel = class {
1912
2002
  };
1913
2003
  const toolCall2 = toolCalls[index];
1914
2004
  if (toolCall2 == null) {
1915
- throw new Error("Tool call is missing");
2005
+ throw new InvalidResponseDataError({
2006
+ data: { index, toolCallsLength: toolCalls.length },
2007
+ message: `Tool call at index ${index} is missing after creation.`
2008
+ });
1916
2009
  }
1917
2010
  if (((_f = toolCall2.function) == null ? void 0 : _f.name) != null && ((_g = toolCall2.function) == null ? void 0 : _g.arguments) != null && isParsableJson(toolCall2.function.arguments)) {
1918
2011
  toolCall2.inputStarted = true;
@@ -1942,7 +2035,14 @@ var OpenRouterChatLanguageModel = class {
1942
2035
  }
1943
2036
  const toolCall = toolCalls[index];
1944
2037
  if (toolCall == null) {
1945
- throw new Error("Tool call is missing");
2038
+ throw new InvalidResponseDataError({
2039
+ data: {
2040
+ index,
2041
+ toolCallsLength: toolCalls.length,
2042
+ toolCallDelta
2043
+ },
2044
+ message: `Tool call at index ${index} is missing during merge.`
2045
+ });
1946
2046
  }
1947
2047
  if (!toolCall.inputStarted) {
1948
2048
  toolCall.inputStarted = true;
@@ -2267,11 +2367,23 @@ var OpenRouterCompletionLanguageModel = class {
2267
2367
  fetch: this.config.fetch
2268
2368
  });
2269
2369
  if ("error" in response) {
2270
- throw new Error(`${response.error.message}`);
2370
+ throw new APICallError({
2371
+ message: response.error.message,
2372
+ url: this.config.url({
2373
+ path: "/completions",
2374
+ modelId: this.modelId
2375
+ }),
2376
+ requestBodyValues: args,
2377
+ statusCode: 200,
2378
+ responseHeaders,
2379
+ data: response.error
2380
+ });
2271
2381
  }
2272
2382
  const choice = response.choices[0];
2273
2383
  if (!choice) {
2274
- throw new Error("No choice in OpenRouter completion response");
2384
+ throw new NoContentGeneratedError({
2385
+ message: "No choice in OpenRouter completion response"
2386
+ });
2275
2387
  }
2276
2388
  return {
2277
2389
  content: [
@@ -2438,9 +2550,6 @@ var OpenRouter = class {
2438
2550
  }
2439
2551
  };
2440
2552
 
2441
- // src/version.ts
2442
- var VERSION = false ? "0.0.0-test" : "1.2.1";
2443
-
2444
2553
  // src/utils/remove-undefined.ts
2445
2554
  function removeUndefinedEntries2(record) {
2446
2555
  return Object.fromEntries(
@@ -2460,6 +2569,9 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
2460
2569
  });
2461
2570
  }
2462
2571
 
2572
+ // src/version.ts
2573
+ var VERSION = false ? "0.0.0-test" : "1.2.2";
2574
+
2463
2575
  // src/provider.ts
2464
2576
  function createOpenRouter(options = {}) {
2465
2577
  var _a15, _b, _c;