@ai-sdk/mistral 4.0.59 → 4.0.60

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.
@@ -0,0 +1,111 @@
1
+ import {
2
+ UnsupportedFunctionalityError,
3
+ type LanguageModelV4CallOptions,
4
+ type SharedV4Warning,
5
+ } from '@ai-sdk/provider';
6
+ import type { MistralToolChoice } from './mistral-chat-prompt';
7
+ import { createToolNameMapping } from '@ai-sdk/provider-utils';
8
+
9
+ type MistralTool =
10
+ | { type: 'web_search' | 'web_search_premium' }
11
+ | {
12
+ type: 'function';
13
+ function: {
14
+ name: string;
15
+ description: string | undefined;
16
+ parameters: unknown;
17
+ strict?: boolean;
18
+ };
19
+ };
20
+
21
+ export const mistralProviderToolNames = {
22
+ 'mistral.web_search': 'web_search',
23
+ 'mistral.web_search_premium': 'web_search_premium',
24
+ } as const;
25
+
26
+ export function prepareConversationTools({
27
+ tools,
28
+ toolChoice,
29
+ }: {
30
+ tools: LanguageModelV4CallOptions['tools'];
31
+ toolChoice?: LanguageModelV4CallOptions['toolChoice'];
32
+ }): {
33
+ tools: Array<MistralTool> | undefined;
34
+ toolChoice: MistralToolChoice | undefined;
35
+ toolWarnings: SharedV4Warning[];
36
+ } {
37
+ // when the tools array is empty, change it to undefined to prevent errors:
38
+ tools = tools?.length ? tools : undefined;
39
+
40
+ const toolWarnings: SharedV4Warning[] = [];
41
+
42
+ if (tools == null) {
43
+ return { tools: undefined, toolChoice: undefined, toolWarnings };
44
+ }
45
+
46
+ const mistralTools: Array<MistralTool> = [];
47
+
48
+ for (const tool of tools) {
49
+ if (tool.type === 'provider') {
50
+ if (
51
+ tool.id === 'mistral.web_search' ||
52
+ tool.id === 'mistral.web_search_premium'
53
+ ) {
54
+ mistralTools.push({ type: mistralProviderToolNames[tool.id] });
55
+ continue;
56
+ }
57
+ toolWarnings.push({
58
+ type: 'unsupported',
59
+ feature: `provider-defined tool ${tool.id}`,
60
+ });
61
+ } else {
62
+ mistralTools.push({
63
+ type: 'function',
64
+ function: {
65
+ name: tool.name,
66
+ description: tool.description,
67
+ parameters: tool.inputSchema,
68
+ ...(tool.strict != null ? { strict: tool.strict } : {}),
69
+ },
70
+ });
71
+ }
72
+ }
73
+
74
+ if (toolChoice == null) {
75
+ return { tools: mistralTools, toolChoice: undefined, toolWarnings };
76
+ }
77
+
78
+ const type = toolChoice.type;
79
+
80
+ switch (type) {
81
+ case 'auto':
82
+ case 'none':
83
+ return { tools: mistralTools, toolChoice: type, toolWarnings };
84
+ case 'required':
85
+ return { tools: mistralTools, toolChoice: 'any', toolWarnings };
86
+
87
+ // mistral does not support tool mode directly,
88
+ // so we filter the tools and force the tool choice through 'any'
89
+ case 'tool': {
90
+ const toolName = createToolNameMapping({
91
+ tools,
92
+ providerToolNames: mistralProviderToolNames,
93
+ }).toProviderToolName(toolChoice.toolName);
94
+ return {
95
+ tools: mistralTools.filter(tool =>
96
+ tool.type === 'function'
97
+ ? tool.function.name === toolName
98
+ : tool.type === toolName,
99
+ ),
100
+ toolChoice: 'any',
101
+ toolWarnings,
102
+ };
103
+ }
104
+ default: {
105
+ const _exhaustiveCheck: never = type;
106
+ throw new UnsupportedFunctionalityError({
107
+ functionality: `tool choice type: ${_exhaustiveCheck}`,
108
+ });
109
+ }
110
+ }
111
+ }
@@ -13,6 +13,7 @@ import {
13
13
  type FetchFunction,
14
14
  } from '@ai-sdk/provider-utils';
15
15
  import { MistralChatLanguageModel } from './mistral-chat-language-model';
