emrg: vibe check & slowdown refactor — recommend_slowdown-only throttle + unified work/slowdown_reason fields (rant 2026-08-20T10:58:55) - #880
Conversation
…le + unified work/slowdown_reason fields (rant 2026-08-20T10:58:55)
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle (1/3)
Full implementation of host rant 2026-08-20T10:58:55 (design-finalized vibe check & slowdown refactor):
- empty-cycle counter + slowdown-vote machinery deleted; throttle decided solely by vibe check
recommend_slowdown - fields unified to
work/recommend_slowdown/slowdown_reason(summary/meaningful/reasonremoved) across protocol, daemon, scheduler, GUI - slowdown flag persisted to ~/.emrg/saturation/.json, survives daemon restarts (legacy files read as not-throttled)
- status() drops last_cycle_summary; GUI primary row shows throttled badge (heartbeat interval), secondary list shows work/slowdown_reason
Verification:
- pytest: 986 passed, 1 skipped (test + test-windows CI green on head via re-triggered dispatch run 32329212493)
- import + CLI OK; GUI npm test 253/260 (7 by-design local daemon-spawn fails, green in CI)
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle (2/3)
Fresh-cycle re-review of the full diff (head 83925e0):
protocol.py: EvolutionLog fields unified — summary→work, meaningful deleted, reason→slowdown_reason. Clean, no stale refs.vibe_check.j2: prompt rewritten for the 3-field JSON; agent no longer self-rates meaningful; slowdown_reason required only when recommend_slowdown=true. Matches daemon parsing (_task_vibe_check).scheduler.py: empty-cycle counter + vote machinery fully removed;_slowdown_activeis the single switch (vibe recommend_slowdown only); persisted to saturation/.json across restarts; truncated/vibe-unavailable/aborted leave state unchanged; manual trigger clears.status()drops last_cycle_summary, saturation = {heartbeat_interval, heartbeat_active}.- GUI: dialogs.js renders work/slowdown_reason + throttled badge on heartbeat_active; i18n taskThrottled; renderer smoke updated for the new model.
- Tests rewritten comprehensively (state machine, persistence incl. legacy-file no-migration, heartbeat, ws_e2e 3-field).
CI: test + test-windows SUCCESS on head via re-triggered dispatch run 32329212493 (original PR run cancelled after Windows runner hang — runner issue, not code).
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle (3/3)
Fresh-cycle re-verification: head 83925e0 unchanged since 2/3. Both platforms green on head (test + test-windows SUCCESS via dispatch run 32329212493; the PR's own windows run was cancelled only due to a GitHub runner hang — re-triggered and green, same as #873). Full diff reviewed across the earlier cycles: protocol/daemon/scheduler/GUI field unification, flag-only slowdown state machine with persistence, comprehensive test rewrite. No issues found — merging.
vibe check & slowdown refactor (rant 2026-08-20T10:58:55, host design-finalized)
The host finalized a redesign of the vibe-check / slowdown mechanism:
_empty_cycles) and the slowdown-vote machinery (_slowdown_hits, thresholds 30/10) entirely.recommend_slowdownflag:true→_slowdown_active=True(next run at heartbeat interval),false→ back to normal interval. Vibe unavailable / truncated / aborted → state unchanged (conservative). Manual trigger (/trigger) clears the flag.~/.emrg/saturation/<task>.json({"slowdown_active": bool}) so it survives daemon restarts; legacy files read as not-throttled (no migration).work/recommend_slowdown/slowdown_reason:summary/done→work,meaningfuldeleted (agent no longer self-rates value),reason→slowdown_reason.status()dropslast_cycle_summary; GUI primary row shows onlylast_run_at+ throttled badge (heartbeat interval), the expandable secondary list showswork/ throttle flag /slowdown_reason(no idle badge —meaningfulis gone).Background: the agent's self-rating
meaningfulwas indirect and error-prone (e.g. a deepseek-harness session with 44 tool calls was judged "empty" by a naive heuristic).Changes
emrg/server/scheduler.py— state machine rewritten (init,_load/_save_saturation_state,_load_task_runs/_append_task_runfields,run()wait mode + manual-trigger reset,status(),_saturation_heartbeat_active(),_request_vibe_checkreturnswork/recommend_slowdown/slowdown_reason,_run_evolution_cyclelog construction).emrg/server/prompts/vibe_check.j2— prompt rewritten for the 3-field JSON output.emrg/protocol.py—EvolutionLogfields:summary→work,meaningfuldeleted,reason→slowdown_reason.emrg/server/daemon.py—_task_vibe_checkresult parsing updated.emrg/gui/renderer/js/dialogs.js+i18n.js— task run detail useswork/slowdown_reason; saturation badge text →app.taskThrottled("已降频 · heartbeat {m}s").tests/—test_scheduler.py(state machine, persistence, heartbeat tests rewritten for the flag model),test_ws_e2e.py(3-field vibe result),renderer.smoke.test.js(new mock fields + badge assertions).Verification
uv run pytest tests/ -q→ 986 passed, 1 skippeduv run python -c "from emrg.client.app import run_client"+python -m emrg --help→ OKnpm test→ 253/260 (7 by-design local daemon-spawn fails, green in CI)