@ai-sdk/provider-utils 5.0.0-beta.2 → 5.0.0-beta.21

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +226 -0
  2. package/dist/index.d.ts +433 -174
  3. package/dist/index.js +322 -284
  4. package/dist/index.js.map +1 -1
  5. package/dist/test/index.js +2 -35
  6. package/dist/test/index.js.map +1 -1
  7. package/package.json +8 -10
  8. package/src/convert-image-model-file-to-data-uri.ts +3 -3
  9. package/src/create-tool-name-mapping.ts +5 -21
  10. package/src/get-error-message.ts +1 -15
  11. package/src/has-required-key.ts +6 -0
  12. package/src/index.ts +17 -7
  13. package/src/inject-json-instruction.ts +5 -5
  14. package/src/is-json-serializable.ts +29 -0
  15. package/src/is-provider-reference.ts +18 -0
  16. package/src/load-api-key.ts +1 -1
  17. package/src/load-setting.ts +1 -1
  18. package/src/map-reasoning-to-provider.ts +105 -0
  19. package/src/provider-tool-factory.ts +43 -32
  20. package/src/resolve-provider-reference.ts +27 -0
  21. package/src/resolve.ts +15 -0
  22. package/src/response-handler.ts +1 -1
  23. package/src/secure-json-parse.ts +1 -1
  24. package/src/serialize-model-options.ts +63 -0
  25. package/src/to-json-schema/zod3-to-json-schema/parsers/date.ts +1 -1
  26. package/src/to-json-schema/zod3-to-json-schema/parsers/intersection.ts +1 -1
  27. package/src/to-json-schema/zod3-to-json-schema/parsers/record.ts +2 -2
  28. package/src/types/assistant-model-message.ts +4 -0
  29. package/src/types/content-part.ts +98 -14
  30. package/src/types/context.ts +4 -0
  31. package/src/types/executable-tool.ts +17 -0
  32. package/src/types/execute-tool.ts +28 -9
  33. package/src/types/index.ts +11 -9
  34. package/src/types/infer-tool-context.ts +12 -0
  35. package/src/types/infer-tool-input.ts +7 -0
  36. package/src/types/infer-tool-output.ts +7 -0
  37. package/src/types/infer-tool-set-context.ts +17 -0
  38. package/src/types/provider-options.ts +2 -2
  39. package/src/types/provider-reference.ts +10 -0
  40. package/src/types/tool-set.ts +22 -0
  41. package/src/types/tool.ts +74 -40
  42. package/src/types/union-to-intersection.ts +17 -0
  43. package/src/validate-download-url.ts +7 -2
  44. package/dist/index.d.mts +0 -1433
  45. package/dist/index.mjs +0 -2759
  46. package/dist/index.mjs.map +0 -1
  47. package/dist/test/index.d.mts +0 -17
  48. package/dist/test/index.mjs +0 -77
  49. package/dist/test/index.mjs.map +0 -1
package/src/types/tool.ts CHANGED
@@ -3,11 +3,14 @@ import { FlexibleSchema } from '../schema';
3
3
  import { ToolResultOutput } from './content-part';
4
4
  import { ModelMessage } from './model-message';
5
5
  import { ProviderOptions } from './provider-options';
6
+ import { Context } from './context';
6
7
 
7
8
  /**
8
- * Additional options that are sent into each tool call.
9
+ * Additional options that are sent into each tool execution.
9
10
  */
