Concepts
Workflows
Declarative multi-step pipelines — Workflow.create with 7 control-flow primitives.
Canonical contract:
packages/sdk/docs.md— "Workflows (v1.17+)".
Workflow is a declarative DSL for multi-step pipelines. Inspired by Mastra + Temporal. Use when imperative agent.send loops get awkward.
Build + run
import { Workflow, Agent } from "@theokit/sdk";
const triage = Workflow
.create({ name: "support-triage" })
.then("fetch", async (input: { ticketId: string }) => {
return { text: await db.getTicket(input.ticketId) };
})
.branch("route", [
[(s) => s.text.includes("refund"), {
step: { kind: "fn", id: "refund-flow", fn: async (s) => ({ result: "refund handled" }) },
}],
[(s) => s.text.includes("bug"), {
step: { kind: "fn", id: "bug-flow", fn: async (s) => ({ result: "bug logged" }) },
}],
])
.commit();
const result = await Workflow.run(triage, { ticketId: "T-1234" });
console.log(result.output);7 primitives
| Primitive | Purpose |
|---|---|
.then(id, fn) | Sequential step |
.parallel([...], { errorPolicy }) | Run N steps concurrently |
.branch(id, [[pred, branch], ...]) | First-match-wins routing |
.foreach(id, items, fn, { concurrency }) | Map over a collection |
.dowhile(id, predicate, body) | Loop until predicate false |
.sleep(id, ms) | Wait |
.suspend(payload?) | Pause; resume via Workflow.resume(...) |
Suspend / resume
For long-running flows (human in the loop, external webhook):
const wf = Workflow.create({ name: "pr-review" })
.then("draft", draftReview)
.suspend() // ← pause here
.then("publish", publishReview)
.commit();
const run = await Workflow.run(wf, input);
// run.status === "suspended", run.suspendPayload visible
// Later, after the human reviews:
const finished = await Workflow.resume({
workflowId: run.workflowId,
runId: run.runId,
resumeInput: { approved: true },
});Retry policies
Per-step Temporal-style retry (ADR D237):
.then("flaky", flakyApiCall, {
retry: { maxAttempts: 3, backoffMs: 500, coef: 2 },
})Cancellation
AbortSignal is honored at step boundaries (ADR D245). Pass via options:
const ctrl = new AbortController();
const run = Workflow.run(wf, input, { signal: ctrl.signal });
// elsewhere: ctrl.abort();Persistence
Default: in-memory. Opt-in JSON snapshots:
Workflow.run(wf, input, {
persistence: { backend: "json", dir: ".theokit/workflows" },
});Telemetry
OTel spans workflow.run + workflow.step.<id> via the existing telemetry seam (ADR D241).
CloudAgent
Workflow steps throw UnsupportedRunOperationError on CloudAgent — local-only in v1 (ADR D244).