@ai-sdk/provider-utils 5.0.0-beta.6 → 5.0.0-beta.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/provider-utils",
3
- "version": "5.0.0-beta.6",
3
+ "version": "5.0.0-beta.8",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -35,7 +35,7 @@
35
35
  "dependencies": {
36
36
  "@standard-schema/spec": "^1.1.0",
37
37
  "eventsource-parser": "^3.0.6",
38
- "@ai-sdk/provider": "4.0.0-beta.4"
38
+ "@ai-sdk/provider": "4.0.0-beta.5"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "20.17.24",
@@ -1,24 +1,33 @@
1
1
  import { tool, Tool, ToolExecuteFunction } from './types/tool';
2
2
  import { FlexibleSchema } from './schema';
3
+ import { Context } from './types/context';
3
4
 
4
- export type ProviderToolFactory<INPUT, ARGS extends object> = <OUTPUT>(
5
+ export type ProviderToolFactory<
6
+ INPUT,
7
+ ARGS extends object,
8
+ CONTEXT extends Context = {},
9
+ > = <OUTPUT>(
5
10
  options: ARGS & {
6
- execute?: ToolExecuteFunction<INPUT, OUTPUT>;
7
- needsApproval?: Tool<INPUT, OUTPUT>['needsApproval'];
8
- toModelOutput?: Tool<INPUT, OUTPUT>['toModelOutput'];
9
- onInputStart?: Tool<INPUT, OUTPUT>['onInputStart'];
10
- onInputDelta?: Tool<INPUT, OUTPUT>['onInputDelta'];
11
- onInputAvailable?: Tool<INPUT, OUTPUT>['onInputAvailable'];
11
+ execute?: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
12
+ needsApproval?: Tool<INPUT, OUTPUT, CONTEXT>['needsApproval'];
13
+ toModelOutput?: Tool<INPUT, OUTPUT, CONTEXT>['toModelOutput'];
14
+ onInputStart?: Tool<INPUT, OUTPUT, CONTEXT>['onInputStart'];
15
+ onInputDelta?: Tool<INPUT, OUTPUT, CONTEXT>['onInputDelta'];
16
+ onInputAvailable?: Tool<INPUT, OUTPUT, CONTEXT>['onInputAvailable'];
12
17
  },
13
- ) => Tool<INPUT, OUTPUT>;
18
+ ) => Tool<INPUT, OUTPUT, CONTEXT>;
14
19
 
15
- export function createProviderToolFactory<INPUT, ARGS extends object>({
20
+ export function createProviderToolFactory<
21
+ INPUT,
22
+ ARGS extends object,
23
+ CONTEXT extends Context = {},
24
+ >({
16
25
  id,
17
26
  inputSchema,
18
27
  }: {
19
28
  id: `${string}.${string}`;
20
29
  inputSchema: FlexibleSchema<INPUT>;
21
- }): ProviderToolFactory<INPUT, ARGS> {
30
+ }): ProviderToolFactory<INPUT, ARGS, CONTEXT> {
22
31
  return <OUTPUT>({
23
32
  execute,
24
33
  outputSchema,
@@ -29,14 +38,14 @@ export function createProviderToolFactory<INPUT, ARGS extends object>({
29
38
  onInputAvailable,
30
39
  ...args
31
40
  }: ARGS & {
32
- execute?: ToolExecuteFunction<INPUT, OUTPUT>;
41
+ execute?: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
33
42
  outputSchema?: FlexibleSchema<OUTPUT>;
34
- needsApproval?: Tool<INPUT, OUTPUT>['needsApproval'];
35
- toModelOutput?: Tool<INPUT, OUTPUT>['toModelOutput'];
36
- onInputStart?: Tool<INPUT, OUTPUT>['onInputStart'];
37
- onInputDelta?: Tool<INPUT, OUTPUT>['onInputDelta'];
38
- onInputAvailable?: Tool<INPUT, OUTPUT>['onInputAvailable'];
39
- }): Tool<INPUT, OUTPUT> =>
43
+ needsApproval?: Tool<INPUT, OUTPUT, CONTEXT>['needsApproval'];
44
+ toModelOutput?: Tool<INPUT, OUTPUT, CONTEXT>['toModelOutput'];
45
+ onInputStart?: Tool<INPUT, OUTPUT, CONTEXT>['onInputStart'];
46
+ onInputDelta?: Tool<INPUT, OUTPUT, CONTEXT>['onInputDelta'];
47
+ onInputAvailable?: Tool<INPUT, OUTPUT, CONTEXT>['onInputAvailable'];
48
+ }): Tool<INPUT, OUTPUT, CONTEXT> =>
40
49
  tool({
41
50
  type: 'provider',
42
51
  id,
@@ -56,21 +65,23 @@ export type ProviderToolFactoryWithOutputSchema<
56
65
  INPUT,
57
66
  OUTPUT,
58
67
  ARGS extends object,
68
+ CONTEXT extends Context = {},
59
69
  > = (
60
70
  options: ARGS & {
61
- execute?: ToolExecuteFunction<INPUT, OUTPUT>;
62
- needsApproval?: Tool<INPUT, OUTPUT>['needsApproval'];
63
- toModelOutput?: Tool<INPUT, OUTPUT>['toModelOutput'];
64
- onInputStart?: Tool<INPUT, OUTPUT>['onInputStart'];
65
- onInputDelta?: Tool<INPUT, OUTPUT>['onInputDelta'];
66
- onInputAvailable?: Tool<INPUT, OUTPUT>['onInputAvailable'];
71
+ execute?: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
72
+ needsApproval?: Tool<INPUT, OUTPUT, CONTEXT>['needsApproval'];
73
+ toModelOutput?: Tool<INPUT, OUTPUT, CONTEXT>['toModelOutput'];
74
+ onInputStart?: Tool<INPUT, OUTPUT, CONTEXT>['onInputStart'];
75
+ onInputDelta?: Tool<INPUT, OUTPUT, CONTEXT>['onInputDelta'];
76
+ onInputAvailable?: Tool<INPUT, OUTPUT, CONTEXT>['onInputAvailable'];
67
77
  },
68
- ) => Tool<INPUT, OUTPUT>;
78
+ ) => Tool<INPUT, OUTPUT, CONTEXT>;
69
79
 
70
80
  export function createProviderToolFactoryWithOutputSchema<
71
81
  INPUT,
72
82
  OUTPUT,
73
83
  ARGS extends object,
84
+ CONTEXT extends Context = {},
74
85
  >({
75
86
  id,
76
87
  inputSchema,
@@ -91,7 +102,7 @@ export function createProviderToolFactoryWithOutputSchema<
91
102
  * @default false
92
103
  */
93
104
  supportsDeferredResults?: boolean;
94
- }): ProviderToolFactoryWithOutputSchema<INPUT, OUTPUT, ARGS> {
105
+ }): ProviderToolFactoryWithOutputSchema<INPUT, OUTPUT, ARGS, CONTEXT> {
95
106
  return ({
96
107
  execute,
97
108
  needsApproval,
@@ -101,13 +112,13 @@ export function createProviderToolFactoryWithOutputSchema<
101
112
  onInputAvailable,
102
113
  ...args
103
114
  }: ARGS & {
104
- execute?: ToolExecuteFunction<INPUT, OUTPUT>;
105
- needsApproval?: Tool<INPUT, OUTPUT>['needsApproval'];
106
- toModelOutput?: Tool<INPUT, OUTPUT>['toModelOutput'];
107
- onInputStart?: Tool<INPUT, OUTPUT>['onInputStart'];
108
- onInputDelta?: Tool<INPUT, OUTPUT>['onInputDelta'];
109
- onInputAvailable?: Tool<INPUT, OUTPUT>['onInputAvailable'];
110
- }): Tool<INPUT, OUTPUT> =>
115
+ execute?: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
116
+ needsApproval?: Tool<INPUT, OUTPUT, CONTEXT>['needsApproval'];
117
+ toModelOutput?: Tool<INPUT, OUTPUT, CONTEXT>['toModelOutput'];
118
+ onInputStart?: Tool<INPUT, OUTPUT, CONTEXT>['onInputStart'];
119
+ onInputDelta?: Tool<INPUT, OUTPUT, CONTEXT>['onInputDelta'];
120
+ onInputAvailable?: Tool<INPUT, OUTPUT, CONTEXT>['onInputAvailable'];
121
+ }): Tool<INPUT, OUTPUT, CONTEXT> =>
111
122
  tool({
112
123
  type: 'provider',
113
124
  id,
@@ -111,9 +111,9 @@ export interface CustomPart {
111
111
  type: 'custom';
112
112
 
113
113
  /**
114
- * The kind of custom content, in the format `{provider}-{provider-type}`.
114
+ * The kind of custom content, in the format `{provider}.{provider-type}`.
115
115
  */
116
- kind: string;
116
+ kind: `${string}.${string}`;
117
117
 
118
118
  /**
119
119
  * Additional provider-specific metadata. They are passed through
@@ -0,0 +1,4 @@
1
+ /**
2
+ * A context object that is passed into tool execution.
3
+ */
4
+ export type Context = Record<string, unknown>;
@@ -1,14 +1,34 @@
1
1
  import { isAsyncIterable } from '../is-async-iterable';
2
- import { ToolExecutionOptions, ToolExecuteFunction } from './tool';
2
+ import { Context } from './context';
3
+ import { ToolExecuteFunction, ToolExecutionOptions } from './tool';
3
4
 
4
- export async function* executeTool<INPUT, OUTPUT>({
5
+ /**
6
+ * Executes a tool function, supporting both synchronous and streaming/asynchronous results.
7
+ *
8
+ * This generator yields intermediate ("preliminary") outputs as they're produced, allowing callers
9
+ * to stream partial tool results before completion. When execution is finished, it yields a final output,
10
+ * ensuring all consumers receive a conclusive result.
11
+ *
12
+ * - If the tool's `execute` function returns an `AsyncIterable`, all intermediate values are yielded
13
+ * as `{ type: "preliminary", output }` except the last, which is yielded as `{ type: "final", output }`.
14
+ * - If the tool returns a direct value or Promise, a single `{ type: "final", output }` is yielded.
15
+ *
16
+ * @template INPUT Input type for the tool execution.
17
+ * @template OUTPUT Output type for the tool execution.
18
+ * @template CONTEXT Context object extension for execution (extends Context).
19
+ * @param params.execute The tool execute function.
20
+ * @param params.input Input value to pass to the execute function.
21
+ * @param params.options Additional options for tool execution.
22
+ * @yields An object containing either a preliminary or final output from the tool.
23
+ */
24
+ export async function* executeTool<INPUT, OUTPUT, CONTEXT extends Context>({
5
25
  execute,
6
26
  input,
7
27
  options,
8
28
  }: {
9
- execute: ToolExecuteFunction<INPUT, OUTPUT>;
29
+ execute: ToolExecuteFunction<INPUT, OUTPUT, CONTEXT>;
10
30
  input: INPUT;
11
- options: ToolExecutionOptions;
31
+ options: ToolExecutionOptions<NoInfer<CONTEXT>>;
12
32
  }): AsyncGenerator<
13
33
  { type: 'preliminary'; output: OUTPUT } | { type: 'final'; output: OUTPUT }
14
34
  > {
@@ -13,19 +13,21 @@ export type {
13
13
  ToolResultOutput,
14
14
  ToolResultPart,
15
15
  } from './content-part';
16
+ export type { Context } from './context';
16
17
  export type { DataContent } from './data-content';
17
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';
18
22
  export type { ModelMessage } from './model-message';
19
23
  export type { ProviderOptions } from './provider-options';
20
24
  export type { SystemModelMessage } from './system-model-message';
21
25
  export {
22
26
  dynamicTool,
23
27
  tool,
24
- type InferToolInput,
25
- type InferToolOutput,
26
28
  type Tool,
27
- type ToolExecutionOptions,
28
29
  type ToolExecuteFunction,
30
+ type ToolExecutionOptions,
29
31
  type ToolNeedsApprovalFunction,
30
32
  } from './tool';
31
33
  export type { ToolApprovalRequest } from './tool-approval-request';
@@ -34,9 +36,3 @@ export type { ToolCall } from './tool-call';
34
36
  export type { ToolContent, ToolModelMessage } from './tool-model-message';
35
37
  export type { ToolResult } from './tool-result';
36
38
  export type { UserContent, UserModelMessage } from './user-model-message';
37
- import type { ToolExecutionOptions } from './tool';
38
-
39
- /**
40
- * @deprecated Use ToolExecutionOptions instead.
41
- */
42
- 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;
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,9 +206,9 @@ 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
  *
@@ -257,28 +283,22 @@ export type Tool<
257
283
  }
258
284
  );
259
285
 
260
- /**
261
- * Infer the input type of a tool.
262
- */
263
- export type InferToolInput<TOOL extends Tool> =
264
- TOOL extends Tool<infer INPUT, any> ? INPUT : never;
265
-
266
- /**
267
- * Infer the output type of a tool.
268
- */
269
- export type InferToolOutput<TOOL extends Tool> =
270
- TOOL extends Tool<any, infer OUTPUT> ? OUTPUT : never;
271
-
272
286
  /**
273
287
  * Helper function for inferring the execute args of a tool.
274
288
  */
275
289
  // Note: overload order is important for auto-completion
276
- export function tool<INPUT, OUTPUT>(
277
- tool: Tool<INPUT, OUTPUT>,
278
- ): Tool<INPUT, OUTPUT>;
279
- export function tool<INPUT>(tool: Tool<INPUT, never>): Tool<INPUT, never>;
280
- export function tool<OUTPUT>(tool: Tool<never, OUTPUT>): Tool<never, OUTPUT>;
281
- 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>;
282
302
  export function tool(tool: any): any {
283
303
  return tool;
284
304
  }
@@ -291,7 +311,7 @@ export function dynamicTool(tool: {
291
311
  title?: string;
292
312
  providerOptions?: ProviderOptions;
293
313
  inputSchema: FlexibleSchema<unknown>;
294
- execute: ToolExecuteFunction<unknown, unknown>;
314
+ execute: ToolExecuteFunction<unknown, unknown, Context>;
295
315
 
296
316
  /**
297
317
  * Optional conversion function that maps the tool result to an output that can be used by the language model.
@@ -318,8 +338,8 @@ export function dynamicTool(tool: {
318
338
  /**
319
339
  * Whether the tool needs approval before it can be executed.
320
340
  */
321
- needsApproval?: boolean | ToolNeedsApprovalFunction<unknown>;
322
- }): Tool<unknown, unknown> & {
341
+ needsApproval?: boolean | ToolNeedsApprovalFunction<unknown, Context>;
342
+ }): Tool<unknown, unknown, Context> & {
323
343
  type: 'dynamic';
324
344
  } {
325
345
  return { ...tool, type: 'dynamic' };