ai 7.0.42 → 7.0.44
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 +17 -0
- package/dist/index.d.ts +23 -4
- package/dist/index.js +145 -11
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +1 -1
- package/docs/03-ai-sdk-core/18-code-mode.mdx +246 -0
- package/docs/03-ai-sdk-core/65-lifecycle-callbacks.mdx +1 -1
- package/docs/03-ai-sdk-core/index.mdx +6 -0
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +9 -1
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +2 -1
- package/docs/07-reference/01-ai-sdk-core/23-create-mcp-client.mdx +7 -0
- package/package.json +4 -4
- package/src/generate-text/generate-text.ts +33 -8
- package/src/generate-text/index.ts +4 -0
- package/src/generate-text/stream-language-model-call.ts +3 -1
- package/src/generate-text/tool-caller-configuration.ts +186 -0
- package/src/index.ts +2 -0
package/dist/internal/index.js
CHANGED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Code Mode
|
|
3
|
+
description: Let models orchestrate AI SDK tools with sandboxed JavaScript and TypeScript.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code Mode
|
|
7
|
+
|
|
8
|
+
Code mode lets a model write JavaScript or TypeScript that calls your AI SDK
|
|
9
|
+
tools. The generated code runs in an isolated QuickJS sandbox and returns a JSON-serializable result.
|
|
10
|
+
|
|
11
|
+
Instead of calling tools one at a time, a model can use code mode to:
|
|
12
|
+
|
|
13
|
+
- call independent tools concurrently
|
|
14
|
+
- transform and combine tool results
|
|
15
|
+
- filter large tool responses before returning them to the model
|
|
16
|
+
- use JavaScript control flow for multi-step operations
|
|
17
|
+
|
|
18
|
+
Code mode is provided by the `@ai-sdk/code-mode` package.
|
|
19
|
+
|
|
20
|
+
<Note type="warning">
|
|
21
|
+
Code mode is experimental and its APIs may change in future releases. It
|
|
22
|
+
requires Node.js 22 or newer and is not available in browser or edge runtimes.
|
|
23
|
+
</Note>
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add ai @ai-sdk/code-mode zod
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Using Code Mode with `generateText`
|
|
32
|
+
|
|
33
|
+
Define your tools in one tool set and use `experimental_toolCallers` to select
|
|
34
|
+
which tools code mode can call:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { experimental_codeModeTool as codeModeTool } from '@ai-sdk/code-mode';
|
|
38
|
+
import { generateText, isStepCount, tool } from 'ai';
|
|
39
|
+
import { z } from 'zod';
|
|
40
|
+
|
|
41
|
+
const getInventory = tool({
|
|
42
|
+
description: 'Get available inventory for a product.',
|
|
43
|
+
inputSchema: z.object({
|
|
44
|
+
productId: z.string(),
|
|
45
|
+
}),
|
|
46
|
+
outputSchema: z.object({
|
|
47
|
+
productId: z.string(),
|
|
48
|
+
availableUnits: z.number(),
|
|
49
|
+
}),
|
|
50
|
+
execute: async ({ productId }) => ({
|
|
51
|
+
productId,
|
|
52
|
+
availableUnits: 42,
|
|
53
|
+
}),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const getDemand = tool({
|
|
57
|
+
description: 'Get requested units for a product.',
|
|
58
|
+
inputSchema: z.object({
|
|
59
|
+
productId: z.string(),
|
|
60
|
+
}),
|
|
61
|
+
outputSchema: z.object({
|
|
62
|
+
productId: z.string(),
|
|
63
|
+
requestedUnits: z.number(),
|
|
64
|
+
}),
|
|
65
|
+
execute: async ({ productId }) => ({
|
|
66
|
+
productId,
|
|
67
|
+
requestedUnits: 31,
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const tools = {
|
|
72
|
+
code_mode: codeModeTool({
|
|
73
|
+
executionPolicy: {
|
|
74
|
+
timeoutMs: 30_000,
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
getInventory,
|
|
78
|
+
getDemand,
|
|
79
|
+
} as const;
|
|
80
|
+
|
|
81
|
+
const result = await generateText({
|
|
82
|
+
model: __MODEL__,
|
|
83
|
+
tools,
|
|
84
|
+
experimental_toolCallers: ({ code_mode }) => ({
|
|
85
|
+
getInventory: [code_mode],
|
|
86
|
+
getDemand: [code_mode],
|
|
87
|
+
}),
|
|
88
|
+
stopWhen: isStepCount(10),
|
|
89
|
+
prompt: 'Compare inventory and demand for product sku_123.',
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The keys returned by `experimental_toolCallers` are the tools being governed.
|
|
94
|
+
The values identify their allowed callers. In this example, `getInventory` and
|
|
95
|
+
`getDemand` are available through `code_mode`, but they are not exposed to the
|
|
96
|
+
model as directly callable tools. Include `'direct'` when a tool should also be
|
|
97
|
+
callable directly:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
experimental_toolCallers: ({ code_mode }) => ({
|
|
101
|
+
getInventory: ['direct', code_mode],
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Tools without an `experimental_toolCallers` entry keep their existing direct
|
|
106
|
+
tool-calling behavior.
|
|
107
|
+
|
|
108
|
+
The code mode tool description includes TypeScript signatures generated from
|
|
109
|
+
the input and output schemas of its allowed tools. Descriptions,
|
|
110
|
+
`inputExamples`, and precise schemas help the model write correct code.
|
|
111
|
+
|
|
112
|
+
For the example above, the model can generate a program like:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
const [inventory, demand] = await Promise.all([
|
|
116
|
+
tools.getInventory({ productId: 'sku_123' }),
|
|
117
|
+
tools.getDemand({ productId: 'sku_123' }),
|
|
118
|
+
]);
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
sufficient: inventory.availableUnits >= demand.requestedUnits,
|
|
122
|
+
remaining: inventory.availableUnits - demand.requestedUnits,
|
|
123
|
+
};
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Each provided tool is available through the global `tools` object. Tool names
|
|
127
|
+
that are not valid JavaScript identifiers use bracket notation:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
const user = await tools['lookup-user']({ userId: 'user_123' });
|
|
131
|
+
return { id: user.id, plan: user.plan };
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Writing Code Mode Programs
|
|
135
|
+
|
|
136
|
+
Generated programs support:
|
|
137
|
+
|
|
138
|
+
- JavaScript and type-stripped TypeScript
|
|
139
|
+
- top-level `await` and `return`
|
|
140
|
+
- standard JavaScript control flow and data transformations
|
|
141
|
+
- `Promise.all` for concurrent tool calls
|
|
142
|
+
- `JSON.parse` and `JSON.stringify`
|
|
143
|
+
- `console.log`, `console.info`, `console.debug`, and `console.error`
|
|
144
|
+
|
|
145
|
+
Every tool call is asynchronous and must be awaited or otherwise observed.
|
|
146
|
+
Returning while tool calls are still detached fails the invocation and aborts
|
|
147
|
+
the outstanding work.
|
|
148
|
+
|
|
149
|
+
Programs and tool inputs and outputs cross the sandbox boundary as JSON. Return
|
|
150
|
+
only JSON-serializable values. TypeScript support is limited to removing type
|
|
151
|
+
syntax; code mode does not perform type checking or provide a full TypeScript
|
|
152
|
+
compiler.
|
|
153
|
+
|
|
154
|
+
## Direct Execution
|
|
155
|
+
|
|
156
|
+
Use `experimental_runCodeMode` when you want to execute a program directly
|
|
157
|
+
instead of exposing code mode to a model:
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
import { experimental_runCodeMode as runCodeMode } from '@ai-sdk/code-mode';
|
|
161
|
+
|
|
162
|
+
const result = await runCodeMode({
|
|
163
|
+
js: `
|
|
164
|
+
const inventory = await tools.getInventory({
|
|
165
|
+
productId: 'sku_123',
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
productId: inventory.productId,
|
|
170
|
+
available: inventory.availableUnits > 0,
|
|
171
|
+
};
|
|
172
|
+
`,
|
|
173
|
+
tools: { getInventory },
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
`runCodeMode` returns the value returned by the program. It uses the same
|
|
178
|
+
sandbox and execution limits as the AI SDK tool.
|
|
179
|
+
|
|
180
|
+
## Execution Limits
|
|
181
|
+
|
|
182
|
+
Every invocation has limits for runtime, memory, source size, results, tool
|
|
183
|
+
payloads, console output, and tool calls. Override them with
|
|
184
|
+
`executionPolicy`:
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
const codeMode = codeModeTool({
|
|
188
|
+
executionPolicy: {
|
|
189
|
+
timeoutMs: 30_000,
|
|
190
|
+
memoryLimitBytes: 64 * 1024 * 1024,
|
|
191
|
+
maxResultBytes: 1024 * 1024,
|
|
192
|
+
maxBridgeRequests: 100,
|
|
193
|
+
maxInFlightBridgeRequests: 10,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
The available limits are:
|
|
199
|
+
|
|
200
|
+
- `timeoutMs`: total execution time
|
|
201
|
+
- `memoryLimitBytes`: QuickJS memory
|
|
202
|
+
- `maxStackSizeBytes`: QuickJS stack
|
|
203
|
+
- `maxSourceBytes`: generated source code
|
|
204
|
+
- `maxResultBytes`: returned result
|
|
205
|
+
- `maxConsoleOutputBytes`: combined console output
|
|
206
|
+
- `maxToolInputBytes`: input for each tool call
|
|
207
|
+
- `maxToolOutputBytes`: output from each tool call
|
|
208
|
+
- `maxBridgeRequests`: total tool calls
|
|
209
|
+
- `maxInFlightBridgeRequests`: concurrent tool calls
|
|
210
|
+
|
|
211
|
+
Use `experimental_setMaxWorkers` to set a process-wide cap on concurrent code
|
|
212
|
+
mode workers:
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
import { experimental_setMaxWorkers as setMaxWorkers } from '@ai-sdk/code-mode';
|
|
216
|
+
|
|
217
|
+
setMaxWorkers(4);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Without an explicit cap, code mode chooses one based on available memory, up to
|
|
221
|
+
32 workers.
|
|
222
|
+
|
|
223
|
+
## Isolation and Tool Access
|
|
224
|
+
|
|
225
|
+
Each invocation receives a fresh QuickJS context. Sandboxed code cannot access:
|
|
226
|
+
|
|
227
|
+
- Node.js globals such as `process`, `require`, or `module`
|
|
228
|
+
- the host file system or module loader
|
|
229
|
+
- `fetch`, WebCrypto, or performance APIs
|
|
230
|
+
- `eval` or dynamic `Function` construction
|
|
231
|
+
|
|
232
|
+
Network or system access must be implemented in a tool and explicitly provided
|
|
233
|
+
to code mode.
|
|
234
|
+
|
|
235
|
+
<Note type="warning">
|
|
236
|
+
Treat the sandbox as defense in depth. Generated code and tool arguments are
|
|
237
|
+
untrusted. Tools execute in your host application, outside the QuickJS
|
|
238
|
+
sandbox, and every capability exposed by a provided tool is available to the
|
|
239
|
+
generated program. Enforce authorization and validate inputs inside each tool.
|
|
240
|
+
</Note>
|
|
241
|
+
|
|
242
|
+
Tool input schemas are validated before their `execute` functions run. Abort
|
|
243
|
+
signals and AI SDK tool execution context are forwarded to nested tool calls.
|
|
244
|
+
|
|
245
|
+
Code mode does not currently support approval flows for nested tool calls.
|
|
246
|
+
Tools that require approval are rejected instead of being executed.
|
|
@@ -653,7 +653,7 @@ Called after the provider response has been normalized and parsed, before local
|
|
|
653
653
|
{
|
|
654
654
|
name: 'modelId',
|
|
655
655
|
type: 'string',
|
|
656
|
-
description: '
|
|
656
|
+
description: 'Provider-returned model identifier for this model call.',
|
|
657
657
|
},
|
|
658
658
|
{
|
|
659
659
|
name: 'finishReason',
|
|
@@ -28,6 +28,12 @@ description: Learn about AI SDK Core.
|
|
|
28
28
|
description: 'Learn how to do tool calling with AI SDK Core.',
|
|
29
29
|
href: '/docs/ai-sdk-core/tools-and-tool-calling',
|
|
30
30
|
},
|
|
31
|
+
{
|
|
32
|
+
title: 'Code Mode',
|
|
33
|
+
description:
|
|
34
|
+
'Learn how models can orchestrate tools with sandboxed JavaScript and TypeScript.',
|
|
35
|
+
href: '/docs/ai-sdk-core/code-mode',
|
|
36
|
+
},
|
|
31
37
|
{
|
|
32
38
|
title: 'Realtime',
|
|
33
39
|
description: 'Learn how to build realtime voice conversations.',
|
|
@@ -578,6 +578,13 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
578
578
|
description:
|
|
579
579
|
"Approval configuration for this call. Pass a `GenericToolApprovalFunction` to handle all tool calls in one callback with `toolCall`, `tools`, `toolsContext`, `messages`, and `runtimeContext`, or pass a per-tool object where each key can be a status (`'not-applicable'`, `'approved'`, `'denied'`, or `'user-approval'`), an object form such as `{ type: 'denied', reason: 'blocked by policy' }`, or a `SingleToolApprovalFunction` that receives the tool input and options `toolCallId`, `messages`, `toolContext`, and `runtimeContext` (same shape as tool execution options without `abortSignal`, with `context` renamed to `toolContext`). The `RUNTIME_CONTEXT` type parameter matches the call's `runtimeContext`. A `GenericToolApprovalFunction` or `SingleToolApprovalFunction` may return `undefined` for the same effect as `'not-applicable'`. `'not-applicable'` is the default execution path and runs the tool without approval metadata. Use `'approved'`, `'denied'`, or their object forms when you want explicit automatic approval request/response parts in the output. Automatic approvals and denials can include a `reason`, which is forwarded to the emitted approval response. This setting takes precedence over a tool's `needsApproval` default.",
|
|
580
580
|
},
|
|
581
|
+
{
|
|
582
|
+
name: 'experimental_toolCallers',
|
|
583
|
+
type: 'Experimental_ToolCallers<TOOLS>',
|
|
584
|
+
isOptional: true,
|
|
585
|
+
description:
|
|
586
|
+
"Configures which caller tools may invoke each tool. The callback receives typed references for caller-capable tools in the `tools` set and returns an object keyed by callee tool name. Include `'direct'` to keep a configured tool directly callable by the model. Local-only callees are hidden from direct model calls and bound to their local caller for each generation step. Provider caller references are translated to provider-native allowed-caller options. Tools without an entry keep their existing direct tool-calling behavior.",
|
|
587
|
+
},
|
|
581
588
|
{
|
|
582
589
|
name: 'experimental_refineToolInput',
|
|
583
590
|
type: 'ToolInputRefinement<TOOLS>',
|
|
@@ -1406,7 +1413,8 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
1406
1413
|
{
|
|
1407
1414
|
name: 'modelId',
|
|
1408
1415
|
type: 'string',
|
|
1409
|
-
description:
|
|
1416
|
+
description:
|
|
1417
|
+
'The provider-returned model identifier for this model call.',
|
|
1410
1418
|
},
|
|
1411
1419
|
{
|
|
1412
1420
|
name: 'finishReason',
|
|
@@ -2390,7 +2390,8 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
2390
2390
|
{
|
|
2391
2391
|
name: 'modelId',
|
|
2392
2392
|
type: 'string',
|
|
2393
|
-
description:
|
|
2393
|
+
description:
|
|
2394
|
+
'The provider-returned model identifier for this model call.',
|
|
2394
2395
|
},
|
|
2395
2396
|
{
|
|
2396
2397
|
name: 'finishReason',
|
|
@@ -162,6 +162,13 @@ It currently does not support accepting notifications from an MCP server, and cu
|
|
|
162
162
|
},
|
|
163
163
|
],
|
|
164
164
|
},
|
|
165
|
+
{
|
|
166
|
+
name: 'initializationOptions',
|
|
167
|
+
type: 'RequestOptions',
|
|
168
|
+
isOptional: true,
|
|
169
|
+
description:
|
|
170
|
+
'Optional signal and timeout settings that bound transport startup and the initialize request. A timeout or abort closes the transport and rejects createMCPClient.',
|
|
171
|
+
},
|
|
165
172
|
{
|
|
166
173
|
name: 'clientName',
|
|
167
174
|
type: 'string',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.44",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@ai-sdk/gateway": "4.0.
|
|
45
|
+
"@ai-sdk/gateway": "4.0.33",
|
|
46
46
|
"@ai-sdk/provider": "4.0.4",
|
|
47
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
47
|
+
"@ai-sdk/provider-utils": "5.0.16"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@edge-runtime/vm": "^5.0.0",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"tsx": "^4.22.0",
|
|
56
56
|
"typescript": "5.8.3",
|
|
57
57
|
"zod": "3.25.76",
|
|
58
|
-
"@ai-sdk/test-server": "2.0.
|
|
58
|
+
"@ai-sdk/test-server": "2.0.1",
|
|
59
59
|
"@vercel/ai-tsconfig": "0.0.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
@@ -104,6 +104,11 @@ import { toResponseMessages } from './to-response-messages';
|
|
|
104
104
|
import type { ToolApprovalConfiguration } from './tool-approval-configuration';
|
|
105
105
|
import type { ToolApprovalRequestOutput } from './tool-approval-request-output';
|
|
106
106
|
import type { ToolApprovalResponseOutput } from './tool-approval-response-output';
|
|
107
|
+
import {
|
|
108
|
+
prepareToolsForToolCallers,
|
|
109
|
+
resolveToolCallerConfiguration,
|
|
110
|
+
type Experimental_ToolCallers,
|
|
111
|
+
} from './tool-caller-configuration';
|
|
107
112
|
import type { TypedToolCall } from './tool-call';
|
|
108
113
|
import type { ToolCallRepairFunction } from './tool-call-repair-function';
|
|
109
114
|
import type { TypedToolError } from './tool-error';
|
|
@@ -242,6 +247,7 @@ export async function generateText<
|
|
|
242
247
|
experimental_sandbox: sandbox,
|
|
243
248
|
output,
|
|
244
249
|
toolApproval,
|
|
250
|
+
experimental_toolCallers,
|
|
245
251
|
experimental_toolApprovalSecret,
|
|
246
252
|
experimental_telemetry,
|
|
247
253
|
telemetry = experimental_telemetry,
|
|
@@ -358,6 +364,11 @@ export async function generateText<
|
|
|
358
364
|
*/
|
|
359
365
|
toolApproval?: ToolApprovalConfiguration<TOOLS, RUNTIME_CONTEXT>;
|
|
360
366
|
|
|
367
|
+
/**
|
|
368
|
+
* Configures which caller tools may invoke each tool.
|
|
369
|
+
*/
|
|
370
|
+
experimental_toolCallers?: Experimental_ToolCallers<NoInfer<TOOLS>>;
|
|
371
|
+
|
|
361
372
|
/**
|
|
362
373
|
* Secret for HMAC-signing tool approval requests. When set, the server
|
|
363
374
|
* signs each approval request at issuance and verifies the signature when
|
|
@@ -560,6 +571,10 @@ export async function generateText<
|
|
|
560
571
|
};
|
|
561
572
|
|
|
562
573
|
const model = resolveLanguageModel(modelArg);
|
|
574
|
+
const resolvedToolCallers = resolveToolCallerConfiguration({
|
|
575
|
+
tools,
|
|
576
|
+
toolCallers: experimental_toolCallers,
|
|
577
|
+
});
|
|
563
578
|
const stopConditions = asArray(stopWhen);
|
|
564
579
|
const resolvedOnStart = onStart ?? experimental_onStart;
|
|
565
580
|
const resolvedOnStepStart = onStepStart ?? experimental_onStepStart;
|
|
@@ -863,10 +878,20 @@ export async function generateText<
|
|
|
863
878
|
tools,
|
|
864
879
|
activeTools: prepareStepResult?.activeTools ?? activeTools,
|
|
865
880
|
});
|
|
881
|
+
const {
|
|
882
|
+
executionTools: stepExecutionTools,
|
|
883
|
+
modelTools: stepModelTools,
|
|
884
|
+
} = prepareToolsForToolCallers({
|
|
885
|
+
tools: stepActiveTools,
|
|
886
|
+
toolCallers: resolvedToolCallers,
|
|
887
|
+
});
|
|
866
888
|
const stepToolOrder = prepareStepResult?.toolOrder ?? toolOrder;
|
|
867
889
|
|
|
868
890
|
const stepTools = await prepareTools({
|
|
869
|
-
tools:
|
|
891
|
+
tools: stepModelTools as ActiveToolSubset<
|
|
892
|
+
TOOLS,
|
|
893
|
+
ActiveTools<NoInfer<TOOLS>>
|
|
894
|
+
>,
|
|
870
895
|
toolOrder: stepToolOrder as ToolOrder<
|
|
871
896
|
ActiveToolSubset<TOOLS, ActiveTools<NoInfer<TOOLS>>>
|
|
872
897
|
>,
|
|
@@ -994,7 +1019,7 @@ export async function generateText<
|
|
|
994
1019
|
.map(toolCall =>
|
|
995
1020
|
parseToolCall({
|
|
996
1021
|
toolCall,
|
|
997
|
-
tools,
|
|
1022
|
+
tools: stepExecutionTools as TOOLS,
|
|
998
1023
|
repairToolCall,
|
|
999
1024
|
refineToolInput,
|
|
1000
1025
|
instructions: stepInstructions,
|
|
@@ -1025,7 +1050,7 @@ export async function generateText<
|
|
|
1025
1050
|
event: {
|
|
1026
1051
|
callId,
|
|
1027
1052
|
provider: stepModel.provider,
|
|
1028
|
-
modelId:
|
|
1053
|
+
modelId: currentModelResponse.response.modelId,
|
|
1029
1054
|
finishReason: currentModelResponse.finishReason.unified,
|
|
1030
1055
|
usage: stepUsage,
|
|
1031
1056
|
content: modelCallContent,
|
|
@@ -1062,7 +1087,7 @@ export async function generateText<
|
|
|
1062
1087
|
continue; // ignore invalid tool calls
|
|
1063
1088
|
}
|
|
1064
1089
|
|
|
1065
|
-
const tool = getOwn(
|
|
1090
|
+
const tool = getOwn(stepExecutionTools, toolCall.toolName);
|
|
1066
1091
|
|
|
1067
1092
|
if (tool == null) {
|
|
1068
1093
|
// ignore tool calls for tools that are not available,
|
|
@@ -1090,7 +1115,7 @@ export async function generateText<
|
|
|
1090
1115
|
}
|
|
1091
1116
|
|
|
1092
1117
|
const toolApprovalStatus = await resolveToolApproval({
|
|
1093
|
-
tools,
|
|
1118
|
+
tools: stepExecutionTools as TOOLS,
|
|
1094
1119
|
toolApproval,
|
|
1095
1120
|
toolCall,
|
|
1096
1121
|
messages: stepMessages,
|
|
@@ -1199,14 +1224,14 @@ export async function generateText<
|
|
|
1199
1224
|
);
|
|
1200
1225
|
const toolExecutionMs: Record<string, number> = {};
|
|
1201
1226
|
|
|
1202
|
-
if (
|
|
1227
|
+
if (stepExecutionTools != null) {
|
|
1203
1228
|
const toolExecutionResults = await executeTools({
|
|
1204
1229
|
toolCalls: clientToolCalls.filter(
|
|
1205
1230
|
toolCall =>
|
|
1206
1231
|
!toolCall.invalid &&
|
|
1207
1232
|
!blockedToolCallIds.has(toolCall.toolCallId),
|
|
1208
1233
|
),
|
|
1209
|
-
tools,
|
|
1234
|
+
tools: stepExecutionTools as TOOLS,
|
|
1210
1235
|
callId,
|
|
1211
1236
|
messages: stepMessages,
|
|
1212
1237
|
abortSignal: mergedAbortSignal,
|
|
@@ -1268,7 +1293,7 @@ export async function generateText<
|
|
|
1268
1293
|
// the client tool's result is sent back.
|
|
1269
1294
|
for (const toolCall of stepToolCalls) {
|
|
1270
1295
|
if (!toolCall.providerExecuted) continue;
|
|
1271
|
-
const tool = getOwn(
|
|
1296
|
+
const tool = getOwn(stepExecutionTools, toolCall.toolName);
|
|
1272
1297
|
if (tool?.type === 'provider' && tool.supportsDeferredResults) {
|
|
1273
1298
|
// Check if this tool call already has a result in the current response
|
|
1274
1299
|
const hasResultInResponse = currentModelResponse.content.some(
|
|
@@ -80,6 +80,10 @@ export type {
|
|
|
80
80
|
ToolApprovalConfiguration,
|
|
81
81
|
ToolApprovalStatus,
|
|
82
82
|
} from './tool-approval-configuration';
|
|
83
|
+
export type {
|
|
84
|
+
Experimental_ToolCallerReference,
|
|
85
|
+
Experimental_ToolCallers,
|
|
86
|
+
} from './tool-caller-configuration';
|
|
83
87
|
export { detectToolDrift, fingerprintTools } from './tool-fingerprint';
|
|
84
88
|
export type { ToolApprovalRequestOutput } from './tool-approval-request-output';
|
|
85
89
|
export type { ToolApprovalResponseOutput } from './tool-approval-response-output';
|
|
@@ -422,6 +422,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform<
|
|
|
422
422
|
const textPartIndexes = new Map<string, number>();
|
|
423
423
|
const reasoningPartIndexes = new Map<string, number>();
|
|
424
424
|
let responseId = generateId();
|
|
425
|
+
let responseModelId = modelId;
|
|
425
426
|
let timeToFirstOutputMs: number | undefined;
|
|
426
427
|
let previousOutputChunkTimestampMs: number | undefined;
|
|
427
428
|
const timeBetweenOutputChunksMs: number[] = [];
|
|
@@ -590,7 +591,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform<
|
|
|
590
591
|
event: {
|
|
591
592
|
callId,
|
|
592
593
|
provider,
|
|
593
|
-
modelId,
|
|
594
|
+
modelId: responseModelId,
|
|
594
595
|
finishReason: chunk.finishReason.unified,
|
|
595
596
|
usage,
|
|
596
597
|
content: modelCallContent,
|
|
@@ -739,6 +740,7 @@ function createLanguageModelV4StreamPartToLanguageModelStreamPartTransform<
|
|
|
739
740
|
|
|
740
741
|
case 'response-metadata': {
|
|
741
742
|
responseId = chunk.id ?? responseId;
|
|
743
|
+
responseModelId = chunk.modelId ?? responseModelId;
|
|
742
744
|
|
|
743
745
|
controller.enqueue({
|
|
744
746
|
type: 'model-call-response-metadata',
|