WorkflowAgent
API Reference for the WorkflowAgent class.
Creates a durable, resumable AI agent for use inside a workflow. WorkflowAgent handles the agent loop, tool schema serialization across workflow step boundaries, and built-in tool approval flows.
Unlike ToolLoopAgent from the ai package, WorkflowAgent is designed to survive process restarts, pause for human approval, and integrate with the Workflow DevKit's step mechanism.
WorkflowAgent supports runtimeContext for shared agent state and toolsContext for per-tool context. Because these values can cross workflow and step boundaries, keep them serializable durable data. Unlike ToolLoopAgent, do not place functions, class instances, symbols, database clients, or SDK clients in context; pass identifiers or configuration and recreate non-serializable resources inside step functions.
To see WorkflowAgent in action, check out these examples.
Import
import { WorkflowAgent } from "@ai-sdk/workflow"
Constructor
Parameters
id?:
model:
openai('gpt-6-astra')).instructions?:
tools?:
toolChoice?:
stopWhen?:
isStepCount() to bound execution. Per-call values override this default.activeTools?:
output?:
repairToolCall?:
experimental_download?:
experimental_sandbox?:
experimental_sandbox, and exposed to prepareStep. Per-stream values override this default.experimental_toolApprovalSecret?:
prepareStep?:
experimental_sandbox for the current step. Receives step number, previous steps, messages, context, and sandbox.prepareCall?:
tools (bound at construction for type safety).runtimeContext?:
prepareStep, lifecycle callbacks, and step results. Per-stream values override this default. Must be serializable when used in workflows.toolsContext?:
context. Per-stream values override this default. Must be serializable when used in workflows.telemetry?:
onStart?:
stream(), both callbacks fire (constructor first). Takes precedence over experimental_onStart when both are provided in the constructor.model:
messages:
runtimeContext:
toolsContext:
experimental_onStart?:
onStart. Used only when onStart is not provided in the constructor.onStepStart?:
stream(), both callbacks fire (constructor first). Takes precedence over experimental_onStepStart when both are provided in the constructor.model:
messages:
steps:
runtimeContext:
toolsContext:
experimental_onStepStart?:
onStepStart. Used only when onStepStart is not provided in the constructor.onToolExecutionStart?:
stream(), both callbacks fire (constructor first). Experimental (can break in patch releases).toolCall:
stepNumber:
messages:
toolContext:
onToolExecutionEnd?:
success to determine whether output or error is available. If also specified in stream(), both callbacks fire (constructor first). Experimental (can break in patch releases).toolCall:
stepNumber:
durationMs:
durationMs; AI SDK Core generation callbacks use toolExecutionMs.messages:
toolContext:
success:
output?:
success is true and correlated with the configured tool.error?:
success is false.onStepEnd?:
stream(), both callbacks fire (constructor first).onStepFinish?:
onStepEnd instead. This alias is only used as a fallback when onStepEnd is not provided.onEnd?:
stream(), both callbacks fire (constructor first).maxOutputTokens?:
temperature?:
topP?:
topK?:
presencePenalty?:
frequencyPenalty?:
stopSequences?:
seed?:
maxRetries?:
headers?:
providerOptions?:
Properties
id:
tools:
Methods
generate()
Runs the durable agent loop using the model's non-streaming doGenerate() method. Model calls and tool execution use the same orchestration as stream().
Accepts WorkflowAgentGenerateOptions, sharing prompt/messages, instructions, generation settings, tools and runtime context, preparation, stopping, output, and lifecycle options with stream(). It does not accept writable, includeRawChunks, experimental_transform, sendFinish, or preventClose. Without a configured stop condition, generation stops after at most 20 steps. stream() retains its existing unbounded default.
The include option accepts requestBody, responseBody, and requestMessages booleans, all defaulting to false. Enable them only when the additional request/response data is needed. Response IDs, timestamps, model IDs, headers, and provider metadata are retained when supplied by the model.
Returns
Returns Promise<WorkflowAgentGenerateResult> with the core GenerateTextResult semantics:
text,finishReason,rawFinishReason, andfinalStepdescribe the final step.content,files,sources,warnings, tool calls, and tool results cover all steps.usageandtotalUsagesum all steps while retaining token details and unknown counts.responseMessagesincludes generated messages, even whenprepareStepreplaces the input history.outputdefaults to text, or follows the constructor/per-call output specification. Reading it throwsNoOutputGeneratedErrorwhen output is unavailable, such as a finaltool-callsresponse.
Inside a workflow, timeout bounds model calls, including retries and dispatch after suspension. It does not cancel a hook that a tool is waiting on. Use the Workflow runtime’s run.cancel() to stop a suspended run. See deadlines, cancellation, and replay.
Generation failures reject. The end callback runs before complete-output parsing; a parsing failure can therefore reject after onEnd has run. Existing Workflow callback shapes and preparation precedence apply; they are not all identical to core's callback APIs.
Use the result API inside workflow code and return selected serializable
fields (for example, text and usage) through run.returnValue. Returning
the whole result class is not supported. Performance data currently measures
the model response; complete tool/step timing is not yet reported.
Approval requests appear in content and responseMessages without requiring a writable. To continue, append responseMessages to the original history and add a tool message containing the user's tool-approval-response. Preserve the request signature and tool-call input; use the same experimental_toolApprovalSecret environment-variable reference on continuation. Local approvals are validated before execution, and provider-executed approval responses are forwarded to the provider. See approval round trips.
stream()
Runs the agent loop, streaming responses and executing tool calls as needed. Returns a promise resolving to a WorkflowAgentStreamResult.
prompt:
prompt or messages but not both.messages:
prompt or messages but not both.writable?:
createModelCallToUIChunkTransform().instructions?:
system?:
instructions instead.stopWhen?:
isStepCount() to bound execution.toolChoice?:
activeTools?:
output?:
Output.object({ schema }) for typed objects or Output.text() for text.timeout?:
sendFinish?:
preventClose?:
includeRawChunks?:
repairToolCall?:
experimental_transform?:
experimental_download?:
experimental_sandbox?:
experimental_sandbox, and exposed to prepareStep. Overrides the constructor default.experimental_toolApprovalSecret?:
telemetry?:
runtimeContext?:
prepareStep, lifecycle callbacks, and step results. Must be serializable when used in workflows.toolsContext?:
context. Must be serializable when used in workflows.prepareStep?:
onStart?:
experimental_onStart when both are provided in this call.experimental_onStart?:
onStart callback. Used only when onStart is not provided in this call.onStepStart?:
experimental_onStepStart when both are provided in this call.experimental_onStepStart?:
onStepStart callback. Used only when onStepStart is not provided in this call.onToolExecutionStart?:
onToolExecutionEnd?:
onStepEnd?:
onStepFinish?:
onStepEnd instead. This alias is only used as a fallback when onStepEnd is not provided.onEnd?:
onError?:
onAbort?:
Returns
Returns a Promise<WorkflowAgentStreamResult> with the following properties:
messages:
steps:
toolCalls:
toolResults:
error:
'error' in result to distinguish that case.output:
output specification was provided.repairToolCall in a workflow
repairToolCall runs inside the model step. When you use it in a workflow,
define the callback as a function with a 'use step' directive. You can set
it on the constructor or pass it to stream().
Workflow saves a reference to the registered function and loads its implementation inside the model step. Keep any values captured by the function serializable. An ordinary inline callback causes a serialization error when it crosses this step boundary.
The callback can be asynchronous. Return the repaired tool call, or null
if the repair cannot be completed. See tool call repair
for repair strategies.
experimental_transform in a workflow
Pass a transform factory, or an array of factories, to stream().
Mark each factory with 'use step' so Workflow can load it inside the model
step. The factory must return a TransformStream synchronously. Keep any
captured values serializable.
Utilities
createModelCallToUIChunkTransform(options?)
Creates a TransformStream that converts raw ModelCallStreamPart chunks (written by the agent to the writable stream) into UIMessageChunk objects suitable for client consumption.
When resuming with a WorkflowChatTransport cursor, replay the raw workflow
stream from index 0 and pass the non-negative UI chunk index to the transform:
uiStartIndex must be a non-negative safe integer. Raw model stream parts and
UI message chunks are not one-to-one, so do not pass a UI chunk index to
getReadable. Negative tail indexes require a durable stream that already
stores UIMessageChunk objects.
toUIMessageChunk()
Converts a single ModelCallStreamPart to a UIMessageChunk. Returns undefined for parts that don't map to UI chunks.
Types
ActiveTools
Limits a workflow agent call to the listed tool names. undefined means no tool restriction is applied.
InferWorkflowAgentUIMessage
Infers the UI message type for a WorkflowAgent instance. Optionally accepts a second type argument for custom message metadata.
InferWorkflowAgentTools
Infers the tool set type of a WorkflowAgent instance.
Examples
Basic Agent with Tools
Agent in a Workflow with Durable Tools
Agent with Structured Output
Agent with Tool Approval
For WorkflowAgent, tool approval is configured on the tool definition with
needsApproval. For generateText, streamText, and ToolLoopAgent, use
toolApproval instead.
When experimental_toolApprovalSecret is configured, each approval request is
signed over its approval ID, tool call ID, tool name, and validated input.
Replayed approvals with a missing or invalid signature do not execute the tool.
The signature is preserved in the durable stream and UI message history, while
only the environment variable name crosses workflow boundaries. Signing and
verification steps read the raw secret from their local environment and do not
serialize it. A stream-level reference overrides the constructor value.