Skip to main content

Module progress_watcher

Module progress_watcher 

Source
Expand description

Pushed per-agent progress: the agent’s current todo checklist and the tool it is running right now, published as an agent:progress MuxEvent so the Swarm pane can list them under the agent’s name.

Sibling of super::activity_watcher, and deliberately a separate loop: that one spends a Haiku call per agent to write an English one-liner and is throttled accordingly. This one only reads NEW bytes of a block’s output file and parses JSON, so it costs nothing per tick and can run far more often — which is the point, since a checklist that lags 20s behind the agent is worse than no checklist.

Why the backend and not the frontend: agent-document-store already holds every tool call, but only for panes that are currently MOUNTED. The Swarm pane’s whole value is seeing agents you are not looking at, so the data has to come from the same place the shell/cron/summary rows come from.

Why state is carried across ticks (reagent P1 on PR #2952): the checklist cannot be rebuilt from a fixed tail window. TodoWrite-style calls are immune — one call carries the whole list — but the vocabulary AgentMux actually ships against (TaskCreate/TaskUpdate) describes ONE item per call, so reconstructing the list needs every still-open task’s original TaskCreate to be inside the window. A verbose Bash or a large Read pushes those out within seconds, and the task would then vanish from the checklist while still open, silently. So each block keeps an accumulated BlockState and each tick only consumes the bytes appended since the last one.

Structs§

AgentProgress
What we currently believe about one agent.
BlockState 🔒
Everything we accumulate for one block across ticks.
NewPrCommand 🔒
The head and base a PR-create command names (--head, --base).
RecentFile
One file an agent changed, as its tool call named it.
SweepOutcome 🔒
Run the progress sweep loop. Never returns. One block’s worth of work decided by a sweep — what to publish, if anything.
TodoItem
One checklist entry as the Swarm renders it.
WatchedWork
What the watcher currently knows about one block, for readers outside the sweep loop.

Constants§

EVENT_AGENT_PROGRESS
FILE_EDIT_TOOL_NAMES 🔒
Tools whose input names a file the agent is changing. Their paths become the agent’s recent files, which backend::work_facts compares across agents (docs/specs/SPEC_AGENT_OVERLAP_AWARENESS_2026_10_10.md §3.1).
MAX_NEW_PRS 🔒
PR creations kept per sweep, at most.
MAX_OPEN_TOOLS 🔒
Bound on remembered in-flight tool calls. Real concurrency is a handful; a larger number means results are being missed, and the oldest entries are the ones least likely to still be running.
MAX_READ_BYTES 🔒
Most bytes consumed in one tick, and the most read when first catching up on a block. A block seen from its first byte is exact; one that already had more than this when we first saw it (srv restarted mid-session) is seeded from its tail and flagged — see BlockState::partial.
MAX_RECENT_FILES
Most recent files kept per block, distinct paths, newest first.
MAX_TODOS 🔒
Cap on rows published per agent, so one pathological checklist can’t flood the Swarm tree. Truncation is reported rather than silent — see AgentProgress::todos_truncated.
REPUBLISH_EVERY_TICKS 🔒
Republish an unchanged payload every N ticks (~15s at a 3s sweep).
SWEEP_INTERVAL_SECS 🔒
How often to sweep registered agents. Much tighter than the summary loop’s 20s: this is an incremental read + JSON parse, with no model call to bill.
TODO_TOOL_NAMES 🔒
Tool names whose call arguments carry checklist state.

Functions§

apply_lines 🔒
Fold newly-appended transcript lines into state.
consume_new_output 🔒
Consume whatever has been appended to this block’s output since the last tick, folding it into state.
first_string 🔒
frame_input 🔒
Call arguments under either vocabulary.
frame_tool_id 🔒
Call id under either vocabulary.
frame_tool_name 🔒
Tool name under either vocabulary (name for Claude, tool_name for Gemini-shaped frames).
is_create_call 🔒
Fold a Task-style call describing a SINGLE item into the accumulated rows.
is_shell_tool 🔒
A tool that runs a shell command (Claude’s Bash, a provider’s shell, AgentMux’s own Shell), by name.
is_todo_tool 🔒
line_timestamp 🔒
A transcript line’s own time, when it carries one (timestamp, RFC 3339 or Unix ms, as Claude’s session lines do).
merge_single_task 🔒
note_recent_file 🔒
Record that path was just changed by tool: moved to the front if it was already listed, and the list kept to MAX_RECENT_FILES.
parse_todo_array 🔒
input.todos (or input.items) as a whole checklist.
parse_todo_entry 🔒
pr_create 🔒
The PR being opened in a shell command (see [is_pr_create]), with the --head and --base it names, if any. Flags may sit between the words (gh --repo o/r pr create, gh pr -R o/r create); the command ends at a shell separator.
run_agent_progress_loop
Run the progress sweep loop. Never returns.
snapshot 🔒
The latest WatchedWork per block id, replaced after every sweep.
sweep_blocking 🔒
The whole file-reading half of a sweep, run OFF the async runtime.
tool_frames 🔒
Every frame in a transcript line that could be a tool call or result.
tool_result_ids 🔒
watched_work
Read access to the watcher’s state for one block: its checklist, current tool and recent files. None until the watcher has swept it once.

Type Aliases§

Swept 🔒
One sweep’s result: the states back, what to publish, and the edits and PRs the overlap notes check.