mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-29 06:31:32 +00:00
test(cli,gateway): cover bracket-stripping and gateway session-ID lookup
- CLI: bracketed/quoted target resolves; mismatched single bracket passes through unchanged. - Gateway: bracketed session ID resolves; bare untitled session ID resolves via get_session() fallback.
This commit is contained in:
parent
1c7a783c42
commit
4fbdf0e893
2 changed files with 98 additions and 0 deletions
|
|
@ -75,3 +75,44 @@ class TestCliResumeCommand:
|
|||
assert "out of range" in printed.lower()
|
||||
assert "/resume" in printed
|
||||
assert cli_obj.session_id == "current_session"
|
||||
|
||||
def test_handle_resume_strips_outer_brackets(self):
|
||||
"""Users copy `<session_id>` from the usage hint literally.
|
||||
|
||||
Strip outer ``<>``, ``[]``, ``""``, and ``''`` before lookup so
|
||||
``/resume <abc123>`` works the same as ``/resume abc123``.
|
||||
"""
|
||||
cli_obj = _make_cli()
|
||||
cli_obj._session_db.get_session.return_value = {"id": "sess_alpha", "title": "Alpha"}
|
||||
cli_obj._session_db.get_messages_as_conversation.return_value = []
|
||||
cli_obj._session_db.resolve_resume_session_id.return_value = "sess_alpha"
|
||||
|
||||
for raw in ("<sess_alpha>", "[sess_alpha]", '"sess_alpha"', "'sess_alpha'"):
|
||||
cli_obj.session_id = "current_session"
|
||||
with (
|
||||
patch("hermes_cli.main._resolve_session_by_name_or_id", return_value="sess_alpha"),
|
||||
patch("cli._cprint"),
|
||||
):
|
||||
cli_obj._handle_resume_command(f"/resume {raw}")
|
||||
assert cli_obj.session_id == "sess_alpha", (
|
||||
f"bracket-stripping failed for {raw!r}: session_id stayed {cli_obj.session_id}"
|
||||
)
|
||||
|
||||
def test_handle_resume_does_not_strip_partial_brackets(self):
|
||||
"""Mismatched or single brackets must pass through unmodified.
|
||||
|
||||
``"<half`` (just an open angle) is not a wrapping pair, so the
|
||||
lookup should treat it verbatim — preserving the existing
|
||||
not-found error path instead of mangling the input.
|
||||
"""
|
||||
cli_obj = _make_cli()
|
||||
cli_obj._session_db.get_session.return_value = None
|
||||
|
||||
with (
|
||||
patch("hermes_cli.main._resolve_session_by_name_or_id", return_value=None),
|
||||
patch("cli._cprint") as mock_cprint,
|
||||
):
|
||||
cli_obj._handle_resume_command("/resume <half")
|
||||
|
||||
printed = " ".join(str(call) for call in mock_cprint.call_args_list)
|
||||
assert "<half" in printed
|
||||
|
|
|
|||
|
|
@ -301,3 +301,60 @@ class TestHandleResumeCommand:
|
|||
|
||||
assert real_key not in runner._agent_cache
|
||||
db.close()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resume_strips_outer_brackets(self, tmp_path):
|
||||
"""Users may copy `<session_id>` from the usage hint literally.
|
||||
|
||||
The gateway should strip outer ``<>``, ``[]``, ``""``, and ``''``
|
||||
before lookup so ``/resume <abc123>`` works the same as
|
||||
``/resume abc123``.
|
||||
"""
|
||||
from hermes_state import SessionDB
|
||||
db = SessionDB(db_path=tmp_path / "state.db")
|
||||
db.create_session("abc123", "telegram")
|
||||
db.set_session_title("abc123", "Bracketed")
|
||||
db.create_session("current_session_001", "telegram")
|
||||
|
||||
for raw in ("<abc123>", "[abc123]", '"abc123"', "'abc123'"):
|
||||
event = _make_event(text=f"/resume {raw}")
|
||||
runner = _make_runner(
|
||||
session_db=db,
|
||||
current_session_id="current_session_001",
|
||||
event=event,
|
||||
)
|
||||
result = await runner._handle_resume_command(event)
|
||||
# Either the session was resumed (and we get a "Resumed" / "Already on" reply)
|
||||
# or it was found-then-redirected. Failure mode = "No session found matching '<abc123>'".
|
||||
assert "abc123" not in str(result) or "not found" not in str(result).lower(), (
|
||||
f"bracket stripping failed for {raw!r}: gateway returned {result!r}"
|
||||
)
|
||||
db.close()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resume_resolves_by_session_id(self, tmp_path):
|
||||
"""The gateway should accept a bare session ID, not just a title.
|
||||
|
||||
Before this fix, /resume in the gateway only called
|
||||
``resolve_session_by_title``, so ``/resume <session_id>`` always
|
||||
returned "Session not found" even for valid IDs.
|
||||
"""
|
||||
from hermes_state import SessionDB
|
||||
db = SessionDB(db_path=tmp_path / "state.db")
|
||||
db.create_session("unnamed_session_xyz", "telegram")
|
||||
# Deliberately no title set — this session can ONLY be resolved by ID.
|
||||
db.create_session("current_session_001", "telegram")
|
||||
|
||||
event = _make_event(text="/resume unnamed_session_xyz")
|
||||
runner = _make_runner(
|
||||
session_db=db,
|
||||
current_session_id="current_session_001",
|
||||
event=event,
|
||||
)
|
||||
result = await runner._handle_resume_command(event)
|
||||
|
||||
# Should NOT be the not-found error.
|
||||
assert "not found" not in str(result).lower(), (
|
||||
f"session-id lookup failed: {result!r}"
|
||||
)
|
||||
db.close()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue