You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(ai): add onStepFinish to agent.generate and agent.stream (#11980)
## Background
For things such as token tracking, it would be helpful if callbacks can
be registered on a per-call basis. See #11468
## Summary
Add `onStepFinish` callback support to `Agent.generate()` and
`Agent.stream()`
## Related Issues
Resolves#11468
You can also define `onStepFinish` in the constructor for agent-wide tracking. When both constructor and method callbacks are provided, both are called (constructor first, then the method callback):
351
+
352
+
```ts
353
+
const agent =newToolLoopAgent({
354
+
model: __MODEL__,
355
+
onStepFinish: async ({ usage }) => {
356
+
// Agent-wide logging
357
+
console.log('Agent step:', usage.totalTokens);
358
+
},
359
+
});
360
+
361
+
// Method-level callback runs after constructor callback
362
+
const result =awaitagent.generate({
363
+
prompt: 'Hello',
364
+
onStepFinish: async ({ usage }) => {
365
+
// Per-call tracking (e.g., for billing)
366
+
awaittrackUsage(usage);
367
+
},
368
+
});
369
+
```
370
+
332
371
## End-to-end Type Safety
333
372
334
373
You can infer types for your agent's `UIMessage`s:
Both `generate()` and `stream()` accept an `AgentCallParameters<CALL_OPTIONS>` object with:
138
+
Both `generate()` and `stream()` accept an `AgentCallParameters<CALL_OPTIONS, TOOLS>` object with:
133
139
134
140
-`prompt` (optional): A string prompt or array of `ModelMessage` objects
135
141
-`messages` (optional): An array of `ModelMessage` objects (mutually exclusive with `prompt`)
136
142
-`options` (optional): Additional call options when `CALL_OPTIONS` is not `never`
137
143
-`abortSignal` (optional): An `AbortSignal` to cancel the operation
138
144
-`timeout` (optional): A timeout in milliseconds. Can be specified as a number or as an object with a `totalMs` property. The call will be aborted if it takes longer than the specified timeout. Can be used alongside `abortSignal`.
145
+
-`onStepFinish` (optional): A callback invoked after each agent step (LLM/tool call) completes. Useful for tracking token usage or logging.
Copy file name to clipboardExpand all lines: content/docs/07-reference/01-ai-sdk-core/16-tool-loop-agent.mdx
+14Lines changed: 14 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -248,6 +248,13 @@ const result = await agent.generate({
248
248
description:
249
249
'Timeout in milliseconds. Can be specified as a number or as an object with a totalMs property. The call will be aborted if it takes longer than the specified timeout. Can be used alongside abortSignal.',
250
250
},
251
+
{
252
+
name: 'onStepFinish',
253
+
type: 'ToolLoopAgentOnStepFinishCallback',
254
+
isOptional: true,
255
+
description:
256
+
'Callback invoked after each agent step (LLM/tool call) completes. If also specified in the constructor, both callbacks are called (constructor first, then this one).',
257
+
},
251
258
]}
252
259
/>
253
260
@@ -302,6 +309,13 @@ for await (const chunk of stream.textStream) {
302
309
description:
303
310
'Optional stream transformation(s). They are applied in the order provided and must maintain the stream structure. See `streamText` docs for details.',
304
311
},
312
+
{
313
+
name: 'onStepFinish',
314
+
type: 'ToolLoopAgentOnStepFinishCallback',
315
+
isOptional: true,
316
+
description:
317
+
'Callback invoked after each agent step (LLM/tool call) completes. If also specified in the constructor, both callbacks are called (constructor first, then this one).',
0 commit comments