docs/01-agent-loop.md
01 — Agent Loop
The plan-act-observe-reflect loop. Every turn the agent takes is one trip through this cycle. Depth and step caps prevent runaway loops. Error recovery is deterministic. Hooks fire at every transition. The same loop underlies interactive turns, plan-mode runs, subagent invocations, and long-horizon /goal runs.
Loop semantics
┌─────────┐ ┌─────────┐ ┌────────────┐ ┌──────────┐
│ plan │ ──▶ │ act │ ──▶ │ observe │ ──▶ │ reflect │
└─────────┘ └─────────┘ └────────────┘ └──────────┘
▲ │
└───────────────── next step, or the turn ends ─────┘When the agent needs you
- Questions and plan review reach the person:
ask_user_questionshows the question inline (TUI) or as a card (Mac), and plan mode's review asks before anything is implemented. Tool results read as text, not JSON. - Decisions: two or more asks in one turn show as one card, numbered, with "N of M answered" and Continue on the Mac; the TUI reads "Needs you · N decisions · answer each with its number; …". Approvals are Allow / Allow for this thread / Deny (TUI
1/2/3;a/s/dstill work). - Options: the
present_optionsdeferred tool offers two to four options (each html, an image, code or text). The Mac opens an options window (Open options; Pick this or1–4; an optional note; Send ⏎; Skip esc); the TUI shows a numbered list (←/→orn/pto move,oopens one). - Steer, queue and interrupt: while a turn runs, Enter queues, steer sends into the running turn, Enter in an empty composer sends a queued message now, and interrupt (⌥⏎ on the Mac,
ctrl+qin the TUI) stops the current step and sends at once. - Progress reports arrive about every 10 minutes on long tasks (setting
progressReports). - Failed turns read "503 · <message>"; engine exit reasons are shown with secrets redacted. Nothing is synthesized when the engine fails.
Runtime note
The engine adapter in packages/core (createDshAgentLoop) implements the run()/LoopEvent surface, projecting the engine's session log onto the LoopEvent union. The former in-repo AgentLoop was removed when Picasso adopted the engine (see architecture).