ai 7.0.41 → 7.0.43
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 +25 -0
- package/dist/index.d.ts +35 -9
- package/dist/index.js +175 -12
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +2 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index.js.map +1 -1
- package/docs/03-agents/02-building-agents.mdx +4 -0
- package/docs/03-agents/04-loop-control.mdx +40 -0
- package/docs/03-ai-sdk-core/18-code-mode.mdx +246 -0
- package/docs/03-ai-sdk-core/36-transcription.mdx +1 -0
- package/docs/03-ai-sdk-core/65-devtools.mdx +47 -1
- package/docs/03-ai-sdk-core/index.mdx +6 -0
- package/docs/06-advanced/11-secure-url-fetching.mdx +18 -24
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +75 -3
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +64 -1
- package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +1 -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-result.ts +3 -1
- package/src/generate-text/generate-text.ts +40 -9
- package/src/generate-text/index.ts +4 -0
- package/src/generate-text/prepare-step-call-settings.ts +31 -0
- package/src/generate-text/prepare-step.ts +8 -3
- package/src/generate-text/step-result.ts +2 -1
- package/src/generate-text/stream-text.ts +16 -2
- package/src/generate-text/tool-caller-configuration.ts +186 -0
- package/src/index.ts +2 -0
|
@@ -129,6 +129,10 @@ const result = await agent.generate({
|
|
|
129
129
|
});
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
+
Model call settings returned from `prepareStep`, such as `temperature`, apply
|
|
133
|
+
only to the current step. Later steps use the agent's top-level setting unless
|
|
134
|
+
they return another override.
|
|
135
|
+
|
|
132
136
|
For the full model, including sensitive context filtering and where each context
|
|
133
137
|
value is available, see [Runtime and Tool
|
|
134
138
|
Context](/docs/ai-sdk-core/runtime-and-tool-context).
|
|
@@ -180,6 +180,46 @@ const result = await agent.generate({
|
|
|
180
180
|
});
|
|
181
181
|
```
|
|
182
182
|
|
|
183
|
+
### Model Call Settings
|
|
184
|
+
|
|
185
|
+
Override provider-agnostic model call settings for an individual step. This can
|
|
186
|
+
be useful when tool-calling steps need more deterministic sampling than the
|
|
187
|
+
final response:
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
import { ToolLoopAgent } from 'ai';
|
|
191
|
+
__PROVIDER_IMPORT__;
|
|
192
|
+
|
|
193
|
+
const agent = new ToolLoopAgent({
|
|
194
|
+
model: __MODEL__,
|
|
195
|
+
temperature: 0.7,
|
|
196
|
+
tools: {
|
|
197
|
+
// your tools
|
|
198
|
+
},
|
|
199
|
+
prepareStep: async ({ stepNumber }) => {
|
|
200
|
+
if (stepNumber === 0) {
|
|
201
|
+
return {
|
|
202
|
+
temperature: 0,
|
|
203
|
+
maxOutputTokens: 300,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return {};
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const result = await agent.generate({
|
|
212
|
+
prompt: '...',
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`prepareStep` can override `maxOutputTokens`, `temperature`, `topP`, `topK`,
|
|
217
|
+
`presencePenalty`, `frequencyPenalty`, `stopSequences`, `seed`, and
|
|
218
|
+
`reasoning`. These overrides apply only to the current step. When a setting is
|
|
219
|
+
omitted or `undefined`, the top-level value is used for that step. Defined
|
|
220
|
+
falsy values such as `temperature: 0`, `seed: 0`, and an empty
|
|
221
|
+
`stopSequences` array are preserved.
|
|
222
|
+
|
|
183
223
|
### Context Management
|
|
184
224
|
|
|
185
225
|
Long-running agents can accumulate large tool results, reasoning parts, and assistant messages. Use `prepareStep` to mutate the message state that will be used by later steps. This is useful for compaction, and you decide when compaction should happen.
|
|
@@ -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.
|
|
@@ -304,6 +304,7 @@ try {
|
|
|
304
304
|
| [ElevenLabs](/providers/ai-sdk-providers/elevenlabs#streaming-transcription-models) | `scribe_v2_realtime` |
|
|
305
305
|
| [Groq](/providers/ai-sdk-providers/groq#transcription-models) | `whisper-large-v3-turbo` |
|
|
306
306
|
| [Groq](/providers/ai-sdk-providers/groq#transcription-models) | `whisper-large-v3` |
|
|
307
|
+
| [Mistral](/providers/ai-sdk-providers/mistral#transcription-models) | `voxtral-mini-latest` |
|
|
307
308
|
| [Azure OpenAI](/providers/ai-sdk-providers/azure#transcription-models) | `whisper-1` |
|
|
308
309
|
| [Azure OpenAI](/providers/ai-sdk-providers/azure#transcription-models) | `gpt-4o-transcribe` |
|
|
309
310
|
| [Azure OpenAI](/providers/ai-sdk-providers/azure#transcription-models) | `gpt-4o-mini-transcribe` |
|
|
@@ -105,10 +105,56 @@ the workspace.
|
|
|
105
105
|
DevTools captures the following information from your AI SDK calls:
|
|
106
106
|
|
|
107
107
|
- **Input parameters and prompts**: View the complete input sent to your LLM
|
|
108
|
-
- **Output content and tool calls**: Inspect generated text and tool
|
|
108
|
+
- **Output content and tool calls**: Inspect generated text, tool invocations, and tool results
|
|
109
|
+
- **Media previews**: View images, audio, and video included in prompts, tool inputs, and tool outputs
|
|
109
110
|
- **Token usage and timing**: Monitor resource consumption and performance
|
|
110
111
|
- **Raw provider data**: Access provider request and response payloads when body retention is enabled
|
|
111
112
|
|
|
113
|
+
### Media previews
|
|
114
|
+
|
|
115
|
+
DevTools recognizes current `file` content parts as well as the deprecated
|
|
116
|
+
`image-*`, `file-*`, and `media` tool-result aliases. Inline image, audio, and
|
|
117
|
+
video data is previewed directly, while the captured JSON shape and metadata
|
|
118
|
+
remain available for inspection. The viewer displays at most 8 previews per
|
|
119
|
+
value, traverses at most 12 nested levels, and embeds inline previews up to 5
|
|
120
|
+
MiB. Longer JSON strings are truncated in the viewer to avoid duplicating large
|
|
121
|
+
base64 payloads. Binary values in recognized media-bearing fields are persisted
|
|
122
|
+
as base64 so they remain previewable; unrelated binary values retain their
|
|
123
|
+
normal JSON representation.
|
|
124
|
+
|
|
125
|
+
For example, a tool can return media through `toModelOutput`:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import { tool } from 'ai';
|
|
129
|
+
import { z } from 'zod';
|
|
130
|
+
|
|
131
|
+
const captureScreenshot = tool({
|
|
132
|
+
inputSchema: z.object({}),
|
|
133
|
+
execute: async () => ({
|
|
134
|
+
base64: await captureScreenshotAsBase64(),
|
|
135
|
+
}),
|
|
136
|
+
toModelOutput: ({ output }) => ({
|
|
137
|
+
type: 'content',
|
|
138
|
+
value: [
|
|
139
|
+
{
|
|
140
|
+
type: 'file',
|
|
141
|
+
filename: 'screenshot.png',
|
|
142
|
+
mediaType: 'image/png',
|
|
143
|
+
data: { type: 'data', data: output.base64 },
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
}),
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Remote `http` and `https` media is not loaded automatically. Select **Load
|
|
151
|
+
preview** in the viewer to fetch it with anonymous CORS and no referrer.
|
|
152
|
+
Cross-origin browser credentials are omitted, but same-origin browser
|
|
153
|
+
credentials may still be included by the browser. URLs containing embedded
|
|
154
|
+
usernames or passwords are rejected. Unsupported media, provider references,
|
|
155
|
+
malformed values, unsafe URL schemes, and inline values over the preview limit
|
|
156
|
+
retain their JSON and metadata fallback without an embedded preview.
|
|
157
|
+
|
|
112
158
|
Telemetry is enabled automatically, but AI SDK 7 excludes raw request and response bodies from step results by default. To make them available to DevTools for `generateText`, enable body retention on the call:
|
|
113
159
|
|
|
114
160
|
```ts highlight="4-7"
|
|
@@ -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.',
|
|
@@ -27,6 +27,10 @@ When the SDK fetches a URL taken from a provider response, it:
|
|
|
27
27
|
are rejected too.
|
|
28
28
|
- **Re-validates every redirect hop** — a URL that passes but then redirects to
|
|
29
29
|
an internal address is blocked; the redirect is never followed blindly.
|
|
30
|
+
- **Validates DNS at connection time on Node.js** — every resolved address is
|
|
31
|
+
checked, and the socket is pinned to the validated DNS result so DNS
|
|
32
|
+
rebinding cannot introduce a different address between validation and
|
|
33
|
+
connection.
|
|
30
34
|
- **Strips risky request headers** — proxy-forwarding, cloud-metadata, and
|
|
31
35
|
cookie headers are removed before the request.
|
|
32
36
|
- **Drops credentials across origins** — caller headers (`Authorization`,
|
|
@@ -43,28 +47,17 @@ custom `baseURL` pointing at a self-hosted or `localhost` deployment) are
|
|
|
43
47
|
exempt from these checks — they target exactly the host you told the SDK to
|
|
44
48
|
talk to. Any redirect off that origin is still validated.
|
|
45
49
|
|
|
46
|
-
##
|
|
50
|
+
## DNS validation across runtimes
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
On Node.js, the default validated download fetch uses `node:dns` and an
|
|
53
|
+
`undici` connector hook to validate every resolved address at connection time.
|
|
54
|
+
The connector uses those exact results, closing both hostname-to-private-IP and
|
|
55
|
+
DNS-rebinding bypasses.
|
|
50
56
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
time-of-check/time-of-use window).
|
|
56
|
-
|
|
57
|
-
### Why this isn't built in
|
|
58
|
-
|
|
59
|
-
Closing these requires resolving DNS and pinning the resolved IP **at connect
|
|
60
|
-
time** — Node-only capabilities (`node:dns`, a custom `undici` dispatcher). The
|
|
61
|
-
SDK's provider utilities are **cross-runtime**: they run on the edge, in the
|
|
62
|
-
browser, and on Bun/Deno, with no Node-only dependencies, so those APIs aren't
|
|
63
|
-
available there. The threat is also specifically a **server-side** one — on the
|
|
64
|
-
edge and in the browser, outbound `fetch` cannot reach a host's internal network
|
|
65
|
-
or metadata endpoint in the first place. So connect-time IP pinning is only
|
|
66
|
-
meaningful, and only available, on a Node server — which is exactly where you
|
|
67
|
-
can add it yourself.
|
|
57
|
+
If you inject or globally replace `fetch`, it is responsible for equivalent DNS
|
|
58
|
+
validation and connection pinning. Other runtimes do not expose Node's
|
|
59
|
+
DNS/socket hooks, so server deployments on those runtimes should restrict
|
|
60
|
+
network egress to private, loopback, link-local, and cloud-metadata ranges.
|
|
68
61
|
|
|
69
62
|
## Hardening your deployment
|
|
70
63
|
|
|
@@ -77,9 +70,10 @@ Deny your server's network egress to `169.254.0.0/16`, RFC-1918 ranges, and
|
|
|
77
70
|
loopback. This is the most robust control and is independent of application
|
|
78
71
|
code.
|
|
79
72
|
|
|
80
|
-
### 2.
|
|
73
|
+
### 2. Harden an injected `fetch`
|
|
81
74
|
|
|
82
|
-
|
|
75
|
+
The Node.js default is already pinned. If you inject or globally replace
|
|
76
|
+
`fetch`, back it with an `undici`
|
|
83
77
|
`Agent` whose `connect.lookup` validates the resolved IP and lets the socket
|
|
84
78
|
connect only to a safe address — closing both the hostname-to-private and the
|
|
85
79
|
DNS-rebinding windows:
|
|
@@ -113,5 +107,5 @@ import { createFal } from '@ai-sdk/fal';
|
|
|
113
107
|
const fal = createFal({ fetch: safeFetch });
|
|
114
108
|
```
|
|
115
109
|
|
|
116
|
-
The SDK's
|
|
117
|
-
keep both.
|
|
110
|
+
The SDK's URL validation and your custom fetch's connect-time pinning are
|
|
111
|
+
complementary — keep both.
|
|
@@ -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>',
|
|
@@ -597,7 +604,7 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
597
604
|
type: '(options: PrepareStepOptions) => PrepareStepResult<TOOLS> | Promise<PrepareStepResult<TOOLS>>',
|
|
598
605
|
isOptional: true,
|
|
599
606
|
description:
|
|
600
|
-
'Optional function that you can use to provide different settings for a step. You can modify the model, tool choices, active tools, instructions, input messages, and experimental sandbox for each step.',
|
|
607
|
+
'Optional function that you can use to provide different settings for a step. You can modify the model, model call settings, tool choices, active tools, instructions, input messages, and experimental sandbox for each step.',
|
|
601
608
|
properties: [
|
|
602
609
|
{
|
|
603
610
|
type: 'PrepareStepFunction<TOOLS>',
|
|
@@ -682,6 +689,69 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
682
689
|
description:
|
|
683
690
|
'Optionally override which LanguageModel instance is used for this step.',
|
|
684
691
|
},
|
|
692
|
+
{
|
|
693
|
+
name: 'maxOutputTokens',
|
|
694
|
+
type: 'number',
|
|
695
|
+
isOptional: true,
|
|
696
|
+
description:
|
|
697
|
+
'Maximum number of tokens to generate for this step. Uses the top-level value when omitted or undefined.',
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
name: 'temperature',
|
|
701
|
+
type: 'number',
|
|
702
|
+
isOptional: true,
|
|
703
|
+
description:
|
|
704
|
+
'Temperature for this step. Uses the top-level value when omitted or undefined.',
|
|
705
|
+
},
|
|
706
|
+
{
|
|
707
|
+
name: 'topP',
|
|
708
|
+
type: 'number',
|
|
709
|
+
isOptional: true,
|
|
710
|
+
description:
|
|
711
|
+
'Nucleus sampling value for this step. Uses the top-level value when omitted or undefined.',
|
|
712
|
+
},
|
|
713
|
+
{
|
|
714
|
+
name: 'topK',
|
|
715
|
+
type: 'number',
|
|
716
|
+
isOptional: true,
|
|
717
|
+
description:
|
|
718
|
+
'Top-K sampling value for this step. Uses the top-level value when omitted or undefined.',
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
name: 'presencePenalty',
|
|
722
|
+
type: 'number',
|
|
723
|
+
isOptional: true,
|
|
724
|
+
description:
|
|
725
|
+
'Presence penalty for this step. Uses the top-level value when omitted or undefined.',
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
name: 'frequencyPenalty',
|
|
729
|
+
type: 'number',
|
|
730
|
+
isOptional: true,
|
|
731
|
+
description:
|
|
732
|
+
'Frequency penalty for this step. Uses the top-level value when omitted or undefined.',
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
name: 'stopSequences',
|
|
736
|
+
type: 'string[]',
|
|
737
|
+
isOptional: true,
|
|
738
|
+
description:
|
|
739
|
+
'Stop sequences for this step. Uses the top-level value when omitted or undefined.',
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
name: 'seed',
|
|
743
|
+
type: 'number',
|
|
744
|
+
isOptional: true,
|
|
745
|
+
description:
|
|
746
|
+
'Random sampling seed for this step. Uses the top-level value when omitted or undefined.',
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
name: 'reasoning',
|
|
750
|
+
type: 'LanguageModelV4CallOptions["reasoning"]',
|
|
751
|
+
isOptional: true,
|
|
752
|
+
description:
|
|
753
|
+
'Reasoning effort for this step. Uses the top-level value when omitted or undefined.',
|
|
754
|
+
},
|
|
685
755
|
{
|
|
686
756
|
name: 'toolChoice',
|
|
687
757
|
type: 'ToolChoice<TOOLS>',
|
|
@@ -2362,7 +2432,8 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
2362
2432
|
{
|
|
2363
2433
|
name: 'text',
|
|
2364
2434
|
type: 'string',
|
|
2365
|
-
description:
|
|
2435
|
+
description:
|
|
2436
|
+
'The concatenation of all text parts generated in the final step. It is an empty string if the final step contains no text parts. Inspect `finalStep.content` to distinguish that case.',
|
|
2366
2437
|
},
|
|
2367
2438
|
{
|
|
2368
2439
|
name: 'reasoning',
|
|
@@ -2795,7 +2866,8 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
2795
2866
|
{
|
|
2796
2867
|
name: 'text',
|
|
2797
2868
|
type: 'string',
|
|
2798
|
-
description:
|
|
2869
|
+
description:
|
|
2870
|
+
'The concatenation of all text parts generated in this step. It is an empty string if the step contains no text parts.',
|
|
2799
2871
|
},
|
|
2800
2872
|
{
|
|
2801
2873
|
name: 'reasoning',
|
|
@@ -641,7 +641,7 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
641
641
|
type: '(options: PrepareStepOptions) => PrepareStepResult<TOOLS> | Promise<PrepareStepResult<TOOLS>>',
|
|
642
642
|
isOptional: true,
|
|
643
643
|
description:
|
|
644
|
-
'Optional function that you can use to provide different settings for a step. You can modify the model, tool choices, active tools, instructions, input messages, and experimental sandbox for each step.',
|
|
644
|
+
'Optional function that you can use to provide different settings for a step. You can modify the model, model call settings, tool choices, active tools, instructions, input messages, and experimental sandbox for each step.',
|
|
645
645
|
properties: [
|
|
646
646
|
{
|
|
647
647
|
type: 'PrepareStepFunction<TOOLS>',
|
|
@@ -726,6 +726,69 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
726
726
|
description:
|
|
727
727
|
'Optionally override which LanguageModel instance is used for this step.',
|
|
728
728
|
},
|
|
729
|
+
{
|
|
730
|
+
name: 'maxOutputTokens',
|
|
731
|
+
type: 'number',
|
|
732
|
+
isOptional: true,
|
|
733
|
+
description:
|
|
734
|
+
'Maximum number of tokens to generate for this step. Uses the top-level value when omitted or undefined.',
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
name: 'temperature',
|
|
738
|
+
type: 'number',
|
|
739
|
+
isOptional: true,
|
|
740
|
+
description:
|
|
741
|
+
'Temperature for this step. Uses the top-level value when omitted or undefined.',
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
name: 'topP',
|
|
745
|
+
type: 'number',
|
|
746
|
+
isOptional: true,
|
|
747
|
+
description:
|
|
748
|
+
'Nucleus sampling value for this step. Uses the top-level value when omitted or undefined.',
|
|
749
|
+
},
|
|
750
|
+
{
|
|
751
|
+
name: 'topK',
|
|
752
|
+
type: 'number',
|
|
753
|
+
isOptional: true,
|
|
754
|
+
description:
|
|
755
|
+
'Top-K sampling value for this step. Uses the top-level value when omitted or undefined.',
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
name: 'presencePenalty',
|
|
759
|
+
type: 'number',
|
|
760
|
+
isOptional: true,
|
|
761
|
+
description:
|
|
762
|
+
'Presence penalty for this step. Uses the top-level value when omitted or undefined.',
|
|
763
|
+
},
|
|
764
|
+
{
|
|
765
|
+
name: 'frequencyPenalty',
|
|
766
|
+
type: 'number',
|
|
767
|
+
isOptional: true,
|
|
768
|
+
description:
|
|
769
|
+
'Frequency penalty for this step. Uses the top-level value when omitted or undefined.',
|
|
770
|
+
},
|
|
771
|
+
{
|
|
772
|
+
name: 'stopSequences',
|
|
773
|
+
type: 'string[]',
|
|
774
|
+
isOptional: true,
|
|
775
|
+
description:
|
|
776
|
+
'Stop sequences for this step. Uses the top-level value when omitted or undefined.',
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
name: 'seed',
|
|
780
|
+
type: 'number',
|
|
781
|
+
isOptional: true,
|
|
782
|
+
description:
|
|
783
|
+
'Random sampling seed for this step. Uses the top-level value when omitted or undefined.',
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
name: 'reasoning',
|
|
787
|
+
type: 'LanguageModelV4CallOptions["reasoning"]',
|
|
788
|
+
isOptional: true,
|
|
789
|
+
description:
|
|
790
|
+
'Reasoning effort for this step. Uses the top-level value when omitted or undefined.',
|
|
791
|
+
},
|
|
729
792
|
{
|
|
730
793
|
name: 'toolChoice',
|
|
731
794
|
type: 'ToolChoice<TOOLS>',
|
|
@@ -123,7 +123,7 @@ To see `ToolLoopAgent` in action, check out [these examples](#examples).
|
|
|
123
123
|
type: 'PrepareStepFunction',
|
|
124
124
|
isOptional: true,
|
|
125
125
|
description:
|
|
126
|
-
'Optional function to mutate step settings or inject state for each agent step.',
|
|
126
|
+
'Optional function to mutate step settings or inject state for each agent step, including per-step model call settings such as temperature, maxOutputTokens, sampling controls, penalties, stop sequences, seed, and reasoning. Model call setting overrides apply only to the current step.',
|
|
127
127
|
},
|
|
128
128
|
{
|
|
129
129
|
name: 'include',
|
|
@@ -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',
|