@ai-sdk/mistral 0.0.0-1c33ba03-20260114162300 → 0.0.0-4115c213-20260122152721
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 +32 -3
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/docs/20-mistral.mdx +327 -0
- package/package.json +15 -6
- package/src/convert-mistral-usage.ts +46 -0
- package/src/convert-to-mistral-chat-messages.ts +163 -0
- package/src/get-response-metadata.ts +15 -0
- package/src/index.ts +7 -0
- package/src/map-mistral-finish-reason.ts +17 -0
- package/src/mistral-chat-language-model.ts +580 -0
- package/src/mistral-chat-options.ts +63 -0
- package/src/mistral-chat-prompt.ts +46 -0
- package/src/mistral-embedding-model.ts +94 -0
- package/src/mistral-embedding-options.ts +1 -0
- package/src/mistral-error.ts +17 -0
- package/src/mistral-prepare-tools.ts +97 -0
- package/src/mistral-provider.ts +147 -0
- package/src/version.ts +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,40 @@
|
|
|
1
1
|
# @ai-sdk/mistral
|
|
2
2
|
|
|
3
|
-
## 0.0.0-
|
|
3
|
+
## 0.0.0-4115c213-20260122152721
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
|
|
7
|
+
- 4caafb2: chore: excluded tests from src folder in npm package
|
|
8
|
+
- Updated dependencies [4caafb2]
|
|
9
|
+
- @ai-sdk/provider@0.0.0-4115c213-20260122152721
|
|
10
|
+
- @ai-sdk/provider-utils@0.0.0-4115c213-20260122152721
|
|
11
|
+
|
|
12
|
+
## 3.0.11
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 2b8369d: chore: add docs to package dist
|
|
17
|
+
|
|
18
|
+
## 3.0.10
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- 8dc54db: chore: add src folders to package bundle
|
|
23
|
+
|
|
24
|
+
## 3.0.9
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies [5c090e7]
|
|
29
|
+
- @ai-sdk/provider@3.0.4
|
|
30
|
+
- @ai-sdk/provider-utils@4.0.8
|
|
31
|
+
|
|
32
|
+
## 3.0.8
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- Updated dependencies [46f46e4]
|
|
37
|
+
- @ai-sdk/provider-utils@4.0.7
|
|
9
38
|
|
|
10
39
|
## 3.0.7
|
|
11
40
|
|
package/dist/index.js
CHANGED
|
@@ -828,7 +828,7 @@ var MistralTextEmbeddingResponseSchema = import_v44.z.object({
|
|
|
828
828
|
});
|
|
829
829
|
|
|
830
830
|
// src/version.ts
|
|
831
|
-
var VERSION = true ? "0.0.0-
|
|
831
|
+
var VERSION = true ? "0.0.0-4115c213-20260122152721" : "0.0.0-test";
|
|
832
832
|
|
|
833
833
|
// src/mistral-provider.ts
|
|
834
834
|
function createMistral(options = {}) {
|
package/dist/index.mjs
CHANGED
|
@@ -824,7 +824,7 @@ var MistralTextEmbeddingResponseSchema = z4.object({
|
|
|
824
824
|
});
|
|
825
825
|
|
|
826
826
|
// src/version.ts
|
|
827
|
-
var VERSION = true ? "0.0.0-
|
|
827
|
+
var VERSION = true ? "0.0.0-4115c213-20260122152721" : "0.0.0-test";
|
|
828
828
|
|
|
829
829
|
// src/mistral-provider.ts
|
|
830
830
|
function createMistral(options = {}) {
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Mistral AI
|
|
3
|
+
description: Learn how to use Mistral.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Mistral AI Provider
|
|
7
|
+
|
|
8
|
+
The [Mistral AI](https://mistral.ai/) provider contains language model support for the Mistral chat API.
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
The Mistral provider is available in the `@ai-sdk/mistral` module. You can install it with
|
|
13
|
+
|
|
14
|
+
<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
|
|
15
|
+
<Tab>
|
|
16
|
+
<Snippet text="pnpm add @ai-sdk/mistral" dark />
|
|
17
|
+
</Tab>
|
|
18
|
+
<Tab>
|
|
19
|
+
<Snippet text="npm install @ai-sdk/mistral" dark />
|
|
20
|
+
</Tab>
|
|
21
|
+
<Tab>
|
|
22
|
+
<Snippet text="yarn add @ai-sdk/mistral" dark />
|
|
23
|
+
</Tab>
|
|
24
|
+
|
|
25
|
+
<Tab>
|
|
26
|
+
<Snippet text="bun add @ai-sdk/mistral" dark />
|
|
27
|
+
</Tab>
|
|
28
|
+
</Tabs>
|
|
29
|
+
|
|
30
|
+
## Provider Instance
|
|
31
|
+
|
|
32
|
+
You can import the default provider instance `mistral` from `@ai-sdk/mistral`:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { mistral } from '@ai-sdk/mistral';
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
If you need a customized setup, you can import `createMistral` from `@ai-sdk/mistral`
|
|
39
|
+
and create a provider instance with your settings:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { createMistral } from '@ai-sdk/mistral';
|
|
43
|
+
|
|
44
|
+
const mistral = createMistral({
|
|
45
|
+
// custom settings
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
You can use the following optional settings to customize the Mistral provider instance:
|
|
50
|
+
|
|
51
|
+
- **baseURL** _string_
|
|
52
|
+
|
|
53
|
+
Use a different URL prefix for API calls, e.g. to use proxy servers.
|
|
54
|
+
The default prefix is `https://api.mistral.ai/v1`.
|
|
55
|
+
|
|
56
|
+
- **apiKey** _string_
|
|
57
|
+
|
|
58
|
+
API key that is being sent using the `Authorization` header.
|
|
59
|
+
It defaults to the `MISTRAL_API_KEY` environment variable.
|
|
60
|
+
|
|
61
|
+
- **headers** _Record<string,string>_
|
|
62
|
+
|
|
63
|
+
Custom headers to include in the requests.
|
|
64
|
+
|
|
65
|
+
- **fetch** _(input: RequestInfo, init?: RequestInit) => Promise<Response>_
|
|
66
|
+
|
|
67
|
+
Custom [fetch](https://developer.mozilla.org/en-US/docs/Web/API/fetch) implementation.
|
|
68
|
+
Defaults to the global `fetch` function.
|
|
69
|
+
You can use it as a middleware to intercept requests,
|
|
70
|
+
or to provide a custom fetch implementation for e.g. testing.
|
|
71
|
+
|
|
72
|
+
## Language Models
|
|
73
|
+
|
|
74
|
+
You can create models that call the [Mistral chat API](https://docs.mistral.ai/api/#operation/createChatCompletion) using a provider instance.
|
|
75
|
+
The first argument is the model id, e.g. `mistral-large-latest`.
|
|
76
|
+
Some Mistral chat models support tool calls.
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const model = mistral('mistral-large-latest');
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Mistral chat models also support additional model settings that are not part of the [standard call settings](/docs/ai-sdk-core/settings).
|
|
83
|
+
You can pass them as an options argument and utilize `MistralLanguageModelOptions` for typing:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { mistral, type MistralLanguageModelOptions } from '@ai-sdk/mistral';
|
|
87
|
+
const model = mistral('mistral-large-latest');
|
|
88
|
+
|
|
89
|
+
await generateText({
|
|
90
|
+
model,
|
|
91
|
+
providerOptions: {
|
|
92
|
+
mistral: {
|
|
93
|
+
safePrompt: true, // optional safety prompt injection
|
|
94
|
+
parallelToolCalls: false, // disable parallel tool calls (one tool per response)
|
|
95
|
+
} satisfies MistralLanguageModelOptions,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The following optional provider options are available for Mistral models:
|
|
101
|
+
|
|
102
|
+
- **safePrompt** _boolean_
|
|
103
|
+
|
|
104
|
+
Whether to inject a safety prompt before all conversations.
|
|
105
|
+
|
|
106
|
+
Defaults to `false`.
|
|
107
|
+
|
|
108
|
+
- **documentImageLimit** _number_
|
|
109
|
+
|
|
110
|
+
Maximum number of images to process in a document.
|
|
111
|
+
|
|
112
|
+
- **documentPageLimit** _number_
|
|
113
|
+
|
|
114
|
+
Maximum number of pages to process in a document.
|
|
115
|
+
|
|
116
|
+
- **strictJsonSchema** _boolean_
|
|
117
|
+
|
|
118
|
+
Whether to use strict JSON schema validation for structured outputs. Only applies when a schema is provided and only sets the [`strict` flag](https://docs.mistral.ai/api/#tag/chat/operation/chat_completion_v1_chat_completions_post) in addition to using [Custom Structured Outputs](https://docs.mistral.ai/capabilities/structured-output/custom_structured_output/), which is used by default if a schema is provided.
|
|
119
|
+
|
|
120
|
+
Defaults to `false`.
|
|
121
|
+
|
|
122
|
+
- **structuredOutputs** _boolean_
|
|
123
|
+
|
|
124
|
+
Whether to use [structured outputs](#structured-outputs). When enabled, tool calls and object generation will be strict and follow the provided schema.
|
|
125
|
+
|
|
126
|
+
Defaults to `true`.
|
|
127
|
+
|
|
128
|
+
- **parallelToolCalls** _boolean_
|
|
129
|
+
|
|
130
|
+
Whether to enable parallel function calling during tool use. When set to false, the model will use at most one tool per response.
|
|
131
|
+
|
|
132
|
+
Defaults to `true`.
|
|
133
|
+
|
|
134
|
+
### Document OCR
|
|
135
|
+
|
|
136
|
+
Mistral chat models support document OCR for PDF files.
|
|
137
|
+
You can optionally set image and page limits using the provider options.
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
const result = await generateText({
|
|
141
|
+
model: mistral('mistral-small-latest'),
|
|
142
|
+
messages: [
|
|
143
|
+
{
|
|
144
|
+
role: 'user',
|
|
145
|
+
content: [
|
|
146
|
+
{
|
|
147
|
+
type: 'text',
|
|
148
|
+
text: 'What is an embedding model according to this document?',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
type: 'file',
|
|
152
|
+
data: new URL(
|
|
153
|
+
'https://github.com/vercel/ai/blob/main/examples/ai-functions/data/ai.pdf?raw=true',
|
|
154
|
+
),
|
|
155
|
+
mediaType: 'application/pdf',
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
// optional settings:
|
|
161
|
+
providerOptions: {
|
|
162
|
+
mistral: {
|
|
163
|
+
documentImageLimit: 8,
|
|
164
|
+
documentPageLimit: 64,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Reasoning Models
|
|
171
|
+
|
|
172
|
+
Mistral offers reasoning models that provide step-by-step thinking capabilities:
|
|
173
|
+
|
|
174
|
+
- **magistral-small-2506**: Smaller reasoning model for efficient step-by-step thinking
|
|
175
|
+
- **magistral-medium-2506**: More powerful reasoning model balancing performance and cost
|
|
176
|
+
|
|
177
|
+
These models return content that includes `<think>...</think>` tags containing the reasoning process. To properly extract and separate the reasoning from the final answer, use the [extract reasoning middleware](/docs/reference/ai-sdk-core/extract-reasoning-middleware):
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
import { mistral } from '@ai-sdk/mistral';
|
|
181
|
+
import {
|
|
182
|
+
extractReasoningMiddleware,
|
|
183
|
+
generateText,
|
|
184
|
+
wrapLanguageModel,
|
|
185
|
+
} from 'ai';
|
|
186
|
+
|
|
187
|
+
const result = await generateText({
|
|
188
|
+
model: wrapLanguageModel({
|
|
189
|
+
model: mistral('magistral-small-2506'),
|
|
190
|
+
middleware: extractReasoningMiddleware({
|
|
191
|
+
tagName: 'think',
|
|
192
|
+
}),
|
|
193
|
+
}),
|
|
194
|
+
prompt: 'What is 15 * 24?',
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
console.log('REASONING:', result.reasoningText);
|
|
198
|
+
// Output: "Let me calculate this step by step..."
|
|
199
|
+
|
|
200
|
+
console.log('ANSWER:', result.text);
|
|
201
|
+
// Output: "360"
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The middleware automatically parses the `<think>` tags and provides separate `reasoningText` and `text` properties in the result.
|
|
205
|
+
|
|
206
|
+
### Example
|
|
207
|
+
|
|
208
|
+
You can use Mistral language models to generate text with the `generateText` function:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import { mistral } from '@ai-sdk/mistral';
|
|
212
|
+
import { generateText } from 'ai';
|
|
213
|
+
|
|
214
|
+
const { text } = await generateText({
|
|
215
|
+
model: mistral('mistral-large-latest'),
|
|
216
|
+
prompt: 'Write a vegetarian lasagna recipe for 4 people.',
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Mistral language models can also be used in the `streamText`, `generateObject`, and `streamObject` functions
|
|
221
|
+
(see [AI SDK Core](/docs/ai-sdk-core)).
|
|
222
|
+
|
|
223
|
+
#### Structured Outputs
|
|
224
|
+
|
|
225
|
+
Mistral chat models support structured outputs using JSON Schema. You can use `generateObject` or `streamObject`
|
|
226
|
+
with Zod, Valibot, or raw JSON Schema. The SDK sends your schema via Mistral's `response_format: { type: 'json_schema' }`.
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
import { mistral } from '@ai-sdk/mistral';
|
|
230
|
+
import { generateObject } from 'ai';
|
|
231
|
+
import { z } from 'zod';
|
|
232
|
+
|
|
233
|
+
const result = await generateObject({
|
|
234
|
+
model: mistral('mistral-large-latest'),
|
|
235
|
+
schema: z.object({
|
|
236
|
+
recipe: z.object({
|
|
237
|
+
name: z.string(),
|
|
238
|
+
ingredients: z.array(z.string()),
|
|
239
|
+
instructions: z.array(z.string()),
|
|
240
|
+
}),
|
|
241
|
+
}),
|
|
242
|
+
prompt: 'Generate a simple pasta recipe.',
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
console.log(JSON.stringify(result.object, null, 2));
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
You can enable strict JSON Schema validation using a provider option:
|
|
249
|
+
|
|
250
|
+
```ts highlight="7-11"
|
|
251
|
+
import { mistral } from '@ai-sdk/mistral';
|
|
252
|
+
import { generateObject } from 'ai';
|
|
253
|
+
import { z } from 'zod';
|
|
254
|
+
|
|
255
|
+
const result = await generateObject({
|
|
256
|
+
model: mistral('mistral-large-latest'),
|
|
257
|
+
providerOptions: {
|
|
258
|
+
mistral: {
|
|
259
|
+
strictJsonSchema: true, // reject outputs that don't strictly match the schema
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
schema: z.object({
|
|
263
|
+
title: z.string(),
|
|
264
|
+
items: z.array(z.object({ id: z.string(), qty: z.number().int().min(1) })),
|
|
265
|
+
}),
|
|
266
|
+
prompt: 'Generate a small shopping list.',
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
<Note>
|
|
271
|
+
When using structured outputs, the SDK no longer injects an extra "answer with
|
|
272
|
+
JSON" instruction. It relies on Mistral's native `json_schema`/`json_object`
|
|
273
|
+
response formats instead. You can customize the schema name/description via
|
|
274
|
+
the standard structured-output APIs.
|
|
275
|
+
</Note>
|
|
276
|
+
|
|
277
|
+
### Model Capabilities
|
|
278
|
+
|
|
279
|
+
| Model | Image Input | Object Generation | Tool Usage | Tool Streaming |
|
|
280
|
+
| ----------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
|
|
281
|
+
| `pixtral-large-latest` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
282
|
+
| `mistral-large-latest` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
283
|
+
| `mistral-medium-latest` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
284
|
+
| `mistral-medium-2505` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
285
|
+
| `mistral-small-latest` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
286
|
+
| `magistral-small-2506` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
287
|
+
| `magistral-medium-2506` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
288
|
+
| `ministral-3b-latest` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
289
|
+
| `ministral-8b-latest` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
290
|
+
| `pixtral-12b-2409` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
291
|
+
| `open-mistral-7b` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
292
|
+
| `open-mixtral-8x7b` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
293
|
+
| `open-mixtral-8x22b` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
|
|
294
|
+
|
|
295
|
+
<Note>
|
|
296
|
+
The table above lists popular models. Please see the [Mistral
|
|
297
|
+
docs](https://docs.mistral.ai/getting-started/models/models_overview/) for a
|
|
298
|
+
full list of available models. The table above lists popular models. You can
|
|
299
|
+
also pass any available provider model ID as a string if needed.
|
|
300
|
+
</Note>
|
|
301
|
+
|
|
302
|
+
## Embedding Models
|
|
303
|
+
|
|
304
|
+
You can create models that call the [Mistral embeddings API](https://docs.mistral.ai/api/#operation/createEmbedding)
|
|
305
|
+
using the `.embedding()` factory method.
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
const model = mistral.embedding('mistral-embed');
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
You can use Mistral embedding models to generate embeddings with the `embed` function:
|
|
312
|
+
|
|
313
|
+
```ts
|
|
314
|
+
import { mistral } from '@ai-sdk/mistral';
|
|
315
|
+
import { embed } from 'ai';
|
|
316
|
+
|
|
317
|
+
const { embedding } = await embed({
|
|
318
|
+
model: mistral.embedding('mistral-embed'),
|
|
319
|
+
value: 'sunny day at the beach',
|
|
320
|
+
});
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Model Capabilities
|
|
324
|
+
|
|
325
|
+
| Model | Default Dimensions |
|
|
326
|
+
| --------------- | ------------------ |
|
|
327
|
+
| `mistral-embed` | 1024 |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/mistral",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-4115c213-20260122152721",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -8,9 +8,18 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist/**/*",
|
|
11
|
+
"docs/**/*",
|
|
12
|
+
"src",
|
|
13
|
+
"!src/**/*.test.ts",
|
|
14
|
+
"!src/**/*.test-d.ts",
|
|
15
|
+
"!src/**/__snapshots__",
|
|
16
|
+
"!src/**/__fixtures__",
|
|
11
17
|
"CHANGELOG.md",
|
|
12
18
|
"README.md"
|
|
13
19
|
],
|
|
20
|
+
"directories": {
|
|
21
|
+
"doc": "./docs"
|
|
22
|
+
},
|
|
14
23
|
"exports": {
|
|
15
24
|
"./package.json": "./package.json",
|
|
16
25
|
".": {
|
|
@@ -20,16 +29,16 @@
|
|
|
20
29
|
}
|
|
21
30
|
},
|
|
22
31
|
"dependencies": {
|
|
23
|
-
"@ai-sdk/provider": "
|
|
24
|
-
"@ai-sdk/provider-utils": "0.0.0-
|
|
32
|
+
"@ai-sdk/provider": "0.0.0-4115c213-20260122152721",
|
|
33
|
+
"@ai-sdk/provider-utils": "0.0.0-4115c213-20260122152721"
|
|
25
34
|
},
|
|
26
35
|
"devDependencies": {
|
|
27
36
|
"@types/node": "20.17.24",
|
|
28
37
|
"tsup": "^8",
|
|
29
38
|
"typescript": "5.8.3",
|
|
30
39
|
"zod": "3.25.76",
|
|
31
|
-
"@
|
|
32
|
-
"@ai-
|
|
40
|
+
"@ai-sdk/test-server": "0.0.0-4115c213-20260122152721",
|
|
41
|
+
"@vercel/ai-tsconfig": "0.0.0"
|
|
33
42
|
},
|
|
34
43
|
"peerDependencies": {
|
|
35
44
|
"zod": "^3.25.76 || ^4.1.8"
|
|
@@ -54,7 +63,7 @@
|
|
|
54
63
|
"scripts": {
|
|
55
64
|
"build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
|
|
56
65
|
"build:watch": "pnpm clean && tsup --watch",
|
|
57
|
-
"clean": "del-cli dist *.tsbuildinfo",
|
|
66
|
+
"clean": "del-cli dist docs *.tsbuildinfo",
|
|
58
67
|
"lint": "eslint \"./**/*.ts*\"",
|
|
59
68
|
"type-check": "tsc --build",
|
|
60
69
|
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { LanguageModelV3Usage } from '@ai-sdk/provider';
|
|
2
|
+
|
|
3
|
+
export type MistralUsage = {
|
|
4
|
+
prompt_tokens: number;
|
|
5
|
+
completion_tokens: number;
|
|
6
|
+
total_tokens: number;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function convertMistralUsage(
|
|
10
|
+
usage: MistralUsage | undefined | null,
|
|
11
|
+
): LanguageModelV3Usage {
|
|
12
|
+
if (usage == null) {
|
|
13
|
+
return {
|
|
14
|
+
inputTokens: {
|
|
15
|
+
total: undefined,
|
|
16
|
+
noCache: undefined,
|
|
17
|
+
cacheRead: undefined,
|
|
18
|
+
cacheWrite: undefined,
|
|
19
|
+
},
|
|
20
|
+
outputTokens: {
|
|
21
|
+
total: undefined,
|
|
22
|
+
text: undefined,
|
|
23
|
+
reasoning: undefined,
|
|
24
|
+
},
|
|
25
|
+
raw: undefined,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const promptTokens = usage.prompt_tokens;
|
|
30
|
+
const completionTokens = usage.completion_tokens;
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
inputTokens: {
|
|
34
|
+
total: promptTokens,
|
|
35
|
+
noCache: promptTokens,
|
|
36
|
+
cacheRead: undefined,
|
|
37
|
+
cacheWrite: undefined,
|
|
38
|
+
},
|
|
39
|
+
outputTokens: {
|
|
40
|
+
total: completionTokens,
|
|
41
|
+
text: completionTokens,
|
|
42
|
+
reasoning: undefined,
|
|
43
|
+
},
|
|
44
|
+
raw: usage,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LanguageModelV3DataContent,
|
|
3
|
+
LanguageModelV3Prompt,
|
|
4
|
+
UnsupportedFunctionalityError,
|
|
5
|
+
} from '@ai-sdk/provider';
|
|
6
|
+
import { MistralPrompt } from './mistral-chat-prompt';
|
|
7
|
+
import { convertToBase64 } from '@ai-sdk/provider-utils';
|
|
8
|
+
|
|
9
|
+
function formatFileUrl({
|
|
10
|
+
data,
|
|
11
|
+
mediaType,
|
|
12
|
+
}: {
|
|
13
|
+
data: LanguageModelV3DataContent;
|
|
14
|
+
mediaType: string;
|
|
15
|
+
}): string {
|
|
16
|
+
return data instanceof URL
|
|
17
|
+
? data.toString()
|
|
18
|
+
: `data:${mediaType};base64,${convertToBase64(data as Uint8Array)}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function convertToMistralChatMessages(
|
|
22
|
+
prompt: LanguageModelV3Prompt,
|
|
23
|
+
): MistralPrompt {
|
|
24
|
+
const messages: MistralPrompt = [];
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < prompt.length; i++) {
|
|
27
|
+
const { role, content } = prompt[i];
|
|
28
|
+
const isLastMessage = i === prompt.length - 1;
|
|
29
|
+
|
|
30
|
+
switch (role) {
|
|
31
|
+
case 'system': {
|
|
32
|
+
messages.push({ role: 'system', content });
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
case 'user': {
|
|
37
|
+
messages.push({
|
|
38
|
+
role: 'user',
|
|
39
|
+
content: content.map(part => {
|
|
40
|
+
switch (part.type) {
|
|
41
|
+
case 'text': {
|
|
42
|
+
return { type: 'text', text: part.text };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
case 'file': {
|
|
46
|
+
if (part.mediaType.startsWith('image/')) {
|
|
47
|
+
const mediaType =
|
|
48
|
+
part.mediaType === 'image/*'
|
|
49
|
+
? 'image/jpeg'
|
|
50
|
+
: part.mediaType;
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
type: 'image_url',
|
|
54
|
+
image_url: formatFileUrl({ data: part.data, mediaType }),
|
|
55
|
+
};
|
|
56
|
+
} else if (part.mediaType === 'application/pdf') {
|
|
57
|
+
return {
|
|
58
|
+
type: 'document_url',
|
|
59
|
+
document_url: formatFileUrl({
|
|
60
|
+
data: part.data,
|
|
61
|
+
mediaType: 'application/pdf',
|
|
62
|
+
}),
|
|
63
|
+
};
|
|
64
|
+
} else {
|
|
65
|
+
throw new UnsupportedFunctionalityError({
|
|
66
|
+
functionality:
|
|
67
|
+
'Only images and PDF file parts are supported',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}),
|
|
73
|
+
});
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
case 'assistant': {
|
|
78
|
+
let text = '';
|
|
79
|
+
const toolCalls: Array<{
|
|
80
|
+
id: string;
|
|
81
|
+
type: 'function';
|
|
82
|
+
function: { name: string; arguments: string };
|
|
83
|
+
}> = [];
|
|
84
|
+
|
|
85
|
+
for (const part of content) {
|
|
86
|
+
switch (part.type) {
|
|
87
|
+
case 'text': {
|
|
88
|
+
text += part.text;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case 'tool-call': {
|
|
92
|
+
toolCalls.push({
|
|
93
|
+
id: part.toolCallId,
|
|
94
|
+
type: 'function',
|
|
95
|
+
function: {
|
|
96
|
+
name: part.toolName,
|
|
97
|
+
arguments: JSON.stringify(part.input),
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case 'reasoning': {
|
|
103
|
+
text += part.text;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
default: {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Unsupported content type in assistant message: ${part.type}`,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
messages.push({
|
|
115
|
+
role: 'assistant',
|
|
116
|
+
content: text,
|
|
117
|
+
prefix: isLastMessage ? true : undefined,
|
|
118
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
case 'tool': {
|
|
124
|
+
for (const toolResponse of content) {
|
|
125
|
+
if (toolResponse.type === 'tool-approval-response') {
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const output = toolResponse.output;
|
|
129
|
+
|
|
130
|
+
let contentValue: string;
|
|
131
|
+
switch (output.type) {
|
|
132
|
+
case 'text':
|
|
133
|
+
case 'error-text':
|
|
134
|
+
contentValue = output.value;
|
|
135
|
+
break;
|
|
136
|
+
case 'execution-denied':
|
|
137
|
+
contentValue = output.reason ?? 'Tool execution denied.';
|
|
138
|
+
break;
|
|
139
|
+
case 'content':
|
|
140
|
+
case 'json':
|
|
141
|
+
case 'error-json':
|
|
142
|
+
contentValue = JSON.stringify(output.value);
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
messages.push({
|
|
147
|
+
role: 'tool',
|
|
148
|
+
name: toolResponse.toolName,
|
|
149
|
+
tool_call_id: toolResponse.toolCallId,
|
|
150
|
+
content: contentValue,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
default: {
|
|
156
|
+
const _exhaustiveCheck: never = role;
|
|
157
|
+
throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return messages;
|
|
163
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function getResponseMetadata({
|
|
2
|
+
id,
|
|
3
|
+
model,
|
|
4
|
+
created,
|
|
5
|
+
}: {
|
|
6
|
+
id?: string | undefined | null;
|
|
7
|
+
created?: number | undefined | null;
|
|
8
|
+
model?: string | undefined | null;
|
|
9
|
+
}) {
|
|
10
|
+
return {
|
|
11
|
+
id: id ?? undefined,
|
|
12
|
+
modelId: model ?? undefined,
|
|
13
|
+
timestamp: created != null ? new Date(created * 1000) : undefined,
|
|
14
|
+
};
|
|
15
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { createMistral, mistral } from './mistral-provider';
|
|
2
|
+
export type {
|
|
3
|
+
MistralProvider,
|
|
4
|
+
MistralProviderSettings,
|
|
5
|
+
} from './mistral-provider';
|
|
6
|
+
export type { MistralLanguageModelOptions } from './mistral-chat-options';
|
|
7
|
+
export { VERSION } from './version';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { LanguageModelV3FinishReason } from '@ai-sdk/provider';
|
|
2
|
+
|
|
3
|
+
export function mapMistralFinishReason(
|
|
4
|
+
finishReason: string | null | undefined,
|
|
5
|
+
): LanguageModelV3FinishReason['unified'] {
|
|
6
|
+
switch (finishReason) {
|
|
7
|
+
case 'stop':
|
|
8
|
+
return 'stop';
|
|
9
|
+
case 'length':
|
|
10
|
+
case 'model_length':
|
|
11
|
+
return 'length';
|
|
12
|
+
case 'tool_calls':
|
|
13
|
+
return 'tool-calls';
|
|
14
|
+
default:
|
|
15
|
+
return 'other';
|
|
16
|
+
}
|
|
17
|
+
}
|