Code holds the plan
Phases, branches, Barriers, retry limits, and stopping rules live in code, where they can be reviewed and tested.
Program stability × Agent initiative
Dynamic Workflow puts orchestration in TypeScript. Order, concurrency, and stopping rules become explicit; a complete Agent Loop runs only where the task needs understanding and judgment.
WHY DYNAMIC WORKFLOW
Skills carry knowledge and strategy. When mechanical steps also live in natural language, the Agent often has to interpret the plan again as it advances. Dynamic Workflow moves that control flow into code.
Phases, branches, Barriers, retry limits, and stopping rules live in code, where they can be reviewed and tested.
agent() starts a complete ReAct Loop with tools and its own Context—not a one-shot Prompt completion.
When code consumes an Agent result, JSON Schema validates its shape before the next step runs.
CREATE & RUN
Generate a Workflow from one sentence, or run the bundled Deep Research example from the repository root.
Open the examplePORTABLE BY DESIGN
Run the same workflow.ts as a cloud or FaaS service, inside CI/CD, a desktop app, or directly from the CLI.
Bring the runtime · keep the Workflow
THE WORKFLOW IS CODE
Use arrays, branches, loops, and concurrency for the mechanical work. Call agent() when a step needs understanding, exploration, or judgment.
Read the Workflow API contract01 import { agent, log, parallel, phase, pipeline } from "@deerwork-ai/deer-workflow";
02
03 export const meta = {
04 name: "research-synthesis",
05 description: "Researches and synthesizes a topic.",
06 phases: [
07 { title: "Plan" },
08 { title: "Research" },
09 { title: "Synthesize" },
10 ],
11 exampleArgs: { topic: "Agentic workflow design" },
12 };
13
14 export default async function workflow(args: { topic: string }) {
15 phase("Plan");
16 log(`Planning research for ${args.topic}`);
17 const plan = await agent<{ angles: string[] }>(
18 `Plan independent research angles for ${args.topic}`,
19 {
20 schema: {
21 type: "object",
22 properties: { angles: { type: "array", items: { type: "string" } } },
23 required: ["angles"],
24 additionalProperties: false,
25 },
26 },
27 );
28
29 phase("Research");
30 log(`Researching ${plan.angles.length} angles`);
31 const signals = await parallel(
32 plan.angles.map((angle) => () => agent(`Research ${angle}`)),
33 );
34 const findings = await pipeline(
35 signals.filter(Boolean),
36 (signal) => agent(`Extract key facts:\n${signal}`),
37 );
38 log(`Prepared ${findings.length} findings`);
39
40 phase("Synthesize");
41 return agent(`Synthesize:\n${JSON.stringify(findings)}`);
42 }