@ai-sdk/provider-utils 5.0.0-beta.1 → 5.0.0-beta.10

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.
@@ -3,38 +3,39 @@ export type {
3
3
  AssistantModelMessage,
4
4
  } from './assistant-model-message';
5
5
  export type {
6
+ CustomPart,
6
7
  FilePart,
7
8
  ImagePart,
9
+ ReasoningFilePart,
8
10
  ReasoningPart,
9
11
  TextPart,
10
12
  ToolCallPart,
11
13
  ToolResultOutput,
12
14
  ToolResultPart,
13
15
  } from './content-part';
16
+ export type { Context } from './context';
14
17
  export type { DataContent } from './data-content';
15
18
  export { executeTool } from './execute-tool';
19
+ export type { InferToolContext } from './infer-tool-context';
20
+ export type { InferToolInput } from './infer-tool-input';
21
+ export type { InferToolOutput } from './infer-tool-output';
22
+ export type { InferToolSetContext } from './infer-tool-set-context';
16
23
  export type { ModelMessage } from './model-message';
17
24
  export type { ProviderOptions } from './provider-options';
25
+ export type { ProviderReference } from './provider-reference';
18
26
  export type { SystemModelMessage } from './system-model-message';
19
27
  export {
20
28
  dynamicTool,
21
29
  tool,
22
- type InferToolInput,
23
- type InferToolOutput,
24
30
  type Tool,
25
- type ToolExecutionOptions,
26
31
  type ToolExecuteFunction,
32
+ type ToolExecutionOptions,
27
33
  type ToolNeedsApprovalFunction,
28
34
  } from './tool';
35
+ export type { ToolSet } from './tool-set';
29
36
  export type { ToolApprovalRequest } from './tool-approval-request';
30
37
  export type { ToolApprovalResponse } from './tool-approval-response';
31
38
  export type { ToolCall } from './tool-call';
32
39
  export type { ToolContent, ToolModelMessage } from './tool-model-message';
33
40
  export type { ToolResult } from './tool-result';
34
41
  export type { UserContent, UserModelMessage } from './user-model-message';
35
- import type { ToolExecutionOptions } from './tool';
36
-
37
- /**
38
- * @deprecated Use ToolExecutionOptions instead.
39
- */
40
- export type ToolCallOptions = ToolExecutionOptions;
@@ -0,0 +1,7 @@
1
+ import type { Tool } from './tool';
2
+
3
+ /**
4
+ * Infer the context type of a tool.
5
+ */
6
+ export type InferToolContext<TOOL extends Tool<any, any, any>> =
7
+ TOOL extends Tool<any, any, infer CONTEXT> ? CONTEXT : never;
@@ -0,0 +1,7 @@
1
+ import type { Tool } from './tool';
2
+
3
+ /**
4
+ * Infer the input type of a tool.
5
+ */
6
+ export type InferToolInput<TOOL extends Tool<any, any, any>> =
7
+ TOOL extends Tool<infer INPUT, any, any> ? INPUT : never;
@@ -0,0 +1,7 @@
1
+ import type { Tool } from './tool';
2
+
3
+ /**
4
+ * Infer the output type of a tool.
5
+ */
6
+ export type InferToolOutput<TOOL extends Tool<any, any, any>> =
7
+ TOOL extends Tool<any, infer OUTPUT, any> ? OUTPUT : never;
@@ -0,0 +1,17 @@
1
+ import type { InferToolContext } from './infer-tool-context';
2
+ import type { ToolSet } from './tool-set';
3
+ import type { UnionToIntersection } from './union-to-intersection';
4
+
5
+ /**
6
+ * Infer the context type for a tool set.
7
+ *
8
+ * The inferred type contains all properties required by the contexts of the
9
+ * tools in the set.
10
+ *
11
+ * If there are incompatible properties, they will be of type `never`.
12
+ */
13
+ export type InferToolSetContext<TOOLS extends ToolSet> = UnionToIntersection<
14
+ {
15
+ [K in keyof TOOLS]: InferToolContext<NoInfer<TOOLS[K]>>;
16
+ }[keyof TOOLS]
17
+ >;
@@ -1,4 +1,4 @@
1
- import { SharedV3ProviderOptions } from '@ai-sdk/provider';
1
+ import { SharedV4ProviderOptions } from '@ai-sdk/provider';
2
2
 
3
3
  /**
4
4
  * Additional provider-specific options.
@@ -6,4 +6,4 @@ import { SharedV3ProviderOptions } from '@ai-sdk/provider';
6
6
  * They are passed through to the provider from the AI SDK and enable
7
7
  * provider-specific functionality that can be fully encapsulated in the provider.
8
8
  */
