ai 7.0.18 → 7.0.20
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 +28 -0
- package/dist/index.d.ts +58 -5
- package/dist/index.js +168 -79
- package/dist/index.js.map +1 -1
- package/dist/internal/index.js +43 -31
- package/dist/internal/index.js.map +1 -1
- package/docs/02-foundations/02-providers-and-models.mdx +57 -52
- package/docs/02-getting-started/00-choosing-a-provider.mdx +1 -16
- package/docs/02-getting-started/01-navigating-the-library.mdx +12 -12
- package/docs/02-getting-started/02-nextjs-app-router.mdx +2 -36
- package/docs/02-getting-started/03-nextjs-pages-router.mdx +2 -36
- package/docs/02-getting-started/04-svelte.mdx +2 -34
- package/docs/02-getting-started/05-nuxt.mdx +2 -36
- package/docs/02-getting-started/06-nodejs.mdx +1 -18
- package/docs/02-getting-started/07-expo.mdx +3 -62
- package/docs/02-getting-started/08-tanstack-start.mdx +2 -36
- package/docs/02-getting-started/09-coding-agents.mdx +2 -32
- package/docs/03-agents/07-workflow-agent.mdx +1 -1
- package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +3 -12
- package/docs/03-ai-sdk-core/16-mcp-tools.mdx +44 -0
- package/docs/03-ai-sdk-core/30-embeddings.mdx +18 -18
- package/docs/03-ai-sdk-core/38-video-generation.mdx +22 -3
- package/docs/03-ai-sdk-harnesses/02-harness-agent.mdx +1 -28
- package/docs/03-ai-sdk-harnesses/05-harness-adapters.mdx +7 -7
- package/docs/03-ai-sdk-harnesses/06-workflow-utilities.mdx +1 -16
- package/docs/03-ai-sdk-harnesses/08-terminal-ui.mdx +1 -28
- package/docs/04-ai-sdk-ui/01-overview.mdx +5 -5
- package/docs/07-reference/01-ai-sdk-core/01-generate-text.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/02-stream-text.mdx +1 -1
- package/docs/07-reference/01-ai-sdk-core/13-generate-video.mdx +3 -2
- package/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx +1 -1
- package/docs/07-reference/02-ai-sdk-ui/index.mdx +5 -5
- package/docs/07-reference/04-ai-sdk-workflow/01-workflow-agent.mdx +2 -2
- package/package.json +4 -4
- package/src/agent/tool-loop-agent-settings.ts +7 -0
- package/src/generate-text/collect-tool-approvals.ts +17 -4
- package/src/generate-text/execute-tool-call.ts +3 -2
- package/src/generate-text/execute-tools-from-stream.ts +2 -1
- package/src/generate-text/generate-text.ts +14 -5
- package/src/generate-text/index.ts +1 -0
- package/src/generate-text/invoke-tool-callbacks-from-stream.ts +6 -4
- package/src/generate-text/parse-tool-call.ts +5 -4
- package/src/generate-text/resolve-tool-approval.ts +9 -6
- package/src/generate-text/stream-language-model-call.ts +2 -1
- package/src/generate-text/stream-text.ts +12 -3
- package/src/generate-text/to-response-messages.ts +4 -3
- package/src/generate-text/tool-approval-signature.ts +4 -40
- package/src/generate-text/tool-fingerprint.ts +76 -0
- package/src/generate-text/validate-tool-approvals.ts +6 -1
- package/src/generate-video/generate-video.ts +96 -21
- package/src/ui/convert-to-model-messages.ts +3 -2
- package/src/ui/process-ui-message-stream.ts +3 -0
- package/src/ui/validate-ui-messages.ts +2 -1
- package/src/util/canonical-hash.ts +44 -0
- package/src/util/get-own.ts +18 -0
- package/src/util/write-to-server-response.ts +9 -0
|
@@ -33,22 +33,7 @@ Once you've installed the `ai` package, you already have the full AI SDK documen
|
|
|
33
33
|
|
|
34
34
|
Install the `ai` package if you haven't already:
|
|
35
35
|
|
|
36
|
-
<
|
|
37
|
-
<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
|
|
38
|
-
<Tab>
|
|
39
|
-
<Snippet text="pnpm add ai" dark />
|
|
40
|
-
</Tab>
|
|
41
|
-
<Tab>
|
|
42
|
-
<Snippet text="npm install ai" dark />
|
|
43
|
-
</Tab>
|
|
44
|
-
<Tab>
|
|
45
|
-
<Snippet text="yarn add ai" dark />
|
|
46
|
-
</Tab>
|
|
47
|
-
<Tab>
|
|
48
|
-
<Snippet text="bun add ai" dark />
|
|
49
|
-
</Tab>
|
|
50
|
-
</Tabs>
|
|
51
|
-
</div>
|
|
36
|
+
<InstallPackages packages="ai" />
|
|
52
37
|
|
|
53
38
|
After installation, your agent can reference the bundled source code and documentation at paths like:
|
|
54
39
|
|
|
@@ -70,22 +55,7 @@ AI SDK DevTools gives you full visibility into your AI SDK calls during developm
|
|
|
70
55
|
|
|
71
56
|
Install the DevTools package:
|
|
72
57
|
|
|
73
|
-
<
|
|
74
|
-
<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
|
|
75
|
-
<Tab>
|
|
76
|
-
<Snippet text="pnpm add @ai-sdk/devtools" dark />
|
|
77
|
-
</Tab>
|
|
78
|
-
<Tab>
|
|
79
|
-
<Snippet text="npm install @ai-sdk/devtools" dark />
|
|
80
|
-
</Tab>
|
|
81
|
-
<Tab>
|
|
82
|
-
<Snippet text="yarn add @ai-sdk/devtools" dark />
|
|
83
|
-
</Tab>
|
|
84
|
-
<Tab>
|
|
85
|
-
<Snippet text="bun add @ai-sdk/devtools" dark />
|
|
86
|
-
</Tab>
|
|
87
|
-
</Tabs>
|
|
88
|
-
</div>
|
|
58
|
+
<InstallPackages packages="@ai-sdk/devtools" />
|
|
89
59
|
|
|
90
60
|
### Register the integration
|
|
91
61
|
|
|
@@ -702,7 +702,7 @@ For persistence, store `UIMessage[]` as your source of truth and call [`convertT
|
|
|
702
702
|
|
|
703
703
|
### Everything else
|
|
704
704
|
|
|
705
|
-
Other options carry over with the same names: `prepareStep`, `onStepEnd`, `onEnd`, `onError`, `toolChoice`, `activeTools`, `timeout`, `
|
|
705
|
+
Other options carry over with the same names: `prepareStep`, `onStepEnd`, `onEnd`, `onError`, `toolChoice`, `activeTools`, `timeout`, `repairToolCall`, `experimental_sandbox`, and the usual generation settings (`temperature`, `maxOutputTokens`, `topP`, …). `WorkflowAgent` additionally adds `prepareCall` (runs once before the loop) and the `experimental_onStart` / `experimental_onStepStart` / `onToolExecutionStart` / `onToolExecutionEnd` lifecycle callbacks documented above.
|
|
706
706
|
|
|
707
707
|
## Next Steps
|
|
708
708
|
|
|
@@ -1207,10 +1207,6 @@ return createUIMessageStreamResponse({
|
|
|
1207
1207
|
|
|
1208
1208
|
## Tool Call Repair
|
|
1209
1209
|
|
|
1210
|
-
<Note type="warning">
|
|
1211
|
-
The tool call repair feature is experimental and may change in the future.
|
|
1212
|
-
</Note>
|
|
1213
|
-
|
|
1214
1210
|
Language models sometimes fail to generate valid tool calls,
|
|
1215
1211
|
especially when the input schema is complex or the model is smaller.
|
|
1216
1212
|
|
|
@@ -1219,7 +1215,7 @@ in the next step to give it an opportunity to fix it.
|
|
|
1219
1215
|
However, you may want to control how invalid tool calls are repaired without requiring
|
|
1220
1216
|
additional steps that pollute the message history.
|
|
1221
1217
|
|
|
1222
|
-
You can use the `
|
|
1218
|
+
You can use the `repairToolCall` function to attempt to repair the tool call
|
|
1223
1219
|
with a custom function.
|
|
1224
1220
|
|
|
1225
1221
|
You can use different strategies to repair the tool call:
|
|
@@ -1239,12 +1235,7 @@ const result = await generateText({
|
|
|
1239
1235
|
tools,
|
|
1240
1236
|
prompt,
|
|
1241
1237
|
|
|
1242
|
-
|
|
1243
|
-
toolCall,
|
|
1244
|
-
tools,
|
|
1245
|
-
inputSchema,
|
|
1246
|
-
error,
|
|
1247
|
-
}) => {
|
|
1238
|
+
repairToolCall: async ({ toolCall, tools, inputSchema, error }) => {
|
|
1248
1239
|
if (NoSuchToolError.isInstance(error)) {
|
|
1249
1240
|
return null; // do not attempt to fix invalid tool names
|
|
1250
1241
|
}
|
|
@@ -1280,7 +1271,7 @@ const result = await generateText({
|
|
|
1280
1271
|
tools,
|
|
1281
1272
|
prompt,
|
|
1282
1273
|
|
|
1283
|
-
|
|
1274
|
+
repairToolCall: async ({
|
|
1284
1275
|
toolCall,
|
|
1285
1276
|
tools,
|
|
1286
1277
|
error,
|
|
@@ -518,6 +518,50 @@ Your handler must return an object with an `action` field that can be one of:
|
|
|
518
518
|
- `'decline'`: User chose not to provide the information.
|
|
519
519
|
- `'cancel'`: User cancelled the operation entirely.
|
|
520
520
|
|
|
521
|
+
## Detecting tool-definition drift ("rug pull")
|
|
522
|
+
|
|
523
|
+
An MCP server sends tool definitions (name, description, input schema) when your
|
|
524
|
+
app first connects, and you typically review and approve them at that point.
|
|
525
|
+
Nothing in the protocol prevents the server from later serving a _different_
|
|
526
|
+
definition for the same tool name — for example a description carrying injected
|
|
527
|
+
instructions, or an input schema widened with an extra field. Because the SDK
|
|
528
|
+
uses whatever tools you pass on each call, a mutated definition returned by a
|
|
529
|
+
later `mcpClient.tools()` fetch would be used without any comparison to what was
|
|
530
|
+
approved. This is the MCP ["rug pull"](https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks)
|
|
531
|
+
class of attack.
|
|
532
|
+
|
|
533
|
+
The AI SDK provides two functions to pin the approved definitions and detect
|
|
534
|
+
changes. `fingerprintTools` digests the server-controlled, security-relevant
|
|
535
|
+
fields of each tool (string `description`, resolved input schema, and `title`)
|
|
536
|
+
into a stable map of tool name to digest. `detectToolDrift` diffs two such maps.
|
|
537
|
+
Your app owns baseline storage and the response to drift (block, force
|
|
538
|
+
re-approval, or alert):
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
import { fingerprintTools, detectToolDrift } from 'ai';
|
|
542
|
+
|
|
543
|
+
// Trust time (first connect, human-reviewed): capture and persist the baseline.
|
|
544
|
+
const baseline = await fingerprintTools(await mcpClient.tools());
|
|
545
|
+
|
|
546
|
+
// Every later fetch, before handing tools to generateText:
|
|
547
|
+
const tools = await mcpClient.tools();
|
|
548
|
+
const drift = detectToolDrift(await fingerprintTools(tools), baseline);
|
|
549
|
+
|
|
550
|
+
if (drift.changed.length || drift.added.length) {
|
|
551
|
+
// A pinned definition changed, or a new tool appeared. Block, re-approve,
|
|
552
|
+
// or alert per your policy — do not silently pass `tools` to the model.
|
|
553
|
+
}
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
<Note>
|
|
557
|
+
This detects mutation of a tool's description, input schema, or title — the
|
|
558
|
+
prompt-injection and schema-widening vectors. It cannot detect a
|
|
559
|
+
behavior/endpoint swap where the name, description, and schema are all
|
|
560
|
+
unchanged, because the tool runs remotely on the MCP server and that change is
|
|
561
|
+
invisible to the client. Core stays unopinionated: it does not persist
|
|
562
|
+
baselines or block calls — those are your app's responsibility.
|
|
563
|
+
</Note>
|
|
564
|
+
|
|
521
565
|
## Examples
|
|
522
566
|
|
|
523
567
|
You can see MCP in action in the following examples:
|
|
@@ -219,21 +219,21 @@ const embeddingModelWithDefaults = wrapEmbeddingModel({
|
|
|
219
219
|
|
|
220
220
|
Several providers offer embedding models:
|
|
221
221
|
|
|
222
|
-
| Provider | Model | Embedding Dimensions | Multimodal
|
|
223
|
-
| ----------------------------------------------------------------------------- | ------------------------------- | -------------------- |
|
|
224
|
-
| [OpenAI](/providers/ai-sdk-providers/openai#embedding-models) | `text-embedding-3-large` | 3072 | <Cross
|
|
225
|
-
| [OpenAI](/providers/ai-sdk-providers/openai#embedding-models) | `text-embedding-3-small` | 1536 | <Cross
|
|
226
|
-
| [OpenAI](/providers/ai-sdk-providers/openai#embedding-models) | `text-embedding-ada-002` | 1536 | <Cross
|
|
227
|
-
| [Google](/providers/ai-sdk-providers/google#embedding-models) | `gemini-embedding-001` | 3072 | <Cross
|
|
228
|
-
| [Google](/providers/ai-sdk-providers/google#embedding-models) | `gemini-embedding-2` | 3072 | <Check
|
|
229
|
-
| [Google](/providers/ai-sdk-providers/google#embedding-models) | `gemini-embedding-2-preview` | 3072 | <Check
|
|
230
|
-
| [Mistral](/providers/ai-sdk-providers/mistral#embedding-models) | `mistral-embed` | 1024 | <Cross
|
|
231
|
-
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-english-v3.0` | 1024 | <Cross
|
|
232
|
-
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-multilingual-v3.0` | 1024 | <Cross
|
|
233
|
-
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-english-light-v3.0` | 384 | <Cross
|
|
234
|
-
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-multilingual-light-v3.0` | 384 | <Cross
|
|
235
|
-
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-english-v2.0` | 4096 | <Cross
|
|
236
|
-
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-english-light-v2.0` | 1024 | <Cross
|
|
237
|
-
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-multilingual-v2.0` | 768 | <Cross
|
|
238
|
-
| [Amazon Bedrock](/providers/ai-sdk-providers/amazon-bedrock#embedding-models) | `amazon.titan-embed-text-v1` | 1536 | <Cross
|
|
239
|
-
| [Amazon Bedrock](/providers/ai-sdk-providers/amazon-bedrock#embedding-models) | `amazon.titan-embed-text-v2:0` | 1024 | <Cross
|
|
222
|
+
| Provider | Model | Embedding Dimensions | Multimodal |
|
|
223
|
+
| ----------------------------------------------------------------------------- | ------------------------------- | -------------------- | ---------- |
|
|
224
|
+
| [OpenAI](/providers/ai-sdk-providers/openai#embedding-models) | `text-embedding-3-large` | 3072 | <Cross /> |
|
|
225
|
+
| [OpenAI](/providers/ai-sdk-providers/openai#embedding-models) | `text-embedding-3-small` | 1536 | <Cross /> |
|
|
226
|
+
| [OpenAI](/providers/ai-sdk-providers/openai#embedding-models) | `text-embedding-ada-002` | 1536 | <Cross /> |
|
|
227
|
+
| [Google](/providers/ai-sdk-providers/google#embedding-models) | `gemini-embedding-001` | 3072 | <Cross /> |
|
|
228
|
+
| [Google](/providers/ai-sdk-providers/google#embedding-models) | `gemini-embedding-2` | 3072 | <Check /> |
|
|
229
|
+
| [Google](/providers/ai-sdk-providers/google#embedding-models) | `gemini-embedding-2-preview` | 3072 | <Check /> |
|
|
230
|
+
| [Mistral](/providers/ai-sdk-providers/mistral#embedding-models) | `mistral-embed` | 1024 | <Cross /> |
|
|
231
|
+
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-english-v3.0` | 1024 | <Cross /> |
|
|
232
|
+
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-multilingual-v3.0` | 1024 | <Cross /> |
|
|
233
|
+
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-english-light-v3.0` | 384 | <Cross /> |
|
|
234
|
+
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-multilingual-light-v3.0` | 384 | <Cross /> |
|
|
235
|
+
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-english-v2.0` | 4096 | <Cross /> |
|
|
236
|
+
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-english-light-v2.0` | 1024 | <Cross /> |
|
|
237
|
+
| [Cohere](/providers/ai-sdk-providers/cohere#embedding-models) | `embed-multilingual-v2.0` | 768 | <Cross /> |
|
|
238
|
+
| [Amazon Bedrock](/providers/ai-sdk-providers/amazon-bedrock#embedding-models) | `amazon.titan-embed-text-v1` | 1536 | <Cross /> |
|
|
239
|
+
| [Amazon Bedrock](/providers/ai-sdk-providers/amazon-bedrock#embedding-models) | `amazon.titan-embed-text-v2:0` | 1024 | <Cross /> |
|
|
@@ -194,11 +194,11 @@ const { video } = await generateVideo({
|
|
|
194
194
|
});
|
|
195
195
|
```
|
|
196
196
|
|
|
197
|
-
### Reference
|
|
197
|
+
### Reference Inputs
|
|
198
198
|
|
|
199
199
|
Some video models support reference-to-video generation, where you provide one or
|
|
200
|
-
more reference images that the model incorporates into the generated video. Use the `inputReferences` option to pass
|
|
201
|
-
these
|
|
200
|
+
more reference images or videos that the model incorporates into the generated video. Use the `inputReferences` option to pass
|
|
201
|
+
these inputs in a provider-agnostic way:
|
|
202
202
|
|
|
203
203
|
```tsx highlight={"5-8"}
|
|
204
204
|
const { video } = await generateVideo({
|
|
@@ -211,6 +211,25 @@ const { video } = await generateVideo({
|
|
|
211
211
|
});
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
+
For URL-based video references, use the object form with an explicit `mediaType`:
|
|
215
|
+
|
|
216
|
+
```tsx highlight={"5-10"}
|
|
217
|
+
const { video } = await generateVideo({
|
|
218
|
+
model: __VIDEO_MODEL__,
|
|
219
|
+
prompt: 'Match the motion in the reference clip',
|
|
220
|
+
inputReferences: [
|
|
221
|
+
{
|
|
222
|
+
data: 'https://example.com/reference.mp4',
|
|
223
|
+
mediaType: 'video/mp4',
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Providers route each reference by its media type (image vs. video) and emit a
|
|
230
|
+
warning when a reference kind is unsupported (for example, providers that accept
|
|
231
|
+
only image references warn and ignore a video reference).
|
|
232
|
+
|
|
214
233
|
### Providing a Seed
|
|
215
234
|
|
|
216
235
|
You can provide a seed to the `experimental_generateVideo` function to control the output of the video generation process.
|
|
@@ -13,34 +13,7 @@ results while a preconfigured harness powers these results.
|
|
|
13
13
|
|
|
14
14
|
Install the core harness package, a harness adapter, and a sandbox provider:
|
|
15
15
|
|
|
16
|
-
<
|
|
17
|
-
<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
|
|
18
|
-
<Tab>
|
|
19
|
-
<Snippet
|
|
20
|
-
text="pnpm add @ai-sdk/harness @ai-sdk/harness-claude-code @ai-sdk/sandbox-vercel"
|
|
21
|
-
dark
|
|
22
|
-
/>
|
|
23
|
-
</Tab>
|
|
24
|
-
<Tab>
|
|
25
|
-
<Snippet
|
|
26
|
-
text="npm install @ai-sdk/harness @ai-sdk/harness-claude-code @ai-sdk/sandbox-vercel"
|
|
27
|
-
dark
|
|
28
|
-
/>
|
|
29
|
-
</Tab>
|
|
30
|
-
<Tab>
|
|
31
|
-
<Snippet
|
|
32
|
-
text="yarn add @ai-sdk/harness @ai-sdk/harness-claude-code @ai-sdk/sandbox-vercel"
|
|
33
|
-
dark
|
|
34
|
-
/>
|
|
35
|
-
</Tab>
|
|
36
|
-
<Tab>
|
|
37
|
-
<Snippet
|
|
38
|
-
text="bun add @ai-sdk/harness @ai-sdk/harness-claude-code @ai-sdk/sandbox-vercel"
|
|
39
|
-
dark
|
|
40
|
-
/>
|
|
41
|
-
</Tab>
|
|
42
|
-
</Tabs>
|
|
43
|
-
</div>
|
|
16
|
+
<InstallPackages packages="@ai-sdk/harness @ai-sdk/harness-claude-code @ai-sdk/sandbox-vercel" />
|
|
44
17
|
|
|
45
18
|
Bridge-backed harnesses such as Claude Code and Codex require using real network sandbox
|
|
46
19
|
like `@ai-sdk/sandbox-vercel`. Host-runtime harnesses such as Pi can also run with
|
|
@@ -28,10 +28,10 @@ The AI SDK includes the following harness adapters:
|
|
|
28
28
|
|
|
29
29
|
## Adapter Capabilities
|
|
30
30
|
|
|
31
|
-
| Adapter | Runtime location | Custom tools
|
|
32
|
-
| ------------------------------------------------------ | ---------------- |
|
|
33
|
-
| [Claude Code](/providers/ai-sdk-harnesses/claude-code) | Sandbox bridge | <Check
|
|
34
|
-
| [Codex](/providers/ai-sdk-harnesses/codex) | Sandbox bridge | <Check
|
|
35
|
-
| [Deep Agents](/providers/ai-sdk-harnesses/deepagents) | Sandbox bridge | <Check
|
|
36
|
-
| [OpenCode](/providers/ai-sdk-harnesses/opencode) | Sandbox bridge | <Check
|
|
37
|
-
| [Pi](/providers/ai-sdk-harnesses/pi) | Host process | <Check
|
|
31
|
+
| Adapter | Runtime location | Custom tools | Custom skills | Built-in tool approval | Built-in tool filtering |
|
|
32
|
+
| ------------------------------------------------------ | ---------------- | ------------ | ------------- | ---------------------- | ---------------------------- |
|
|
33
|
+
| [Claude Code](/providers/ai-sdk-harnesses/claude-code) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> |
|
|
34
|
+
| [Codex](/providers/ai-sdk-harnesses/codex) | Sandbox bridge | <Check /> | <Check /> | <Cross /> | <Cross /> |
|
|
35
|
+
| [Deep Agents](/providers/ai-sdk-harnesses/deepagents) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> via auto-rejection |
|
|
36
|
+
| [OpenCode](/providers/ai-sdk-harnesses/opencode) | Sandbox bridge | <Check /> | <Check /> | <Check /> | <Check /> via auto-rejection |
|
|
37
|
+
| [Pi](/providers/ai-sdk-harnesses/pi) | Host process | <Check /> | <Check /> | <Check /> | <Check /> |
|
|
@@ -18,22 +18,7 @@ integration.
|
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
20
20
|
|
|
21
|
-
<
|
|
22
|
-
<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
|
|
23
|
-
<Tab>
|
|
24
|
-
<Snippet text="pnpm add @ai-sdk/workflow-harness workflow" dark />
|
|
25
|
-
</Tab>
|
|
26
|
-
<Tab>
|
|
27
|
-
<Snippet text="npm install @ai-sdk/workflow-harness workflow" dark />
|
|
28
|
-
</Tab>
|
|
29
|
-
<Tab>
|
|
30
|
-
<Snippet text="yarn add @ai-sdk/workflow-harness workflow" dark />
|
|
31
|
-
</Tab>
|
|
32
|
-
<Tab>
|
|
33
|
-
<Snippet text="bun add @ai-sdk/workflow-harness workflow" dark />
|
|
34
|
-
</Tab>
|
|
35
|
-
</Tabs>
|
|
36
|
-
</div>
|
|
21
|
+
<InstallPackages packages="@ai-sdk/workflow-harness workflow" />
|
|
37
22
|
|
|
38
23
|
Install the core harness package, a harness adapter, and a sandbox provider as
|
|
39
24
|
shown in [HarnessAgent](/docs/ai-sdk-harnesses/harness-agent).
|
|
@@ -12,34 +12,7 @@ session for the lifetime of the terminal UI.
|
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
|
-
<
|
|
16
|
-
<Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
|
|
17
|
-
<Tab>
|
|
18
|
-
<Snippet
|
|
19
|
-
text="pnpm add @ai-sdk/tui @ai-sdk/harness @ai-sdk/harness-codex @ai-sdk/sandbox-vercel"
|
|
20
|
-
dark
|
|
21
|
-
/>
|
|
22
|
-
</Tab>
|
|
23
|
-
<Tab>
|
|
24
|
-
<Snippet
|
|
25
|
-
text="npm install @ai-sdk/tui @ai-sdk/harness @ai-sdk/harness-codex @ai-sdk/sandbox-vercel"
|
|
26
|
-
dark
|
|
27
|
-
/>
|
|
28
|
-
</Tab>
|
|
29
|
-
<Tab>
|
|
30
|
-
<Snippet
|
|
31
|
-
text="yarn add @ai-sdk/tui @ai-sdk/harness @ai-sdk/harness-codex @ai-sdk/sandbox-vercel"
|
|
32
|
-
dark
|
|
33
|
-
/>
|
|
34
|
-
</Tab>
|
|
35
|
-
<Tab>
|
|
36
|
-
<Snippet
|
|
37
|
-
text="bun add @ai-sdk/tui @ai-sdk/harness @ai-sdk/harness-codex @ai-sdk/sandbox-vercel"
|
|
38
|
-
dark
|
|
39
|
-
/>
|
|
40
|
-
</Tab>
|
|
41
|
-
</Tabs>
|
|
42
|
-
</div>
|
|
15
|
+
<InstallPackages packages="@ai-sdk/tui @ai-sdk/harness @ai-sdk/harness-codex @ai-sdk/sandbox-vercel" />
|
|
43
16
|
|
|
44
17
|
## Example
|
|
45
18
|
|
|
@@ -24,11 +24,11 @@ Here is a comparison of the supported functions across these frameworks:
|
|
|
24
24
|
|
|
25
25
|
| | [useChat](/docs/reference/ai-sdk-ui/use-chat) | [useCompletion](/docs/reference/ai-sdk-ui/use-completion) | [useObject](/docs/reference/ai-sdk-ui/use-object) | [MCP Apps](/docs/ai-sdk-core/mcp-apps) |
|
|
26
26
|
| --------------------------------------------------------------- | --------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------- | -------------------------------------- |
|
|
27
|
-
| React `@ai-sdk/react` | <Check
|
|
28
|
-
| Vue.js `@ai-sdk/vue` | <Check
|
|
29
|
-
| Svelte `@ai-sdk/svelte` | <Check
|
|
30
|
-
| Angular `@ai-sdk/angular` | <Check
|
|
31
|
-
| [SolidJS](https://github.com/kodehort/ai-sdk-solid) (community) | <Check
|
|
27
|
+
| React `@ai-sdk/react` | <Check /> | <Check /> | <Check /> | <Check /> |
|
|
28
|
+
| Vue.js `@ai-sdk/vue` | <Check /> | <Check /> | <Check /> | <Cross /> |
|
|
29
|
+
| Svelte `@ai-sdk/svelte` | <Check /> Chat | <Check /> Completion | <Check /> StructuredObject | <Cross /> |
|
|
30
|
+
| Angular `@ai-sdk/angular` | <Check /> Chat | <Check /> Completion | <Check /> StructuredObject | <Cross /> |
|
|
31
|
+
| [SolidJS](https://github.com/kodehort/ai-sdk-solid) (community) | <Check /> | <Check /> | <Check /> | <Cross /> |
|
|
32
32
|
|
|
33
33
|
## Framework Examples
|
|
34
34
|
|
|
@@ -811,7 +811,7 @@ To see `generateText` in action, check out [these examples](#examples).
|
|
|
811
811
|
],
|
|
812
812
|
},
|
|
813
813
|
{
|
|
814
|
-
name: '
|
|
814
|
+
name: 'repairToolCall',
|
|
815
815
|
type: '(options: ToolCallRepairOptions) => Promise<LanguageModelV4ToolCall | null>',
|
|
816
816
|
isOptional: true,
|
|
817
817
|
description:
|
|
@@ -855,7 +855,7 @@ To see `streamText` in action, check out [these examples](#examples).
|
|
|
855
855
|
],
|
|
856
856
|
},
|
|
857
857
|
{
|
|
858
|
-
name: '
|
|
858
|
+
name: 'repairToolCall',
|
|
859
859
|
type: '(options: ToolCallRepairOptions) => Promise<LanguageModelV4ToolCall | null>',
|
|
860
860
|
isOptional: true,
|
|
861
861
|
description:
|
|
@@ -118,9 +118,10 @@ console.log(videos);
|
|
|
118
118
|
},
|
|
119
119
|
{
|
|
120
120
|
name: 'inputReferences',
|
|
121
|
-
type: 'Array<DataContent>',
|
|
121
|
+
type: 'Array<DataContent | { data: DataContent; mediaType?: string }>',
|
|
122
122
|
isOptional: true,
|
|
123
|
-
description:
|
|
123
|
+
description:
|
|
124
|
+
'Reference image or video inputs for reference-to-video generation. Use the object form with an explicit mediaType for URL-based video references. Providers route each reference by its media type and warn when a reference kind is unsupported.',
|
|
124
125
|
},
|
|
125
126
|
{
|
|
126
127
|
name: 'generateAudio',
|
|
@@ -133,7 +133,7 @@ To see `ToolLoopAgent` in action, check out [these examples](#examples).
|
|
|
133
133
|
'Settings for controlling what data is included in step results. requestBody, requestMessages, and responseBody apply to generate(); requestBody, requestMessages, and rawChunks apply to stream().',
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
|
-
name: '
|
|
136
|
+
name: 'repairToolCall',
|
|
137
137
|
type: 'ToolCallRepairFunction',
|
|
138
138
|
isOptional: true,
|
|
139
139
|
description:
|
|
@@ -87,11 +87,11 @@ Here is a comparison of the supported functions across these frameworks:
|
|
|
87
87
|
|
|
88
88
|
| | [useChat](/docs/reference/ai-sdk-ui/use-chat) | [useCompletion](/docs/reference/ai-sdk-ui/use-completion) | [useObject](/docs/reference/ai-sdk-ui/use-object) | [MCP Apps](/docs/ai-sdk-core/mcp-apps) |
|
|
89
89
|
| --------------------------------------------------------------- | --------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------- | -------------------------------------- |
|
|
90
|
-
| React `@ai-sdk/react` | <Check
|
|
91
|
-
| Vue.js `@ai-sdk/vue` | <Check
|
|
92
|
-
| Svelte `@ai-sdk/svelte` | <Check
|
|
93
|
-
| Angular `@ai-sdk/angular` | <Check
|
|
94
|
-
| [SolidJS](https://github.com/kodehort/ai-sdk-solid) (community) | <Check
|
|
90
|
+
| React `@ai-sdk/react` | <Check /> | <Check /> | <Check /> | <Check /> |
|
|
91
|
+
| Vue.js `@ai-sdk/vue` | <Check /> Chat | <Check /> | <Check /> | <Cross /> |
|
|
92
|
+
| Svelte `@ai-sdk/svelte` | <Check /> Chat | <Check /> Completion | <Check /> StructuredObject | <Cross /> |
|
|
93
|
+
| Angular `@ai-sdk/angular` | <Check /> Chat | <Check /> Completion | <Check /> StructuredObject | <Cross /> |
|
|
94
|
+
| [SolidJS](https://github.com/kodehort/ai-sdk-solid) (community) | <Check /> | <Check /> | <Check /> | <Cross /> |
|
|
95
95
|
|
|
96
96
|
<Note>
|
|
97
97
|
[Contributions](https://github.com/vercel/ai/blob/main/CONTRIBUTING.md) are
|
|
@@ -116,7 +116,7 @@ To see `WorkflowAgent` in action, check out [these examples](#examples).
|
|
|
116
116
|
'Default structured output specification. Per-stream values override this default.',
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
|
-
name: '
|
|
119
|
+
name: 'repairToolCall',
|
|
120
120
|
type: 'ToolCallRepairFunction',
|
|
121
121
|
isOptional: true,
|
|
122
122
|
description:
|
|
@@ -528,7 +528,7 @@ const result = await agent.stream({
|
|
|
528
528
|
description: 'Include raw, unprocessed chunks from the provider in the stream. Default: false.',
|
|
529
529
|
},
|
|
530
530
|
{
|
|
531
|
-
name: '
|
|
531
|
+
name: 'repairToolCall',
|
|
532
532
|
type: 'ToolCallRepairFunction',
|
|
533
533
|
isOptional: true,
|
|
534
534
|
description: 'Callback to attempt automatic recovery when a tool call cannot be parsed.',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.20",
|
|
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.
|
|
46
|
-
"@ai-sdk/provider": "4.0.
|
|
47
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
45
|
+
"@ai-sdk/gateway": "4.0.15",
|
|
46
|
+
"@ai-sdk/provider": "4.0.3",
|
|
47
|
+
"@ai-sdk/provider-utils": "5.0.7"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@edge-runtime/vm": "^5.0.0",
|
|
@@ -142,6 +142,13 @@ export type ToolLoopAgentSettings<
|
|
|
142
142
|
/**
|
|
143
143
|
* A function that attempts to repair a tool call that failed to parse.
|
|
144
144
|
*/
|
|
145
|
+
repairToolCall?: ToolCallRepairFunction<NoInfer<TOOLS>>;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* A function that attempts to repair a tool call that failed to parse.
|
|
149
|
+
*
|
|
150
|
+
* @deprecated Use `repairToolCall` instead.
|
|
151
|
+
*/
|
|
145
152
|
experimental_repairToolCall?: ToolCallRepairFunction<NoInfer<TOOLS>>;
|
|
146
153
|
|
|
147
154
|
/**
|
|
@@ -36,8 +36,19 @@ export function collectToolApprovals<TOOLS extends ToolSet>({
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
// gather tool calls and prepare lookup
|
|
40
|
-
|
|
39
|
+
// gather tool calls and prepare lookup.
|
|
40
|
+
//
|
|
41
|
+
// These maps are keyed by client-supplied ids (`toolCallId`, `approvalId`)
|
|
42
|
+
// from the message history. Using `Object.create(null)` gives them no
|
|
43
|
+
// prototype, so an id that matches an inherited object property (e.g.
|
|
44
|
+
// `toString`, `constructor`, `__proto__`) is treated as absent instead of
|
|
45
|
+
// resolving to a prototype value and slipping past the `== null` guards
|
|
46
|
+
// below (which would otherwise skip the InvalidToolApproval /
|
|
47
|
+
// ToolCallNotFound checks).
|
|
48
|
+
const toolCallsByToolCallId: Record<
|
|
49
|
+
string,
|
|
50
|
+
TypedToolCall<TOOLS>
|
|
51
|
+
> = Object.create(null);
|
|
41
52
|
for (const message of messages) {
|
|
42
53
|
if (message.role === 'assistant' && typeof message.content !== 'string') {
|
|
43
54
|
const content = message.content;
|
|
@@ -51,7 +62,7 @@ export function collectToolApprovals<TOOLS extends ToolSet>({
|
|
|
51
62
|
|
|
52
63
|
// gather approval responses and prepare lookup
|
|
53
64
|
const toolApprovalRequestsByApprovalId: Record<string, ToolApprovalRequest> =
|
|
54
|
-
|
|
65
|
+
Object.create(null);
|
|
55
66
|
for (const message of messages) {
|
|
56
67
|
if (message.role === 'assistant' && typeof message.content !== 'string') {
|
|
57
68
|
const content = message.content;
|
|
@@ -64,7 +75,9 @@ export function collectToolApprovals<TOOLS extends ToolSet>({
|
|
|
64
75
|
}
|
|
65
76
|
|
|
66
77
|
// gather tool results from the last tool message
|
|
67
|
-
const toolResults: Record<string, TypedToolResult<TOOLS>> =
|
|
78
|
+
const toolResults: Record<string, TypedToolResult<TOOLS>> = Object.create(
|
|
79
|
+
null,
|
|
80
|
+
);
|
|
68
81
|
for (const part of lastMessage.content) {
|
|
69
82
|
if (part.type === 'tool-result') {
|
|
70
83
|
toolResults[part.toolCallId] = part as TypedToolResult<TOOLS>;
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
type TimeoutConfiguration,
|
|
14
14
|
} from '../prompt/request-options';
|
|
15
15
|
import type { TelemetryDispatcher } from '../telemetry/telemetry';
|
|
16
|
+
import { getOwn } from '../util/get-own';
|
|
16
17
|
import { mergeAbortSignals } from '../util/merge-abort-signals';
|
|
17
18
|
import { notify } from '../util/notify';
|
|
18
19
|
import { now } from '../util/now';
|
|
@@ -83,7 +84,7 @@ export async function executeToolCall<TOOLS extends ToolSet>({
|
|
|
83
84
|
| undefined
|
|
84
85
|
> {
|
|
85
86
|
const { toolName, toolCallId, input } = toolCall;
|
|
86
|
-
const tool = tools
|
|
87
|
+
const tool = getOwn(tools, toolName);
|
|
87
88
|
|
|
88
89
|
if (!isExecutableTool(tool)) {
|
|
89
90
|
return undefined;
|
|
@@ -91,7 +92,7 @@ export async function executeToolCall<TOOLS extends ToolSet>({
|
|
|
91
92
|
|
|
92
93
|
const context = await validateToolContext({
|
|
93
94
|
toolName,
|
|
94
|
-
context: toolsContext
|
|
95
|
+
context: getOwn(toolsContext, toolName),
|
|
95
96
|
contextSchema: tool.contextSchema,
|
|
96
97
|
});
|
|
97
98
|
|
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
} from '@ai-sdk/provider-utils';
|
|
10
10
|
import type { TimeoutConfiguration } from '../prompt/request-options';
|
|
11
11
|
import type { Telemetry, TelemetryDispatcher } from '../telemetry/telemetry';
|
|
12
|
+
import { getOwn } from '../util/get-own';
|
|
12
13
|
import { executeToolCall } from './execute-tool-call';
|
|
13
14
|
import { resolveToolApproval } from './resolve-tool-approval';
|
|
14
15
|
import type { LanguageModelStreamPart } from './stream-language-model-call';
|
|
@@ -95,7 +96,7 @@ export function executeToolsFromStream<
|
|
|
95
96
|
return;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
|
-
const tool = tools
|
|
99
|
+
const tool = getOwn(tools, chunk.toolName);
|
|
99
100
|
|
|
100
101
|
if (tool == null) {
|
|
101
102
|
// ignore tool calls for tools that are not available,
|