[{"data":1,"prerenderedAt":673},["ShallowReactive",2],{"docs-\u002Fdocs\u002Ffeatures\u002Fdynamic-workflows":3},{"id":4,"title":5,"body":6,"description":665,"extension":666,"meta":667,"navigation":668,"path":669,"seo":670,"stem":671,"__hash__":672},"docs\u002Fdocs\u002Ffeatures\u002Fdynamic-workflows.md","Dynamic Workflows",{"type":7,"value":8,"toc":654},"minimark",[9,13,31,42,51,56,59,66,94,101,105,114,120,198,201,267,286,292,299,309,312,338,386,391,458,469,487,491,505,538,541,594,598,622,626,650],[10,11,5],"h1",{"id":12},"dynamic-workflows",[14,15,16,17,21,22,26,27,30],"p",{},"A normal workflow runs inside a single Slo session: one agent, one context window, one thing at a time. A ",[18,19,20],"strong",{},"dynamic workflow"," is different. Slo becomes an ",[23,24,25],"em",{},"orchestrator"," — it reads the workflow, breaks it into phases, and fans each phase out to its own ",[18,28,29],{},"sub-agent"," running in its own process. The orchestrator dispatches the phases, watches the children, retries what fails, and synthesizes the results into one answer.",[14,32,33,34,37,38,41],{},"The trigger phrase is exactly that: say ",[18,35,36],{},"\"dynamic workflows\""," (Slo also understands the common misspelling \"dyanmic workflows\") and Slo switches from doing the work itself to ",[23,39,40],{},"decomposing and delegating"," it.",[43,44,45],"blockquote",{},[14,46,47,50],{},[18,48,49],{},"Why the name?"," The plan isn't fixed up front. The orchestrator decides — at run time — how many sub-agents to spawn, what each one does, and whether phases run one-after-another or all at once. The shape of the work is discovered as it runs.",[52,53,55],"h2",{"id":54},"why-dynamic-workflows-give-better-results","Why dynamic workflows give better results",[14,57,58],{},"A single agent working a long, multi-step task accumulates everything in one context window: the spec, the code it wrote three steps ago, the test output, the review notes. Signal gets diluted and later steps drift.",[14,60,61,62,65],{},"Dynamic workflows fix that by giving ",[18,63,64],{},"each phase a clean, dedicated context",":",[67,68,69,76,82,88],"ul",{},[70,71,72,75],"li",{},[18,73,74],{},"Focus"," — the \"write tests\" sub-agent sees only what it needs to write tests. Nothing from the review phase is crowding its window.",[70,77,78,81],{},[18,79,80],{},"Isolation"," — a phase that fails or goes off the rails is one child process. The orchestrator retries it once with corrected parameters instead of poisoning the whole run.",[70,83,84,87],{},[18,85,86],{},"Parallelism"," — independent phases run at the same time, up to the concurrency cap, so a review that touches five modules finishes in the time of the slowest one, not the sum of all five.",[70,89,90,93],{},[18,91,92],{},"Oversight"," — the orchestrator is a supervisor that never does the bulk work. Its only job is to decompose, dispatch, check in, and synthesize — so it always has room to reason about the whole.",[14,95,96],{},[97,98],"img",{"alt":99,"src":100},"The slo visualize TUI showing the orchestrator's sub-agents, their status, and the transcript of the selected child.","\u002Fmedia\u002Fvisualize-tui.svg",[52,102,104],{"id":103},"a-simple-example-code-test-review","A simple example: code-test-review",[14,106,107,108,113],{},"The ",[109,110,112],"a",{"href":111},"\u002Fdocs\u002Fworkflows\u002Fcode-test-review","code-test-review workflow"," has four phases — write code, write tests, review, ship a PR. Run it the ordinary way and one agent carries all four in a single context.",[14,115,116,117,119],{},"Run it as a ",[18,118,20],{}," and each phase becomes a sub-agent:",[121,122,127],"pre",{"className":123,"code":124,"language":125,"meta":126,"style":126},"language-bash shiki shiki-themes github-dark-high-contrast","slo run \\\n  -p \"Use dynamic workflows: run the code-test-review workflow for\n      the feature in specs\u002F42-payments\u002Foverview.md\" \\\n  --orchestrator \\\n  --enable-history \\\n  --session-id ctr-20260718 \\\n  --json\n","bash","",[128,129,130,147,157,165,173,181,192],"code",{"__ignoreMap":126},[131,132,135,139,143],"span",{"class":133,"line":134},"line",1,[131,136,138],{"class":137},"s_sBn","slo",[131,140,142],{"class":141},"sTRMh"," run",[131,144,146],{"class":145},"sWyjQ"," \\\n",[131,148,150,154],{"class":133,"line":149},2,[131,151,153],{"class":152},"sCcAr","  -p",[131,155,156],{"class":141}," \"Use dynamic workflows: run the code-test-review workflow for\n",[131,158,160,163],{"class":133,"line":159},3,[131,161,162],{"class":141},"      the feature in specs\u002F42-payments\u002Foverview.md\"",[131,164,146],{"class":145},[131,166,168,171],{"class":133,"line":167},4,[131,169,170],{"class":152},"  --orchestrator",[131,172,146],{"class":145},[131,174,176,179],{"class":133,"line":175},5,[131,177,178],{"class":152},"  --enable-history",[131,180,146],{"class":145},[131,182,184,187,190],{"class":133,"line":183},6,[131,185,186],{"class":152},"  --session-id",[131,188,189],{"class":141}," ctr-20260718",[131,191,146],{"class":145},[131,193,195],{"class":133,"line":194},7,[131,196,197],{"class":152},"  --json\n",[14,199,200],{},"Here is what changes:",[202,203,204,219],"table",{},[205,206,207],"thead",{},[208,209,210,213,216],"tr",{},[211,212],"th",{},[211,214,215],{},"Single session",[211,217,218],{},"Dynamic workflow",[220,221,222,234,245,256],"tbody",{},[208,223,224,228,231],{},[225,226,227],"td",{},"Context",[225,229,230],{},"One window holds code + tests + review",[225,232,233],{},"Each phase gets a fresh, focused window",[208,235,236,239,242],{},[225,237,238],{},"Failure",[225,240,241],{},"A bad step contaminates the rest",[225,243,244],{},"The orchestrator retries just that phase",[208,246,247,250,253],{},[225,248,249],{},"Review breadth",[225,251,252],{},"Serial, one file at a time",[225,254,255],{},"Fan out — one sub-agent per module, in parallel",[208,257,258,261,264],{},[225,259,260],{},"Result",[225,262,263],{},"Model does the work and self-checks",[225,265,266],{},"An independent reviewer checks another agent's output",[14,268,269,270,273,274,277,278,281,282,285],{},"The code-test-review workflow is a ",[23,271,272],{},"pipeline",", so its phases run ",[18,275,276],{},"serially",": code → test → review → ship, each waiting for the previous phase's ",[128,279,280],{},"READY"," verdict before the next is dispatched. A ",[23,283,284],{},"parallel"," workflow (for example, reviewing several modules at once) dispatches all independent phases in one call and then runs a synthesis phase after they all complete.",[14,287,288],{},[97,289],{"alt":290,"src":291},"Slo running as an orchestrator, spawning one sub-agent per phase and printing the visualize command.","\u002Fmedia\u002Fdynamic-workflow-launch.svg",[52,293,295,296],{"id":294},"watching-sub-agents-with-slo-visualize","Watching sub-agents with ",[128,297,298],{},"slo visualize",[14,300,301,302,305,306,308],{},"When phases run in parallel across several processes, you want to ",[23,303,304],{},"see"," them. ",[128,307,298],{}," is a read-only TUI that attaches to the orchestrator's session and shows every sub-agent, its live status, and its transcript. It reads from the history store — it never interferes with the running workflow, and you can open it while the workflow is still going or after it has finished.",[14,310,311],{},"The orchestrator prints the exact command when it starts. Run it in a second terminal:",[121,313,315],{"className":123,"code":314,"language":125,"meta":126,"style":126},"slo visualize --session ctr-20260718 --follow --refresh-seconds 2\n",[128,316,317],{"__ignoreMap":126},[131,318,319,321,324,327,329,332,335],{"class":133,"line":134},[131,320,138],{"class":137},[131,322,323],{"class":141}," visualize",[131,325,326],{"class":152}," --session",[131,328,189],{"class":141},[131,330,331],{"class":152}," --follow",[131,333,334],{"class":152}," --refresh-seconds",[131,336,337],{"class":152}," 2\n",[67,339,340,366,372],{},[70,341,342,345,346,349,350,353,354,357,358,361,362,365],{},[18,343,344],{},"Left pane"," — every discovered sub-agent, each with a status icon: ",[128,347,348],{},"⏳"," running, ",[128,351,352],{},"✓"," completed, ",[128,355,356],{},"✗"," failed, ",[128,359,360],{},"⊘"," aborted, ",[128,363,364],{},"◌"," pending.",[70,367,368,371],{},[18,369,370],{},"Right pane"," — the transcript of the selected child: its prompt, tool calls, test output, and final verdict.",[70,373,374,377,378,381,382,385],{},[18,375,376],{},"Status bar"," — parent session id, workflow state (",[128,379,380],{},"running"," \u002F ",[128,383,384],{},"complete","), child count, follow mode, and the last refresh time.",[387,388,390],"h3",{"id":389},"keyboard-controls","Keyboard controls",[202,392,393,403],{},[205,394,395],{},[208,396,397,400],{},[211,398,399],{},"Key",[211,401,402],{},"Action",[220,404,405,418,428,438,448],{},[208,406,407,415],{},[225,408,409,381,412],{},[128,410,411],{},"↑",[128,413,414],{},"↓",[225,416,417],{},"Move through the sub-agent list",[208,419,420,425],{},[225,421,422],{},[128,423,424],{},"Enter",[225,426,427],{},"Select a sub-agent and load its transcript",[208,429,430,435],{},[225,431,432],{},[128,433,434],{},"r",[225,436,437],{},"Force an immediate refresh",[208,439,440,445],{},[225,441,442],{},[128,443,444],{},"f",[225,446,447],{},"Toggle follow (live polling) on \u002F off",[208,449,450,455],{},[225,451,452],{},[128,453,454],{},"q",[225,456,457],{},"Quit",[14,459,460,461,464,465,468],{},"Use ",[128,462,463],{},"--follow"," (the default) to poll for live updates while the workflow runs; polling stops automatically once the orchestrator reaches a terminal state. Use ",[128,466,467],{},"--no-follow"," to inspect a workflow that has already finished:",[121,470,472],{"className":123,"code":471,"language":125,"meta":126,"style":126},"slo visualize --session ctr-20260718 --no-follow\n",[128,473,474],{"__ignoreMap":126},[131,475,476,478,480,482,484],{"class":133,"line":134},[131,477,138],{"class":137},[131,479,323],{"class":141},[131,481,326],{"class":152},[131,483,189],{"class":141},[131,485,486],{"class":152}," --no-follow\n",[52,488,490],{"id":489},"how-the-orchestrator-supervises-its-children","How the orchestrator supervises its children",[14,492,107,493,496,497,500,501,504],{},[128,494,495],{},"--orchestrator"," flag injects a built-in orchestrator system prompt, so you don't have to explain the role — you describe the ",[23,498,499],{},"task",", not the ",[23,502,503],{},"procedure",". Under the hood the orchestrator:",[506,507,508,511,518,529,535],"ol",{},[70,509,510],{},"Reads the workflow file and enumerates its phases.",[70,512,513,514,517],{},"Builds a ",[18,515,516],{},"self-contained"," prompt for each phase (no pronouns, no \"the previous step\" — every sub-agent prompt stands alone).",[70,519,520,521,524,525,528],{},"Dispatches phases serially (pipeline) or in parallel, up to ",[128,522,523],{},"SLO_SUBAGENT_MAX_CONCURRENCY"," (default ",[128,526,527],{},"6"," for workflows).",[70,530,531,534],{},[18,532,533],{},"Checks in"," on the children as they run, retrying a failed or aborted phase once with corrected parameters.",[70,536,537],{},"Collects every child's answer and synthesizes one coherent result.",[14,539,540],{},"For a long workflow, set the guard timeouts before launching so a big synthesis call is never mistaken for a hang:",[121,542,544],{"className":123,"code":543,"language":125,"meta":126,"style":126},"export SLO_STREAM_INACTIVITY_TIMEOUT_SECONDS=2400   # orchestrator's own LLM stream\nexport SLO_SUBAGENT_INACTIVITY_TIMEOUT_SECONDS=1800 # each child's stdout pipe\nexport SLO_SUBAGENT_MAX_CONCURRENCY=6               # simultaneous sub-agents\n",[128,545,546,565,580],{"__ignoreMap":126},[131,547,548,551,555,558,561],{"class":133,"line":134},[131,549,550],{"class":145},"export",[131,552,554],{"class":553},"sMAXC"," SLO_STREAM_INACTIVITY_TIMEOUT_SECONDS",[131,556,557],{"class":145},"=",[131,559,560],{"class":152},"2400",[131,562,564],{"class":563},"sQrFR","   # orchestrator's own LLM stream\n",[131,566,567,569,572,574,577],{"class":133,"line":149},[131,568,550],{"class":145},[131,570,571],{"class":553}," SLO_SUBAGENT_INACTIVITY_TIMEOUT_SECONDS",[131,573,557],{"class":145},[131,575,576],{"class":152},"1800",[131,578,579],{"class":563}," # each child's stdout pipe\n",[131,581,582,584,587,589,591],{"class":133,"line":159},[131,583,550],{"class":145},[131,585,586],{"class":553}," SLO_SUBAGENT_MAX_CONCURRENCY",[131,588,557],{"class":145},[131,590,527],{"class":152},[131,592,593],{"class":563},"               # simultaneous sub-agents\n",[52,595,597],{"id":596},"when-to-reach-for-a-dynamic-workflow","When to reach for a dynamic workflow",[67,599,600,603,606,614],{},[70,601,602],{},"A multi-phase workflow where phases benefit from clean, separate context (code-test-review, specification-development).",[70,604,605],{},"A review or audit that fans out over many files or modules and should run in parallel.",[70,607,608,609,613],{},"Any unattended, long-running job you want to launch ",[109,610,612],{"href":611},"\u002Fdocs\u002Ffeatures\u002Fheadless","headlessly"," and watch from the visualizer.",[70,615,616,617,621],{},"Recurring supervised work — pair it with the ",[109,618,620],{"href":619},"\u002Fdocs\u002Ffeatures\u002Fschedulers","scheduler"," so the orchestrator wakes on a timer and checks in on its own sub-agents.",[52,623,625],{"id":624},"next-steps","Next steps",[67,627,628,638,644],{},[70,629,630,633,634,637],{},[109,631,632],{"href":611},"Run it headlessly"," — the full ",[128,635,636],{},"slo run --orchestrator"," reference.",[70,639,640,643],{},[109,641,642],{"href":619},"Schedule it"," — fire a dynamic workflow on a timer.",[70,645,646,649],{},[109,647,648],{"href":111},"Code-test-review"," — the workflow used in the example above.",[651,652,653],"style",{},"html pre.shiki code .s_sBn, html code.shiki .s_sBn{--shiki-default:#FFB757}html pre.shiki code .sTRMh, html code.shiki .sTRMh{--shiki-default:#ADDCFF}html pre.shiki code .sWyjQ, html code.shiki .sWyjQ{--shiki-default:#FF9492}html pre.shiki code .sCcAr, html code.shiki .sCcAr{--shiki-default:#91CBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sMAXC, html code.shiki .sMAXC{--shiki-default:#F0F3F6}html pre.shiki code .sQrFR, html code.shiki .sQrFR{--shiki-default:#BDC4CC}",{"title":126,"searchDepth":149,"depth":149,"links":655},[656,657,658,662,663,664],{"id":54,"depth":149,"text":55},{"id":103,"depth":149,"text":104},{"id":294,"depth":149,"text":659,"children":660},"Watching sub-agents with slo visualize",[661],{"id":389,"depth":159,"text":390},{"id":489,"depth":149,"text":490},{"id":596,"depth":149,"text":597},{"id":624,"depth":149,"text":625},"Let Slo orchestrate a workflow across a fleet of parallel sub-agents — and watch them progress live with slo visualize.","md",{},true,"\u002Fdocs\u002Ffeatures\u002Fdynamic-workflows",{"title":5,"description":665},"docs\u002Ffeatures\u002Fdynamic-workflows","vReo4mL4tVsIqvwVBCxKds3e_W1COirxBkH7qOkbltY",1785676470387]