1f3912d277
Independent review found two gaps in the first fix. The TUI/Desktop/dashboard goal path (tui_gateway/prompt_turn.py) still passed every agent's processes to the judge; it now filters by the session's own key like the CLI and gateway loops. And the 30-minute barrier cap (and a pid/timer barrier lifting at all) was only checked lazily, on the next turn, so a parked session with nothing else arriving stayed parked. The CLI idle hook now checks the barrier every 5 s while idle and queues the goal's continuation the moment it lifts. Tests (2 new): an elapsed timed barrier queues the continuation from the idle hook and clears the barrier; an unparked or inactive goal is a no-op.
59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
"""A parked /goal resumes from the idle hook once its barrier lifts, without waiting for another turn."""
|
|
import queue
|
|
import time
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from hermes_cli import goals
|
|
from hermes_cli.cli_loops_mixin import CLILoopsMixin
|
|
|
|
|
|
@pytest.fixture
|
|
def hermes_home(tmp_path, monkeypatch):
|
|
from pathlib import Path
|
|
home = tmp_path / ".hermes"; home.mkdir()
|
|
monkeypatch.setattr(Path, "home", lambda: tmp_path)
|
|
monkeypatch.setenv("HERMES_HOME", str(home))
|
|
goals._DB_CACHE.clear()
|
|
yield home
|
|
goals._DB_CACHE.clear()
|
|
|
|
|
|
class _Cli(CLILoopsMixin):
|
|
def __init__(self, mgr):
|
|
self._pending_input = queue.Queue()
|
|
self._mgr = mgr
|
|
|
|
def _get_goal_manager(self):
|
|
return self._mgr
|
|
|
|
|
|
def test_idle_hook_queues_the_continuation_when_a_timed_barrier_has_elapsed(hermes_home):
|
|
mgr = goals.GoalManager(session_id="resume-idle")
|
|
mgr.set("finish the thing")
|
|
mgr.wait_for_seconds(1, reason="cooldown")
|
|
cli = _Cli(mgr)
|
|
with patch("cli._cprint"), patch("cli._DIM", ""), patch("cli._RST", ""):
|
|
cli._maybe_resume_parked_goal()
|
|
assert cli._pending_input.empty() # still parked
|
|
mgr.state.waiting_until = time.time() - 1
|
|
mgr._save()
|
|
cli._last_goal_barrier_check = 0.0
|
|
cli._maybe_resume_parked_goal()
|
|
assert not cli._pending_input.empty() # continuation queued
|
|
assert "finish the thing" in cli._pending_input.get()
|
|
assert mgr.state.waiting_until == 0.0 # barrier cleared
|
|
|
|
|
|
def test_idle_hook_is_a_no_op_for_an_unparked_or_inactive_goal(hermes_home):
|
|
mgr = goals.GoalManager(session_id="resume-noop")
|
|
mgr.set("g")
|
|
cli = _Cli(mgr)
|
|
cli._maybe_resume_parked_goal()
|
|
assert cli._pending_input.empty()
|
|
mgr.clear()
|
|
cli._last_goal_barrier_check = 0.0
|
|
cli._maybe_resume_parked_goal()
|
|
assert cli._pending_input.empty()
|