@openrouter/ai-sdk-provider 2.0.2 → 2.1.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/README.md CHANGED
@@ -307,6 +307,34 @@ for await (const partialComponent of result.partialObjectStream) {
307
307
 
308
308
  ## Use Cases
309
309
 
310
+ ### Response Healing for Structured Outputs
311
+
312
+ The provider supports the [Response Healing plugin](https://openrouter.ai/docs/guides/features/plugins/response-healing), which automatically validates and repairs malformed JSON responses from AI models. This is particularly useful when using `generateObject` or structured outputs, as it can fix common issues like missing brackets, trailing commas, markdown wrappers, and mixed text.
313
+
314
+ ```typescript
315
+ import { createOpenRouter } from '@openrouter/ai-sdk-provider';
316
+ import { generateObject } from 'ai';
317
+ import { z } from 'zod';
318
+
319
+ const openrouter = createOpenRouter({ apiKey: 'your-api-key' });
320
+ const model = openrouter('openai/gpt-4o', {
321
+ plugins: [{ id: 'response-healing' }],
322
+ });
323
+
324
+ const { object } = await generateObject({
325
+ model,
326
+ schema: z.object({
327
+ name: z.string(),
328
+ age: z.number(),
329
+ }),
330
+ prompt: 'Generate a person with name and age.',
331
+ });
332
+
333
+ console.log(object); // { name: "John", age: 30 }
334
+ ```
335
+
336
+ Note that Response Healing only works with non-streaming requests. When the model returns imperfect JSON formatting, the plugin attempts to repair the response so you receive valid, parseable JSON.
337
+
310
338
  ### Debugging API Requests
311
339
 
312
340
  The provider supports a debug mode that echoes back the request body sent to the upstream provider. This is useful for troubleshooting and understanding how your requests are being processed. Note that debug mode only works with streaming requests.
package/dist/index.d.mts CHANGED
@@ -1,9 +1,52 @@
1
1
  import * as _ai_sdk_provider from '@ai-sdk/provider';
2
- import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3Content, LanguageModelV3FinishReason, LanguageModelV3Usage, SharedV3Warning, LanguageModelV3ResponseMetadata, SharedV3Headers, LanguageModelV3StreamPart, EmbeddingModelV3, SharedV3ProviderMetadata, ProviderV3 } from '@ai-sdk/provider';
2
+ import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3Content, LanguageModelV3FinishReason, LanguageModelV3Usage, SharedV3Warning, LanguageModelV3ResponseMetadata, SharedV3Headers, LanguageModelV3StreamPart, EmbeddingModelV3, SharedV3ProviderMetadata, ImageModelV3, ImageModelV3CallOptions, ImageModelV3ProviderMetadata, ImageModelV3Usage, ProviderV3 } from '@ai-sdk/provider';
3
3
  export { LanguageModelV3, LanguageModelV3Prompt } from '@ai-sdk/provider';
4
- import * as models from '@openrouter/sdk/models';
5
4
  import { z } from 'zod/v4';
6
5
 
