workflowTool adapts a Smithers workflow to the same AI SDK tool contract used
by defineTool, MCP tools, and OpenAPI tools. It is intended for in-process SDK
agents such as OpenAIAgent and AnthropicAgent.
Input and result
The child workflow’s existing Zodinput schema is the tool parameter schema.
There is no second schema to keep synchronized. A workflow with no input schema
gets a strict empty-object schema, so the agent calls it with {}. A successful
call returns the workflow’s declared RunResult.output.
Durable child run
Each distinct parsed input creates a real child run through the same executor as<Subflow mode="childRun">. The child is visible in the run tree, has
parentRunId set to the calling run, and records startedBy.harness as
smithers-workflow-tool. Repeating the same tool call in the same task and
iteration uses the same input-derived child run ID, so retries attach or resume
instead of duplicating work.
The agent task holds one parent scheduler slot while its child runs. Parallel
workflow-tool calls from that task are serialized, so they remain one admitted
subtree and cannot bypass the parent’s concurrency budget.
Pauses and human decisions
The call waits while the child is actively executing. If the child parks for an approval, human request, event, timer, quota, or explicit pause, the tool returns an immediateWORKFLOW_TOOL_SUSPENDED error to the agent. The error includes
the child run ID and status. Resolve the request against that child run, then
retry the calling task to resume it. The tool never polls a parked child
forever. The whole invocation, including its local queue wait, is bounded by
timeoutMs, which defaults to 5 minutes, and by the calling task’s
cancellation and timeout signals.
Failed and cancelled children become WORKFLOW_TOOL_CHILD_FAILED tool errors.
The agent receives the child run ID, terminal status, and a bounded public error
code and summary when available. Stacks, causes, and internal metadata are not
copied into the tool error.
Recursion
Nested workflow-tool calls carry a durable depth counter. The default maximum depth is 4 andmaxDepth accepts 1 through 32. Crossing the limit raises
WORKFLOW_TOOL_DEPTH_EXCEEDED before another child starts.
See the runnable examples/workflow-tool.tsx.