Skip to main content
Sometimes the caller is code, not a person, and prose is the wrong answer. Hand run() a schema and the report comes back with typed output.

Typed output

output takes any AI-SDK FlexibleSchema — a zod schema is the usual one — and the result is validated before it reaches you. T is inferred from the schema, so report.output is typed without a cast. Leave output unset and it costs nothing: no schema is sent, and report.output is simply absent.
The result channel is the one call in a run() that is not guarded — it reaches nothing, so it always comes back. Your own tools are the opposite: every host tool call in an unattended run parks for approval and comes back denied, so a typed run answers from the model and whatever you put in the task.
status is "ok", "error", or "stopped". Check it before you trust output — a run that was aborted or hit its maxToolCalls budget is "stopped", and it still returns a report.

Meter on usage

Every report carries the run’s token totals. This is the number to bill, budget, and alert on — nothing else in the SDK counts for you.
report.toolCalls is the other half of the picture: the calls the run attempted, in order, each with the outcome the guard returned. A run that came back "ok" with zero tool calls answered from the model alone.

Cancel it

There is no cancel(). Cancellation is an AbortSignal, the same as everywhere else on the platform:
An aborted run still returns a report — the summary, the calls it made, and the usage it spent are all preserved.

Ship it as a product surface

The same run, streamed to a screen you built.

Reference

Every field on AgentReport, including refs and usage.