6
+ /**
7
+ * Plugin identifier for web search functionality.
8
+ */
9
+ type IdWeb = 'web';
10
+ /**
11
+ * Plugin identifier for file parsing functionality.
12
+ */
13
+ type IdFileParser = 'file-parser';
14
+ /**
15
+ * Plugin identifier for content moderation.
16
+ */
17
+ type IdModeration = 'moderation';
18
+ /**
19
+ * Plugin identifier for response healing.
20
+ * Automatically validates and repairs malformed JSON responses.
21
+ * @see https://openrouter.ai/docs/guides/features/plugins/response-healing
22
+ */
23
+ type IdResponseHealing = 'response-healing';
24
+ /**
25
+ * Search engine options for web search.
26
+ * Open enum - accepts known values or any string for forward compatibility.
27
+ */
28
+ type Engine = 'native' | 'exa' | (string & {});
29
+ /**
30
+ * PDF processing engine options.
31
+ * Open enum - accepts known values or any string for forward compatibility.
32
+ */
33
+ type PdfEngine = 'mistral-ocr' | 'pdf-text' | 'native' | (string & {});
34
+ /**
35
+ * Data collection preference for provider routing.
36
+ * Open enum - accepts known values or any string for forward compatibility.
37
+ */
38
+ type DataCollection = 'deny' | 'allow' | (string & {});
39
+ /**
40
+ * Model quantization levels for provider filtering.
41
+ * Open enum - accepts known values or any string for forward compatibility.
42
+ */
43
+ type Quantization = 'int4' | 'int8' | 'fp4' | 'fp6' | 'fp8' | 'fp16' | 'bf16' | 'fp32' | 'unknown' | (string & {});
44
+ /**
45
+ * Provider sorting strategy options.
46
+ * Open enum - accepts known values or any string for forward compatibility.
47
+ */
48
+ type ProviderSort = 'price' | 'throughput' | 'latency' | (string & {});
49
+
7
50
  type OpenRouterChatModelId = string;
8
51
  type OpenRouterChatSettings = {
9
52
  /**
@@ -46,18 +89,29 @@ type OpenRouterChatSettings = {
46
89
  * Plugin configurations for enabling various capabilities
47
90
  */
48
91
  plugins?: Array<{
49
- id: models.IdWeb;
92
+ id: IdWeb;
50
93
  max_results?: number;
51
94
  search_prompt?: string;
52
- engine?: models.Engine;
95
+ engine?: Engine;
53
96
  } | {
54
- id: models.IdFileParser;
97
+ id: IdFileParser;
55
98
  max_files?: number;
56
99
  pdf?: {
57
- engine?: models.PdfEngine;
100
+ engine?: PdfEngine;
58
101
  };
59
102
  } | {
60
- id: models.IdModeration;
103
+ id: IdModeration;
104
+ } | {
105
+ /**
106
+ * Response healing plugin - automatically validates and repairs malformed JSON responses.
107
+ *
108
+ * **Important:** This plugin only works with non-streaming requests (e.g., `generateObject`).
109
+ * It has no effect when used with streaming methods like `streamObject` or `streamText`.
110
+ * The plugin activates when using `response_format` with `json_schema` or `json_object`.
111
+ *
112
+ * @see https://openrouter.ai/docs/guides/features/plugins/response-healing
113
+ */
114
+ id: IdResponseHealing;
61
115
  }>;
62
116
  /**
63
117
  * Built-in web search options for models that support native web search
@@ -78,7 +132,7 @@ type OpenRouterChatSettings = {
78
132
  * - undefined: Native if supported, otherwise Exa
79
133
  * @see https://openrouter.ai/docs/features/web-search
80
134
  */
81
- engine?: models.Engine;
135
+ engine?: Engine;
82
136
  };
83
137
  /**
84
138
  * Debug options for troubleshooting API requests.
@@ -112,7 +166,7 @@ type OpenRouterChatSettings = {
112
166
  /**
113
167
  * Control whether to use providers that may store data
114
168
  */
115
- data_collection?: models.DataCollection;
169
+ data_collection?: DataCollection;
116
170
  /**
117
171
  * List of provider slugs to allow for this request
118
172
  */
@@ -124,11 +178,11 @@ type OpenRouterChatSettings = {
124
178
  /**
125
179
  * List of quantization levels to filter by (e.g. ["int4", "int8"])
126
180
  */
127
- quantizations?: Array<models.Quantization>;
181
+ quantizations?: Array<Quantization>;
128
182
  /**
129
183
  * Sort providers by price, throughput, or latency
130
184
  */
131
- sort?: models.ProviderSort;
185
+ sort?: ProviderSort;
132
186
  /**
133
187
  * Maximum pricing you want to pay for this request
134
188
  */
@@ -199,6 +253,52 @@ type OpenRouterEmbeddingSettings = {
199
253
  };
200
254
  } & OpenRouterSharedSettings;
201
255
 