10
- export interface ToolExecutionOptions {
11
+ export interface ToolExecutionOptions<
12
+ CONTEXT extends Context | unknown | never,
13
+ > {
11
14
  /**
12
15
  * The ID of the tool call. You can use it e.g. when sending tool-call related information with stream data.
13
16
  */
@@ -25,7 +28,7 @@ export interface ToolExecutionOptions {
25
28
  abortSignal?: AbortSignal;
26
29
 
27
30
  /**
28
- * User-defined context.
31
+ * User-defined runtime context.
29
32
  *
30
33
  * Treat the context object as immutable inside tools.
31
34
  * Mutating the context object can lead to race conditions and unexpected results
@@ -33,16 +36,17 @@ export interface ToolExecutionOptions {
33
36
  *
34
37
  * If you need to mutate the context, analyze the tool calls and results
35
38
  * in `prepareStep` and update it there.
36
- *
37
- * Experimental (can break in patch releases).
38
39
  */
39
- experimental_context?: unknown;
40
+ context: CONTEXT;
40
41
  }
41
42
 
42
43
  /**
43
44
  * Function that is called to determine if the tool needs approval before it can be executed.
44
45
  */
45
- export type ToolNeedsApprovalFunction<INPUT> = (
46
+ export type ToolNeedsApprovalFunction<
47
+ INPUT,
48
+ CONTEXT extends Context | unknown | never,
49
+ > = (
46
50
  input: INPUT,
47
51
  options: {
48
52
  /**
@@ -57,17 +61,29 @@ export type ToolNeedsApprovalFunction<INPUT> = (
57
61
  messages: ModelMessage[];
58
62
 
59
63
  /**
60
- * Additional context.
64
+ * User-defined runtime context.
65
+ *
66
+ * Treat the context object as immutable inside tools.
67
+ * Mutating the context object can lead to race conditions and unexpected results
68
+ * when tools are called in parallel.
61
69
  *
62
- * Experimental (can break in patch releases).
70
+ * If you need to mutate the context, analyze the tool calls and results
71
+ * in `prepareStep` and update it there.
63
72
  */
64
- experimental_context?: unknown;
73
+ context: CONTEXT;
65
74
  },
66
75
  ) => boolean | PromiseLike<boolean>;
67
76
 
68
- export type ToolExecuteFunction<INPUT, OUTPUT> = (
77
+ /**
78
+ * Function that executes the tool and returns either a single result or a stream of results.
79
+ */
80
+ export type ToolExecuteFunction<
81
+ INPUT,
82
+ OUTPUT,
83
+ CONTEXT extends Context | unknown | never,
84
+ > = (
69
85
  input: INPUT,
70
- options: ToolExecutionOptions,
86
+ options: ToolExecutionOptions<CONTEXT>,
71
87
  ) => AsyncIterable<OUTPUT> | PromiseLike<OUTPUT> | OUTPUT;
72
88
 
73
89
  // 0 extends 1 & N checks for any
@@ -78,7 +94,14 @@ type NeverOptional<N, T> = 0 extends 1 & N
78
94
  ? Partial<Record<keyof T, undefined>>
79
95
  : T;
80
96
 
81
- type ToolOutputProperties<INPUT, OUTPUT> = NeverOptional<
97
+ /**
98
+ * Helper type to determine the output properties of a tool.
99
+ */
100
+ type ToolOutputProperties<
101
+ INPUT,
102
+ OUTPUT,
103
+ CONTEXT extends Context | unknown | never,
104
+ > = NeverOptional<
82
105
  OUTPUT,
83
106
  | {
84
107
  /**
@@ -88,7 +111,7 @@ type ToolOutputProperties<INPUT, OUTPUT> = NeverOptional<
88
111
  * @args is the input of the tool call.
89
112
  * @options.abortSignal is a signal that can be used to abort the tool call.
90
113
  */
91
- execute: ToolExecuteFunction<INPUT, OUTPUT>;
114
+ execute: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
92
115
 
93
116
  outputSchema?: FlexibleSchema<OUTPUT>;
94
117
  }
@@ -108,6 +131,7 @@ type ToolOutputProperties<INPUT, OUTPUT> = NeverOptional<
108
131
  export type Tool<
109
132
  INPUT extends JSONValue | unknown | never = any,
110
133
  OUTPUT extends JSONValue | unknown | never = any,
134
+ CONTEXT extends Context | unknown | never = any,
111
135
  > = {
112
136
  /**
113
137
  * An optional description of what the tool does.
@@ -143,12 +167,22 @@ export type Tool<
143
167
  */
144
168
  inputExamples?: Array<{ input: NoInfer<INPUT> }>;
145
169
 
170
+ /**
171
+ * An optional schema describing the context that the tool expects.
172
+ *
173
+ * The context is passed to execute function as part of the execution options.
174
+ */
175
+ contextSchema?: FlexibleSchema<CONTEXT>;
176
+
146
177
  /**
147
178
  * Whether the tool needs approval before it can be executed.
148
179
  */
149
180
  needsApproval?:
150
181
  | boolean
151
- | ToolNeedsApprovalFunction<[INPUT] extends [never] ? unknown : INPUT>;
182
+ | ToolNeedsApprovalFunction<
183
+ [INPUT] extends [never] ? unknown : INPUT,
184
+ NoInfer<CONTEXT>
185
+ >;
152
186
 
153
187
  /**
154
188
  * Strict mode setting for the tool.
@@ -163,14 +197,18 @@ export type Tool<
163
197
  * Optional function that is called when the argument streaming starts.
164
198
  * Only called when the tool is used in a streaming context.
165
199
  */
166
- onInputStart?: (options: ToolExecutionOptions) => void | PromiseLike<void>;
200
+ onInputStart?: (
201
+ options: ToolExecutionOptions<NoInfer<CONTEXT>>,
202
+ ) => void | PromiseLike<void>;
167
203
 
168
204
  /**
169
205
  * Optional function that is called when an argument streaming delta is available.
170
206
  * Only called when the tool is used in a streaming context.
171
207
  */
172
208
  onInputDelta?: (
173
- options: { inputTextDelta: string } & ToolExecutionOptions,
209
+ options: { inputTextDelta: string } & ToolExecutionOptions<
210
+ NoInfer<CONTEXT>
211
+ >,
174
212
  ) => void | PromiseLike<void>;
175
213
 
176
214
  /**
@@ -180,13 +218,15 @@ export type Tool<
180
218
  onInputAvailable?: (
181
219
  options: {
182
220
  input: [INPUT] extends [never] ? unknown : INPUT;
183
- } & ToolExecutionOptions,
221
+ } & ToolExecutionOptions<NoInfer<CONTEXT>>,
184
222
  ) => void | PromiseLike<void>;
185
- } & ToolOutputProperties<INPUT, OUTPUT> & {
223
+ } & ToolOutputProperties<INPUT, OUTPUT, NoInfer<CONTEXT>> & {
186
224
  /**
187
225
  * Optional conversion function that maps the tool result to an output that can be used by the language model.
188
226
  *
189
227
  * If not provided, the tool result will be sent as a JSON object.
228
+ *
229
+ * This function is invoked on the server by `convertToModelMessages`, so ensure that you pass the same "tools" (ToolSet) to both "convertToModelMessages" and "streamText" (or other generation APIs).
190
230
  */
191
231
  toModelOutput?: (options: {
192
232
  /**
@@ -255,28 +295,22 @@ export type Tool<
255
295
  }
256
296
  );
257
297
 
258
- /**
259
- * Infer the input type of a tool.
260
- */
261
- export type InferToolInput<TOOL extends Tool> =
262
- TOOL extends Tool<infer INPUT, any> ? INPUT : never;
263
-
264
- /**
265
- * Infer the output type of a tool.
266
- */
267
- export type InferToolOutput<TOOL extends Tool> =
268
- TOOL extends Tool<any, infer OUTPUT> ? OUTPUT : never;
269
-
270
298
  /**
271
299
  * Helper function for inferring the execute args of a tool.
272
300
  */
273
301
  // Note: overload order is important for auto-completion
274
- export function tool<INPUT, OUTPUT>(
275
- tool: Tool<INPUT, OUTPUT>,
276
- ): Tool<INPUT, OUTPUT>;
277
- export function tool<INPUT>(tool: Tool<INPUT, never>): Tool<INPUT, never>;
278
- export function tool<OUTPUT>(tool: Tool<never, OUTPUT>): Tool<never, OUTPUT>;
279
- export function tool(tool: Tool<never, never>): Tool<never, never>;
302
+ export function tool<INPUT, OUTPUT, CONTEXT extends Context>(
303
+ tool: Tool<INPUT, OUTPUT, CONTEXT>,
304
+ ): Tool<INPUT, OUTPUT, CONTEXT>;
305
+ export function tool<INPUT, CONTEXT extends Context>(
306
+ tool: Tool<INPUT, never, CONTEXT>,
307
+ ): Tool<INPUT, never, CONTEXT>;
308
+ export function tool<OUTPUT, CONTEXT extends Context>(
309
+ tool: Tool<never, OUTPUT, CONTEXT>,
310
+ ): Tool<never, OUTPUT, CONTEXT>;
311
+ export function tool<CONTEXT extends Context>(
312
+ tool: Tool<never, never, CONTEXT>,
313
+ ): Tool<never, never, CONTEXT>;
280
314
  export function tool(tool: any): any {
281
315
  return tool;
282
316
  }
@@ -289,7 +323,7 @@ export function dynamicTool(tool: {
289
323
  title?: string;
290
324
  providerOptions?: ProviderOptions;
291
325
  inputSchema: FlexibleSchema<unknown>;
292
- execute: ToolExecuteFunction<unknown, unknown>;
326
+ execute: ToolExecuteFunction<unknown, unknown, Context>;
293
327
 
294
328
  /**
295
329
  * Optional conversion function that maps the tool result to an output that can be used by the language model.
@@ -316,8 +350,8 @@ export function dynamicTool(tool: {
316
350
  /**
317
351
  * Whether the tool needs approval before it can be executed.
318
352
  */
319
- needsApproval?: boolean | ToolNeedsApprovalFunction<unknown>;
320
- }): Tool<unknown, unknown> & {
353
+ needsApproval?: boolean | ToolNeedsApprovalFunction<unknown, Context>;
354
+ }): Tool<unknown, unknown, Context> & {
321
355
  type: 'dynamic';
322
356
  } {
323
357
  return { ...tool, type: 'dynamic' };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Converts a union type `U` into an intersection type.
3
+ *
4
+ * For example:
5
+ * type A = { a: number };
6
+ * type B = { b: string };
7
+ * type Union = A | B;
8
+ * type Intersection = UnionToIntersection<Union>;
9
+ * // Intersection is: { a: number } & { b: string }
10
+ *
11
+ * This is useful when you have a union of object types and need a type with all possible properties.
12
+ */
13
+ export type UnionToIntersection<U> = (
14
+ U extends unknown ? (arg: U) => void : never
15
+ ) extends (arg: infer I) => void
16
+ ? I
17
+ : never;
@@ -18,11 +18,16 @@ export function validateDownloadUrl(url: string): void {
18
18
  });
19
19
  }
20
20
 
21
- // Only allow http and https protocols
21
+ // data: URLs are inline content, so they do not trigger a network fetch or SSRF risk.
22
+ if (parsed.protocol === 'data:') {
23
+ return;
24
+ }
25
+
26
+ // Only allow http and https network protocols
22
27
  if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
23
28
  throw new DownloadError({
24
29
  url,
25
- message: `URL scheme must be http or https, got ${parsed.protocol}`,
30
+ message: `URL scheme must be http, https, or data, got ${parsed.protocol}`,
26
31
  });
27
32
  }
28
33