16
+ import { MistralConversationLanguageModel } from './mistral-conversation-language-model';
16
17
  import type { MistralChatModelId } from './mistral-chat-language-model-options';
17
18
  import { MistralEmbeddingModel } from './mistral-embedding-model';
18
19
  import type { MistralEmbeddingModelId } from './mistral-embedding-model-options';
@@ -21,8 +22,10 @@ import type { MistralSpeechModelId } from './mistral-speech-model-options';
21
22
  import { MistralTranscriptionModel } from './mistral-transcription-model';
22
23
  import type { MistralTranscriptionModelId } from './mistral-transcription-model-options';
23
24
  import { VERSION } from './version';
25
+ import { mistralTools } from './tool';
24
26
 
25
27
  export interface MistralProvider extends ProviderV4 {
28
+ tools: typeof mistralTools;
26
29
  (modelId: MistralChatModelId): LanguageModelV4;
27
30
 
28
31
  /**
@@ -35,6 +38,11 @@ export interface MistralProvider extends ProviderV4 {
35
38
  */
36
39
  chat(modelId: MistralChatModelId): LanguageModelV4;
37
40
 
41
+ /**
42
+ * Creates a model using the Conversations API, with support for web search.
43
+ */
44
+ conversation(modelId: MistralChatModelId): LanguageModelV4;
45
+
38
46
  /**
39
47
  * Creates a model for text embeddings.
40
48
  */
@@ -144,6 +152,15 @@ export function createMistral(
144
152
  fetch: options.fetch,
145
153
  });
146
154
 
155
+ const createConversationModel = (modelId: MistralChatModelId) =>
156
+ new MistralConversationLanguageModel(modelId, {
157
+ provider: 'mistral.conversation',
158
+ baseURL,
159
+ headers: getHeaders,
160
+ fetch: options.fetch,
161
+ generateId: options.generateId,
162
+ });
163
+
147
164
  const createSpeechModel = (modelId: MistralSpeechModelId) =>
148
165
  new MistralSpeechModel(modelId, {
149
166
  provider: 'mistral.speech',
@@ -173,6 +190,8 @@ export function createMistral(
173
190
  provider.specificationVersion = 'v4' as const;
174
191
  provider.languageModel = createChatModel;
175
192
  provider.chat = createChatModel;
193
+ provider.conversation = createConversationModel;
194
+ provider.tools = mistralTools;
176
195
  provider.embedding = createEmbeddingModel;
177
196
  provider.embeddingModel = createEmbeddingModel;
178
197
  provider.textEmbedding = createEmbeddingModel;
@@ -0,0 +1,3 @@
1
+ import { webSearch, webSearchPremium } from './web-search';
2
+
3
+ export const mistralTools = { webSearch, webSearchPremium };
@@ -0,0 +1,35 @@
1
+ import type { JSONValue } from '@ai-sdk/provider';
2
+ import {
3
+ createProviderExecutedToolFactory,
4
+ lazySchema,
5
+ zodSchema,
6
+ } from '@ai-sdk/provider-utils';
7
+ import { z } from 'zod/v4';
8
+
9
+ const inputSchema = lazySchema(() =>
10
+ zodSchema(z.object({ arguments: z.string() })),
11
+ );
12
+ const outputSchema = lazySchema(() =>
13
+ zodSchema(z.object({ info: z.record(z.string(), z.json()).optional() })),
14
+ );
15
+
16
+ const webSearchFactory = createProviderExecutedToolFactory<
17
+ { arguments: string },
18
+ { info?: Record<string, JSONValue> },
19
+ {}
20
+ >({ id: 'mistral.web_search', inputSchema, outputSchema });
21
+
22
+ const webSearchPremiumFactory = createProviderExecutedToolFactory<
23
+ { arguments: string },
24
+ { info?: Record<string, JSONValue> },
25
+ {}
26
+ >({ id: 'mistral.web_search_premium', inputSchema, outputSchema });
27
+
28
+ /** Search the web using Mistral's Conversations API. */
29
+ export const webSearch = (args: Parameters<typeof webSearchFactory>[0] = {}) =>
30
+ webSearchFactory(args);
31
+
32
+ /** Search the web and verified news using Mistral's Conversations API. */
33
+ export const webSearchPremium = (
34
+ args: Parameters<typeof webSearchPremiumFactory>[0] = {},
35
+ ) => webSearchPremiumFactory(args);