fix: cap kanban card titles so an overlong card still names its worker
Kanban cards have no length limit, but the session title store rejects titles past SessionDB.MAX_TITLE_LENGTH with ValueError. _persist_session_title reads that as a unique-title collision, retries with a "#N" suffix (longer still), and the caller suppresses the second failure - so a worker spawned on a >100-char card ended up with no title at all, where main at least gave it a derived one. Trim the card title (with room for the "#N" retry suffix) before persisting; a retried card now gets "<trimmed> #2" within the cap. Review finding: >100-char card title left the kanban worker session untitled.
This commit is contained in:
@@ -473,9 +473,15 @@ def _kanban_task_title() -> Optional[str]:
|
||||
return None
|
||||
try:
|
||||
from hermes_cli import kanban_db, kanban_db_connect
|
||||
from hermes_state import SessionDB
|
||||
with kanban_db_connect.connect_closing() as conn:
|
||||
task = kanban_db.get_task(conn, task_id)
|
||||
title = (task.title or "").strip() if task is not None else ""
|
||||
title = " ".join((task.title or "").split()) if task is not None else ""
|
||||
# Cards have no length cap; the title store rejects past MAX_TITLE_LENGTH (and the ``#N``
|
||||
# retry suffix needs room), which would leave the worker nameless.
|
||||
cap = SessionDB.MAX_TITLE_LENGTH - 4
|
||||
if len(title) > cap:
|
||||
title = title[: cap - 1].rstrip() + "…"
|
||||
except Exception:
|
||||
logger.debug("Kanban task %s unreadable; naming the session after its id", task_id, exc_info=True)
|
||||
title = ""
|
||||
|
||||
@@ -374,6 +374,27 @@ class TestMaybeAutoTitle:
|
||||
assert db.get_session_title_source("sess-1") == "llm"
|
||||
mock_auto.assert_not_called()
|
||||
|
||||
def test_kanban_worker_with_an_overlong_card_title_is_still_named(self, tmp_path, monkeypatch):
|
||||
"""Cards have no length cap; the store rejects past MAX_TITLE_LENGTH, so the card title is trimmed, not dropped."""
|
||||
from hermes_cli import kanban_db, kanban_db_connect
|
||||
|
||||
card = "Investigate why the swap modal intermittently fails to render its confirmation step on mobile Safari after a retry"
|
||||
assert len(card) > SessionDB.MAX_TITLE_LENGTH
|
||||
with kanban_db_connect.connect_closing(board="default") as conn:
|
||||
task_id = kanban_db.create_task(conn, title=card, board="default")
|
||||
conn.commit()
|
||||
monkeypatch.setenv("HERMES_KANBAN_TASK", task_id)
|
||||
db = SessionDB(tmp_path / "state.db")
|
||||
for sid in ("sess-1", "sess-2"): # a retried card must still get the ``#N`` suffix within the cap
|
||||
db.create_session(session_id=sid, source="kanban")
|
||||
with patch("agent.title_generator.auto_title_session"):
|
||||
maybe_auto_title(db, sid, f"work kanban task {task_id}", [])
|
||||
|
||||
first, second = db.get_session_title("sess-1"), db.get_session_title("sess-2")
|
||||
assert first and first.startswith(card[:40]) and first.endswith("…")
|
||||
assert second == f"{first} #2"
|
||||
assert len(second) <= SessionDB.MAX_TITLE_LENGTH
|
||||
|
||||
def test_kanban_worker_with_unreadable_card_falls_back_to_the_task_id(self, tmp_path, monkeypatch):
|
||||
monkeypatch.setenv("HERMES_KANBAN_TASK", "t_missing")
|
||||
db = SessionDB(tmp_path / "state.db")
|
||||
|
||||
Reference in New Issue
Block a user