harness: emit needs_login_idle on every wait_for_login entry (closes #563)
mara on #563: 'we fixed the agent to not start turns in that state (it fell back to online before), but this does not show on dashboard properly'. Root cause: the per-agent harness flips LoginState::NeedsLogin in memory on three entry paths (cold-boot without a session, 401 mid-turn, /api/logout) and parks in wait_for_login. But wait_for_login itself never called bus.emit_status('needs_login_idle') at entry — only the /api/logout handler does that today. So: - Cold boot: agent has no session, harness shows 'needs login' on its own web UI (via LoginState mutex), but the dashboard's needs_login field stays false because the {state_dir}/hyperhive-needs-login sentinel was never written. - 401 mid-turn: same — the 'after a turn failed' path in hive-ag3nt.rs / hive-m1nd.rs flips LoginState directly without emitting status, then calls wait_for_login, which now waits silently with no sentinel write. Fix: hoist the emit_status('needs_login_idle') call into wait_for_login itself. All three entry paths get the sentinel write for free; the /api/logout handler's explicit call (web_ui.rs line 966) becomes redundant but idempotent — no behaviour change there. The 'online' clear at session refresh stays exactly where it was at the loop's exit. Both hive-ag3nt and hive-m1nd binaries share wait_for_login, so the manager harness benefits without a separate change.
This commit is contained in:
parent
5a0b6ca907
commit
a725d34b19
1 changed files with 11 additions and 0 deletions
|
|
@ -497,6 +497,17 @@ pub async fn wait_for_login(
|
|||
claude_dir = %claude_dir.display(),
|
||||
"no claude session — staying in partial-run mode (web UI only)"
|
||||
);
|
||||
// #563: announce `needs_login_idle` to the bus so the sentinel file
|
||||
// (`{state_dir}/hyperhive-needs-login`) gets written on every entry
|
||||
// path — cold-boot, 401-mid-turn, and `/api/logout`. The host's
|
||||
// `auth_failed_sentinel` reads that file to surface `needs_login` on
|
||||
// the dashboard; prior to this call the cold-boot + 401 paths flipped
|
||||
// `LoginState::NeedsLogin` in memory but never touched the sentinel,
|
||||
// so the dashboard kept rendering `online` for a parked harness.
|
||||
// Idempotent — `emit_status` is a `write` on a small empty file, so
|
||||
// re-entering this function after a transient operator action is a
|
||||
// no-op for the on-disk state.
|
||||
bus.emit_status("needs_login_idle");
|
||||
let snapshot = snapshot_dir(claude_dir);
|
||||
let probe = Duration::from_millis(poll_ms.max(2000));
|
||||
loop {
|
||||
|
|
|
|||
Loading…
Reference in a new issue