9
- export type ProviderOptions = SharedV3ProviderOptions;
9
+ export type ProviderOptions = SharedV4ProviderOptions;
@@ -0,0 +1,10 @@
1
+ import { SharedV4ProviderReference } from '@ai-sdk/provider';
2
+
3
+ /**
4
+ * A mapping of provider names to provider-specific file identifiers.
5
+ *
6
+ * Provider references allow files to be identified across different
7
+ * providers without re-uploading, by storing each provider's own
8
+ * identifier for the same logical file.
9
+ */
10
+ export type ProviderReference = SharedV4ProviderReference;
@@ -0,0 +1,22 @@
1
+ import type { Tool } from './tool';
2
+
3
+ /**
4
+ * A mapping of tool names to tool definitions.
5
+ */
6
+ export type ToolSet = Record<
7
+ string,
8
+ (
9
+ | Tool<never, never, any>
10
+ | Tool<any, any, any>
11
+ | Tool<any, never, any>
12
+ | Tool<never, any, any>
13
+ ) &
14
+ Pick<
15
+ Tool<any, any, any>,
16
+ | 'execute'
17
+ | 'onInputAvailable'
18
+ | 'onInputStart'
19
+ | 'onInputDelta'
20
+ | 'needsApproval'
21
+ >
22
+ >;
package/src/types/tool.ts CHANGED
@@ -3,11 +3,12 @@ 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<CONTEXT extends Context> {
11
12
  /**
12
13
  * The ID of the tool call. You can use it e.g. when sending tool-call related information with stream data.
13
14
  */
@@ -36,13 +37,13 @@ export interface ToolExecutionOptions {
36
37
  *
37
38
  * Experimental (can break in patch releases).
38
39
  */
39
- experimental_context?: unknown;
40
+ experimental_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<INPUT, CONTEXT extends Context> = (
46
47
  input: INPUT,
47
48
  options: {
48
49
  /**
@@ -61,13 +62,16 @@ export type ToolNeedsApprovalFunction<INPUT> = (
61
62
  *
62
63
  * Experimental (can break in patch releases).
63
64
  */
64
- experimental_context?: unknown;
65
+ experimental_context: CONTEXT;
65
66
  },
66
67
  ) => boolean | PromiseLike<boolean>;
67
68
 
68
- export type ToolExecuteFunction<INPUT, OUTPUT> = (
69
+ /**
70
+ * Function that executes the tool and returns either a single result or a stream of results.
71
+ */
72
+ export type ToolExecuteFunction<INPUT, OUTPUT, CONTEXT extends Context> = (
69
73
  input: INPUT,
70
- options: ToolExecutionOptions,
74
+ options: ToolExecutionOptions<CONTEXT>,
71
75
  ) => AsyncIterable<OUTPUT> | PromiseLike<OUTPUT> | OUTPUT;
72
76
 
73
77
  // 0 extends 1 & N checks for any
@@ -78,7 +82,14 @@ type NeverOptional<N, T> = 0 extends 1 & N
78
82
  ? Partial<Record<keyof T, undefined>>
79
83
  : T;
80
84
 
81
- type ToolOutputProperties<INPUT, OUTPUT> = NeverOptional<
85
+ /**
86
+ * Helper type to determine the output properties of a tool.
87
+ */
88
+ type ToolOutputProperties<
89
+ INPUT,
90
+ OUTPUT,
91
+ CONTEXT extends Context,
92
+ > = NeverOptional<
82
93
  OUTPUT,
83
94
  | {
84
95
  /**
@@ -88,7 +99,7 @@ type ToolOutputProperties<INPUT, OUTPUT> = NeverOptional<
88
99
  * @args is the input of the tool call.
89
100
  * @options.abortSignal is a signal that can be used to abort the tool call.
90
101
  */
91
- execute: ToolExecuteFunction<INPUT, OUTPUT>;
102
+ execute: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
92
103
 
93
104
  outputSchema?: FlexibleSchema<OUTPUT>;
94
105
  }
@@ -108,6 +119,7 @@ type ToolOutputProperties<INPUT, OUTPUT> = NeverOptional<
108
119
  export type Tool<
109
120
  INPUT extends JSONValue | unknown | never = any,
110
121
  OUTPUT extends JSONValue | unknown | never = any,
122
+ CONTEXT extends Context = Context,
111
123
  > = {
112
124
  /**
113
125
  * An optional description of what the tool does.
@@ -143,12 +155,22 @@ export type Tool<
143
155
  */
144
156
  inputExamples?: Array<{ input: NoInfer<INPUT> }>;
145
157
 
158
+ /**
159
+ * An optional schema describing the context that the tool expects.
160
+ *
161
+ * The context is passed to execute function as part of the execution options.
162
+ */
163
+ contextSchema?: FlexibleSchema<CONTEXT>;
164
+
146
165
  /**
147
166
  * Whether the tool needs approval before it can be executed.
148
167
  */
149
168
  needsApproval?:
150
169
  | boolean
151
- | ToolNeedsApprovalFunction<[INPUT] extends [never] ? unknown : INPUT>;
170
+ | ToolNeedsApprovalFunction<
171
+ [INPUT] extends [never] ? unknown : INPUT,
172
+ NoInfer<CONTEXT>
173
+ >;
152
174
 
153
175
  /**
154
176
  * Strict mode setting for the tool.
@@ -163,14 +185,18 @@ export type Tool<
163
185
  * Optional function that is called when the argument streaming starts.
164
186
  * Only called when the tool is used in a streaming context.
165
187
  */
166
- onInputStart?: (options: ToolExecutionOptions) => void | PromiseLike<void>;
188
+ onInputStart?: (
189
+ options: ToolExecutionOptions<NoInfer<CONTEXT>>,
190
+ ) => void | PromiseLike<void>;
167
191
 
168
192
  /**
169
193
  * Optional function that is called when an argument streaming delta is available.
170
194
  * Only called when the tool is used in a streaming context.
171
195
  */
172
196
  onInputDelta?: (
173
- options: { inputTextDelta: string } & ToolExecutionOptions,
197
+ options: { inputTextDelta: string } & ToolExecutionOptions<
198
+ NoInfer<CONTEXT>
199
+ >,
174
200
  ) => void | PromiseLike<void>;
175
201
 
176
202
  /**
@@ -180,13 +206,15 @@ export type Tool<
180
206
  onInputAvailable?: (
181
207
  options: {
182
208
  input: [INPUT] extends [never] ? unknown : INPUT;
183
- } & ToolExecutionOptions,
209
+ } & ToolExecutionOptions<NoInfer<CONTEXT>>,
184
210
  ) => void | PromiseLike<void>;
185
- } & ToolOutputProperties<INPUT, OUTPUT> & {
211
+ } & ToolOutputProperties<INPUT, OUTPUT, NoInfer<CONTEXT>> & {
186
212
  /**
187
213
  * Optional conversion function that maps the tool result to an output that can be used by the language model.
188
214
  *
189
215
  * If not provided, the tool result will be sent as a JSON object.
216
+ *
217
+ * 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
218
  */
191
219
  toModelOutput?: (options: {
192
220
  /**
@@ -255,28 +283,22 @@ export type Tool<
255
283
  }
256
284
  );
257
285
 
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
286
  /**
271
287
  * Helper function for inferring the execute args of a tool.
272
288
  */
273
289
  // 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>;
290
+ export function tool<INPUT, OUTPUT, CONTEXT extends Context>(
291
+ tool: Tool<INPUT, OUTPUT, CONTEXT>,
292
+ ): Tool<INPUT, OUTPUT, CONTEXT>;
293
+ export function tool<INPUT, CONTEXT extends Context>(
294
+ tool: Tool<INPUT, never, CONTEXT>,
295
+ ): Tool<INPUT, never, CONTEXT>;
296
+ export function tool<OUTPUT, CONTEXT extends Context>(
297
+ tool: Tool<never, OUTPUT, CONTEXT>,
298
+ ): Tool<never, OUTPUT, CONTEXT>;
299
+ export function tool<CONTEXT extends Context>(
300
+ tool: Tool<never, never, CONTEXT>,
301
+ ): Tool<never, never, CONTEXT>;
280
302
  export function tool(tool: any): any {
281
303
  return tool;
282
304
  }
@@ -289,7 +311,7 @@ export function dynamicTool(tool: {
289
311
  title?: string;
290
312
  providerOptions?: ProviderOptions;
291
313
  inputSchema: FlexibleSchema<unknown>;
292
- execute: ToolExecuteFunction<unknown, unknown>;
314
+ execute: ToolExecuteFunction<unknown, unknown, Context>;
293
315
 
294
316
  /**
295
317
  * Optional conversion function that maps the tool result to an output that can be used by the language model.
@@ -316,8 +338,8 @@ export function dynamicTool(tool: {
316
338
  /**
317
339
  * Whether the tool needs approval before it can be executed.
318
340
  */
319
- needsApproval?: boolean | ToolNeedsApprovalFunction<unknown>;
320
- }): Tool<unknown, unknown> & {
341
+ needsApproval?: boolean | ToolNeedsApprovalFunction<unknown, Context>;
342
+ }): Tool<unknown, unknown, Context> & {
321
343
  type: 'dynamic';
322
344
  } {
323
345
  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