@openrouter/ai-sdk-provider 1.4.0 → 1.5.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.js CHANGED
@@ -49,6 +49,8 @@ var index_exports = {};
49
49
  __export(index_exports, {
50
50
  OpenRouter: () => OpenRouter,
51
51
  createOpenRouter: () => createOpenRouter,
52
+ decodeToon: () => decodeToon,
53
+ encodeToon: () => encodeToon,
52
54
  openrouter: () => openrouter
53
55
  });
54
56
  module.exports = __toCommonJS(index_exports);
@@ -1071,6 +1073,19 @@ function mapOpenRouterFinishReason(finishReason) {
1071
1073
  }
1072
1074
  }
1073
1075
 
1076
+ // src/types/openrouter-chat-completions-input.ts
1077
+ var OPENROUTER_AUDIO_FORMATS = [
1078
+ "wav",
1079
+ "mp3",
1080
+ "aiff",
1081
+ "aac",
1082
+ "ogg",
1083
+ "flac",
1084
+ "m4a",
1085
+ "pcm16",
1086
+ "pcm24"
1087
+ ];
1088
+
1074
1089
  // src/chat/is-url.ts
1075
1090
  function isUrl({
1076
1091
  url,
@@ -1112,6 +1127,34 @@ function getBase64FromDataUrl(dataUrl) {
1112
1127
  const match = dataUrl.match(/^data:[^;]*;base64,(.+)$/);
1113
1128
  return match ? match[1] : dataUrl;
1114
1129
  }
1130
+ var MIME_TO_FORMAT = {
1131
+ // MP3 variants
1132
+ mpeg: "mp3",
1133
+ mp3: "mp3",
1134
+ // WAV variants
1135
+ "x-wav": "wav",
1136
+ wave: "wav",
1137
+ wav: "wav",
1138
+ // OGG variants
1139
+ ogg: "ogg",
1140
+ vorbis: "ogg",
1141
+ // AAC variants
1142
+ aac: "aac",
1143
+ "x-aac": "aac",
1144
+ // M4A variants
1145
+ m4a: "m4a",
1146
+ "x-m4a": "m4a",
1147
+ mp4: "m4a",
1148
+ // AIFF variants
1149
+ aiff: "aiff",
1150
+ "x-aiff": "aiff",
1151
+ // FLAC
1152
+ flac: "flac",
1153
+ "x-flac": "flac",
1154
+ // PCM variants
1155
+ pcm16: "pcm16",
1156
+ pcm24: "pcm24"
1157
+ };
1115
1158
  function getInputAudioData(part) {
1116
1159
  const fileData = getFileUrl({
1117
1160
  part,
@@ -1136,19 +1179,14 @@ Learn more: https://openrouter.ai/docs/features/multimodal/audio`
1136
1179
  }
1137
1180
  const data = getBase64FromDataUrl(fileData);
1138
1181
  const mediaType = part.mediaType || "audio/mpeg";
1139
- let format = mediaType.replace("audio/", "");
1140
- if (format === "mpeg" || format === "mp3") {
1141
- format = "mp3";
1142
- } else if (format === "x-wav" || format === "wave" || format === "wav") {
1143
- format = "wav";
1144
- }
1145
- if (format !== "mp3" && format !== "wav") {
1182
+ const rawFormat = mediaType.replace("audio/", "");
1183
+ const format = MIME_TO_FORMAT[rawFormat];
1184
+ if (format === void 0) {
1185
+ const supportedList = OPENROUTER_AUDIO_FORMATS.join(", ");
1146
1186
  throw new Error(
1147
1187
  `Unsupported audio format: "${mediaType}"
1148
1188
 
1149
- OpenRouter only supports MP3 and WAV audio formats.
1150
- \u2022 For MP3: use "audio/mpeg" or "audio/mp3"
1151
- \u2022 For WAV: use "audio/wav" or "audio/x-wav"
1189
+ OpenRouter supports the following audio formats: ${supportedList}
1152
1190
 
1153
1191
  Learn more: https://openrouter.ai/docs/features/multimodal/audio`
1154
1192
  );
@@ -1643,7 +1681,16 @@ var OpenRouterChatLanguageModel = class {
1643
1681
  presence_penalty: presencePenalty,
1644
1682
  seed,
1645
1683
  stop: stopSequences,
1646
- response_format: responseFormat,
1684
+ response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? responseFormat.schema != null ? {
1685
+ type: "json_schema",
1686
+ json_schema: __spreadValues({
1687
+ schema: responseFormat.schema,
1688
+ strict: true,
1689
+ name: (_a15 = responseFormat.name) != null ? _a15 : "response"
1690
+ }, responseFormat.description && {
1691
+ description: responseFormat.description
1692
+ })
1693
+ } : { type: "json_object" } : void 0,
1647
1694
  top_k: topK,
1648
1695
  // messages:
1649
1696
  messages: convertToOpenRouterChatMessages(prompt),
@@ -1659,20 +1706,6 @@ var OpenRouterChatLanguageModel = class {
1659
1706
  // Debug settings:
1660
1707
  debug: this.settings.debug
1661
1708
  }, this.config.extraBody), this.settings.extraBody);
1662
- if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null) {
1663
- return __spreadProps(__spreadValues({}, baseArgs), {
1664
- response_format: {
1665
- type: "json_schema",
1666
- json_schema: __spreadValues({
1667
- schema: responseFormat.schema,
1668
- strict: true,
1669
- name: (_a15 = responseFormat.name) != null ? _a15 : "response"
1670
- }, responseFormat.description && {
1671
- description: responseFormat.description
1672
- })
1673
- }
1674
- });
1675
- }
1676
1709
  if (tools && tools.length > 0) {
1677
1710
  const mappedTools = tools.filter(
1678
1711
  (tool) => tool.type === "function"
@@ -2675,6 +2708,78 @@ var OpenRouterCompletionLanguageModel = class {
2675
2708
  }
2676
2709
  };
2677
2710
 
2711
+ // src/embedding/schemas.ts
2712
+ var import_v48 = require("zod/v4");
2713
+ var openrouterEmbeddingUsageSchema = import_v48.z.object({
2714
+ prompt_tokens: import_v48.z.number(),
2715
+ total_tokens: import_v48.z.number(),
2716
+ cost: import_v48.z.number().optional()
2717
+ });
2718
+ var openrouterEmbeddingDataSchema = import_v48.z.object({
2719
+ object: import_v48.z.literal("embedding"),
2720
+ embedding: import_v48.z.array(import_v48.z.number()),
2721
+ index: import_v48.z.number().optional()
2722
+ });
2723
+ var OpenRouterEmbeddingResponseSchema = import_v48.z.object({
2724
+ id: import_v48.z.string().optional(),
2725
+ object: import_v48.z.literal("list"),
2726
+ data: import_v48.z.array(openrouterEmbeddingDataSchema),
2727
+ model: import_v48.z.string(),
2728
+ usage: openrouterEmbeddingUsageSchema.optional()
2729
+ });
2730
+
2731
+ // src/embedding/index.ts
2732
+ var OpenRouterEmbeddingModel = class {
2733
+ constructor(modelId, settings, config) {
2734
+ this.specificationVersion = "v2";
2735
+ this.provider = "openrouter";
2736
+ this.maxEmbeddingsPerCall = void 0;
2737
+ this.supportsParallelCalls = true;
2738
+ this.modelId = modelId;
2739
+ this.settings = settings;
2740
+ this.config = config;
2741
+ }
2742
+ async doEmbed(options) {
2743
+ var _a15;
2744
+ const { values, abortSignal, headers } = options;
2745
+ const args = __spreadValues(__spreadValues({
2746
+ model: this.modelId,
2747
+ input: values,
2748
+ user: this.settings.user,
2749
+ provider: this.settings.provider
2750
+ }, this.config.extraBody), this.settings.extraBody);
2751
+ const { value: responseValue, responseHeaders } = await postJsonToApi({
2752
+ url: this.config.url({
2753
+ path: "/embeddings",
2754
+ modelId: this.modelId
2755
+ }),
2756
+ headers: combineHeaders(this.config.headers(), headers),
2757
+ body: args,
2758
+ failedResponseHandler: openrouterFailedResponseHandler,
2759
+ successfulResponseHandler: createJsonResponseHandler(
2760
+ OpenRouterEmbeddingResponseSchema
2761
+ ),
2762
+ abortSignal,
2763
+ fetch: this.config.fetch
2764
+ });
2765
+ return {
2766
+ embeddings: responseValue.data.map((item) => item.embedding),
2767
+ usage: responseValue.usage ? { tokens: responseValue.usage.prompt_tokens } : void 0,
2768
+ providerMetadata: ((_a15 = responseValue.usage) == null ? void 0 : _a15.cost) ? {
2769
+ openrouter: {
2770
+ usage: {
2771
+ cost: responseValue.usage.cost
2772
+ }
2773
+ }
2774
+ } : void 0,
2775
+ response: {
2776
+ headers: responseHeaders,
2777
+ body: responseValue
2778
+ }
2779
+ };
2780
+ }
2781
+ };
2782
+
2678
2783
  // src/facade.ts
2679
2784
  var OpenRouter = class {
2680
2785
  /**
@@ -2685,17 +2790,20 @@ var OpenRouter = class {
2685
2790
  this.baseURL = (_b = withoutTrailingSlash((_a15 = options.baseURL) != null ? _a15 : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
2686
2791
  this.apiKey = options.apiKey;
2687
2792
  this.headers = options.headers;
2793
+ this.api_keys = options.api_keys;
2688
2794
  }
2689
2795
  get baseConfig() {
2690
2796
  return {
2691
2797
  baseURL: this.baseURL,
2692
- headers: () => __spreadValues({
2798
+ headers: () => __spreadValues(__spreadValues({
2693
2799
  Authorization: `Bearer ${loadApiKey({
2694
2800
  apiKey: this.apiKey,
2695
2801
  environmentVariableName: "OPENROUTER_API_KEY",
2696
2802
  description: "OpenRouter"
2697
2803
  })}`
2698
- }, this.headers)
2804
+ }, this.headers), this.api_keys && Object.keys(this.api_keys).length > 0 && {
2805
+ "X-Provider-API-Keys": JSON.stringify(this.api_keys)
2806
+ })
2699
2807
  };
2700
2808
  }
2701
2809
  chat(modelId, settings = {}) {
@@ -2714,6 +2822,19 @@ var OpenRouter = class {
2714
2822
  url: ({ path }) => `${this.baseURL}${path}`
2715
2823
  }));
2716
2824
  }
2825
+ textEmbeddingModel(modelId, settings = {}) {
2826
+ return new OpenRouterEmbeddingModel(modelId, settings, __spreadProps(__spreadValues({
2827
+ provider: "openrouter.embedding"
2828
+ }, this.baseConfig), {
2829
+ url: ({ path }) => `${this.baseURL}${path}`
2830
+ }));
2831
+ }
2832
+ /**
2833
+ * @deprecated Use textEmbeddingModel instead
2834
+ */
2835
+ embedding(modelId, settings = {}) {
2836
+ return this.textEmbeddingModel(modelId, settings);
2837
+ }
2717
2838
  };
2718
2839
 
2719
2840
  // src/utils/remove-undefined.ts
@@ -2736,7 +2857,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
2736
2857
  }
2737
2858
 
2738
2859
  // src/version.ts
2739
- var VERSION = false ? "0.0.0-test" : "1.4.0";
2860
+ var VERSION = false ? "0.0.0-test" : "1.5.0";
2740
2861
 
2741
2862
  // src/provider.ts
2742
2863
  function createOpenRouter(options = {}) {
@@ -2744,13 +2865,15 @@ function createOpenRouter(options = {}) {
2744
2865
  const baseURL = (_b = withoutTrailingSlash((_a15 = options.baseURL) != null ? _a15 : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
2745
2866
  const compatibility = (_c = options.compatibility) != null ? _c : "compatible";
2746
2867
  const getHeaders = () => withUserAgentSuffix(
2747
- __spreadValues({
2868
+ __spreadValues(__spreadValues({
2748
2869
  Authorization: `Bearer ${loadApiKey({
2749
2870
  apiKey: options.apiKey,
2750
2871
  environmentVariableName: "OPENROUTER_API_KEY",
2751
2872
  description: "OpenRouter"
2752
2873
  })}`
2753
- }, options.headers),
2874
+ }, options.headers), options.api_keys && Object.keys(options.api_keys).length > 0 && {
2875
+ "X-Provider-API-Keys": JSON.stringify(options.api_keys)
2876
+ }),
2754
2877
  `ai-sdk/openrouter/${VERSION}`
2755
2878
  );
2756
2879
  const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
@@ -2769,6 +2892,13 @@ function createOpenRouter(options = {}) {
2769
2892
  fetch: options.fetch,
2770
2893
  extraBody: options.extraBody
2771
2894
  });
2895
+ const createEmbeddingModel = (modelId, settings = {}) => new OpenRouterEmbeddingModel(modelId, settings, {
2896
+ provider: "openrouter.embedding",
2897
+ url: ({ path }) => `${baseURL}${path}`,
2898
+ headers: getHeaders,
2899
+ fetch: options.fetch,
2900
+ extraBody: options.extraBody
2901
+ });
2772
2902
  const createLanguageModel = (modelId, settings) => {
2773
2903
  if (new.target) {
2774
2904
  throw new Error(
@@ -2787,16 +2917,39 @@ function createOpenRouter(options = {}) {
2787
2917
  provider.languageModel = createLanguageModel;
2788
2918
  provider.chat = createChatModel;
2789
2919
  provider.completion = createCompletionModel;
2920
+ provider.textEmbeddingModel = createEmbeddingModel;
2921
+ provider.embedding = createEmbeddingModel;
2790
2922
  return provider;
2791
2923
  }
2792
2924
  var openrouter = createOpenRouter({
2793
2925
  compatibility: "strict"
2794
2926
  // strict for OpenRouter API
2795
2927
  });
2928
+
2929
+ // src/toon/index.ts
2930
+ async function getToonModule() {
2931
+ try {
2932
+ return await import("@toon-format/toon");
2933
+ } catch (e) {
2934
+ throw new Error(
2935
+ "The @toon-format/toon package is required for TOON encoding/decoding. Install it with: npm install @toon-format/toon"
2936
+ );
2937
+ }
2938
+ }
2939
+ async function encodeToon(value, options) {
2940
+ const toon = await getToonModule();
2941
+ return toon.encode(value, options);
2942
+ }
2943
+ async function decodeToon(input, options) {
2944
+ const toon = await getToonModule();
2945
+ return toon.decode(input, options);
2946
+ }
2796
2947
  // Annotate the CommonJS export names for ESM import in node:
2797
2948
  0 && (module.exports = {
2798
2949
  OpenRouter,
2799
2950
  createOpenRouter,
2951
+ decodeToon,
2952
+ encodeToon,
2800
2953
  openrouter
2801
2954
  });
2802
2955
  //# sourceMappingURL=index.js.map