@openrouter/ai-sdk-provider 1.3.0 → 1.4.1

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({
@@ -1000,7 +1014,8 @@ var OpenRouterProviderMetadataSchema = z3.object({
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,7 +1129,7 @@ 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, _g, _h;
1132
+ var _a15, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1118
1133
  const messages = [];
1119
1134
  for (const { role, content, providerOptions } of prompt) {
1120
1135
  switch (role) {
@@ -1268,6 +1283,7 @@ function convertToOpenRouterChatMessages(prompt) {
1268
1283
  }
1269
1284
  const parsedProviderOptions = OpenRouterProviderOptionsSchema.safeParse(providerOptions);
1270
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;
1271
1287
  const finalReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : accumulatedReasoningDetails.length > 0 ? accumulatedReasoningDetails : void 0;
1272
1288
  messages.push({
1273
1289
  role: "assistant",
@@ -1275,6 +1291,7 @@ function convertToOpenRouterChatMessages(prompt) {
1275
1291
  tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
1276
1292
  reasoning: reasoning || void 0,
1277
1293
  reasoning_details: finalReasoningDetails,
1294
+ annotations: messageAnnotations,
1278
1295
  cache_control: getCacheControl(providerOptions)
1279
1296
  });
1280
1297
  break;
@@ -1286,7 +1303,7 @@ function convertToOpenRouterChatMessages(prompt) {
1286
1303
  role: "tool",
1287
1304
  tool_call_id: toolResponse.toolCallId,
1288
1305
  content: content2,
1289
- cache_control: (_h = getCacheControl(providerOptions)) != null ? _h : getCacheControl(toolResponse.providerOptions)
1306
+ cache_control: (_j = getCacheControl(providerOptions)) != null ? _j : getCacheControl(toolResponse.providerOptions)
1290
1307
  });
1291
1308
  }
1292
1309
  break;
@@ -1545,6 +1562,7 @@ var OpenRouterChatLanguageModel = class {
1545
1562
  this.specificationVersion = "v2";
1546
1563
  this.provider = "openrouter";
1547
1564
  this.defaultObjectGenerationMode = "tool";
1565
+ this.supportsImageUrls = true;
1548
1566
  this.supportedUrls = {
1549
1567
  "image/*": [
1550
1568
  /^data:image\/[a-zA-Z]+;base64,/,
@@ -1590,7 +1608,16 @@ var OpenRouterChatLanguageModel = class {
1590
1608
  presence_penalty: presencePenalty,
1591
1609
  seed,
1592
1610
  stop: stopSequences,
1593
- response_format: responseFormat,
1611
+ response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? responseFormat.schema != null ? {
1612
+ type: "json_schema",
1613
+ json_schema: __spreadValues({
1614
+ schema: responseFormat.schema,
1615
+ strict: true,
1616
+ name: (_a15 = responseFormat.name) != null ? _a15 : "response"
1617
+ }, responseFormat.description && {
1618
+ description: responseFormat.description
1619
+ })
1620
+ } : { type: "json_object" } : void 0,
1594
1621
  top_k: topK,
1595
1622
  // messages:
1596
1623
  messages: convertToOpenRouterChatMessages(prompt),
@@ -1606,20 +1633,6 @@ var OpenRouterChatLanguageModel = class {
1606
1633
  // Debug settings:
1607
1634
  debug: this.settings.debug
1608
1635
  }, this.config.extraBody), this.settings.extraBody);
1609
- if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null) {
1610
- return __spreadProps(__spreadValues({}, baseArgs), {
1611
- response_format: {
1612
- type: "json_schema",
1613
- json_schema: __spreadValues({
1614
- schema: responseFormat.schema,
1615
- strict: true,
1616
- name: (_a15 = responseFormat.name) != null ? _a15 : "response"
1617
- }, responseFormat.description && {
1618
- description: responseFormat.description
1619
- })
1620
- }
1621
- });
1622
- }
1623
1636
  if (tools && tools.length > 0) {
1624
1637
  const mappedTools = tools.filter(
1625
1638
  (tool) => tool.type === "function"
@@ -1639,7 +1652,7 @@ var OpenRouterChatLanguageModel = class {
1639
1652
  return baseArgs;
1640
1653
  }
1641
1654
  async doGenerate(options) {
1642
- var _a15, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
1655
+ var _a15, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
1643
1656
  const providerOptions = options.providerOptions || {};
1644
1657
  const openrouterOptions = providerOptions.openrouter || {};
1645
1658
  const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
@@ -1797,6 +1810,9 @@ var OpenRouterChatLanguageModel = class {
1797
1810
  }
1798
1811
  }
1799
1812
  }
1813
+ const fileAnnotations = (_k = choice.message.annotations) == null ? void 0 : _k.filter(
1814
+ (a) => a.type === "file"
1815
+ );
1800
1816
  return {
1801
1817
  content,
1802
1818
  finishReason: mapOpenRouterFinishReason(choice.finish_reason),
@@ -1804,22 +1820,23 @@ var OpenRouterChatLanguageModel = class {
1804
1820
  warnings: [],
1805
1821
  providerMetadata: {
1806
1822
  openrouter: OpenRouterProviderMetadataSchema.parse({
1807
- provider: (_k = response.provider) != null ? _k : "",
1808
- reasoning_details: (_l = choice.message.reasoning_details) != null ? _l : [],
1823
+ provider: (_l = response.provider) != null ? _l : "",
1824
+ reasoning_details: (_m = choice.message.reasoning_details) != null ? _m : [],
1825
+ annotations: fileAnnotations && fileAnnotations.length > 0 ? fileAnnotations : void 0,
1809
1826
  usage: __spreadValues(__spreadValues(__spreadValues({
1810
- promptTokens: (_m = usageInfo.inputTokens) != null ? _m : 0,
1811
- completionTokens: (_n = usageInfo.outputTokens) != null ? _n : 0,
1812
- totalTokens: (_o = usageInfo.totalTokens) != null ? _o : 0,
1813
- cost: (_p = response.usage) == null ? void 0 : _p.cost
1814
- }, ((_r = (_q = response.usage) == null ? void 0 : _q.prompt_tokens_details) == null ? void 0 : _r.cached_tokens) != null ? {
1827
+ promptTokens: (_n = usageInfo.inputTokens) != null ? _n : 0,
1828
+ completionTokens: (_o = usageInfo.outputTokens) != null ? _o : 0,
1829
+ totalTokens: (_p = usageInfo.totalTokens) != null ? _p : 0,
1830
+ cost: (_q = response.usage) == null ? void 0 : _q.cost
1831
+ }, ((_s = (_r = response.usage) == null ? void 0 : _r.prompt_tokens_details) == null ? void 0 : _s.cached_tokens) != null ? {
1815
1832
  promptTokensDetails: {
1816
1833
  cachedTokens: response.usage.prompt_tokens_details.cached_tokens
1817
1834
  }
1818
- } : {}), ((_t = (_s = response.usage) == null ? void 0 : _s.completion_tokens_details) == null ? void 0 : _t.reasoning_tokens) != null ? {
1835
+ } : {}), ((_u = (_t = response.usage) == null ? void 0 : _t.completion_tokens_details) == null ? void 0 : _u.reasoning_tokens) != null ? {
1819
1836
  completionTokensDetails: {
1820
1837
  reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
1821
1838
  }
1822
- } : {}), ((_v = (_u = response.usage) == null ? void 0 : _u.cost_details) == null ? void 0 : _v.upstream_inference_cost) != null ? {
1839
+ } : {}), ((_w = (_v = response.usage) == null ? void 0 : _v.cost_details) == null ? void 0 : _w.upstream_inference_cost) != null ? {
1823
1840
  costDetails: {
1824
1841
  upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
1825
1842
  }
@@ -2381,6 +2398,7 @@ var OpenRouterCompletionLanguageModel = class {
2381
2398
  constructor(modelId, settings, config) {
2382
2399
  this.specificationVersion = "v2";
2383
2400
  this.provider = "openrouter";
2401
+ this.supportsImageUrls = true;
2384
2402
  this.supportedUrls = {
2385
2403
  "image/*": [
2386
2404
  /^data:image\/[a-zA-Z]+;base64,/,
@@ -2617,6 +2635,78 @@ var OpenRouterCompletionLanguageModel = class {
2617
2635
  }
2618
2636
  };
2619
2637
 
2638
+ // src/embedding/schemas.ts
2639
+ import { z as z9 } from "zod/v4";
2640
+ var openrouterEmbeddingUsageSchema = z9.object({
2641
+ prompt_tokens: z9.number(),
2642
+ total_tokens: z9.number(),
2643
+ cost: z9.number().optional()
2644
+ });
2645
+ var openrouterEmbeddingDataSchema = z9.object({
2646
+ object: z9.literal("embedding"),
2647
+ embedding: z9.array(z9.number()),
2648
+ index: z9.number().optional()
2649
+ });
2650
+ var OpenRouterEmbeddingResponseSchema = z9.object({
2651
+ id: z9.string().optional(),
2652
+ object: z9.literal("list"),
2653
+ data: z9.array(openrouterEmbeddingDataSchema),
2654
+ model: z9.string(),
2655
+ usage: openrouterEmbeddingUsageSchema.optional()
2656
+ });
2657
+
2658
+ // src/embedding/index.ts
2659
+ var OpenRouterEmbeddingModel = class {
2660
+ constructor(modelId, settings, config) {
2661
+ this.specificationVersion = "v2";
2662
+ this.provider = "openrouter";
2663
+ this.maxEmbeddingsPerCall = void 0;
2664
+ this.supportsParallelCalls = true;
2665
+ this.modelId = modelId;
2666
+ this.settings = settings;
2667
+ this.config = config;
2668
+ }
2669
+ async doEmbed(options) {
2670
+ var _a15;
2671
+ const { values, abortSignal, headers } = options;
2672
+ const args = __spreadValues(__spreadValues({
2673
+ model: this.modelId,
2674
+ input: values,
2675
+ user: this.settings.user,
2676
+ provider: this.settings.provider
2677
+ }, this.config.extraBody), this.settings.extraBody);
2678
+ const { value: responseValue, responseHeaders } = await postJsonToApi({
2679
+ url: this.config.url({
2680
+ path: "/embeddings",
2681
+ modelId: this.modelId
2682
+ }),
2683
+ headers: combineHeaders(this.config.headers(), headers),
2684
+ body: args,
2685
+ failedResponseHandler: openrouterFailedResponseHandler,
2686
+ successfulResponseHandler: createJsonResponseHandler(
2687
+ OpenRouterEmbeddingResponseSchema
2688
+ ),
2689
+ abortSignal,
2690
+ fetch: this.config.fetch
2691
+ });
2692
+ return {
2693
+ embeddings: responseValue.data.map((item) => item.embedding),
2694
+ usage: responseValue.usage ? { tokens: responseValue.usage.prompt_tokens } : void 0,
2695
+ providerMetadata: ((_a15 = responseValue.usage) == null ? void 0 : _a15.cost) ? {
2696
+ openrouter: {
2697
+ usage: {
2698
+ cost: responseValue.usage.cost
2699
+ }
2700
+ }
2701
+ } : void 0,
2702
+ response: {
2703
+ headers: responseHeaders,
2704
+ body: responseValue
2705
+ }
2706
+ };
2707
+ }
2708
+ };
2709
+
2620
2710
  // src/facade.ts
2621
2711
  var OpenRouter = class {
2622
2712
  /**
@@ -2627,17 +2717,20 @@ var OpenRouter = class {
2627
2717
  this.baseURL = (_b = withoutTrailingSlash((_a15 = options.baseURL) != null ? _a15 : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
2628
2718
  this.apiKey = options.apiKey;
2629
2719
  this.headers = options.headers;
2720
+ this.api_keys = options.api_keys;
2630
2721
  }
2631
2722
  get baseConfig() {
2632
2723
  return {
2633
2724
  baseURL: this.baseURL,
2634
- headers: () => __spreadValues({
2725
+ headers: () => __spreadValues(__spreadValues({
2635
2726
  Authorization: `Bearer ${loadApiKey({
2636
2727
  apiKey: this.apiKey,
2637
2728
  environmentVariableName: "OPENROUTER_API_KEY",
2638
2729
  description: "OpenRouter"
2639
2730
  })}`
2640
- }, this.headers)
2731
+ }, this.headers), this.api_keys && Object.keys(this.api_keys).length > 0 && {
2732
+ "X-Provider-API-Keys": JSON.stringify(this.api_keys)
2733
+ })
2641
2734
  };
2642
2735
  }
2643
2736
  chat(modelId, settings = {}) {
@@ -2656,6 +2749,19 @@ var OpenRouter = class {
2656
2749
  url: ({ path }) => `${this.baseURL}${path}`
2657
2750
  }));
2658
2751
  }
2752
+ textEmbeddingModel(modelId, settings = {}) {
2753
+ return new OpenRouterEmbeddingModel(modelId, settings, __spreadProps(__spreadValues({
2754
+ provider: "openrouter.embedding"
2755
+ }, this.baseConfig), {
2756
+ url: ({ path }) => `${this.baseURL}${path}`
2757
+ }));
2758
+ }
2759
+ /**
2760
+ * @deprecated Use textEmbeddingModel instead
2761
+ */
2762
+ embedding(modelId, settings = {}) {
2763
+ return this.textEmbeddingModel(modelId, settings);
2764
+ }
2659
2765
  };
2660
2766
 
2661
2767
  // src/utils/remove-undefined.ts
@@ -2678,7 +2784,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
2678
2784
  }
2679
2785
 
2680
2786
  // src/version.ts
2681
- var VERSION = false ? "0.0.0-test" : "1.3.0";
2787
+ var VERSION = false ? "0.0.0-test" : "1.4.1";
2682
2788
 
2683
2789
  // src/provider.ts
2684
2790
  function createOpenRouter(options = {}) {
@@ -2686,13 +2792,15 @@ function createOpenRouter(options = {}) {
2686
2792
  const baseURL = (_b = withoutTrailingSlash((_a15 = options.baseURL) != null ? _a15 : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
2687
2793
  const compatibility = (_c = options.compatibility) != null ? _c : "compatible";
2688
2794
  const getHeaders = () => withUserAgentSuffix(
2689
- __spreadValues({
2795
+ __spreadValues(__spreadValues({
2690
2796
  Authorization: `Bearer ${loadApiKey({
2691
2797
  apiKey: options.apiKey,
2692
2798
  environmentVariableName: "OPENROUTER_API_KEY",
2693
2799
  description: "OpenRouter"
2694
2800
  })}`
2695
- }, options.headers),
2801
+ }, options.headers), options.api_keys && Object.keys(options.api_keys).length > 0 && {
2802
+ "X-Provider-API-Keys": JSON.stringify(options.api_keys)
2803
+ }),
2696
2804
  `ai-sdk/openrouter/${VERSION}`
2697
2805
  );
2698
2806
  const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
@@ -2711,6 +2819,13 @@ function createOpenRouter(options = {}) {
2711
2819
  fetch: options.fetch,
2712
2820
  extraBody: options.extraBody
2713
2821
  });
2822
+ const createEmbeddingModel = (modelId, settings = {}) => new OpenRouterEmbeddingModel(modelId, settings, {
2823
+ provider: "openrouter.embedding",
2824
+ url: ({ path }) => `${baseURL}${path}`,
2825
+ headers: getHeaders,
2826
+ fetch: options.fetch,
2827
+ extraBody: options.extraBody
2828
+ });
2714
2829
  const createLanguageModel = (modelId, settings) => {
2715
2830
  if (new.target) {
2716
2831
  throw new Error(
@@ -2729,6 +2844,8 @@ function createOpenRouter(options = {}) {
2729
2844
  provider.languageModel = createLanguageModel;
2730
2845
  provider.chat = createChatModel;
2731
2846
  provider.completion = createCompletionModel;
2847
+ provider.textEmbeddingModel = createEmbeddingModel;
2848
+ provider.embedding = createEmbeddingModel;
2732
2849
  return provider;
2733
2850
  }
2734
2851
  var openrouter = createOpenRouter({