@ai-sdk/deepinfra 2.0.18 → 2.0.19

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @ai-sdk/deepinfra
2
2
 
3
+ ## 2.0.19
4
+
5
+ ### Patch Changes
6
+
7
+ - 4de5a1d: chore: excluded tests from src folder in npm package
8
+ - Updated dependencies [4de5a1d]
9
+ - @ai-sdk/openai-compatible@2.0.18
10
+ - @ai-sdk/provider@3.0.5
11
+ - @ai-sdk/provider-utils@4.0.9
12
+
3
13
  ## 2.0.18
4
14
 
5
15
  ### Patch Changes
package/dist/index.js CHANGED
@@ -161,7 +161,7 @@ async function fileToBlob(file) {
161
161
  }
162
162
 
163
163
  // src/version.ts
164
- var VERSION = true ? "2.0.18" : "0.0.0-test";
164
+ var VERSION = true ? "2.0.19" : "0.0.0-test";
165
165
 
166
166
  // src/deepinfra-provider.ts
167
167
  function createDeepInfra(options = {}) {
package/dist/index.mjs CHANGED
@@ -150,7 +150,7 @@ async function fileToBlob(file) {
150
150
  }
151
151
 
152
152
  // src/version.ts
153
- var VERSION = true ? "2.0.18" : "0.0.0-test";
153
+ var VERSION = true ? "2.0.19" : "0.0.0-test";
154
154
 
155
155
  // src/deepinfra-provider.ts
156
156
  function createDeepInfra(options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/deepinfra",
3
- "version": "2.0.18",
3
+ "version": "2.0.19",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -10,6 +10,10 @@
10
10
  "dist/**/*",
11
11
  "docs/**/*",
12
12
  "src",
13
+ "!src/**/*.test.ts",
14
+ "!src/**/*.test-d.ts",
15
+ "!src/**/__snapshots__",
16
+ "!src/**/__fixtures__",
13
17
  "CHANGELOG.md",
14
18
  "README.md"
15
19
  ],
@@ -25,16 +29,16 @@
25
29
  }
26
30
  },
27
31
  "dependencies": {
28
- "@ai-sdk/openai-compatible": "2.0.17",
29
- "@ai-sdk/provider": "3.0.4",
30
- "@ai-sdk/provider-utils": "4.0.8"
32
+ "@ai-sdk/openai-compatible": "2.0.18",
33
+ "@ai-sdk/provider": "3.0.5",
34
+ "@ai-sdk/provider-utils": "4.0.9"
31
35
  },
32
36
  "devDependencies": {
33
37
  "@types/node": "20.17.24",
34
38
  "tsup": "^8",
35
39
  "typescript": "5.8.3",
36
40
  "zod": "3.25.76",
37
- "@ai-sdk/test-server": "1.0.2",
41
+ "@ai-sdk/test-server": "1.0.3",
38
42
  "@vercel/ai-tsconfig": "0.0.0"
39
43
  },
