feat(agent): add MOA progress indicator (#59546) - #59646
Conversation
Adds per-reference progress events and a phase-transition marker to the
MoA display pipeline so TUI / CLI / desktop surfaces can render a status
bar like `MOA: 2/3 refs done` and surface which phase (reference vs
aggregator) is currently active.
- `moa.progress` — fired once per reference completion with
`refs_done`, `refs_total`, and the source label
- `moa.phase` — fired on phase transitions (currently the single
`phase="aggregator"` transition once the fan-out
finishes)
Plumbed through the existing `reference_callback` →
`tool_progress_callback` → gateway path; no new UI surface. The legacy
`moa.reference` / `moa.aggregating` events are unchanged for backwards
compatibility.
AI-assisted fix by https://github.com/SquabbyZ/peaks-loop
teknium1
left a comment
There was a problem hiding this comment.
Thanks for exposing the MoA execution path. The backend event idea matches issue #59546, but this version does not yet reach a visible UI.
Problems
- The diff changes only
agent/agent_init.py,agent/moa_loop.py,tui_gateway/server.py, and a Python test. Current TUI protocol/dispatch recognizes onlymoa.referenceandmoa.aggregating(ui-tui/src/gatewayTypes.ts:662-668,ui-tui/src/app/createGatewayEventHandler.ts:691-704), andStatusRulehas no MoA progress input (ui-tui/src/components/appChrome.tsx:405-425).moa.progressandmoa.phasewill therefore be dropped rather than render the requested status bar. - The new loop iterates
futures.items()and waits withfuture.result(). That is submission order, not completion order, so the advertised completion counter can lag behind already-finished references. - The new ordering test says progress follows its matching reference, but it never asserts that relationship. The proposed flow emits progress during fan-out; reference events are emitted only afterward (
agent/moa_loop.py:1040-1059on current main).
Suggested changes
- Wire the events into the TUI state/StatusRule and add client rendering tests.
- Use
as_completedfor progress emission while retaining stable result ordering. - Assert the full event ordering with delayed reference stubs.
Automated hermes-sweeper review.
| @@ -381,6 +390,13 @@ def _run_references_parallel( | |||
| # complete set, so there is no early-exit / first-completed path here. | |||
| for future, idx in futures.items(): | |||
| results[idx] = future.result() | |||
There was a problem hiding this comment.
futures.items() preserves submission order, and future.result() blocks on each earlier future. A later, already-completed reference cannot advance this counter until every earlier submission resolves, so this is not completion-order progress. Please use as_completed with a future-to-index map.
| if event_type == "moa.aggregating": | ||
| _emit("moa.aggregating", sid, {"aggregator": str(name or "")}) | ||
| return | ||
| if event_type == "moa.progress": |
There was a problem hiding this comment.
This introduces a gateway event, but the PR does not update ui-tui/src/gatewayTypes.ts, createGatewayEventHandler.ts, or StatusRule state/rendering. Current clients will not consume this event, so the requested visible progress indicator is not implemented.
| ) | ||
|
|
||
| # Walk the events; every progress event must be preceded by its reference | ||
| # text event (matching ``index``). The full sequence ends with the |
There was a problem hiding this comment.
The test description says each progress event must be preceded by its matching moa.reference, but the loop only checks independent counter bounds. Please assert the captured event sequence; the proposed implementation emits progress during fan-out before its later reference-emission loop.
….phase Frontend consumers for the events added by PR #59646: the TUI shows a replace-in-place 'MoA: refs k/n' activity line (swapped for 'MoA: aggregating…' on the aggregator phase), and desktop streams '◇ MoA refs k/n' lines into the reasoning disclosure, self-cleaned by the first moa.reference block.
….phase Frontend consumers for the events added by PR #59646: the TUI shows a replace-in-place 'MoA: refs k/n' activity line (swapped for 'MoA: aggregating…' on the aggregator phase), and desktop streams '◇ MoA refs k/n' lines into the reasoning disclosure, self-cleaned by the first moa.reference block.
….phase Frontend consumers for the events added by PR #59646: the TUI shows a replace-in-place 'MoA: refs k/n' activity line (swapped for 'MoA: aggregating…' on the aggregator phase), and desktop streams '◇ MoA refs k/n' lines into the reasoning disclosure, self-cleaned by the first moa.reference block.
|
Merged via cluster PR #70283 (commit 385a065) — your commit cherry-picked with authorship preserved, plus frontend consumers we added on top (TUI 'MoA: refs k/n' + desktop event registration) so #59546's indicator is user-visible, not plumbing-only. Your event design (moa.progress/moa.phase) is unchanged. Thanks! |
….phase Frontend consumers for the events added by PR NousResearch#59646: the TUI shows a replace-in-place 'MoA: refs k/n' activity line (swapped for 'MoA: aggregating…' on the aggregator phase), and desktop streams '◇ MoA refs k/n' lines into the reasoning disclosure, self-cleaned by the first moa.reference block.
….phase Frontend consumers for the events added by PR NousResearch#59646: the TUI shows a replace-in-place 'MoA: refs k/n' activity line (swapped for 'MoA: aggregating…' on the aggregator phase), and desktop streams '◇ MoA refs k/n' lines into the reasoning disclosure, self-cleaned by the first moa.reference block.
Fixes #59546
Summary
Adds a minimal MOA progress indicator to the existing display pipeline so TUI / CLI / desktop surfaces can render a status bar like
MOA: 2/3 refs doneand surface which phase of the MoA pipeline is currently active (reference fan-out vs aggregator synthesis). The MoA flow is no longer a black box while it runs.Changes
agent/moa_loop.py— emits two new events on the existingreference_callbacksurface:moa.progress— fired once per reference completion withrefs_done,refs_total, and the source-model label (drives the status-bar counter).moa.phase— fired on phase transitions, currentlyphase="aggregator"once the fan-out finishes and the aggregator is about to act.moa.reference/moa.aggregatingevents are unchanged for backwards compatibility.agent/agent_init.py— relays the two new events through the existingtool_progress_callbackso every surface that already consumes MoA events (CLI scrollback, TUI, desktop, gateway) sees them automatically.tui_gateway/server.py— emitsmoa.progressandmoa.phaseto the TUI / Ink client with a typed payload.tests/agent/test_moa_progress.py— five new unit tests covering per-reference progress emission, phase-transition marker, counter monotonicity, event ordering, and the no-callback safety path.The fan-out itself is unchanged — this is purely a display-layer addition plumbed into the existing trace mechanism. No re-architecture.
How to test
refs_done/refs_totalcounter and amoa.phase=aggregatormarker fires right before the aggregator acts.Platforms tested
AI-assisted fix by https://github.com/SquabbyZ/peaks-loop