@openrouter/ai-sdk-provider 1.4.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/README.md CHANGED
@@ -55,6 +55,64 @@ This list is not a definitive list of models supported by OpenRouter, as it cons
55
55
 
56
56
  You can find the latest list of tool-supported models supported by OpenRouter [here](https://openrouter.ai/models?order=newest&supported_parameters=tools). (Note: This list may contain models that are not compatible with the AI SDK.)
57
57
 
58
+ ## Embeddings
59
+
60
+ OpenRouter supports embedding models for semantic search, RAG pipelines, and vector-native features. The provider exposes embeddings compatible with both AI SDK v5 and v4.
61
+
62
+ ### AI SDK v5 (Recommended)
63
+
64
+ ```ts
65
+ import { embed } from 'ai';
66
+ import { openrouter } from '@openrouter/ai-sdk-provider';
67
+
68
+ const { embedding } = await embed({
69
+ model: openrouter.textEmbeddingModel('openai/text-embedding-3-small'),
70
+ value: 'sunny day at the beach',
71
+ });
72
+
73
+ console.log(embedding); // Array of numbers representing the embedding
74
+ ```
75
+
76
+ ### Batch Embeddings
77
+
78
+ ```ts
79
+ import { embedMany } from 'ai';
80
+ import { openrouter } from '@openrouter/ai-sdk-provider';
81
+
82
+ const { embeddings } = await embedMany({
83
+ model: openrouter.textEmbeddingModel('openai/text-embedding-3-small'),
84
+ values: [
85
+ 'sunny day at the beach',
86
+ 'rainy day in the city',
87
+ 'snowy mountain peak',
88
+ ],
89
+ });
90
+
91
+ console.log(embeddings); // Array of embedding arrays
92
+ ```
93
+
94
+ ### AI SDK v4 (Deprecated)
95
+
96
+ For backwards compatibility, the `embedding` method is also available:
97
+
98
+ ```ts
99
+ import { embed } from 'ai';
100
+ import { openrouter } from '@openrouter/ai-sdk-provider';
101
+
102
+ const { embedding } = await embed({
103
+ model: openrouter.embedding('openai/text-embedding-3-small'),
104
+ value: 'sunny day at the beach',
105
+ });
106
+ ```
107
+
108
+ ### Supported Embedding Models
109
+
110
+ OpenRouter supports various embedding models including:
111
+ - `openai/text-embedding-3-small`
112
+ - `openai/text-embedding-3-large`
113
+ - `openai/text-embedding-ada-002`
114
+ - And more available on [OpenRouter](https://openrouter.ai/models?output_modalities=embeddings)
115
+
58
116
  ## Passing Extra Body to OpenRouter
59
117
 
60
118
  There are 3 ways to pass extra body to OpenRouter:
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, LanguageModelV2CallWarning, LanguageModelV2ResponseMetadata, SharedV2Headers, LanguageModelV2StreamPart, ProviderV2 } from '@ai-sdk/provider';
1
+ import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, LanguageModelV2CallWarning, LanguageModelV2ResponseMetadata, SharedV2Headers, LanguageModelV2StreamPart, EmbeddingModelV2, SharedV2ProviderMetadata, ProviderV2 } from '@ai-sdk/provider';
2
2
  export { LanguageModelV2, LanguageModelV2Prompt } from '@ai-sdk/provider';
3
3
  import * as models from '@openrouter/sdk/models';
4
4
  import { z } from 'zod/v4';
@@ -70,6 +70,14 @@ type OpenRouterChatSettings = {
70
70
  * Custom search prompt to guide the search query
71
71
  */
72
72
  search_prompt?: string;
73
+ /**
74
+ * Search engine to use for web search
75
+ * - "native": Use provider's built-in web search
76
+ * - "exa": Use Exa's search API
77
+ * - undefined: Native if supported, otherwise Exa
78
+ * @see https://openrouter.ai/docs/features/web-search
79
+ */
80
+ engine?: models.Engine;
73
81
  };
