Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions emrg/server/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -622,9 +622,14 @@ def _saturation_heartbeat_active(self) -> bool:
async def _request_vibe_check(self, ws, prompt: str, completion_summary: str) -> dict | None:
"""Ask the daemon for a structured vibe check on the SAME connection.

Sends ``task_vibe_check`` and waits for ``vibe_check_result`` (~20s).
Fully defensive — any failure/timeout returns None; the caller
conservatively leaves the slowdown state unchanged.
Sends ``task_vibe_check`` and waits for ``vibe_check_result``. Rant
2026-08-20T20:19:31: no timeout — the vibe check is the completion
judgment right after a finished cycle; when concurrent tasks hold the
LLM a single call can exceed 20s, and waiting longer for an accurate
work/reason beats dropping the data (the daemon's LLM call has its own
retry/timeout, and a dead daemon raises ConnectionClosed).
Fully defensive — any failure/connection-close returns None; the
caller conservatively leaves the slowdown state unchanged.
"""
try:
await ws.send(json.dumps({
Expand All @@ -635,13 +640,9 @@ async def _request_vibe_check(self, ws, prompt: str, completion_summary: str) ->
"prompt": (prompt or "")[:2000],
"completion_summary": (completion_summary or "")[:3000],
}, ensure_ascii=False))
deadline = time.monotonic() + 20.0
while time.monotonic() < deadline:
remaining = max(0.5, deadline - time.monotonic())
while True:
try:
frame = json.loads(await asyncio.wait_for(ws.recv(), timeout=remaining))
except asyncio.TimeoutError:
break
frame = json.loads(await ws.recv())
except ConnectionClosed:
break
if frame.get("type") != "vibe_check_result":
Expand Down
Loading