description: "The workflow orchestration capability: run a model-written script that fans out subagents, for users and maintainers choosing or building on ctx.workflowEngine."
English | 中文
Run a plain-JavaScript orchestration script that fans work out to subagents and returns the script's final JSON value. Scripts can use agent(), parallel(), pipeline(), phase(), and log(); models normally access them through the workflow tool. Each run belongs to its caller, attributes every child to the invoking agent, resolves failures and cancellation without rejecting its result, and stops disposal within a bounded grace period. The caller must supply an execution engine, allowing the isolation strategy to change without altering visible behavior.
Run a workflow when a task decomposes into many independent pieces that one script should coordinate — an audit across many files, a migration, multi-angle research — and the model explicitly asks for workflow-style orchestration. For one or two delegations, prefer a plain subagent call.
The model reaches the capability through the workflow tool from dsh-tool-workflow, which owns the call schema and result envelope; the engine supplies the execution underneath. A tool call submits meta, script, and optional args and returns { runId, agentsStarted, result } when the run completes. The tool blocks the parent turn until the whole workflow settles, so the model sees one final outcome, never intermediate child messages.
An orchestration script is a plain JavaScript body (not TypeScript) that runs with top-level await and ends with return <json-value>. The meta identity block and any args arrive as plain JSON data — never evaluated code. During execution the script calls the provided hooks: agent(prompt, opts) starts one subagent and resolves with its final text or, with a schema, a validated structured value; parallel() and pipeline() combine independent work; phase() and log() narrate progress for observers.
// Script body — runs with top-level await, ends with a JSON return value:
const reviews = await parallel([
() => agent('Review src/a.ts for correctness'),
() => agent('Review src/b.ts for correctness'),
])
return { reviewed: reviews.length }
When the script settles, the run's result resolves with the returned value, the stop reason, and the number of children started. A script that returns nothing yields null.
Plugin consumers can start a run directly: ctx.workflowEngine.start({ script, meta, args?, parent, signal? }). parent attributes every child to the invoking agent; signal cancels the run when aborted. start() validates the meta block and parses the script before a run exists, so a malformed request fails immediately with a violation list.
A returned run exposes id, meta, result, cancel(reason?), and dispose(). The result never rejects: a script failure resolves with stopReason: 'error', cancellation with 'cancelled'. The caller owns the run — call dispose() on every path; it cancels remaining work and waits for script and children to settle within a bounded grace.
A script that does not parse, a malformed meta block, an unavailable provider route, or an unsupported per-run limit is rejected synchronously before a run exists; the workflow tool reports these as errors the model can correct from. During execution, hook misuse — bad arguments, unknown options, unsupported schemas, tripped caps — kills the script loudly rather than dissolving into a per-item null. An ordinary child failure is not an infrastructure error: agent() resolves null and the script decides how to handle it.
Read these pages when the package-level contract is not enough. They move from the shared workflow model to the current engine and the model-facing consumers.
Indirectly, through its consumer dsh-tool-workflow and a workflow engine, which render the parent tool result and the child-agent requests.
No direct invalidation; the named consumer and engine own any request-prefix changes.
These limits define what the capability does not yet support. They are current constraints, not a task backlog.
workflow() hook for recursive orchestration.