74
82
  /**
75
83
  * Debug options for troubleshooting API requests.
@@ -130,6 +138,63 @@ type OpenRouterChatSettings = {
130
138
  audio?: number | string;
131
139
  request?: number | string;
132
140
  };
141
+ /**
142
+ * Whether to restrict routing to only ZDR (Zero Data Retention) endpoints.
143
+ * When true, only endpoints that do not retain prompts will be used.
144
+ */
145
+ zdr?: boolean;
146
+ };
147
+ } & OpenRouterSharedSettings;
148
+
149
+ type OpenRouterEmbeddingModelId = string;
150
+ type OpenRouterEmbeddingSettings = {
151
+ /**
152
+ * A unique identifier representing your end-user, which can help OpenRouter to
153
+ * monitor and detect abuse.
154
+ */
155
+ user?: string;
156
+ /**
157
+ * Provider routing preferences to control request routing behavior
158
+ */
159
+ provider?: {
160
+ /**
161
+ * List of provider slugs to try in order (e.g. ["openai", "voyageai"])
162
+ */
163
+ order?: string[];
164
+ /**
165
+ * Whether to allow backup providers when primary is unavailable (default: true)
166
+ */
167
+ allow_fallbacks?: boolean;
168
+ /**
169
+ * Only use providers that support all parameters in your request (default: false)
170
+ */
171
+ require_parameters?: boolean;
172
+ /**
173
+ * Control whether to use providers that may store data
174
+ */
175
+ data_collection?: 'allow' | 'deny';
176
+ /**
177
+ * List of provider slugs to allow for this request
178
+ */
179
+ only?: string[];
180
+ /**
181
+ * List of provider slugs to skip for this request
182
+ */
183
+ ignore?: string[];
184
+ /**
185
+ * Sort providers by price, throughput, or latency
186
+ */
187
+ sort?: 'price' | 'throughput' | 'latency';
188
+ /**
189
+ * Maximum pricing you want to pay for this request
190
+ */
191
+ max_price?: {
192
+ prompt?: number | string;
193
+ completion?: number | string;
194
+ image?: number | string;
195
+ audio?: number | string;
196
+ request?: number | string;
197
+ };
133
198
  };
134
199
  } & OpenRouterSharedSettings;
135
200
 
@@ -342,6 +407,42 @@ declare class OpenRouterCompletionLanguageModel implements LanguageModelV2 {
342
407
  doStream(options: LanguageModelV2CallOptions): Promise<Awaited<ReturnType<LanguageModelV2['doStream']>>>;
343
408
  }
344
409
 
