@openrouter/ai-sdk-provider 0.4.2 → 0.4.4

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
@@ -129,6 +129,7 @@ await streamText({
129
129
  content: 'You are a helpful assistant.',
130
130
  // Add provider options at the message level
131
131
  providerMetadata: {
132
+ // openrouter or anthropic
132
133
  openrouter: {
133
134
  // cache_control also works
134
135
  // cache_control: { type: 'ephemeral' }
package/dist/index.js CHANGED
@@ -65,15 +65,15 @@ var import_zod2 = require("zod");
65
65
 
66
66
  // src/convert-to-openrouter-chat-messages.ts
67
67
  var import_provider_utils = require("@ai-sdk/provider-utils");
68
+ function getCacheControl(providerMetadata) {
69
+ var _a, _b, _c;
70
+ const anthropic = providerMetadata == null ? void 0 : providerMetadata.anthropic;
71
+ const openrouter2 = providerMetadata == null ? void 0 : providerMetadata.openrouter;
72
+ return (_c = (_b = (_a = openrouter2 == null ? void 0 : openrouter2.cacheControl) != null ? _a : openrouter2 == null ? void 0 : openrouter2.cache_control) != null ? _b : anthropic == null ? void 0 : anthropic.cacheControl) != null ? _c : anthropic == null ? void 0 : anthropic.cache_control;
73
+ }
68
74
  function convertToOpenRouterChatMessages(prompt) {
69
75
  var _a, _b, _c;
70
76
  const messages = [];
71
- function getCacheControl(providerMetadata) {
72
- var _a2;
73
- const anthropic = providerMetadata == null ? void 0 : providerMetadata.anthropic;
74
- const cacheControlValue = (_a2 = anthropic == null ? void 0 : anthropic.cacheControl) != null ? _a2 : anthropic == null ? void 0 : anthropic.cache_control;
75
- return cacheControlValue;
76
- }
77
77
  for (const { role, content, providerMetadata } of prompt) {
78
78
  switch (role) {
79
79
  case "system": {
@@ -96,31 +96,31 @@ function convertToOpenRouterChatMessages(prompt) {
96
96
  const messageCacheControl = getCacheControl(providerMetadata);
97
97
  const contentParts = content.map(
98
98
  (part) => {
99
- var _a2, _b2, _c2;
99
+ var _a2, _b2, _c2, _d;
100
100
  switch (part.type) {
101
101
  case "text":
102
102
  return {
103
103
  type: "text",
104
104
  text: part.text,
105
105
  // For text parts, only use part-specific cache control
106
- cache_control: getCacheControl(part.providerMetadata)
106
+ cache_control: (_a2 = getCacheControl(part.providerMetadata)) != null ? _a2 : messageCacheControl
107
107
  };
108
108
  case "image":
109
109
  return {
110
110
  type: "image_url",
111
111
  image_url: {
112
- url: part.image instanceof URL ? part.image.toString() : `data:${(_a2 = part.mimeType) != null ? _a2 : "image/jpeg"};base64,${(0, import_provider_utils.convertUint8ArrayToBase64)(
112
+ url: part.image instanceof URL ? part.image.toString() : `data:${(_b2 = part.mimeType) != null ? _b2 : "image/jpeg"};base64,${(0, import_provider_utils.convertUint8ArrayToBase64)(
113
113
  part.image
114
114
  )}`
115
115
  },
116
116
  // For image parts, use part-specific or message-level cache control
117
- cache_control: (_b2 = getCacheControl(part.providerMetadata)) != null ? _b2 : messageCacheControl
117
+ cache_control: (_c2 = getCacheControl(part.providerMetadata)) != null ? _c2 : messageCacheControl
118
118
  };
119
119
  case "file":
120
120
  return {
121
121
  type: "text",
122
122
  text: part.data instanceof URL ? part.data.toString() : part.data,
123
- cache_control: (_c2 = getCacheControl(part.providerMetadata)) != null ? _c2 : messageCacheControl
123
+ cache_control: (_d = getCacheControl(part.providerMetadata)) != null ? _d : messageCacheControl
124
124
  };
125
125
  default: {
126
126
  const _exhaustiveCheck = part;
@@ -228,7 +228,7 @@ function mapOpenRouterFinishReason(finishReason) {
228
228
  // src/openrouter-error.ts
229
229
  var import_provider_utils2 = require("@ai-sdk/provider-utils");
230
230
  var import_zod = require("zod");
231
- var openAIErrorDataSchema = import_zod.z.object({
231
+ var OpenRouterErrorResponseSchema = import_zod.z.object({
232
232
  error: import_zod.z.object({
233
233
  message: import_zod.z.string(),
234
234
  type: import_zod.z.string(),
@@ -237,7 +237,7 @@ var openAIErrorDataSchema = import_zod.z.object({
237
237
  })
238
238
  });
239
239
  var openrouterFailedResponseHandler = (0, import_provider_utils2.createJsonErrorResponseHandler)({
240
- errorSchema: openAIErrorDataSchema,
240
+ errorSchema: OpenRouterErrorResponseSchema,
241
241
  errorToMessage: (data) => data.error.message
242
242
  });
243
243
 
@@ -333,7 +333,7 @@ var OpenRouterChatLanguageModel = class {
333
333
  }
334
334
  }
335
335
  async doGenerate(options) {
336
- var _b, _c, _d;
336
+ var _b, _c, _d, _e, _f, _g, _h;
337
337
  const args = this.getArgs(options);
338
338
  const { responseHeaders, value: response } = await (0, import_provider_utils3.postJsonToApi)({
339
339
  url: this.config.url({
@@ -344,17 +344,21 @@ var OpenRouterChatLanguageModel = class {
344
344
  body: args,
345
345
  failedResponseHandler: openrouterFailedResponseHandler,
346
346
  successfulResponseHandler: (0, import_provider_utils3.createJsonResponseHandler)(
347
- openAIChatResponseSchema
347
+ OpenRouterNonStreamChatCompletionResponseSchema
348
348
  ),
349
349
  abortSignal: options.abortSignal,
350
350
  fetch: this.config.fetch
351
351
  });
352
352
  const _a = args, { messages: rawPrompt } = _a, rawSettings = __objRest(_a, ["messages"]);
353
353
  const choice = response.choices[0];
354
- if (choice == null) {
354
+ if (!choice) {
355
355
  throw new Error("No choice in response");
356
356
  }
357
357
  return {
358
+ response: {
359
+ id: response.id,
360
+ modelId: response.model
361
+ },
358
362
  text: (_b = choice.message.content) != null ? _b : void 0,
359
363
  reasoning: (_c = choice.message.reasoning) != null ? _c : void 0,
360
364
  toolCalls: (_d = choice.message.tool_calls) == null ? void 0 : _d.map((toolCall) => {
@@ -368,8 +372,8 @@ var OpenRouterChatLanguageModel = class {
368
372
  }),
369
373
  finishReason: mapOpenRouterFinishReason(choice.finish_reason),
370
374
  usage: {
371
- promptTokens: response.usage.prompt_tokens,
372
- completionTokens: response.usage.completion_tokens
375
+ promptTokens: (_f = (_e = response.usage) == null ? void 0 : _e.prompt_tokens) != null ? _f : 0,
376
+ completionTokens: (_h = (_g = response.usage) == null ? void 0 : _g.completion_tokens) != null ? _h : 0
373
377
  },
374
378
  rawCall: { rawPrompt, rawSettings },
375
379
  rawResponse: { headers: responseHeaders },
@@ -392,7 +396,7 @@ var OpenRouterChatLanguageModel = class {
392
396
  }),
393
397
  failedResponseHandler: openrouterFailedResponseHandler,
394
398
  successfulResponseHandler: (0, import_provider_utils3.createEventSourceResponseHandler)(
395
- openrouterChatChunkSchema
399
+ OpenRouterStreamChatCompletionChunkSchema
396
400
  ),
397
401
  abortSignal: options.abortSignal,
398
402
  fetch: this.config.fetch
@@ -427,6 +431,12 @@ var OpenRouterChatLanguageModel = class {
427
431
  id: value.id
428
432
  });
429
433
  }
434
+ if (value.model) {
435
+ controller.enqueue({
436
+ type: "response-metadata",
437
+ modelId: value.model
438
+ });
439
+ }
430
440
  if (value.usage != null) {
431
441
  usage = {
432
442
  promptTokens: value.usage.prompt_tokens,
@@ -554,7 +564,16 @@ var OpenRouterChatLanguageModel = class {
554
564
  };
555
565
  }
556
566
  };
557
- var openAIChatResponseSchema = import_zod2.z.object({
567
+ var OpenRouterChatCompletionBaseResponseSchema = import_zod2.z.object({
568
+ id: import_zod2.z.string().optional(),
569
+ model: import_zod2.z.string().optional(),
570
+ usage: import_zod2.z.object({
571
+ prompt_tokens: import_zod2.z.number(),
572
+ completion_tokens: import_zod2.z.number(),
573
+ total_tokens: import_zod2.z.number()
574
+ }).nullish()
575
+ });
576
+ var OpenRouterNonStreamChatCompletionResponseSchema = OpenRouterChatCompletionBaseResponseSchema.extend({
558
577
  choices: import_zod2.z.array(
559
578
  import_zod2.z.object({
560
579
  message: import_zod2.z.object({
@@ -589,15 +608,10 @@ var openAIChatResponseSchema = import_zod2.z.object({
589
608
  }).nullable().optional(),
590
609
  finish_reason: import_zod2.z.string().optional().nullable()
591
610
  })
592
- ),
593
- usage: import_zod2.z.object({
594
- prompt_tokens: import_zod2.z.number(),
595
- completion_tokens: import_zod2.z.number()
596
- })
611
+ )
597
612
  });
598
- var openrouterChatChunkSchema = import_zod2.z.union([
599
- import_zod2.z.object({
600
- id: import_zod2.z.string().optional(),
613
+ var OpenRouterStreamChatCompletionChunkSchema = import_zod2.z.union([
614
+ OpenRouterChatCompletionBaseResponseSchema.extend({
601
615
  choices: import_zod2.z.array(
602
616
  import_zod2.z.object({
603
617
  delta: import_zod2.z.object({
@@ -633,13 +647,9 @@ var openrouterChatChunkSchema = import_zod2.z.union([
633
647
  finish_reason: import_zod2.z.string().nullable().optional(),
634
648
  index: import_zod2.z.number()
635
649
  })
636
- ),
637
- usage: import_zod2.z.object({
638
- prompt_tokens: import_zod2.z.number(),
639
- completion_tokens: import_zod2.z.number()
640
- }).nullish()
650
+ )
641
651
  }),
642
- openAIErrorDataSchema
652
+ OpenRouterErrorResponseSchema
643
653
  ]);
644
654
  function prepareToolsAndToolChoice(mode) {
645
655
  var _a;
@@ -917,6 +927,7 @@ var OpenRouterCompletionLanguageModel = class {
917
927
  }
918
928
  }
919
929
  async doGenerate(options) {
930
+ var _b, _c, _d, _e, _f;
920
931
  const args = this.getArgs(options);
921
932
  const { responseHeaders, value: response } = await (0, import_provider_utils4.postJsonToApi)({
922
933
  url: this.config.url({
@@ -927,22 +938,29 @@ var OpenRouterCompletionLanguageModel = class {
927
938
  body: args,
928
939
  failedResponseHandler: openrouterFailedResponseHandler,
929
940
  successfulResponseHandler: (0, import_provider_utils4.createJsonResponseHandler)(
930
- openAICompletionResponseSchema
941
+ OpenRouterCompletionChunkSchema
931
942
  ),
932
943
  abortSignal: options.abortSignal,
933
944
  fetch: this.config.fetch
934
945
  });
935
946
  const _a = args, { prompt: rawPrompt } = _a, rawSettings = __objRest(_a, ["prompt"]);
947
+ if ("error" in response) {
948
+ throw new Error(`${response.error.message}`);
949
+ }
936
950
  const choice = response.choices[0];
937
951
  if (!choice) {
938
952
  throw new Error("No choice in OpenRouter completion response");
939
953
  }
940
954
  return {
941
- text: choice.text,
955
+ response: {
956
+ id: response.id,
957
+ modelId: response.model
958
+ },
959
+ text: (_b = choice.text) != null ? _b : "",
942
960
  reasoning: choice.reasoning || void 0,
943
961
  usage: {
944
- promptTokens: response.usage.prompt_tokens,
945
- completionTokens: response.usage.completion_tokens
962
+ promptTokens: (_d = (_c = response.usage) == null ? void 0 : _c.prompt_tokens) != null ? _d : 0,
963
+ completionTokens: (_f = (_e = response.usage) == null ? void 0 : _e.completion_tokens) != null ? _f : 0
946
964
  },
947
965
  finishReason: mapOpenRouterFinishReason(choice.finish_reason),
948
966
  logprobs: mapOpenRouterCompletionLogProbs(choice.logprobs),
@@ -966,7 +984,7 @@ var OpenRouterCompletionLanguageModel = class {
966
984
  }),
967
985
  failedResponseHandler: openrouterFailedResponseHandler,
968
986
  successfulResponseHandler: (0, import_provider_utils4.createEventSourceResponseHandler)(
969
- openrouterCompletionChunkSchema
987
+ OpenRouterCompletionChunkSchema
970
988
  ),
971
989
  abortSignal: options.abortSignal,
972
990
  fetch: this.config.fetch
@@ -1033,29 +1051,14 @@ var OpenRouterCompletionLanguageModel = class {
1033
1051
  };
1034
1052
  }
1035
1053
  };
1036
- var openAICompletionResponseSchema = import_zod3.z.object({
1037
- choices: import_zod3.z.array(
1038
- import_zod3.z.object({
1039
- text: import_zod3.z.string(),
1040
- reasoning: import_zod3.z.string().nullish().optional(),
1041
- finish_reason: import_zod3.z.string(),
1042
- logprobs: import_zod3.z.object({
1043
- tokens: import_zod3.z.array(import_zod3.z.string()),
1044
- token_logprobs: import_zod3.z.array(import_zod3.z.number()),
1045
- top_logprobs: import_zod3.z.array(import_zod3.z.record(import_zod3.z.string(), import_zod3.z.number())).nullable()
1046
- }).nullable().optional()
1047
- })
1048
- ),
1049
- usage: import_zod3.z.object({
1050
- prompt_tokens: import_zod3.z.number(),
1051
- completion_tokens: import_zod3.z.number()
1052
- })
1053
- });
1054
- var openrouterCompletionChunkSchema = import_zod3.z.union([
1054
+ var OpenRouterCompletionChunkSchema = import_zod3.z.union([
1055
1055
  import_zod3.z.object({
1056
+ id: import_zod3.z.string().optional(),
1057
+ model: import_zod3.z.string().optional(),
1056
1058
  choices: import_zod3.z.array(
1057
1059
  import_zod3.z.object({
1058
1060
  text: import_zod3.z.string(),
1061
+ reasoning: import_zod3.z.string().nullish().optional(),
1059
1062
  finish_reason: import_zod3.z.string().nullish(),
1060
1063
  index: import_zod3.z.number(),
1061
1064
  logprobs: import_zod3.z.object({
@@ -1070,7 +1073,7 @@ var openrouterCompletionChunkSchema = import_zod3.z.union([
1070
1073
  completion_tokens: import_zod3.z.number()
1071
1074
  }).optional().nullable()
1072
1075
  }),
1073
- openAIErrorDataSchema
1076
+ OpenRouterErrorResponseSchema
1074
1077
  ]);
1075
1078
 
1076
1079
  // src/openrouter-facade.ts