fix(status): probe a bursting screen for PROCESSING so a spinner that never goes quiet is not read as idle - #766
Conversation
haofeif
left a comment
There was a problem hiding this comment.
Reviewed the standalone PR at 8a81b77d4ea472c382c04d6b9f5c2545b7eeb8ea (reported base c581b3be5555f925adcc3b0d7023182405695c88). Changes requested for one P2: discarding non-PROCESSING verdicts does not discard state changes performed by the detector. The intended Codex continuous-spinner transition, throttling boundaries, and timer cleanup work independently of the separate glyph PR; the blocker concerns another provider already opted into screen detection.
Current-head GitHub workflow runs require approval and do not establish a passing CI result.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #766 +/- ##
=======================================
Coverage ? 91.89%
=======================================
Files ? 207
Lines ? 29266
Branches ? 0
=======================================
Hits ? 26895
Misses ? 2371
Partials ? 0
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
8a81b77 to
9614ac6
Compare
haofeif
left a comment
There was a problem hiding this comment.
Re-reviewed 9614ac61e337310ad070bd1a02b30ddf6dc1ef9a against 405750f8374314f861bfa3c315b671b3f989c8d5, covering all seven changed files and the full provider/monitor state path.
The original MiniMax P2 is fixed. The opt-in predicate prevents discarded detection from changing its completion identity, buffer epoch or awaiting-turn flag; the restored settled frame remains IDLE with the pending turn intact. Providers without the capability remain unprobed, as intended.
One separate P2 remains in Codex's predicate, documented inline with a rectification recommendation. It accepts the normal detector's missing-composer fallback as positive work evidence. A partial redraw can therefore consume the dispatch arm, re-latch the previous completion, and suppress the subsequent genuine processing transition. The comparison with the exact base uses real Codex, pyte, monitor routing, worker-thread execution and quiescence timers, with both a current-style frame and the existing complex-response fixture. This is a monitor-state regression in the PR, not an additional shared-poller requirement or a demand for unsupported providers to opt in.
… never goes quiet is not read as idle
9614ac6 to
73bcc83
Compare
haofeif
left a comment
There was a problem hiding this comment.
Re-reviewed 73bcc830f8eb63b470a9d9342e61388afdae4d23 against base 4ad5e6bf0f94ad34aa528eb08dc88362476d11ce. Both prior findings are fixed; no significant current-diff issue remains.
The Codex mid-burst predicate now requires a positive progress row before consulting the full detector. The normal missing-composer fallback no longer consumes the dispatch arm during a partial redraw. Real provider/pyte/monitor replays with two different composer frames preserve the arm through erase and restored old completion, then accept the genuine new spinner; the previous reviewed head reproduces the earlier failure under the same conditions. Trust, login, update, approval, error and exited-shell guards remain effective, including frames containing a spinner.
The MiniMax repair remains intact: non-opted-in providers are not probed, partial redraw does not mutate the turn/completion bookkeeping, and restored state remains armed and awaiting the dispatched turn. Existing throttling and sticky-latch behavior is preserved.
151 focused existing cases passed, with additional bounded composed controls through actual worker-thread routing and quiescence timers. External I/O alone was substituted; no live-provider acceptance is claimed. All 23 current-head checks returned SUCCESS at publication preparation. The updated Codecov comment was read; approval is not a claim of complete patch coverage.
Fixes #757. Related: #659, #735, #714.
Summary
Rendered-screen detection runs only on the rising edge and at quiescence. Codex repaints its spinner every second while a command runs, so the terminal never goes quiescent, the detector is never invoked mid-turn, and the terminal reads
idlefor its whole busy turn (the rising-edge frame is composited before the spinner is drawn). The provider detector is right on every one of those frames; it just never gets asked. Consequences: inbox delivery pastes into a busy turn, the deferred-assign confirm reads "idle, never working", and external coordinators wait out the handoff timeout.Change
StatusMonitor._midburst_processing_probe: while a terminal is bursting and its last status is not PROCESSING, probe the composited pyte screen at most everyPYTE_MIDBURST_PROBE_S(1.0 s, envCAO_PYTE_MIDBURST_PROBE_S) and apply only a PROCESSING verdict. Ready statuses still wait for quiescence, so the anti-flap rule that ruled out per-chunk detection is preserved: a half-drawn frame can upgrade to busy, never settle to ready. The probe stops once PROCESSING is latched, and_apply_detection's sticky-latch/arm rules are untouched.BaseProvider.probe_processing_from_screen(), and only of providers that opt in withsupports_midburst_processing_probe— the same fail-closed shape assupports_screen_detectionandsupports_direct_status_probe. It never calls the full detector: discarding a verdict does not undo the turn bookkeeping a detector commits while reaching it.minimax_codeopts into screen detection and commits_last_completion_identity/_last_completion_buffer_epochand clears_awaiting_turninsideget_status, so a mid-redraw frame would register as a new completion and the next settled frame would report a pending turn complete on the previous turn's output.CodexProvideropts in and requires positive evidence of work: the progress row must be drawn, and only then does the full detector get the final say, keeping the trust-prompt, login-menu, approval-dialog and error guards. Inheriting the detector's no-composer catch-all would be wrong here, because a partial redraw that erases the composer while the previous response is still on screen carries no evidence of a new turn; taken as busy it spends the monitor's dispatch arm, the restored old completion latches, and the genuine spinner that follows is refused.TestMidBurstProcessingProbe): the Codex spinner transition through the real provider; the minimax bookkeeping unchanged across a burst with the settled frame still IDLE and_awaiting_turnset; a provider without the opt-in never probed and no detector run; the throttle; no probe once PROCESSING. The probe tests feed a real pyte screen rather than stubbing detection.docs/event-driven-architecture.mdStatusMonitor section,docs/configuration.mdenv note.Live verification
Same
sleep 30task oncodex-cli 0.153.4, polled every 4 s: before,idle×12 thencompleted; after,processing×9 thencompleted.Tests
test/services/andtest/providers/: 4817 passed, 9 skipped, 1 xfailed, against 4811 passed onmainat the same commit with the identical 43 pre-existing AG-UI failures in this environment.blackandisortclean on touched files. Rebased ontomain(405750f).