410
+ type OpenRouterEmbeddingConfig = {
411
+ provider: string;
412
+ headers: () => Record<string, string | undefined>;
413
+ url: (options: {
414
+ modelId: string;
415
+ path: string;
416
+ }) => string;
417
+ fetch?: typeof fetch;
418
+ extraBody?: Record<string, unknown>;
419
+ };
420
+ declare class OpenRouterEmbeddingModel implements EmbeddingModelV2<string> {
421
+ readonly specificationVersion: "v2";
422
+ readonly provider = "openrouter";
423
+ readonly modelId: OpenRouterEmbeddingModelId;
424
+ readonly settings: OpenRouterEmbeddingSettings;
425
+ readonly maxEmbeddingsPerCall: undefined;
426
+ readonly supportsParallelCalls = true;
427
+ private readonly config;
428
+ constructor(modelId: OpenRouterEmbeddingModelId, settings: OpenRouterEmbeddingSettings, config: OpenRouterEmbeddingConfig);
429
+ doEmbed(options: {
430
+ values: Array<string>;
431
+ abortSignal?: AbortSignal;
432
+ headers?: Record<string, string | undefined>;
433
+ }): Promise<{
434
+ embeddings: Array<Array<number>>;
435
+ usage?: {
436
+ tokens: number;
437
+ };
438
+ providerMetadata?: SharedV2ProviderMetadata;
439
+ response?: {
440
+ headers?: SharedV2Headers;
441
+ body?: unknown;
442
+ };
443
+ }>;
444
+ }
445
+
345
446
  interface OpenRouterProvider extends ProviderV2 {
346
447
  (modelId: OpenRouterChatModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
347
448
  (modelId: OpenRouterChatModelId, settings?: OpenRouterChatSettings): OpenRouterChatLanguageModel;
@@ -355,6 +456,15 @@ interface OpenRouterProvider extends ProviderV2 {
355
456
  Creates an OpenRouter completion model for text generation.
356
457
  */
357
458
  completion(modelId: OpenRouterCompletionModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
459
+ /**
460
+ Creates an OpenRouter text embedding model. (AI SDK v5)
461
+ */
462
+ textEmbeddingModel(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
463
+ /**
464
+ Creates an OpenRouter text embedding model. (AI SDK v4 - deprecated, use textEmbeddingModel instead)
465
+ @deprecated Use textEmbeddingModel instead
466
+ */
467
+ embedding(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
358
468
  }
359
469
  interface OpenRouterProviderSettings {
360
470
  /**
@@ -388,6 +498,11 @@ interface OpenRouterProviderSettings {
388
498
  A JSON object to send as the request body to access OpenRouter features & upstream provider features.
389
499
  */
390
500
  extraBody?: Record<string, unknown>;
501
+ /**
502
+ * Record of provider slugs to API keys for injecting into provider routing.
503
+ * Maps provider slugs (e.g. "anthropic", "openai") to their respective API keys.
504
+ */
505
+ api_keys?: Record<string, string>;
391
506
  }
392
507
  /**
393
508
  Create an OpenRouter provider instance.
@@ -416,6 +531,10 @@ declare class OpenRouter {
416
531
  Custom headers to include in the requests.
417
532
  */
418
533
  readonly headers?: Record<string, string>;
534
+ /**
535
+ * Record of provider slugs to API keys for injecting into provider routing.
536
+ */
537
+ readonly api_keys?: Record<string, string>;
419
538
  /**
420
539
  * Creates a new OpenRouter provider instance.
421
540
  */
@@ -423,6 +542,11 @@ declare class OpenRouter {
423
542
  private get baseConfig();
424
543
  chat(modelId: OpenRouterChatModelId, settings?: OpenRouterChatSettings): OpenRouterChatLanguageModel;
425
544
  completion(modelId: OpenRouterCompletionModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
545
+ textEmbeddingModel(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
546
+ /**
547
+ * @deprecated Use textEmbeddingModel instead
548
+ */
549
+ embedding(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
426
550
  }
427
551
 
428
- export { OpenRouter, type OpenRouterCompletionSettings, type OpenRouterProvider, type OpenRouterProviderOptions, type OpenRouterProviderSettings, type OpenRouterSharedSettings, type OpenRouterUsageAccounting, createOpenRouter, openrouter };
552
+ export { OpenRouter, type OpenRouterCompletionSettings, type OpenRouterEmbeddingModelId, type OpenRouterEmbeddingSettings, type OpenRouterProvider, type OpenRouterProviderOptions, type OpenRouterProviderSettings, type OpenRouterSharedSettings, type OpenRouterUsageAccounting, createOpenRouter, openrouter };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, LanguageModelV2CallWarning, LanguageModelV2ResponseMetadata, SharedV2Headers, LanguageModelV2StreamPart, ProviderV2 } from '@ai-sdk/provider';
1
+ import { LanguageModelV2, LanguageModelV2CallOptions, LanguageModelV2Content, LanguageModelV2FinishReason, LanguageModelV2Usage, LanguageModelV2CallWarning, LanguageModelV2ResponseMetadata, SharedV2Headers, LanguageModelV2StreamPart, EmbeddingModelV2, SharedV2ProviderMetadata, ProviderV2 } from '@ai-sdk/provider';
2
2
  export { LanguageModelV2, LanguageModelV2Prompt } from '@ai-sdk/provider';
3
3
  import * as models from '@openrouter/sdk/models';
4
4
  import { z } from 'zod/v4';
@@ -70,6 +70,14 @@ type OpenRouterChatSettings = {
70
70
  * Custom search prompt to guide the search query
71
71
  */
72
72
  search_prompt?: string;
73
+ /**
74
+ * Search engine to use for web search
75
+ * - "native": Use provider's built-in web search
76
+ * - "exa": Use Exa's search API
77
+ * - undefined: Native if supported, otherwise Exa
78
+ * @see https://openrouter.ai/docs/features/web-search
79
+ */
80
+ engine?: models.Engine;
73
81
  };
74
82
  /**
75
83
  * Debug options for troubleshooting API requests.
@@ -130,6 +138,63 @@ type OpenRouterChatSettings = {
130
138
  audio?: number | string;
131
139
  request?: number | string;
132
140
  };
141
+ /**
142
+ * Whether to restrict routing to only ZDR (Zero Data Retention) endpoints.
143
+ * When true, only endpoints that do not retain prompts will be used.
144
+ */
145
+ zdr?: boolean;
146
+ };
147
+ } & OpenRouterSharedSettings;
148
+
149
+ type OpenRouterEmbeddingModelId = string;
150
+ type OpenRouterEmbeddingSettings = {
151
+ /**
152
+ * A unique identifier representing your end-user, which can help OpenRouter to
153
+ * monitor and detect abuse.
154
+ */
155
+ user?: string;
156
+ /**
157
+ * Provider routing preferences to control request routing behavior
158
+ */
159
+ provider?: {
160
+ /**
161
+ * List of provider slugs to try in order (e.g. ["openai", "voyageai"])
162
+ */
163
+ order?: string[];
164
+ /**
165
+ * Whether to allow backup providers when primary is unavailable (default: true)
166
+ */
167
+ allow_fallbacks?: boolean;
168
+ /**
169
+ * Only use providers that support all parameters in your request (default: false)
170
+ */
171
+ require_parameters?: boolean;
172
+ /**
173
+ * Control whether to use providers that may store data
174
+ */
175
+ data_collection?: 'allow' | 'deny';
176
+ /**
177
+ * List of provider slugs to allow for this request
178
+ */
179
+ only?: string[];
180
+ /**
181
+ * List of provider slugs to skip for this request
182
+ */
183
+ ignore?: string[];
184
+ /**
185
+ * Sort providers by price, throughput, or latency
186
+ */
187
+ sort?: 'price' | 'throughput' | 'latency';
188
+ /**
189
+ * Maximum pricing you want to pay for this request
190
+ */
191
+ max_price?: {
192
+ prompt?: number | string;
193
+ completion?: number | string;
194
+ image?: number | string;
195
+ audio?: number | string;
196
+ request?: number | string;
197
+ };
133
198
  };
134
199
  } & OpenRouterSharedSettings;
135
200
 
@@ -342,6 +407,42 @@ declare class OpenRouterCompletionLanguageModel implements LanguageModelV2 {
342
407
  doStream(options: LanguageModelV2CallOptions): Promise<Awaited<ReturnType<LanguageModelV2['doStream']>>>;
343
408
  }
344
409
 
410
+ type OpenRouterEmbeddingConfig = {
411
+ provider: string;
412
+ headers: () => Record<string, string | undefined>;
413
+ url: (options: {
414
+ modelId: string;
415
+ path: string;
416
+ }) => string;
417
+ fetch?: typeof fetch;
418
+ extraBody?: Record<string, unknown>;
419
+ };
420
+ declare class OpenRouterEmbeddingModel implements EmbeddingModelV2<string> {
421
+ readonly specificationVersion: "v2";
422
+ readonly provider = "openrouter";
423
+ readonly modelId: OpenRouterEmbeddingModelId;
424
+ readonly settings: OpenRouterEmbeddingSettings;
425
+ readonly maxEmbeddingsPerCall: undefined;
426
+ readonly supportsParallelCalls = true;
427
+ private readonly config;
428
+ constructor(modelId: OpenRouterEmbeddingModelId, settings: OpenRouterEmbeddingSettings, config: OpenRouterEmbeddingConfig);
429
+ doEmbed(options: {
430
+ values: Array<string>;
431
+ abortSignal?: AbortSignal;
432
+ headers?: Record<string, string | undefined>;
433
+ }): Promise<{
434
+ embeddings: Array<Array<number>>;
435
+ usage?: {
436
+ tokens: number;
437
+ };
438
+ providerMetadata?: SharedV2ProviderMetadata;
439
+ response?: {
440
+ headers?: SharedV2Headers;
441
+ body?: unknown;
442
+ };
443
+ }>;
444
+ }
445
+
345
446
  interface OpenRouterProvider extends ProviderV2 {
346
447
  (modelId: OpenRouterChatModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
347
448
  (modelId: OpenRouterChatModelId, settings?: OpenRouterChatSettings): OpenRouterChatLanguageModel;
@@ -355,6 +456,15 @@ interface OpenRouterProvider extends ProviderV2 {
355
456
  Creates an OpenRouter completion model for text generation.
356
457
  */
357
458
  completion(modelId: OpenRouterCompletionModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
459
+ /**
460
+ Creates an OpenRouter text embedding model. (AI SDK v5)
461
+ */
462
+ textEmbeddingModel(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
463
+ /**
464
+ Creates an OpenRouter text embedding model. (AI SDK v4 - deprecated, use textEmbeddingModel instead)
465
+ @deprecated Use textEmbeddingModel instead
466
+ */
467
+ embedding(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
358
468
  }
359
469
  interface OpenRouterProviderSettings {
360
470
  /**
@@ -388,6 +498,11 @@ interface OpenRouterProviderSettings {
388
498
  A JSON object to send as the request body to access OpenRouter features & upstream provider features.
389
499
  */
390
500
  extraBody?: Record<string, unknown>;
501
+ /**
502
+ * Record of provider slugs to API keys for injecting into provider routing.
503
+ * Maps provider slugs (e.g. "anthropic", "openai") to their respective API keys.
504
+ */
505
+ api_keys?: Record<string, string>;
391
506
  }
392
507
  /**
393
508
  Create an OpenRouter provider instance.
@@ -416,6 +531,10 @@ declare class OpenRouter {
416
531
  Custom headers to include in the requests.
417
532
  */
418
533
  readonly headers?: Record<string, string>;
534
+ /**
535
+ * Record of provider slugs to API keys for injecting into provider routing.
536
+ */
537
+ readonly api_keys?: Record<string, string>;
419
538
  /**
420
539
  * Creates a new OpenRouter provider instance.
421
540
  */
@@ -423,6 +542,11 @@ declare class OpenRouter {
423
542
  private get baseConfig();
424
543
  chat(modelId: OpenRouterChatModelId, settings?: OpenRouterChatSettings): OpenRouterChatLanguageModel;
425
544
  completion(modelId: OpenRouterCompletionModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
545
+ textEmbeddingModel(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
546
+ /**
547
+ * @deprecated Use textEmbeddingModel instead
548
+ */
549
+ embedding(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
426
550
  }
427
551
 
428
- export { OpenRouter, type OpenRouterCompletionSettings, type OpenRouterProvider, type OpenRouterProviderOptions, type OpenRouterProviderSettings, type OpenRouterSharedSettings, type OpenRouterUsageAccounting, createOpenRouter, openrouter };
552
+ export { OpenRouter, type OpenRouterCompletionSettings, type OpenRouterEmbeddingModelId, type OpenRouterEmbeddingSettings, type OpenRouterProvider, type OpenRouterProviderOptions, type OpenRouterProviderSettings, type OpenRouterSharedSettings, type OpenRouterUsageAccounting, createOpenRouter, openrouter };
package/dist/index.js CHANGED
@@ -1643,7 +1643,16 @@ var OpenRouterChatLanguageModel = class {
1643
1643
  presence_penalty: presencePenalty,
1644
1644
  seed,
1645
1645
  stop: stopSequences,
1646
- response_format: responseFormat,
1646
+ response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? responseFormat.schema != null ? {
1647
+ type: "json_schema",
1648
+ json_schema: __spreadValues({
1649
+ schema: responseFormat.schema,
1650
+ strict: true,
1651
+ name: (_a15 = responseFormat.name) != null ? _a15 : "response"
1652
+ }, responseFormat.description && {
1653
+ description: responseFormat.description
1654
+ })
1655
+ } : { type: "json_object" } : void 0,
1647
1656
  top_k: topK,
1648
1657
  // messages:
1649
1658
  messages: convertToOpenRouterChatMessages(prompt),
@@ -1659,20 +1668,6 @@ var OpenRouterChatLanguageModel = class {
1659
1668
  // Debug settings:
1660
1669
  debug: this.settings.debug
1661
1670
  }, 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
1671
  if (tools && tools.length > 0) {
1677
1672
  const mappedTools = tools.filter(
1678
1673
  (tool) => tool.type === "function"
@@ -2675,6 +2670,78 @@ var OpenRouterCompletionLanguageModel = class {
2675
2670
  }
2676
2671
  };
2677
2672
 
2673
+ // src/embedding/schemas.ts
2674
+ var import_v48 = require("zod/v4");
2675
+ var openrouterEmbeddingUsageSchema = import_v48.z.object({
2676
+ prompt_tokens: import_v48.z.number(),
2677
+ total_tokens: import_v48.z.number(),
2678
+ cost: import_v48.z.number().optional()
2679
+ });
2680
+ var openrouterEmbeddingDataSchema = import_v48.z.object({
2681
+ object: import_v48.z.literal("embedding"),
2682
+ embedding: import_v48.z.array(import_v48.z.number()),
2683
+ index: import_v48.z.number().optional()
2684
+ });
2685
+ var OpenRouterEmbeddingResponseSchema = import_v48.z.object({
2686
+ id: import_v48.z.string().optional(),
2687
+ object: import_v48.z.literal("list"),
2688
+ data: import_v48.z.array(openrouterEmbeddingDataSchema),
2689
+ model: import_v48.z.string(),
2690
+ usage: openrouterEmbeddingUsageSchema.optional()
2691
+ });
2692
+
2693
+ // src/embedding/index.ts
2694
+ var OpenRouterEmbeddingModel = class {
2695
+ constructor(modelId, settings, config) {
2696
+ this.specificationVersion = "v2";
2697
+ this.provider = "openrouter";
2698
+ this.maxEmbeddingsPerCall = void 0;
2699
+ this.supportsParallelCalls = true;
2700
+ this.modelId = modelId;
2701
+ this.settings = settings;
2702
+ this.config = config;
2703
+ }
2704
+ async doEmbed(options) {
2705
+ var _a15;
2706
+ const { values, abortSignal, headers } = options;
2707
+ const args = __spreadValues(__spreadValues({
2708
+ model: this.modelId,
2709
+ input: values,
2710
+ user: this.settings.user,
2711
+ provider: this.settings.provider
2712
+ }, this.config.extraBody), this.settings.extraBody);
2713
+ const { value: responseValue, responseHeaders } = await postJsonToApi({
2714
+ url: this.config.url({
2715
+ path: "/embeddings",
2716
+ modelId: this.modelId
2717
+ }),
2718
+ headers: combineHeaders(this.config.headers(), headers),
2719
+ body: args,
2720
+ failedResponseHandler: openrouterFailedResponseHandler,
2721
+ successfulResponseHandler: createJsonResponseHandler(
2722
+ OpenRouterEmbeddingResponseSchema
2723
+ ),
2724
+ abortSignal,
2725
+ fetch: this.config.fetch
2726
+ });
2727
+ return {
2728
+ embeddings: responseValue.data.map((item) => item.embedding),
2729
+ usage: responseValue.usage ? { tokens: responseValue.usage.prompt_tokens } : void 0,
2730
+ providerMetadata: ((_a15 = responseValue.usage) == null ? void 0 : _a15.cost) ? {
2731
+ openrouter: {
2732
+ usage: {
2733
+ cost: responseValue.usage.cost
2734
+ }
2735
+ }
2736
+ } : void 0,
2737
+ response: {
2738
+ headers: responseHeaders,
2739
+ body: responseValue
2740
+ }
2741
+ };
2742
+ }
2743
+ };
2744
+
2678
2745
  // src/facade.ts
2679
2746
  var OpenRouter = class {
2680
2747
  /**
@@ -2685,17 +2752,20 @@ var OpenRouter = class {
2685
2752
  this.baseURL = (_b = withoutTrailingSlash((_a15 = options.baseURL) != null ? _a15 : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
2686
2753
  this.apiKey = options.apiKey;
2687
2754
  this.headers = options.headers;
2755
+ this.api_keys = options.api_keys;
2688
2756
  }
2689
2757
  get baseConfig() {
2690
2758
  return {
2691
2759
  baseURL: this.baseURL,
2692
- headers: () => __spreadValues({
2760
+ headers: () => __spreadValues(__spreadValues({
2693
2761
  Authorization: `Bearer ${loadApiKey({
2694
2762
  apiKey: this.apiKey,
2695
2763
  environmentVariableName: "OPENROUTER_API_KEY",
2696
2764
  description: "OpenRouter"
2697
2765
  })}`
2698
- }, this.headers)
2766
+ }, this.headers), this.api_keys && Object.keys(this.api_keys).length > 0 && {
2767
+ "X-Provider-API-Keys": JSON.stringify(this.api_keys)
2768
+ })
2699
2769
  };
2700
2770
  }
2701
2771
  chat(modelId, settings = {}) {
@@ -2714,6 +2784,19 @@ var OpenRouter = class {
2714
2784
  url: ({ path }) => `${this.baseURL}${path}`
2715
2785
  }));
2716
2786
  }
2787
+ textEmbeddingModel(modelId, settings = {}) {
2788
+ return new OpenRouterEmbeddingModel(modelId, settings, __spreadProps(__spreadValues({
2789
+ provider: "openrouter.embedding"
2790
+ }, this.baseConfig), {
2791
+ url: ({ path }) => `${this.baseURL}${path}`
2792
+ }));
2793
+ }
2794
+ /**
2795
+ * @deprecated Use textEmbeddingModel instead
2796
+ */
2797
+ embedding(modelId, settings = {}) {
2798
+ return this.textEmbeddingModel(modelId, settings);
2799
+ }
2717
2800
  };
2718
2801
 
2719
2802
  // src/utils/remove-undefined.ts
@@ -2736,7 +2819,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
2736
2819
  }
2737
2820
 
2738
2821
  // src/version.ts
2739
- var VERSION = false ? "0.0.0-test" : "1.4.0";
2822
+ var VERSION = false ? "0.0.0-test" : "1.4.1";
2740
2823
 
2741
2824
  // src/provider.ts
2742
2825
  function createOpenRouter(options = {}) {
@@ -2744,13 +2827,15 @@ function createOpenRouter(options = {}) {
2744
2827
  const baseURL = (_b = withoutTrailingSlash((_a15 = options.baseURL) != null ? _a15 : options.baseUrl)) != null ? _b : "https://openrouter.ai/api/v1";
2745
2828
  const compatibility = (_c = options.compatibility) != null ? _c : "compatible";
2746
2829
  const getHeaders = () => withUserAgentSuffix(
2747
- __spreadValues({
2830
+ __spreadValues(__spreadValues({
2748
2831
  Authorization: `Bearer ${loadApiKey({
2749
2832
  apiKey: options.apiKey,
2750
2833
  environmentVariableName: "OPENROUTER_API_KEY",
2751
2834
  description: "OpenRouter"
2752
2835
  })}`
2753
- }, options.headers),
2836
+ }, options.headers), options.api_keys && Object.keys(options.api_keys).length > 0 && {
2837
+ "X-Provider-API-Keys": JSON.stringify(options.api_keys)
2838
+ }),
2754
2839
  `ai-sdk/openrouter/${VERSION}`
2755
2840
  );
2756
2841
  const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
@@ -2769,6 +2854,13 @@ function createOpenRouter(options = {}) {
2769
2854
  fetch: options.fetch,
2770
2855
  extraBody: options.extraBody
2771
2856
  });
2857
+ const createEmbeddingModel = (modelId, settings = {}) => new OpenRouterEmbeddingModel(modelId, settings, {
2858
+ provider: "openrouter.embedding",
2859
+ url: ({ path }) => `${baseURL}${path}`,
2860
+ headers: getHeaders,
2861
+ fetch: options.fetch,
2862
+ extraBody: options.extraBody
2863
+ });
2772
2864
  const createLanguageModel = (modelId, settings) => {
2773
2865
  if (new.target) {
2774
2866
  throw new Error(
@@ -2787,6 +2879,8 @@ function createOpenRouter(options = {}) {
2787
2879
  provider.languageModel = createLanguageModel;
2788
2880
  provider.chat = createChatModel;
2789
2881
  provider.completion = createCompletionModel;
2882
+ provider.textEmbeddingModel = createEmbeddingModel;
2883
+ provider.embedding = createEmbeddingModel;
2790
2884
  return provider;
2791
2885
  }
2792
2886
  var openrouter = createOpenRouter({