ai 6.0.141 → 6.0.142
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 +8 -0
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -1
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index.mjs +1 -1
- package/docs/03-agents/01-overview.mdx +1 -3
- package/docs/03-agents/02-building-agents.mdx +3 -4
- package/docs/03-agents/04-loop-control.mdx +35 -2
- package/docs/03-agents/06-memory.mdx +1 -2
- package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +8 -0
- package/docs/03-ai-sdk-core/35-image-generation.mdx +18 -18
- package/docs/03-ai-sdk-core/38-video-generation.mdx +24 -24
- package/docs/07-reference/01-ai-sdk-core/10-generate-image.mdx +2 -1
- package/docs/07-reference/01-ai-sdk-core/13-generate-video.mdx +2 -1
- package/docs/07-reference/01-ai-sdk-core/72-loop-finished.mdx +83 -0
- package/docs/07-reference/01-ai-sdk-core/index.mdx +18 -0
- package/package.json +2 -2
- package/src/generate-text/index.ts +6 -1
- package/src/generate-text/stop-condition.ts +4 -0
package/dist/internal/index.js
CHANGED
|
@@ -153,7 +153,7 @@ var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
|
|
153
153
|
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
154
154
|
|
|
155
155
|
// src/version.ts
|
|
156
|
-
var VERSION = true ? "6.0.
|
|
156
|
+
var VERSION = true ? "6.0.142" : "0.0.0-test";
|
|
157
157
|
|
|
158
158
|
// src/util/download/download.ts
|
|
159
159
|
var download = async ({
|
package/dist/internal/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ These components work together:
|
|
|
20
20
|
The ToolLoopAgent class handles these three components. Here's an agent that uses multiple tools in a loop to accomplish a task:
|
|
21
21
|
|
|
22
22
|
```ts
|
|
23
|
-
import { ToolLoopAgent,
|
|
23
|
+
import { ToolLoopAgent, tool } from 'ai';
|
|
24
24
|
__PROVIDER_IMPORT__;
|
|
25
25
|
import { z } from 'zod';
|
|
26
26
|
|
|
@@ -48,8 +48,6 @@ const weatherAgent = new ToolLoopAgent({
|
|
|
48
48
|
},
|
|
49
49
|
}),
|
|
50
50
|
},
|
|
51
|
-
// Agent's default behavior is to stop after a maximum of 20 steps
|
|
52
|
-
// stopWhen: stepCountIs(20),
|
|
53
51
|
});
|
|
54
52
|
|
|
55
53
|
const result = await weatherAgent.generate({
|
|
@@ -81,7 +81,7 @@ const codeAgent = new ToolLoopAgent({
|
|
|
81
81
|
|
|
82
82
|
By default, agents run for 20 steps (`stopWhen: stepCountIs(20)`). In each step, the model either generates text or calls a tool. If it generates text, the agent completes. If it calls a tool, the AI SDK executes that tool.
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
You can configure `stopWhen` differently to allow more steps. After each tool execution, the agent triggers a new generation where the model can call another tool or generate text:
|
|
85
85
|
|
|
86
86
|
```ts
|
|
87
87
|
import { ToolLoopAgent, stepCountIs } from 'ai';
|
|
@@ -89,7 +89,7 @@ __PROVIDER_IMPORT__;
|
|
|
89
89
|
|
|
90
90
|
const agent = new ToolLoopAgent({
|
|
91
91
|
model: __MODEL__,
|
|
92
|
-
stopWhen: stepCountIs(
|
|
92
|
+
stopWhen: stepCountIs(50), // Increase default from 20 to 50.
|
|
93
93
|
});
|
|
94
94
|
```
|
|
95
95
|
|
|
@@ -160,7 +160,7 @@ const agent = new ToolLoopAgent({
|
|
|
160
160
|
Define structured output schemas:
|
|
161
161
|
|
|
162
162
|
```ts
|
|
163
|
-
import { ToolLoopAgent, Output
|
|
163
|
+
import { ToolLoopAgent, Output } from 'ai';
|
|
164
164
|
__PROVIDER_IMPORT__;
|
|
165
165
|
import { z } from 'zod';
|
|
166
166
|
|
|
@@ -173,7 +173,6 @@ const analysisAgent = new ToolLoopAgent({
|
|
|
173
173
|
keyPoints: z.array(z.string()),
|
|
174
174
|
}),
|
|
175
175
|
}),
|
|
176
|
-
stopWhen: stepCountIs(10),
|
|
177
176
|
});
|
|
178
177
|
|
|
179
178
|
const { output } = await analysisAgent.generate({
|
|
@@ -16,7 +16,7 @@ The AI SDK provides built-in loop control through two parameters: `stopWhen` for
|
|
|
16
16
|
|
|
17
17
|
## Stop Conditions
|
|
18
18
|
|
|
19
|
-
The `stopWhen` parameter controls when to stop execution when there are tool results in the last step. By default, agents stop after 20 steps using `stepCountIs(20)`.
|
|
19
|
+
The `stopWhen` parameter controls when to stop execution when there are tool results in the last step. By default, agents stop after 20 steps using `stepCountIs(20)`. This default is a safety measure to prevent runaway loops that could result in excessive API calls and costs.
|
|
20
20
|
|
|
21
21
|
When you provide `stopWhen`, the agent continues executing after tool calls until a stopping condition is met. When the condition is an array, execution stops when any of the conditions are met.
|
|
22
22
|
|
|
@@ -24,6 +24,12 @@ When you provide `stopWhen`, the agent continues executing after tool calls unti
|
|
|
24
24
|
|
|
25
25
|
The AI SDK provides several built-in stopping conditions:
|
|
26
26
|
|
|
27
|
+
- `stepCountIs(count)` — stops after a specified number of steps
|
|
28
|
+
- `hasToolCall(toolName)` — stops when a specific tool is called
|
|
29
|
+
- `isLoopFinished()` — never triggers, letting the loop run until the agent is naturally finished
|
|
30
|
+
|
|
31
|
+
### Run Up to a Maximum Number of Steps
|
|
32
|
+
|
|
27
33
|
```ts
|
|
28
34
|
import { ToolLoopAgent, stepCountIs } from 'ai';
|
|
29
35
|
__PROVIDER_IMPORT__;
|
|
@@ -33,7 +39,28 @@ const agent = new ToolLoopAgent({
|
|
|
33
39
|
tools: {
|
|
34
40
|
// your tools
|
|
35
41
|
},
|
|
36
|
-
stopWhen: stepCountIs(
|
|
42
|
+
stopWhen: stepCountIs(50), // Increasing the default of 20 to 50.
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const result = await agent.generate({
|
|
46
|
+
prompt: 'Analyze this dataset and create a summary report',
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Run Until Finished
|
|
51
|
+
|
|
52
|
+
If you want the agent to run until the model naturally stops making tool calls, use `isLoopFinished()`. This removes the default step limit:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { ToolLoopAgent, isLoopFinished } from 'ai';
|
|
56
|
+
__PROVIDER_IMPORT__;
|
|
57
|
+
|
|
58
|
+
const agent = new ToolLoopAgent({
|
|
59
|
+
model: __MODEL__,
|
|
60
|
+
tools: {
|
|
61
|
+
// your tools
|
|
62
|
+
},
|
|
63
|
+
stopWhen: isLoopFinished(), // No maximum step limit.
|
|
37
64
|
});
|
|
38
65
|
|
|
39
66
|
const result = await agent.generate({
|
|
@@ -41,6 +68,12 @@ const result = await agent.generate({
|
|
|
41
68
|
});
|
|
42
69
|
```
|
|
43
70
|
|
|
71
|
+
<Note>
|
|
72
|
+
Use `isLoopFinished()` with caution. Without a step limit, the agent could
|
|
73
|
+
potentially run indefinitely or incur significant costs if the model keeps
|
|
74
|
+
making tool calls.
|
|
75
|
+
</Note>
|
|
76
|
+
|
|
44
77
|
### Combine Multiple Conditions
|
|
45
78
|
|
|
46
79
|
Combine multiple stopping conditions. The loop stops when it meets any condition:
|
|
@@ -187,7 +187,7 @@ pnpm add @vectorize-io/hindsight-ai-sdk @vectorize-io/hindsight-client
|
|
|
187
187
|
__PROVIDER_IMPORT__;
|
|
188
188
|
import { HindsightClient } from '@vectorize-io/hindsight-client';
|
|
189
189
|
import { createHindsightTools } from '@vectorize-io/hindsight-ai-sdk';
|
|
190
|
-
import { ToolLoopAgent
|
|
190
|
+
import { ToolLoopAgent } from 'ai';
|
|
191
191
|
import { openai } from '@ai-sdk/openai';
|
|
192
192
|
|
|
193
193
|
const client = new HindsightClient({ baseUrl: process.env.HINDSIGHT_API_URL });
|
|
@@ -195,7 +195,6 @@ const client = new HindsightClient({ baseUrl: process.env.HINDSIGHT_API_URL });
|
|
|
195
195
|
const agent = new ToolLoopAgent({
|
|
196
196
|
model: __MODEL__,
|
|
197
197
|
tools: createHindsightTools({ client, bankId: 'user-123' }),
|
|
198
|
-
stopWhen: stepCountIs(10),
|
|
199
198
|
instructions: 'You are a helpful assistant with long-term memory.',
|
|
200
199
|
});
|
|
201
200
|
|
|
@@ -226,6 +226,14 @@ When using `useChat`, the approval flow is handled through UI state. See [Chatbo
|
|
|
226
226
|
|
|
227
227
|
With the `stopWhen` setting, you can enable multi-step calls in `generateText` and `streamText`. When `stopWhen` is set and the model generates a tool call, the AI SDK will trigger a new generation passing in the tool result until there are no further tool calls or the stopping condition is met.
|
|
228
228
|
|
|
229
|
+
The AI SDK provides several built-in stopping conditions:
|
|
230
|
+
|
|
231
|
+
- `stepCountIs(count)` — stops after a specified number of steps (default: `stepCountIs(20)`)
|
|
232
|
+
- `hasToolCall(toolName)` — stops when a specific tool is called
|
|
233
|
+
- `isLoopFinished()` — never triggers, letting the loop run until naturally finished
|
|
234
|
+
|
|
235
|
+
You can also combine multiple conditions in an array or create custom conditions. See [Loop Control](/docs/agents/loop-control) for more details.
|
|
236
|
+
|
|
229
237
|
<Note>
|
|
230
238
|
The `stopWhen` conditions are only evaluated when the last step contains tool
|
|
231
239
|
results.
|
|
@@ -10,10 +10,10 @@ function to generate images based on a given prompt using an image model.
|
|
|
10
10
|
|
|
11
11
|
```tsx
|
|
12
12
|
import { generateImage } from 'ai';
|
|
13
|
-
|
|
13
|
+
__PROVIDER_IMPORT__;
|
|
14
14
|
|
|
15
15
|
const { image } = await generateImage({
|
|
16
|
-
model:
|
|
16
|
+
model: __IMAGE_MODEL__,
|
|
17
17
|
prompt: 'Santa Claus driving a Cadillac',
|
|
18
18
|
});
|
|
19
19
|
```
|
|
@@ -38,10 +38,10 @@ Models only support a few sizes, and the supported sizes are different for each
|
|
|
38
38
|
|
|
39
39
|
```tsx highlight={"7"}
|
|
40
40
|
import { generateImage } from 'ai';
|
|
41
|
-
|
|
41
|
+
__PROVIDER_IMPORT__;
|
|
42
42
|
|
|
43
43
|
const { image } = await generateImage({
|
|
44
|
-
model:
|
|
44
|
+
model: __IMAGE_MODEL__,
|
|
45
45
|
prompt: 'Santa Claus driving a Cadillac',
|
|
46
46
|
size: '1024x1024',
|
|
47
47
|
});
|
|
@@ -54,10 +54,10 @@ Models only support a few aspect ratios, and the supported aspect ratios are dif
|
|
|
54
54
|
|
|
55
55
|
```tsx highlight={"7"}
|
|
56
56
|
import { generateImage } from 'ai';
|
|
57
|
-
|
|
57
|
+
__PROVIDER_IMPORT__;
|
|
58
58
|
|
|
59
59
|
const { image } = await generateImage({
|
|
60
|
-
model:
|
|
60
|
+
model: __IMAGE_MODEL__,
|
|
61
61
|
prompt: 'Santa Claus driving a Cadillac',
|
|
62
62
|
aspectRatio: '16:9',
|
|
63
63
|
});
|
|
@@ -69,10 +69,10 @@ const { image } = await generateImage({
|
|
|
69
69
|
|
|
70
70
|
```tsx highlight={"7"}
|
|
71
71
|
import { generateImage } from 'ai';
|
|
72
|
-
|
|
72
|
+
__PROVIDER_IMPORT__;
|
|
73
73
|
|
|
74
74
|
const { images } = await generateImage({
|
|
75
|
-
model:
|
|
75
|
+
model: __IMAGE_MODEL__,
|
|
76
76
|
prompt: 'Santa Claus driving a Cadillac',
|
|
77
77
|
n: 4, // number of images to generate
|
|
78
78
|
});
|
|
@@ -89,7 +89,7 @@ If needed, you can override this behavior using the `maxImagesPerCall` setting w
|
|
|
89
89
|
|
|
90
90
|
```tsx
|
|
91
91
|
const { images } = await generateImage({
|
|
92
|
-
model:
|
|
92
|
+
model: __IMAGE_MODEL__,
|
|
93
93
|
prompt: 'Santa Claus driving a Cadillac',
|
|
94
94
|
maxImagesPerCall: 5, // Override the default batch size
|
|
95
95
|
n: 10, // Will make 2 calls of 5 images each
|
|
@@ -103,10 +103,10 @@ If supported by the model, the same seed will always produce the same image.
|
|
|
103
103
|
|
|
104
104
|
```tsx highlight={"7"}
|
|
105
105
|
import { generateImage } from 'ai';
|
|
106
|
-
|
|
106
|
+
__PROVIDER_IMPORT__;
|
|
107
107
|
|
|
108
108
|
const { image } = await generateImage({
|
|
109
|
-
model:
|
|
109
|
+
model: __IMAGE_MODEL__,
|
|
110
110
|
prompt: 'Santa Claus driving a Cadillac',
|
|
111
111
|
seed: 1234567890,
|
|
112
112
|
});
|
|
@@ -140,11 +140,11 @@ type [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSigna
|
|
|
140
140
|
that you can use to abort the image generation process or set a timeout.
|
|
141
141
|
|
|
142
142
|
```ts highlight={"7"}
|
|
143
|
-
import { openai } from '@ai-sdk/openai';
|
|
144
143
|
import { generateImage } from 'ai';
|
|
144
|
+
__PROVIDER_IMPORT__;
|
|
145
145
|
|
|
146
146
|
const { image } = await generateImage({
|
|
147
|
-
model:
|
|
147
|
+
model: __IMAGE_MODEL__,
|
|
148
148
|
prompt: 'Santa Claus driving a Cadillac',
|
|
149
149
|
abortSignal: AbortSignal.timeout(1000), // Abort after 1 second
|
|
150
150
|
});
|
|
@@ -156,11 +156,11 @@ const { image } = await generateImage({
|
|
|
156
156
|
that you can use to add custom headers to the image generation request.
|
|
157
157
|
|
|
158
158
|
```ts highlight={"7"}
|
|
159
|
-
import { openai } from '@ai-sdk/openai';
|
|
160
159
|
import { generateImage } from 'ai';
|
|
160
|
+
__PROVIDER_IMPORT__;
|
|
161
161
|
|
|
162
162
|
const { image } = await generateImage({
|
|
163
|
-
model:
|
|
163
|
+
model: __IMAGE_MODEL__,
|
|
164
164
|
prompt: 'Santa Claus driving a Cadillac',
|
|
165
165
|
headers: { 'X-Custom-Header': 'custom-value' },
|
|
166
166
|
});
|
|
@@ -172,7 +172,7 @@ If the model returns warnings, e.g. for unsupported parameters, they will be ava
|
|
|
172
172
|
|
|
173
173
|
```tsx
|
|
174
174
|
const { image, warnings } = await generateImage({
|
|
175
|
-
model:
|
|
175
|
+
model: __IMAGE_MODEL__,
|
|
176
176
|
prompt: 'Santa Claus driving a Cadillac',
|
|
177
177
|
});
|
|
178
178
|
```
|
|
@@ -236,10 +236,10 @@ Here is an example that sets a default size when none is provided:
|
|
|
236
236
|
|
|
237
237
|
```ts
|
|
238
238
|
import { generateImage, wrapImageModel } from 'ai';
|
|
239
|
-
|
|
239
|
+
__PROVIDER_IMPORT__;
|
|
240
240
|
|
|
241
241
|
const model = wrapImageModel({
|
|
242
|
-
model:
|
|
242
|
+
model: __IMAGE_MODEL__,
|
|
243
243
|
middleware: {
|
|
244
244
|
specificationVersion: 'v3',
|
|
245
245
|
transformParams: async ({ params }) => ({
|
|
@@ -15,10 +15,10 @@ function to generate videos based on a given prompt using a video model.
|
|
|
15
15
|
|
|
16
16
|
```tsx
|
|
17
17
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
18
|
-
|
|
18
|
+
__PROVIDER_IMPORT__;
|
|
19
19
|
|
|
20
20
|
const { video } = await generateVideo({
|
|
21
|
-
model:
|
|
21
|
+
model: __VIDEO_MODEL__,
|
|
22
22
|
prompt: 'A cat walking on a treadmill',
|
|
23
23
|
});
|
|
24
24
|
```
|
|
@@ -39,10 +39,10 @@ Models only support a few aspect ratios, and the supported aspect ratios are dif
|
|
|
39
39
|
|
|
40
40
|
```tsx highlight={"7"}
|
|
41
41
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
42
|
-
|
|
42
|
+
__PROVIDER_IMPORT__;
|
|
43
43
|
|
|
44
44
|
const { video } = await generateVideo({
|
|
45
|
-
model:
|
|
45
|
+
model: __VIDEO_MODEL__,
|
|
46
46
|
prompt: 'A cat walking on a treadmill',
|
|
47
47
|
aspectRatio: '16:9',
|
|
48
48
|
});
|
|
@@ -55,10 +55,10 @@ Models only support specific resolutions, and the supported resolutions are diff
|
|
|
55
55
|
|
|
56
56
|
```tsx highlight={"7"}
|
|
57
57
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
58
|
-
|
|
58
|
+
__PROVIDER_IMPORT__;
|
|
59
59
|
|
|
60
60
|
const { video } = await generateVideo({
|
|
61
|
-
model:
|
|
61
|
+
model: __VIDEO_MODEL__,
|
|
62
62
|
prompt: 'A serene mountain landscape at sunset',
|
|
63
63
|
resolution: '1280x720',
|
|
64
64
|
});
|
|
@@ -70,10 +70,10 @@ Some video models support specifying the duration of the generated video in seco
|
|
|
70
70
|
|
|
71
71
|
```tsx highlight={"7"}
|
|
72
72
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
73
|
-
|
|
73
|
+
__PROVIDER_IMPORT__;
|
|
74
74
|
|
|
75
75
|
const { video } = await generateVideo({
|
|
76
|
-
model:
|
|
76
|
+
model: __VIDEO_MODEL__,
|
|
77
77
|
prompt: 'A timelapse of clouds moving across the sky',
|
|
78
78
|
duration: 5,
|
|
79
79
|
});
|
|
@@ -85,10 +85,10 @@ Some video models allow you to specify the frames per second for the generated v
|
|
|
85
85
|
|
|
86
86
|
```tsx highlight={"7"}
|
|
87
87
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
88
|
-
|
|
88
|
+
__PROVIDER_IMPORT__;
|
|
89
89
|
|
|
90
90
|
const { video } = await generateVideo({
|
|
91
|
-
model:
|
|
91
|
+
model: __VIDEO_MODEL__,
|
|
92
92
|
prompt: 'A hummingbird in slow motion',
|
|
93
93
|
fps: 24,
|
|
94
94
|
});
|
|
@@ -100,10 +100,10 @@ const { video } = await generateVideo({
|
|
|
100
100
|
|
|
101
101
|
```tsx highlight={"7"}
|
|
102
102
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
103
|
-
|
|
103
|
+
__PROVIDER_IMPORT__;
|
|
104
104
|
|
|
105
105
|
const { videos } = await generateVideo({
|
|
106
|
-
model:
|
|
106
|
+
model: __VIDEO_MODEL__,
|
|
107
107
|
prompt: 'A rocket launching into space',
|
|
108
108
|
n: 3, // number of videos to generate
|
|
109
109
|
});
|
|
@@ -120,7 +120,7 @@ If needed, you can override this behavior using the `maxVideosPerCall` setting:
|
|
|
120
120
|
|
|
121
121
|
```tsx
|
|
122
122
|
const { videos } = await generateVideo({
|
|
123
|
-
model:
|
|
123
|
+
model: __VIDEO_MODEL__,
|
|
124
124
|
prompt: 'A rocket launching into space',
|
|
125
125
|
maxVideosPerCall: 2, // Override the default batch size
|
|
126
126
|
n: 4, // Will make 2 calls of 2 videos each
|
|
@@ -133,10 +133,10 @@ Some video models support generating videos from an input image. You can provide
|
|
|
133
133
|
|
|
134
134
|
```tsx highlight={"7-10"}
|
|
135
135
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
136
|
-
|
|
136
|
+
__PROVIDER_IMPORT__;
|
|
137
137
|
|
|
138
138
|
const { video } = await generateVideo({
|
|
139
|
-
model:
|
|
139
|
+
model: __VIDEO_MODEL__,
|
|
140
140
|
prompt: {
|
|
141
141
|
image: 'https://example.com/my-image.png',
|
|
142
142
|
text: 'Animate this image with gentle motion',
|
|
@@ -148,7 +148,7 @@ You can also provide the image as a base64-encoded string or `Uint8Array`:
|
|
|
148
148
|
|
|
149
149
|
```tsx
|
|
150
150
|
const { video } = await generateVideo({
|
|
151
|
-
model:
|
|
151
|
+
model: __VIDEO_MODEL__,
|
|
152
152
|
prompt: {
|
|
153
153
|
image: imageBase64String, // or imageUint8Array
|
|
154
154
|
text: 'Animate this image',
|
|
@@ -163,10 +163,10 @@ If supported by the model, the same seed will always produce the same video.
|
|
|
163
163
|
|
|
164
164
|
```tsx highlight={"7"}
|
|
165
165
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
166
|
-
|
|
166
|
+
__PROVIDER_IMPORT__;
|
|
167
167
|
|
|
168
168
|
const { video } = await generateVideo({
|
|
169
|
-
model:
|
|
169
|
+
model: __VIDEO_MODEL__,
|
|
170
170
|
prompt: 'A cat walking on a treadmill',
|
|
171
171
|
seed: 1234567890,
|
|
172
172
|
});
|
|
@@ -200,11 +200,11 @@ type [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSigna
|
|
|
200
200
|
that you can use to abort the video generation process or set a timeout.
|
|
201
201
|
|
|
202
202
|
```ts highlight={"7"}
|
|
203
|
-
import { fal } from '@ai-sdk/fal';
|
|
204
203
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
204
|
+
__PROVIDER_IMPORT__;
|
|
205
205
|
|
|
206
206
|
const { video } = await generateVideo({
|
|
207
|
-
model:
|
|
207
|
+
model: __VIDEO_MODEL__,
|
|
208
208
|
prompt: 'A cat walking on a treadmill',
|
|
209
209
|
abortSignal: AbortSignal.timeout(60000), // Abort after 60 seconds
|
|
210
210
|
});
|
|
@@ -249,11 +249,11 @@ const { video } = await generateVideo({
|
|
|
249
249
|
that you can use to add custom headers to the video generation request.
|
|
250
250
|
|
|
251
251
|
```ts highlight={"7"}
|
|
252
|
-
import { fal } from '@ai-sdk/fal';
|
|
253
252
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
253
|
+
__PROVIDER_IMPORT__;
|
|
254
254
|
|
|
255
255
|
const { video } = await generateVideo({
|
|
256
|
-
model:
|
|
256
|
+
model: __VIDEO_MODEL__,
|
|
257
257
|
prompt: 'A cat walking on a treadmill',
|
|
258
258
|
headers: { 'X-Custom-Header': 'custom-value' },
|
|
259
259
|
});
|
|
@@ -265,7 +265,7 @@ If the model returns warnings, e.g. for unsupported parameters, they will be ava
|
|
|
265
265
|
|
|
266
266
|
```tsx
|
|
267
267
|
const { video, warnings } = await generateVideo({
|
|
268
|
-
model:
|
|
268
|
+
model: __VIDEO_MODEL__,
|
|
269
269
|
prompt: 'A cat walking on a treadmill',
|
|
270
270
|
});
|
|
271
271
|
```
|
|
@@ -298,7 +298,7 @@ When generating multiple videos with `n > 1`, you can also access per-call metad
|
|
|
298
298
|
|
|
299
299
|
```tsx
|
|
300
300
|
const { videos, responses } = await generateVideo({
|
|
301
|
-
model:
|
|
301
|
+
model: __VIDEO_MODEL__,
|
|
302
302
|
prompt: 'A rocket launching into space',
|
|
303
303
|
n: 5, // May require multiple API calls
|
|
304
304
|
});
|
|
@@ -12,9 +12,10 @@ such as creating visual content or generating images for data augmentation.
|
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
14
|
import { generateImage } from 'ai';
|
|
15
|
+
__PROVIDER_IMPORT__;
|
|
15
16
|
|
|
16
17
|
const { images } = await generateImage({
|
|
17
|
-
model:
|
|
18
|
+
model: __IMAGE_MODEL__,
|
|
18
19
|
prompt: 'A futuristic cityscape at sunset',
|
|
19
20
|
n: 3,
|
|
20
21
|
size: '1024x1024',
|
|
@@ -17,9 +17,10 @@ such as creating visual content, animations, or generating videos from images.
|
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
19
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
20
|
+
__PROVIDER_IMPORT__;
|
|
20
21
|
|
|
21
22
|
const { videos } = await generateVideo({
|
|
22
|
-
model:
|
|
23
|
+
model: __VIDEO_MODEL__,
|
|
23
24
|
prompt: 'A cat walking on a treadmill',
|
|
24
25
|
aspectRatio: '16:9',
|
|
25
26
|
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: isLoopFinished
|
|
3
|
+
description: API Reference for isLoopFinished.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `isLoopFinished()`
|
|
7
|
+
|
|
8
|
+
Creates a stop condition that never triggers, letting the agent loop run until it naturally finishes (i.e., the model stops making tool calls).
|
|
9
|
+
|
|
10
|
+
By default, `ToolLoopAgent` uses `stepCountIs(20)` as a safety measure to prevent runaway loops that could result in excessive API calls and costs. If you are confident that your agent will terminate naturally or you are less concerned about costs, `isLoopFinished()` removes that limit and lets the agent run until the model is truly done.
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { ToolLoopAgent, isLoopFinished } from 'ai';
|
|
14
|
+
__PROVIDER_IMPORT__;
|
|
15
|
+
|
|
16
|
+
const agent = new ToolLoopAgent({
|
|
17
|
+
model: __MODEL__,
|
|
18
|
+
tools: {
|
|
19
|
+
// your tools
|
|
20
|
+
},
|
|
21
|
+
stopWhen: isLoopFinished(),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const result = await agent.generate({
|
|
25
|
+
prompt: 'Analyze this dataset and create a summary report',
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Import
|
|
30
|
+
|
|
31
|
+
<Snippet text={`import { isLoopFinished } from "ai"`} prompt={false} />
|
|
32
|
+
|
|
33
|
+
## API Signature
|
|
34
|
+
|
|
35
|
+
### Parameters
|
|
36
|
+
|
|
37
|
+
This function takes no parameters.
|
|
38
|
+
|
|
39
|
+
### Returns
|
|
40
|
+
|
|
41
|
+
A `StopCondition` function that always returns `false`, meaning it never triggers the stop condition. The agent loop will only stop through its natural termination conditions:
|
|
42
|
+
|
|
43
|
+
- The model stops making tool calls, or
|
|
44
|
+
- A tool without an `execute` function is called, or
|
|
45
|
+
- A tool call needs approval
|
|
46
|
+
|
|
47
|
+
## Examples
|
|
48
|
+
|
|
49
|
+
### Basic Usage
|
|
50
|
+
|
|
51
|
+
Let the agent run until it's finished:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { ToolLoopAgent, isLoopFinished } from 'ai';
|
|
55
|
+
|
|
56
|
+
const agent = new ToolLoopAgent({
|
|
57
|
+
model: yourModel,
|
|
58
|
+
tools: yourTools,
|
|
59
|
+
stopWhen: isLoopFinished(),
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Combining with Other Conditions
|
|
64
|
+
|
|
65
|
+
You can combine `isLoopFinished()` with other conditions. Since `isLoopFinished()` never triggers, the other conditions still apply:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { ToolLoopAgent, isLoopFinished, hasToolCall } from 'ai';
|
|
69
|
+
|
|
70
|
+
const agent = new ToolLoopAgent({
|
|
71
|
+
model: yourModel,
|
|
72
|
+
tools: yourTools,
|
|
73
|
+
stopWhen: [isLoopFinished(), hasToolCall('finalAnswer')],
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
In practice, this does not make much sense in this context, since you could just omit `isLoopFinished()`.
|
|
78
|
+
|
|
79
|
+
## See also
|
|
80
|
+
|
|
81
|
+
- [`stepCountIs()`](/docs/reference/ai-sdk-core/step-count-is)
|
|
82
|
+
- [`hasToolCall()`](/docs/reference/ai-sdk-core/has-tool-call)
|
|
83
|
+
- [`ToolLoopAgent`](/docs/reference/ai-sdk-core/tool-loop-agent)
|
|
@@ -130,6 +130,24 @@ It also contains the following helper functions:
|
|
|
130
130
|
'Extracts JSON from text content by stripping markdown code fences.',
|
|
131
131
|
href: '/docs/reference/ai-sdk-core/extract-json-middleware',
|
|
132
132
|
},
|
|
133
|
+
{
|
|
134
|
+
title: 'stepCountIs()',
|
|
135
|
+
description:
|
|
136
|
+
'Creates a stop condition that triggers after a specified number of steps.',
|
|
137
|
+
href: '/docs/reference/ai-sdk-core/step-count-is',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
title: 'hasToolCall()',
|
|
141
|
+
description:
|
|
142
|
+
'Creates a stop condition that triggers when a specific tool is called.',
|
|
143
|
+
href: '/docs/reference/ai-sdk-core/has-tool-call',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
title: 'isLoopFinished()',
|
|
147
|
+
description:
|
|
148
|
+
'Creates a stop condition that lets the agent loop run until it naturally finishes.',
|
|
149
|
+
href: '/docs/reference/ai-sdk-core/loop-finished',
|
|
150
|
+
},
|
|
133
151
|
{
|
|
134
152
|
title: 'simulateStreamingMiddleware()',
|
|
135
153
|
description:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.142",
|
|
4
4
|
"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.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@opentelemetry/api": "1.9.0",
|
|
48
|
-
"@ai-sdk/gateway": "3.0.
|
|
48
|
+
"@ai-sdk/gateway": "3.0.84",
|
|
49
49
|
"@ai-sdk/provider": "3.0.8",
|
|
50
50
|
"@ai-sdk/provider-utils": "4.0.21"
|
|
51
51
|
},
|
|
@@ -24,7 +24,12 @@ export { pruneMessages } from './prune-messages';
|
|
|
24
24
|
export type { ReasoningOutput } from './reasoning-output';
|
|
25
25
|
export { smoothStream, type ChunkDetector } from './smooth-stream';
|
|
26
26
|
export type { StepResult } from './step-result';
|
|
27
|
-
export {
|
|
27
|
+
export {
|
|
28
|
+
hasToolCall,
|
|
29
|
+
isLoopFinished,
|
|
30
|
+
stepCountIs,
|
|
31
|
+
type StopCondition,
|
|
32
|
+
} from './stop-condition';
|
|
28
33
|
export {
|
|
29
34
|
streamText,
|
|
30
35
|
type StreamTextOnChunkCallback,
|
|
@@ -9,6 +9,10 @@ export function stepCountIs(stepCount: number): StopCondition<any> {
|
|
|
9
9
|
return ({ steps }) => steps.length === stepCount;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
export function isLoopFinished(): StopCondition<any> {
|
|
13
|
+
return () => false;
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
export function hasToolCall(toolName: string): StopCondition<any> {
|
|
13
17
|
return ({ steps }) =>
|
|
14
18
|
steps[steps.length - 1]?.toolCalls?.some(
|