@ai-sdk/deepinfra 2.0.17 → 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 +16 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/docs/11-deepinfra.mdx +292 -0
- package/package.json +14 -6
- package/src/deepinfra-image-model.test.ts +0 -431
- package/src/deepinfra-provider.test.ts +0 -184
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
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
|
+
|
|
13
|
+
## 2.0.18
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- 2b8369d: chore: add docs to package dist
|
|
18
|
+
|
|
3
19
|
## 2.0.17
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/index.js
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: DeepInfra
|
|
3
|
+
description: Learn how to use DeepInfra's models with the AI SDK.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DeepInfra Provider
|
|
7
|
+
|
|
8
|
+
The [DeepInfra](https://deepinfra.com) provider contains support for state-of-the-art models through the DeepInfra API, including Llama 3, Mixtral, Qwen, and many other popular open-source models.
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
The DeepInfra provider is available via the `@ai-sdk/deepinfra` module. You can install it with:
|
|
13
|
+
|
|
14
|
+
<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
|
|
15
|
+
<Tab>
|
|
16
|
+
<Snippet text="pnpm add @ai-sdk/deepinfra" dark />
|
|
17
|
+
</Tab>
|
|
18
|
+
<Tab>
|
|
19
|
+
<Snippet text="npm install @ai-sdk/deepinfra" dark />
|
|
20
|
+
</Tab>
|
|
21
|
+
<Tab>
|
|
22
|
+
<Snippet text="yarn add @ai-sdk/deepinfra" dark />
|
|
23
|
+
</Tab>
|
|
24
|
+
|
|
25
|
+
<Tab>
|
|
26
|
+
<Snippet text="bun add @ai-sdk/deepinfra" dark />
|
|
27
|
+
</Tab>
|
|
28
|
+
</Tabs>
|
|
29
|
+
|
|
30
|
+
## Provider Instance
|
|
31
|
+
|
|
32
|
+
You can import the default provider instance `deepinfra` from `@ai-sdk/deepinfra`:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { deepinfra } from '@ai-sdk/deepinfra';
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If you need a customized setup, you can import `createDeepInfra` from `@ai-sdk/deepinfra` and create a provider instance with your settings:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { createDeepInfra } from '@ai-sdk/deepinfra';
|
|
42
|
+
|
|
43
|
+
const deepinfra = createDeepInfra({
|
|
44
|
+
apiKey: process.env.DEEPINFRA_API_KEY ?? '',
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
You can use the following optional settings to customize the DeepInfra provider instance:
|
|
49
|
+
|
|
50
|
+
- **baseURL** _string_
|
|
51
|
+
|
|
52
|
+
Use a different URL prefix for API calls, e.g. to use proxy servers.
|
|
53
|
+
The default prefix is `https://api.deepinfra.com/v1`.
|
|
54
|
+
|
|
55
|
+
Note: Language models and embeddings use OpenAI-compatible endpoints at `{baseURL}/openai`,
|
|
56
|
+
while image models use `{baseURL}/inference`.
|
|
57
|
+
|
|
58
|
+
- **apiKey** _string_
|
|
59
|
+
|
|
60
|
+
API key that is being sent using the `Authorization` header. It defaults to
|
|
61
|
+
the `DEEPINFRA_API_KEY` environment variable.
|
|
62
|
+
|
|
63
|
+
- **headers** _Record<string,string>_
|
|
64
|
+
|
|
65
|
+
Custom headers to include in the requests.
|
|
66
|
+
|
|
67
|
+
- **fetch** _(input: RequestInfo, init?: RequestInit) => Promise<Response>_
|
|
68
|
+
|
|
69
|
+
Custom [fetch](https://developer.mozilla.org/en-US/docs/Web/API/fetch) implementation.
|
|
70
|
+
Defaults to the global `fetch` function.
|
|
71
|
+
You can use it as a middleware to intercept requests,
|
|
72
|
+
or to provide a custom fetch implementation for e.g. testing.
|
|
73
|
+
|
|
74
|
+
## Language Models
|
|
75
|
+
|
|
76
|
+
You can create language models using a provider instance. The first argument is the model ID, for example:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { deepinfra } from '@ai-sdk/deepinfra';
|
|
80
|
+
import { generateText } from 'ai';
|
|
81
|
+
|
|
82
|
+
const { text } = await generateText({
|
|
83
|
+
model: deepinfra('meta-llama/Meta-Llama-3.1-70B-Instruct'),
|
|
84
|
+
prompt: 'Write a vegetarian lasagna recipe for 4 people.',
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
DeepInfra language models can also be used in the `streamText` function (see [AI SDK Core](/docs/ai-sdk-core)).
|
|
89
|
+
|
|
90
|
+
## Model Capabilities
|
|
91
|
+
|
|
92
|
+
| Model | Image Input | Object Generation | Tool Usage | Tool Streaming |
|
|
93
|
+
| --------------------------------------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
|
|
94
|
+
| `meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8` | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
95
|
+
| `meta-llama/Llama-4-Scout-17B-16E-Instruct` | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
96
|
+
| `meta-llama/Llama-3.3-70B-Instruct-Turbo` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
97
|
+
| `meta-llama/Llama-3.3-70B-Instruct` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
98
|
+
| `meta-llama/Meta-Llama-3.1-405B-Instruct` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
99
|
+
| `meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
100
|
+
| `meta-llama/Meta-Llama-3.1-70B-Instruct` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
101
|
+
| `meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> |
|
|
102
|
+
| `meta-llama/Meta-Llama-3.1-8B-Instruct` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
103
|
+
| `meta-llama/Llama-3.2-11B-Vision-Instruct` | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
104
|
+
| `meta-llama/Llama-3.2-90B-Vision-Instruct` | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
105
|
+
| `mistralai/Mixtral-8x7B-Instruct-v0.1` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> |
|
|
106
|
+
| `deepseek-ai/DeepSeek-V3` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
107
|
+
| `deepseek-ai/DeepSeek-R1` | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
108
|
+
| `deepseek-ai/DeepSeek-R1-Distill-Llama-70B` | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
109
|
+
| `deepseek-ai/DeepSeek-R1-Turbo` | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
110
|
+
| `nvidia/Llama-3.1-Nemotron-70B-Instruct` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> |
|
|
111
|
+
| `Qwen/Qwen2-7B-Instruct` | <Cross size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
112
|
+
| `Qwen/Qwen2.5-72B-Instruct` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
113
|
+
| `Qwen/Qwen2.5-Coder-32B-Instruct` | <Cross size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
114
|
+
| `Qwen/QwQ-32B-Preview` | <Cross size={18} /> | <Check size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
115
|
+
| `google/codegemma-7b-it` | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
116
|
+
| `google/gemma-2-9b-it` | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
117
|
+
| `microsoft/WizardLM-2-8x22B` | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> | <Cross size={18} /> |
|
|
118
|
+
|
|
119
|
+
<Note>
|
|
120
|
+
The table above lists popular models. Please see the [DeepInfra
|
|
121
|
+
docs](https://deepinfra.com) for a full list of available models. You can also
|
|
122
|
+
pass any available provider model ID as a string if needed.
|
|
123
|
+
</Note>
|
|
124
|
+
|
|
125
|
+
## Image Models
|
|
126
|
+
|
|
127
|
+
You can create DeepInfra image models using the `.image()` factory method.
|
|
128
|
+
For more on image generation with the AI SDK see [generateImage()](/docs/reference/ai-sdk-core/generate-image).
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import { deepinfra } from '@ai-sdk/deepinfra';
|
|
132
|
+
import { generateImage } from 'ai';
|
|
133
|
+
|
|
134
|
+
const { image } = await generateImage({
|
|
135
|
+
model: deepinfra.image('stabilityai/sd3.5'),
|
|
136
|
+
prompt: 'A futuristic cityscape at sunset',
|
|
137
|
+
aspectRatio: '16:9',
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
<Note>
|
|
142
|
+
Model support for `size` and `aspectRatio` parameters varies by model. Please
|
|
143
|
+
check the individual model documentation on [DeepInfra's models
|
|
144
|
+
page](https://deepinfra.com/models/text-to-image) for supported options and
|
|
145
|
+
additional parameters.
|
|
146
|
+
</Note>
|
|
147
|
+
|
|
148
|
+
### Model-specific options
|
|
149
|
+
|
|
150
|
+
You can pass model-specific parameters using the `providerOptions.deepinfra` field:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
import { deepinfra } from '@ai-sdk/deepinfra';
|
|
154
|
+
import { generateImage } from 'ai';
|
|
155
|
+
|
|
156
|
+
const { image } = await generateImage({
|
|
157
|
+
model: deepinfra.image('stabilityai/sd3.5'),
|
|
158
|
+
prompt: 'A futuristic cityscape at sunset',
|
|
159
|
+
aspectRatio: '16:9',
|
|
160
|
+
providerOptions: {
|
|
161
|
+
deepinfra: {
|
|
162
|
+
num_inference_steps: 30, // Control the number of denoising steps (1-50)
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Image Editing
|
|
169
|
+
|
|
170
|
+
DeepInfra supports image editing through models like `Qwen/Qwen-Image-Edit`. Pass input images via `prompt.images` to transform or edit existing images.
|
|
171
|
+
|
|
172
|
+
#### Basic Image Editing
|
|
173
|
+
|
|
174
|
+
Transform an existing image using text prompts:
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
const imageBuffer = readFileSync('./input-image.png');
|
|
178
|
+
|
|
179
|
+
const { images } = await generateImage({
|
|
180
|
+
model: deepinfra.image('Qwen/Qwen-Image-Edit'),
|
|
181
|
+
prompt: {
|
|
182
|
+
text: 'Turn the cat into a golden retriever dog',
|
|
183
|
+
images: [imageBuffer],
|
|
184
|
+
},
|
|
185
|
+
size: '1024x1024',
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Inpainting with Mask
|
|
190
|
+
|
|
191
|
+
Edit specific parts of an image using a mask. Transparent areas in the mask indicate where the image should be edited:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
const image = readFileSync('./input-image.png');
|
|
195
|
+
const mask = readFileSync('./mask.png');
|
|
196
|
+
|
|
197
|
+
const { images } = await generateImage({
|
|
198
|
+
model: deepinfra.image('Qwen/Qwen-Image-Edit'),
|
|
199
|
+
prompt: {
|
|
200
|
+
text: 'A sunlit indoor lounge area with a pool containing a flamingo',
|
|
201
|
+
images: [image],
|
|
202
|
+
mask: mask,
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Multi-Image Combining
|
|
208
|
+
|
|
209
|
+
Combine multiple reference images into a single output:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
const cat = readFileSync('./cat.png');
|
|
213
|
+
const dog = readFileSync('./dog.png');
|
|
214
|
+
|
|
215
|
+
const { images } = await generateImage({
|
|
216
|
+
model: deepinfra.image('Qwen/Qwen-Image-Edit'),
|
|
217
|
+
prompt: {
|
|
218
|
+
text: 'Create a scene with both animals together, playing as friends',
|
|
219
|
+
images: [cat, dog],
|
|
220
|
+
},
|
|
221
|
+
});
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
<Note>
|
|
225
|
+
Input images can be provided as `Buffer`, `ArrayBuffer`, `Uint8Array`, or
|
|
226
|
+
base64-encoded strings. DeepInfra uses an OpenAI-compatible image editing API
|
|
227
|
+
at `https://api.deepinfra.com/v1/openai/images/edits`.
|
|
228
|
+
</Note>
|
|
229
|
+
|
|
230
|
+
### Model Capabilities
|
|
231
|
+
|
|
232
|
+
For models supporting aspect ratios, the following ratios are typically supported:
|
|
233
|
+
`1:1 (default), 16:9, 1:9, 3:2, 2:3, 4:5, 5:4, 9:16, 9:21`
|
|
234
|
+
|
|
235
|
+
For models supporting size parameters, dimensions must typically be:
|
|
236
|
+
|
|
237
|
+
- Multiples of 32
|
|
238
|
+
- Width and height between 256 and 1440 pixels
|
|
239
|
+
- Default size is 1024x1024
|
|
240
|
+
|
|
241
|
+
| Model | Dimensions Specification | Notes |
|
|
242
|
+
| ---------------------------------- | ------------------------ | -------------------------------------------------------- |
|
|
243
|
+
| `stabilityai/sd3.5` | Aspect Ratio | Premium quality base model, 8B parameters |
|
|
244
|
+
| `black-forest-labs/FLUX-1.1-pro` | Size | Latest state-of-art model with superior prompt following |
|
|
245
|
+
| `black-forest-labs/FLUX-1-schnell` | Size | Fast generation in 1-4 steps |
|
|
246
|
+
| `black-forest-labs/FLUX-1-dev` | Size | Optimized for anatomical accuracy |
|
|
247
|
+
| `black-forest-labs/FLUX-pro` | Size | Flagship Flux model |
|
|
248
|
+
| `stabilityai/sd3.5-medium` | Aspect Ratio | Balanced 2.5B parameter model |
|
|
249
|
+
| `stabilityai/sdxl-turbo` | Aspect Ratio | Optimized for fast generation |
|
|
250
|
+
|
|
251
|
+
For more details and pricing information, see the [DeepInfra text-to-image models page](https://deepinfra.com/models/text-to-image).
|
|
252
|
+
|
|
253
|
+
## Embedding Models
|
|
254
|
+
|
|
255
|
+
You can create DeepInfra embedding models using the `.embedding()` factory method.
|
|
256
|
+
For more on embedding models with the AI SDK see [embed()](/docs/reference/ai-sdk-core/embed).
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
import { deepinfra } from '@ai-sdk/deepinfra';
|
|
260
|
+
import { embed } from 'ai';
|
|
261
|
+
|
|
262
|
+
const { embedding } = await embed({
|
|
263
|
+
model: deepinfra.embedding('BAAI/bge-large-en-v1.5'),
|
|
264
|
+
value: 'sunny day at the beach',
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Model Capabilities
|
|
269
|
+
|
|
270
|
+
| Model | Dimensions | Max Tokens |
|
|
271
|
+
| ----------------------------------------------------- | ---------- | ---------- |
|
|
272
|
+
| `BAAI/bge-base-en-v1.5` | 768 | 512 |
|
|
273
|
+
| `BAAI/bge-large-en-v1.5` | 1024 | 512 |
|
|
274
|
+
| `BAAI/bge-m3` | 1024 | 8192 |
|
|
275
|
+
| `intfloat/e5-base-v2` | 768 | 512 |
|
|
276
|
+
| `intfloat/e5-large-v2` | 1024 | 512 |
|
|
277
|
+
| `intfloat/multilingual-e5-large` | 1024 | 512 |
|
|
278
|
+
| `sentence-transformers/all-MiniLM-L12-v2` | 384 | 256 |
|
|
279
|
+
| `sentence-transformers/all-MiniLM-L6-v2` | 384 | 256 |
|
|
280
|
+
| `sentence-transformers/all-mpnet-base-v2` | 768 | 384 |
|
|
281
|
+
| `sentence-transformers/clip-ViT-B-32` | 512 | 77 |
|
|
282
|
+
| `sentence-transformers/clip-ViT-B-32-multilingual-v1` | 512 | 77 |
|
|
283
|
+
| `sentence-transformers/multi-qa-mpnet-base-dot-v1` | 768 | 512 |
|
|
284
|
+
| `sentence-transformers/paraphrase-MiniLM-L6-v2` | 384 | 128 |
|
|
285
|
+
| `shibing624/text2vec-base-chinese` | 768 | 512 |
|
|
286
|
+
| `thenlper/gte-base` | 768 | 512 |
|
|
287
|
+
| `thenlper/gte-large` | 1024 | 512 |
|
|
288
|
+
|
|
289
|
+
<Note>
|
|
290
|
+
For a complete list of available embedding models, see the [DeepInfra
|
|
291
|
+
embeddings page](https://deepinfra.com/models/embeddings).
|
|
292
|
+
</Note>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/deepinfra",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.19",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -8,10 +8,18 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist/**/*",
|
|
11
|
+
"docs/**/*",
|
|
11
12
|
"src",
|
|
13
|
+
"!src/**/*.test.ts",
|
|
14
|
+
"!src/**/*.test-d.ts",
|
|
15
|
+
"!src/**/__snapshots__",
|
|
16
|
+
"!src/**/__fixtures__",
|
|
12
17
|
"CHANGELOG.md",
|
|
13
18
|
"README.md"
|
|
14
19
|
],
|
|
20
|
+
"directories": {
|
|
21
|
+
"doc": "./docs"
|
|
22
|
+
},
|
|
15
23
|
"exports": {
|
|
16
24
|
"./package.json": "./package.json",
|
|
17
25
|
".": {
|
|
@@ -21,16 +29,16 @@
|
|
|
21
29
|
}
|
|
22
30
|
},
|
|
23
31
|
"dependencies": {
|
|
24
|
-
"@ai-sdk/openai-compatible": "2.0.
|
|
25
|
-
"@ai-sdk/provider": "3.0.
|
|
26
|
-
"@ai-sdk/provider-utils": "4.0.
|
|
32
|
+
"@ai-sdk/openai-compatible": "2.0.18",
|
|
33
|
+
"@ai-sdk/provider": "3.0.5",
|
|
34
|
+
"@ai-sdk/provider-utils": "4.0.9"
|
|
27
35
|
},
|
|
28
36
|
"devDependencies": {
|
|
29
37
|
"@types/node": "20.17.24",
|
|
30
38
|
"tsup": "^8",
|
|
31
39
|
"typescript": "5.8.3",
|
|
32
40
|
"zod": "3.25.76",
|
|
33
|
-
"@ai-sdk/test-server": "1.0.
|
|
41
|
+
"@ai-sdk/test-server": "1.0.3",
|
|
34
42
|
"@vercel/ai-tsconfig": "0.0.0"
|
|
35
43
|
},
|
|
36
44
|
"peerDependencies": {
|
|
@@ -56,7 +64,7 @@
|
|
|
56
64
|
"scripts": {
|
|
57
65
|
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
58
66
|
"build:watch": "pnpm clean && tsup --watch",
|
|
59
|
-
"clean": "del-cli dist *.tsbuildinfo",
|
|
67
|
+
"clean": "del-cli dist docs *.tsbuildinfo",
|
|
60
68
|
"lint": "eslint \"./**/*.ts*\"",
|
|
61
69
|
"type-check": "tsc --build",
|
|
62
70
|
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
@@ -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
|
-
});
|