hermes-agent/tests/hermes_cli/test_kanban_comment_queries.py
Brooklyn Nicholson 901205420f feat(kanban): talk to a running worker without a restart
A running worker now polls its comment thread and folds new operator notes
into the live turn via the OUT-OF-BAND steer channel (list_comments_after +
a heartbeat-driven bridge, watermarked so history isn't re-injected and the
worker's own notes are skipped). No block→comment→unblock dance. Desktop's
composer sends notes live ("delivered within a few seconds") with "Requeue
with note" as the restart option and a help tooltip.
2026-07-30 07:18:08 -05:00

54 lines
1.6 KiB
Python

"""Comment-watermark queries in kanban_db.
``list_comments_after`` backs the live worker bridge: it returns only comments
newer than a cursor so a running worker folds in new operator notes without
re-reading the whole thread.
"""
from __future__ import annotations
import sys
from pathlib import Path
import pytest
_WORKTREE = Path(__file__).resolve().parents[2]
if str(_WORKTREE) not in sys.path:
sys.path.insert(0, str(_WORKTREE))
from hermes_cli import kanban_db as kb
@pytest.fixture
def fresh_home(tmp_path, monkeypatch):
home = tmp_path / "hermes_home"
home.mkdir()
monkeypatch.setenv("HERMES_HOME", str(home))
monkeypatch.setattr(Path, "home", lambda: tmp_path)
for var in ("HERMES_KANBAN_DB", "HERMES_KANBAN_WORKSPACES_ROOT", "HERMES_KANBAN_HOME", "HERMES_KANBAN_BOARD"):
monkeypatch.delenv(var, raising=False)
try:
import hermes_constants
hermes_constants._cached_default_hermes_root = None # type: ignore[attr-defined]
except Exception:
pass
kb._INITIALIZED_PATHS.clear()
return home
def test_list_comments_after_cursor(fresh_home):
conn = kb.connect()
try:
tid = kb.create_task(conn, title="chat")
c1 = kb.add_comment(conn, tid, author="alice", body="first")
c2 = kb.add_comment(conn, tid, author="bob", body="second")
assert [c.id for c in kb.list_comments_after(conn, tid, after_id=0)] == [c1, c2]
newer = kb.list_comments_after(conn, tid, after_id=c1)
assert [c.id for c in newer] == [c2]
assert newer[0].body == "second"
assert kb.list_comments_after(conn, tid, after_id=c2) == []
finally:
conn.close()