40
44
  "peerDependencies": {
@@ -1,431 +0,0 @@
1
- import { createTestServer } from '@ai-sdk/test-server/with-vitest';
2
- import { describe, expect, it } from 'vitest';
3
- import { DeepInfraImageModel } from './deepinfra-image-model';
4
- import { FetchFunction } from '@ai-sdk/provider-utils';
5
-
6
- const prompt = 'A cute baby sea otter';
7
-
8
- function createBasicModel({
9
- headers,
10
- fetch,
11
- currentDate,
12
- }: {
13
- headers?: () => Record<string, string>;
14
- fetch?: FetchFunction;
15
- currentDate?: () => Date;
16
- } = {}) {
17
- return new DeepInfraImageModel('stability-ai/sdxl', {
18
- provider: 'deepinfra',
19
- baseURL: 'https://api.example.com',
20
- headers: headers ?? (() => ({ 'api-key': 'test-key' })),
21
- fetch,
22
- _internal: {
23
- currentDate,
24
- },
25
- });
26
- }
27
-
28
- describe('DeepInfraImageModel', () => {
29
- const testDate = new Date('2024-01-01T00:00:00Z');
30
- const server = createTestServer({
31
- 'https://api.example.com/*': {
32
- response: {
33
- type: 'json-value',
34
- body: {
35
- images: ['data:image/png;base64,test-image-data'],
36
- },
37
- },
38
- },
39
- });
40
-
41
- describe('doGenerate', () => {
42
- it('should pass the correct parameters including aspect ratio and seed', async () => {
43
- const model = createBasicModel();
44
-
45
- await model.doGenerate({
46
- prompt,
47
- files: undefined,
48
- mask: undefined,
49
- n: 1,
50
- size: undefined,
51
- aspectRatio: '16:9',
52
- seed: 42,
53
- providerOptions: { deepinfra: { additional_param: 'value' } },
54
- });
55
-
56
- expect(await server.calls[0].requestBodyJson).toStrictEqual({
57
- prompt,
58
- aspect_ratio: '16:9',
59
- seed: 42,
60
- num_images: 1,
61
- additional_param: 'value',
62
- });
63
- });
64
-
65
- it('should call the correct url', async () => {
66
- const model = createBasicModel();
67
-
68
- await model.doGenerate({
69
- prompt,
70
- files: undefined,
71
- mask: undefined,
72
- n: 1,
73
- size: undefined,
74
- aspectRatio: undefined,
75
- seed: undefined,
76
- providerOptions: {},
77
- });
78
-
79
- expect(server.calls[0].requestMethod).toStrictEqual('POST');
80
- expect(server.calls[0].requestUrl).toStrictEqual(
81
- 'https://api.example.com/stability-ai/sdxl',
82
- );
83
- });
84
-
85
- it('should pass headers', async () => {
86
- const modelWithHeaders = createBasicModel({
87
- headers: () => ({
88
- 'Custom-Provider-Header': 'provider-header-value',
89
- }),
90
- });
91
-
92
- await modelWithHeaders.doGenerate({
93
- prompt,
94
- files: undefined,
95
- mask: undefined,
96
- n: 1,
97
- size: undefined,
98
- aspectRatio: undefined,
99
- seed: undefined,
100
- providerOptions: {},
101
- headers: {
102
- 'Custom-Request-Header': 'request-header-value',
103
- },
104
- });
105
-
106
- expect(server.calls[0].requestHeaders).toStrictEqual({
107
- 'content-type': 'application/json',
108
- 'custom-provider-header': 'provider-header-value',
109
- 'custom-request-header': 'request-header-value',
110
- });
111
- });
112
-
113
- it('should handle API errors', async () => {
114
- server.urls['https://api.example.com/*'].response = {
115
- type: 'error',
116
- status: 400,
117
- body: JSON.stringify({
118
- error: {
119
- message: 'Bad Request',
120
- },
121
- }),
122
- };
123
-
124
- const model = createBasicModel();
125
- await expect(
126
- model.doGenerate({
127
- prompt,
128
- files: undefined,
129
- mask: undefined,
130
- n: 1,
131
- size: undefined,
132
- aspectRatio: undefined,
133
- seed: undefined,
134
- providerOptions: {},
135
- }),
136
- ).rejects.toThrow('Bad Request');
137
- });
138
-
139
- it('should handle size parameter', async () => {
140
- const model = createBasicModel();
141
-
142
- await model.doGenerate({
143
- prompt,
144
- files: undefined,
145
- mask: undefined,
146
- n: 1,
147
- size: '1024x768',
148
- aspectRatio: undefined,
149
- seed: 42,
150
- providerOptions: {},
151
- });
152
-
153
- expect(await server.calls[0].requestBodyJson).toStrictEqual({
154
- prompt,
155
- width: '1024',
156
- height: '768',
157
- seed: 42,
158
- num_images: 1,
159
- });
160
- });
161
-
162
- it('should respect the abort signal', async () => {
163
- const model = createBasicModel();
164
- const controller = new AbortController();
165
-
166
- const generatePromise = model.doGenerate({
167
- prompt,
168
- files: undefined,
169
- mask: undefined,
170
- n: 1,
171
- size: undefined,
172
- aspectRatio: undefined,
173
- seed: undefined,
174
- providerOptions: {},
175
- abortSignal: controller.signal,
176
- });
177
-
178
- controller.abort();
179
-
180
- await expect(generatePromise).rejects.toThrow(
181
- 'This operation was aborted',
182
- );
183
- });
184
-
185
- describe('response metadata', () => {
186
- it('should include timestamp, headers and modelId in response', async () => {
187
- const model = createBasicModel({
188
- currentDate: () => testDate,
189
- });
190
-
191
- const result = await model.doGenerate({
192
- prompt,
193
- files: undefined,
194
- mask: undefined,
195
- n: 1,
196
- size: undefined,
197
- aspectRatio: undefined,
198
- seed: undefined,
199
- providerOptions: {},
200
- });
201
-
202
- expect(result.response).toStrictEqual({
203
- timestamp: testDate,
204
- modelId: 'stability-ai/sdxl',
205
- headers: expect.any(Object),
206
- });
207
- });
208
-
209
- it('should include response headers from API call', async () => {
210
- server.urls['https://api.example.com/*'].response = {
211
- type: 'json-value',
212
- headers: {
213
- 'x-request-id': 'test-request-id',
214
- },
215
- body: {
216
- images: ['data:image/png;base64,test-image-data'],
217
- },
218
- };
219
-
220
- const model = createBasicModel();
221
- const result = await model.doGenerate({
222
- prompt,
223
- files: undefined,
224
- mask: undefined,
225
- n: 1,
226
- size: undefined,
227
- aspectRatio: undefined,
228
- seed: undefined,
229
- providerOptions: {},
230
- });
231
-
232
- expect(result.response.headers).toStrictEqual({
233
- 'content-length': '52',
234
- 'x-request-id': 'test-request-id',
235
- 'content-type': 'application/json',
236
- });
237
- });
238
- });
239
- });
240
-
241
- describe('constructor', () => {
242
- it('should expose correct provider and model information', () => {
243
- const model = createBasicModel();
244
-
245
- expect(model.provider).toBe('deepinfra');
246
- expect(model.modelId).toBe('stability-ai/sdxl');
247
- expect(model.specificationVersion).toBe('v3');
248
- expect(model.maxImagesPerCall).toBe(1);
249
- });
250
- });
251
-
252
- describe('Image Editing', () => {
253
- const editServer = createTestServer({
254
- 'https://edit.example.com/openai/images/edits': {
255
- response: {
256
- type: 'json-value',
257
- body: {
258
- created: 1234567890,
259
- data: [{ b64_json: 'edited-image-base64' }],
260
- },
261
- },
262
- },
263
- });
264
-
265
- // Model with baseURL that will resolve to edit endpoint
266
- const editModel = new DeepInfraImageModel(
267
- 'black-forest-labs/FLUX.1-Kontext-dev',
268
- {
269
- provider: 'deepinfra',
270
- baseURL: 'https://edit.example.com/inference',
271
- headers: () => ({ 'api-key': 'test-key' }),
272
- },
273
- );
274
-
275
- it('should send edit request with files', async () => {
276
- const imageData = new Uint8Array([137, 80, 78, 71]); // PNG magic bytes
277
-
278
- const result = await editModel.doGenerate({
279
- prompt: 'Turn the cat into a dog',
280
- files: [
281
- {
282
- type: 'file',
283
- data: imageData,
284
- mediaType: 'image/png',
285
- },
286
- ],
287
- mask: undefined,
288
- n: 1,
289
- size: '1024x1024',
290
- aspectRatio: undefined,
291
- seed: undefined,
292
- providerOptions: {},
293
- });
294
-
295
- expect(result.images).toStrictEqual(['edited-image-base64']);
296
- expect(editServer.calls[0].requestUrl).toBe(
297
- 'https://edit.example.com/openai/images/edits',
298
- );
299
- });
300
-
301
- it('should send edit request with files and mask', async () => {
302
- const imageData = new Uint8Array([137, 80, 78, 71]);
303
- const maskData = new Uint8Array([255, 255, 255, 0]);
304
-
305
- const result = await editModel.doGenerate({
306
- prompt: 'Add a flamingo to the pool',
307
- files: [
308
- {
309
- type: 'file',
310
- data: imageData,
311
- mediaType: 'image/png',
312
- },
313
- ],
314
- mask: {
315
- type: 'file',
316
- data: maskData,
317
- mediaType: 'image/png',
318
- },
319
- n: 1,
320
- size: undefined,
321
- aspectRatio: undefined,
322
- seed: undefined,
323
- providerOptions: {},
324
- });
325
-
326
- expect(result.images).toStrictEqual(['edited-image-base64']);
327
- expect(editServer.calls[0].requestUrl).toBe(
328
- 'https://edit.example.com/openai/images/edits',
329
- );
330
- });
331
-
332
- it('should send edit request with multiple images', async () => {
333
- const image1 = new Uint8Array([137, 80, 78, 71]);
334
- const image2 = new Uint8Array([137, 80, 78, 71]);
335
-
336
- const result = await editModel.doGenerate({
337
- prompt: 'Combine these images',
338
- files: [
339
- {
340
- type: 'file',
341
- data: image1,
342
- mediaType: 'image/png',
343
- },
344
- {
345
- type: 'file',
346
- data: image2,
347
- mediaType: 'image/png',
348
- },
349
- ],
350
- mask: undefined,
351
- n: 1,
352
- size: undefined,
353
- aspectRatio: undefined,
354
- seed: undefined,
355
- providerOptions: {},
356
- });
357
-
358
- expect(result.images).toStrictEqual(['edited-image-base64']);
359
- });
360
-
361
- it('should include response metadata for edit requests', async () => {
362
- const testDate = new Date('2024-01-01T00:00:00Z');
363
- const modelWithDate = new DeepInfraImageModel(
364
- 'black-forest-labs/FLUX.1-Kontext-dev',
365
- {
366
- provider: 'deepinfra',
367
- baseURL: 'https://edit.example.com/inference',
368
- headers: () => ({ 'api-key': 'test-key' }),
369
- _internal: {
370
- currentDate: () => testDate,
371
- },
372
- },
373
- );
374
-
375
- const imageData = new Uint8Array([137, 80, 78, 71]);
376
-
377
- const result = await modelWithDate.doGenerate({
378
- prompt: 'Edit this image',
379
- files: [
380
- {
381
- type: 'file',
382
- data: imageData,
383
- mediaType: 'image/png',
384
- },
385
- ],
386
- mask: undefined,
387
- n: 1,
388
- size: undefined,
389
- aspectRatio: undefined,
390
- seed: undefined,
391
- providerOptions: {},
392
- });
393
-
394
- expect(result.response).toStrictEqual({
395
- timestamp: testDate,
396
- modelId: 'black-forest-labs/FLUX.1-Kontext-dev',
397
- headers: expect.any(Object),
398
- });
399
- });
400
-
401
- it('should pass provider options in edit request', async () => {
402
- const imageData = new Uint8Array([137, 80, 78, 71]);
403
-
404
- await editModel.doGenerate({
405
- prompt: 'Edit with custom options',
406
- files: [
407
- {
408
- type: 'file',
409
- data: imageData,
410
- mediaType: 'image/png',
411
- },
412
- ],
413
- mask: undefined,
414
- n: 1,
415
- size: undefined,
416
- aspectRatio: undefined,
417
- seed: undefined,
418
- providerOptions: {
419
- deepinfra: {
420
- guidance: 7.5,
421
- },
422
- },
423
- });
424
-
425
- // The request should have been made to the edit endpoint
426
- expect(editServer.calls[0].requestUrl).toBe(
427
- 'https://edit.example.com/openai/images/edits',
428
- );
429
- });
430
- });
431
- });
@@ -1,184 +0,0 @@
1
- import { DeepInfraImageModel } from './deepinfra-image-model';
2
- import { createDeepInfra } from './deepinfra-provider';
3
- import {
4
- OpenAICompatibleChatLanguageModel,
5
- OpenAICompatibleCompletionLanguageModel,
6
- OpenAICompatibleEmbeddingModel,
7
- } from '@ai-sdk/openai-compatible';
8
- import { LanguageModelV3, EmbeddingModelV3 } from '@ai-sdk/provider';
9
- import { loadApiKey } from '@ai-sdk/provider-utils';
10
- import { describe, it, expect, vi, beforeEach, Mock } from 'vitest';
11
-
12
- // Add type assertion for the mocked class
13
- const OpenAICompatibleChatLanguageModelMock =
14
- OpenAICompatibleChatLanguageModel as unknown as Mock;
15
-
16
- vi.mock('@ai-sdk/openai-compatible', () => ({
17
- OpenAICompatibleChatLanguageModel: vi.fn(),
18
- OpenAICompatibleCompletionLanguageModel: vi.fn(),
19
- OpenAICompatibleEmbeddingModel: vi.fn(),
20
- }));
21
-
22
- vi.mock('@ai-sdk/provider-utils', async () => {
23
- const actual = await vi.importActual('@ai-sdk/provider-utils');
24
- return {
25
- ...actual,
26
- loadApiKey: vi.fn().mockReturnValue('mock-api-key'),
27
- withoutTrailingSlash: vi.fn(url => url),
28
- };
29
- });
30
-
31
- vi.mock('./deepinfra-image-model', () => ({
32
- DeepInfraImageModel: vi.fn(),
33
- }));
34
-
35
- describe('DeepInfraProvider', () => {
36
- let mockLanguageModel: LanguageModelV3;
37
- let mockEmbeddingModel: EmbeddingModelV3;
38
-
39
- beforeEach(() => {
40
- // Mock implementations of models
41
- mockLanguageModel = {
42
- // Add any required methods for LanguageModelV3
43
- } as LanguageModelV3;
44
- mockEmbeddingModel = {
45
- // Add any required methods for EmbeddingModelV3
46
- } as EmbeddingModelV3;
47
-
48
- // Reset mocks
49
- vi.clearAllMocks();
50
- });
51
-
52
- describe('createDeepInfra', () => {
53
- it('should create a DeepInfraProvider instance with default options', () => {
54
- const provider = createDeepInfra();
55
- const model = provider('model-id');
56
-
57
- // Use the mocked version
58
- const constructorCall =
59
- OpenAICompatibleChatLanguageModelMock.mock.calls[0];
60
- const config = constructorCall[1];
61
- config.headers();
62
-
63
- expect(loadApiKey).toHaveBeenCalledWith({
64
- apiKey: undefined,
65
- environmentVariableName: 'DEEPINFRA_API_KEY',
66
- description: "DeepInfra's API key",
67
- });
68
- });
69
-
70
- it('should create a DeepInfraProvider instance with custom options', () => {
71
- const options = {
72
- apiKey: 'custom-key',
73
- baseURL: 'https://custom.url',
74
- headers: { 'Custom-Header': 'value' },
75
- };
76
- const provider = createDeepInfra(options);
77
- const model = provider('model-id');
78
-
79
- const constructorCall =
80
- OpenAICompatibleChatLanguageModelMock.mock.calls[0];
81
- const config = constructorCall[1];
82
- config.headers();
83
-
84
- expect(loadApiKey).toHaveBeenCalledWith({
85
- apiKey: 'custom-key',
86
- environmentVariableName: 'DEEPINFRA_API_KEY',
87
- description: "DeepInfra's API key",
88
- });
89
- });
90
-
91
- it('should return a chat model when called as a function', () => {
92
- const provider = createDeepInfra();
93
- const modelId = 'foo-model-id';
94
-
95
- const model = provider(modelId);
96
- expect(model).toBeInstanceOf(OpenAICompatibleChatLanguageModel);
97
- });
98
- });
99
-
100
- describe('chatModel', () => {
101
- it('should construct a chat model with correct configuration', () => {
102
- const provider = createDeepInfra();
103
- const modelId = 'deepinfra-chat-model';
104
-
105
- const model = provider.chatModel(modelId);
106
-
107
- expect(model).toBeInstanceOf(OpenAICompatibleChatLanguageModel);
108
- expect(OpenAICompatibleChatLanguageModelMock).toHaveBeenCalledWith(
109
- modelId,
110
- expect.objectContaining({
111
- provider: 'deepinfra.chat',
112
- }),
113
- );
114
- });
115
- });
116
-
117
- describe('completionModel', () => {
118
- it('should construct a completion model with correct configuration', () => {
119
- const provider = createDeepInfra();
120
- const modelId = 'deepinfra-completion-model';
121
-
122
- const model = provider.completionModel(modelId);
123
-
124
- expect(model).toBeInstanceOf(OpenAICompatibleCompletionLanguageModel);
125
- });
126
- });
127
-
128
- describe('embeddingModel', () => {
129
- it('should construct a text embedding model with correct configuration', () => {
130
- const provider = createDeepInfra();
131
- const modelId = 'deepinfra-embedding-model';
132
-
133
- const model = provider.embeddingModel(modelId);
134
-
135
- expect(model).toBeInstanceOf(OpenAICompatibleEmbeddingModel);
136
- });
137
- });
138
-
139
- describe('image', () => {
140
- it('should construct an image model with correct configuration', () => {
141
- const provider = createDeepInfra();
142
- const modelId = 'deepinfra-image-model';
143
-
144
- const model = provider.image(modelId);
145
-
146
- expect(model).toBeInstanceOf(DeepInfraImageModel);
147
- expect(DeepInfraImageModel).toHaveBeenCalledWith(
148
- modelId,
149
- expect.objectContaining({
150
- provider: 'deepinfra.image',
151
- baseURL: 'https://api.deepinfra.com/v1/inference',
152
- }),
153
- );
154
- });
155
-
156
- it('should use default settings when none provided', () => {
157
- const provider = createDeepInfra();
158
- const modelId = 'deepinfra-image-model';
159
-
160
- const model = provider.image(modelId);
161
-
162
- expect(model).toBeInstanceOf(DeepInfraImageModel);
163
- expect(DeepInfraImageModel).toHaveBeenCalledWith(
164
- modelId,
165
- expect.any(Object),
166
- );
167
- });
168
-
169
- it('should respect custom baseURL', () => {
170
- const customBaseURL = 'https://custom.api.deepinfra.com';
171
- const provider = createDeepInfra({ baseURL: customBaseURL });
172
- const modelId = 'deepinfra-image-model';
173
-
174
- const model = provider.image(modelId);
175
-
176
- expect(DeepInfraImageModel).toHaveBeenCalledWith(
177
- modelId,
178
- expect.objectContaining({
179
- baseURL: `${customBaseURL}/inference`,
180
- }),
181
- );
182
- });
183
- });
184
- });