Concepts / Todos

Todos & the wake loop

Every session has a built-in todo list. It's not just a notepad — open todos drive the agent forward on their own, so a single request can turn into a multi-step job the agent works through without you prodding it each turn.

What a todo is

A todo belongs to one session and has a status:

StatusMeaning
OpenActionable — still drives the wake loop below.
DoneCompleted and closed.
BlockedHeld, with a reason explaining why work can't proceed.

The skills

The agent manages its own list with three skills:

  • todo_write — add one or more items (items: string[]). Returns each new item's id.
  • todo_list — list this session's todos with ids and statuses (blocked items show their reason).
  • todo_update — close an item: todo_update(id, "done"), or todo_update(id, "blocked", reason).

How todos reach the agent

Todos are deliberately not in the system prompt. They change every turn, and putting per-turn data in the system prompt would poison the model's prompt cache (a real cost and latency hit). Instead, when a session has open todos the runtime injects a short nudge as a user message — and it includes the live list inline, so the agent can act immediately without spending a todo_list round-trip first:

text
You still have open todos — keep working and close each with todo_update(id, "done") as you finish:
  [1842] Roll back the last payments deploy
  [1843] Confirm the queue drained
  [1844] Post-mortem note in the wiki (blocked: waiting on the on-call to confirm root cause)
(todo_list shows the full list at any time.)

Each item carries its id (pass it to todo_update) and blocked items show their reason. todo_list is still there to re-read the list on demand, but the common path spends no extra call.

This is the same discipline used everywhere in AgentParley: the system prompt stays static and cacheable; anything that changes per turn arrives as a message — and that message carries exactly what the agent needs to keep moving.

The wake loop

When a turn finishes and the session still has open todos and isn't parked waiting on something, the session re-enters automatically — no external input needed. It gets the nudge and runs another turn. That's what lets an agent grind through a checklist end-to-end.

This is bounded so a session can't spin forever:

  • Wake budget. Each activation gets up to maxWakeCycles re-entries (default 25).
  • Shared budget. The same budget also covers the reply-nudge and subagent-completion nudges, so they can't fight each other into a loop.
  • Graceful stop. If the budget runs out with todos still open, the session parks Idle rather than spinning — it resumes when fresh input arrives (which resets the budget).

Todos and session state

Todos shape how a session yields. With open todos, a yielding session goes Idle (there's still work to pick back up). With none open, it goes Dormant — fully asleep until a wake source (a human message, a peer reply, a cron kick) arrives. See session states.

Pattern. An agent handed a big task will often todo_write a plan up front, then let the wake loop carry it through the items — closing each with todo_update — and only message you when it's done or blocked.