256
+ type OpenRouterImageModelId = string;
257
+ type OpenRouterImageSettings = {
258
+ /**
259
+ * Provider routing preferences to control request routing behavior
260
+ */
261
+ provider?: {
262
+ /**
263
+ * List of provider slugs to try in order (e.g. ["google", "black-forest-labs"])
264
+ */
265
+ order?: string[];
266
+ /**
267
+ * Whether to allow backup providers when primary is unavailable (default: true)
268
+ */
269
+ allow_fallbacks?: boolean;
270
+ /**
271
+ * Only use providers that support all parameters in your request (default: false)
272
+ */
273
+ require_parameters?: boolean;
274
+ /**
275
+ * Control whether to use providers that may store data
276
+ */
277
+ data_collection?: 'allow' | 'deny';
278
+ /**
279
+ * List of provider slugs to allow for this request
280
+ */
281
+ only?: string[];
282
+ /**
283
+ * List of provider slugs to skip for this request
284
+ */
285
+ ignore?: string[];
286
+ /**
287
+ * Sort providers by price, throughput, or latency
288
+ */
289
+ sort?: 'price' | 'throughput' | 'latency';
290
+ /**
291
+ * Maximum pricing you want to pay for this request
292
+ */
293
+ max_price?: {
294
+ prompt?: number | string;
295
+ completion?: number | string;
296
+ image?: number | string;
297
+ request?: number | string;
298
+ };
299
+ };
300
+ } & OpenRouterSharedSettings;
301
+
202
302
  type OpenRouterProviderOptions = {
203
303
  models?: string[];
204
304
  /**
@@ -445,6 +545,37 @@ declare class OpenRouterEmbeddingModel implements EmbeddingModelV3 {
445
545
  }>;
446
546
  }
447
547
 
548
+ type OpenRouterImageConfig = {
549
+ provider: string;
550
+ headers: () => Record<string, string | undefined>;
551
+ url: (options: {
552
+ modelId: string;
553
+ path: string;
554
+ }) => string;
555
+ fetch?: typeof fetch;
556
+ extraBody?: Record<string, unknown>;
557
+ };
558
+ declare class OpenRouterImageModel implements ImageModelV3 {
559
+ readonly specificationVersion: "v3";
560
+ readonly provider = "openrouter";
561
+ readonly modelId: OpenRouterImageModelId;
562
+ readonly settings: OpenRouterImageSettings;
563
+ readonly maxImagesPerCall = 1;
564
+ private readonly config;
565
+ constructor(modelId: OpenRouterImageModelId, settings: OpenRouterImageSettings, config: OpenRouterImageConfig);
566
+ doGenerate(options: ImageModelV3CallOptions): Promise<{
567
+ images: Array<string>;
568
+ warnings: Array<SharedV3Warning>;
569
+ providerMetadata?: ImageModelV3ProviderMetadata;
570
+ response: {
571
+ timestamp: Date;
572
+ modelId: string;
573
+ headers: Record<string, string> | undefined;
574
+ };
575
+ usage?: ImageModelV3Usage;
576
+ }>;
577
+ }
578
+
448
579
  interface OpenRouterProvider extends ProviderV3 {
449
580
  (modelId: OpenRouterChatModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
450
581
  (modelId: OpenRouterChatModelId, settings?: OpenRouterChatSettings): OpenRouterChatLanguageModel;
@@ -467,6 +598,10 @@ interface OpenRouterProvider extends ProviderV3 {
467
598
  @deprecated Use textEmbeddingModel instead
468
599
  */
469
600
  embedding(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
601
+ /**
602
+ Creates an OpenRouter image model for image generation.
603
+ */
604
+ imageModel(modelId: OpenRouterImageModelId, settings?: OpenRouterImageSettings): OpenRouterImageModel;
470
605
  }
471
606
  interface OpenRouterProviderSettings {
472
607
  /**
@@ -551,4 +686,4 @@ declare class OpenRouter {
551
686
  embedding(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
552
687
  }
553
688
 
554
- export { OpenRouter, type OpenRouterChatSettings, type OpenRouterCompletionSettings, type OpenRouterEmbeddingModelId, type OpenRouterEmbeddingSettings, type OpenRouterProvider, type OpenRouterProviderOptions, type OpenRouterProviderSettings, type OpenRouterSharedSettings, type OpenRouterUsageAccounting, createOpenRouter, openrouter };
689
+ export { OpenRouter, type OpenRouterChatSettings, type OpenRouterCompletionSettings, type OpenRouterEmbeddingModelId, type OpenRouterEmbeddingSettings, type OpenRouterImageModelId, type OpenRouterImageSettings, type OpenRouterProvider, type OpenRouterProviderOptions, type OpenRouterProviderSettings, type OpenRouterSharedSettings, type OpenRouterUsageAccounting, createOpenRouter, openrouter };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,52 @@
1
1
  import * as _ai_sdk_provider from '@ai-sdk/provider';
2
- import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3Content, LanguageModelV3FinishReason, LanguageModelV3Usage, SharedV3Warning, LanguageModelV3ResponseMetadata, SharedV3Headers, LanguageModelV3StreamPart, EmbeddingModelV3, SharedV3ProviderMetadata, ProviderV3 } from '@ai-sdk/provider';
2
+ import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3Content, LanguageModelV3FinishReason, LanguageModelV3Usage, SharedV3Warning, LanguageModelV3ResponseMetadata, SharedV3Headers, LanguageModelV3StreamPart, EmbeddingModelV3, SharedV3ProviderMetadata, ImageModelV3, ImageModelV3CallOptions, ImageModelV3ProviderMetadata, ImageModelV3Usage, ProviderV3 } from '@ai-sdk/provider';
3
3
  export { LanguageModelV3, LanguageModelV3Prompt } from '@ai-sdk/provider';
4
- import * as models from '@openrouter/sdk/models';
5
4
  import { z } from 'zod/v4';
6
5
 
6
+ /**
7
+ * Plugin identifier for web search functionality.
8
+ */
9
+ type IdWeb = 'web';
10
+ /**
11
+ * Plugin identifier for file parsing functionality.
12
+ */
13
+ type IdFileParser = 'file-parser';
14
+ /**
15
+ * Plugin identifier for content moderation.
16
+ */
17
+ type IdModeration = 'moderation';
18
+ /**
19
+ * Plugin identifier for response healing.
20
+ * Automatically validates and repairs malformed JSON responses.
21
+ * @see https://openrouter.ai/docs/guides/features/plugins/response-healing
22
+ */
23
+ type IdResponseHealing = 'response-healing';
24
+ /**
25
+ * Search engine options for web search.
26
+ * Open enum - accepts known values or any string for forward compatibility.
27
+ */
28
+ type Engine = 'native' | 'exa' | (string & {});
29
+ /**
30
+ * PDF processing engine options.
31
+ * Open enum - accepts known values or any string for forward compatibility.
32
+ */
33
+ type PdfEngine = 'mistral-ocr' | 'pdf-text' | 'native' | (string & {});
34
+ /**
35
+ * Data collection preference for provider routing.
36
+ * Open enum - accepts known values or any string for forward compatibility.
37
+ */
38
+ type DataCollection = 'deny' | 'allow' | (string & {});
39
+ /**
40
+ * Model quantization levels for provider filtering.
41
+ * Open enum - accepts known values or any string for forward compatibility.
42
+ */
43
+ type Quantization = 'int4' | 'int8' | 'fp4' | 'fp6' | 'fp8' | 'fp16' | 'bf16' | 'fp32' | 'unknown' | (string & {});
44
+ /**
45
+ * Provider sorting strategy options.
46
+ * Open enum - accepts known values or any string for forward compatibility.
47
+ */
48
+ type ProviderSort = 'price' | 'throughput' | 'latency' | (string & {});
49
+
7
50
  type OpenRouterChatModelId = string;
8
51
  type OpenRouterChatSettings = {
9
52
  /**
@@ -46,18 +89,29 @@ type OpenRouterChatSettings = {
46
89
  * Plugin configurations for enabling various capabilities
47
90
  */
48
91
  plugins?: Array<{
49
- id: models.IdWeb;
92
+ id: IdWeb;
50
93
  max_results?: number;
51
94
  search_prompt?: string;
52
- engine?: models.Engine;
95
+ engine?: Engine;
53
96
  } | {
54
- id: models.IdFileParser;
97
+ id: IdFileParser;
55
98
  max_files?: number;
56
99
  pdf?: {
57
- engine?: models.PdfEngine;
100
+ engine?: PdfEngine;
58
101
  };
59
102
  } | {
60
- id: models.IdModeration;
103
+ id: IdModeration;
104
+ } | {
105
+ /**
106
+ * Response healing plugin - automatically validates and repairs malformed JSON responses.
107
+ *
108
+ * **Important:** This plugin only works with non-streaming requests (e.g., `generateObject`).
109
+ * It has no effect when used with streaming methods like `streamObject` or `streamText`.
110
+ * The plugin activates when using `response_format` with `json_schema` or `json_object`.
111
+ *
112
+ * @see https://openrouter.ai/docs/guides/features/plugins/response-healing
113
+ */
114
+ id: IdResponseHealing;
61
115
  }>;
62
116
  /**
63
117
  * Built-in web search options for models that support native web search
@@ -78,7 +132,7 @@ type OpenRouterChatSettings = {
78
132
  * - undefined: Native if supported, otherwise Exa
79
133
  * @see https://openrouter.ai/docs/features/web-search
80
134
  */
81
- engine?: models.Engine;
135
+ engine?: Engine;
82
136
  };
83
137
  /**
84
138
  * Debug options for troubleshooting API requests.
@@ -112,7 +166,7 @@ type OpenRouterChatSettings = {
112
166
  /**
113
167
  * Control whether to use providers that may store data
114
168
  */
115
- data_collection?: models.DataCollection;
169
+ data_collection?: DataCollection;
116
170
  /**
117
171
  * List of provider slugs to allow for this request
118
172
  */
@@ -124,11 +178,11 @@ type OpenRouterChatSettings = {
124
178
  /**
125
179
  * List of quantization levels to filter by (e.g. ["int4", "int8"])
126
180
  */
127
- quantizations?: Array<models.Quantization>;
181
+ quantizations?: Array<Quantization>;
128
182
  /**
129
183
  * Sort providers by price, throughput, or latency
130
184
  */
131
- sort?: models.ProviderSort;
185
+ sort?: ProviderSort;
132
186
  /**
133
187
  * Maximum pricing you want to pay for this request
134
188
  */
@@ -199,6 +253,52 @@ type OpenRouterEmbeddingSettings = {
199
253
  };
200
254
  } & OpenRouterSharedSettings;
201
255
 
256
+ type OpenRouterImageModelId = string;
257
+ type OpenRouterImageSettings = {
258
+ /**
259
+ * Provider routing preferences to control request routing behavior
260
+ */
261
+ provider?: {
262
+ /**
263
+ * List of provider slugs to try in order (e.g. ["google", "black-forest-labs"])
264
+ */
265
+ order?: string[];
266
+ /**
267
+ * Whether to allow backup providers when primary is unavailable (default: true)
268
+ */
269
+ allow_fallbacks?: boolean;
270
+ /**
271
+ * Only use providers that support all parameters in your request (default: false)
272
+ */
273
+ require_parameters?: boolean;
274
+ /**
275
+ * Control whether to use providers that may store data
276
+ */
277
+ data_collection?: 'allow' | 'deny';
278
+ /**
279
+ * List of provider slugs to allow for this request
280
+ */
281
+ only?: string[];
282
+ /**
283
+ * List of provider slugs to skip for this request
284
+ */
285
+ ignore?: string[];
286
+ /**
287
+ * Sort providers by price, throughput, or latency
288
+ */
289
+ sort?: 'price' | 'throughput' | 'latency';
290
+ /**
291
+ * Maximum pricing you want to pay for this request
292
+ */
293
+ max_price?: {
294
+ prompt?: number | string;
295
+ completion?: number | string;
296
+ image?: number | string;
297
+ request?: number | string;
298
+ };
299
+ };
300
+ } & OpenRouterSharedSettings;
301
+
202
302
  type OpenRouterProviderOptions = {
203
303
  models?: string[];
204
304
  /**
@@ -445,6 +545,37 @@ declare class OpenRouterEmbeddingModel implements EmbeddingModelV3 {
445
545
  }>;
446
546
  }
447
547
 
548
+ type OpenRouterImageConfig = {
549
+ provider: string;
550
+ headers: () => Record<string, string | undefined>;
551
+ url: (options: {
552
+ modelId: string;
553
+ path: string;
554
+ }) => string;
555
+ fetch?: typeof fetch;
556
+ extraBody?: Record<string, unknown>;
557
+ };
558
+ declare class OpenRouterImageModel implements ImageModelV3 {
559
+ readonly specificationVersion: "v3";
560
+ readonly provider = "openrouter";
561
+ readonly modelId: OpenRouterImageModelId;
562
+ readonly settings: OpenRouterImageSettings;
563
+ readonly maxImagesPerCall = 1;
564
+ private readonly config;
565
+ constructor(modelId: OpenRouterImageModelId, settings: OpenRouterImageSettings, config: OpenRouterImageConfig);
566
+ doGenerate(options: ImageModelV3CallOptions): Promise<{
567
+ images: Array<string>;
568
+ warnings: Array<SharedV3Warning>;
569
+ providerMetadata?: ImageModelV3ProviderMetadata;
570
+ response: {
571
+ timestamp: Date;
572
+ modelId: string;
573
+ headers: Record<string, string> | undefined;
574
+ };
575
+ usage?: ImageModelV3Usage;
576
+ }>;
577
+ }
578
+
448
579
  interface OpenRouterProvider extends ProviderV3 {
449
580
  (modelId: OpenRouterChatModelId, settings?: OpenRouterCompletionSettings): OpenRouterCompletionLanguageModel;
450
581
  (modelId: OpenRouterChatModelId, settings?: OpenRouterChatSettings): OpenRouterChatLanguageModel;
@@ -467,6 +598,10 @@ interface OpenRouterProvider extends ProviderV3 {
467
598
  @deprecated Use textEmbeddingModel instead
468
599
  */
469
600
  embedding(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
601
+ /**
602
+ Creates an OpenRouter image model for image generation.
603
+ */
604
+ imageModel(modelId: OpenRouterImageModelId, settings?: OpenRouterImageSettings): OpenRouterImageModel;
470
605
  }
471
606
  interface OpenRouterProviderSettings {
472
607
  /**
@@ -551,4 +686,4 @@ declare class OpenRouter {
551
686
  embedding(modelId: OpenRouterEmbeddingModelId, settings?: OpenRouterEmbeddingSettings): OpenRouterEmbeddingModel;
552
687
  }
553
688
 
554
- export { OpenRouter, type OpenRouterChatSettings, type OpenRouterCompletionSettings, type OpenRouterEmbeddingModelId, type OpenRouterEmbeddingSettings, type OpenRouterProvider, type OpenRouterProviderOptions, type OpenRouterProviderSettings, type OpenRouterSharedSettings, type OpenRouterUsageAccounting, createOpenRouter, openrouter };
689
+ export { OpenRouter, type OpenRouterChatSettings, type OpenRouterCompletionSettings, type OpenRouterEmbeddingModelId, type OpenRouterEmbeddingSettings, type OpenRouterImageModelId, type OpenRouterImageSettings, type OpenRouterProvider, type OpenRouterProviderOptions, type OpenRouterProviderSettings, type OpenRouterSharedSettings, type OpenRouterUsageAccounting, createOpenRouter, openrouter };