diff --git a/tests/hermes_cli/test_quiet_turn_author.py b/tests/hermes_cli/test_quiet_turn_author.py index 6a13c781d3..23bd040f5f 100644 --- a/tests/hermes_cli/test_quiet_turn_author.py +++ b/tests/hermes_cli/test_quiet_turn_author.py @@ -60,3 +60,48 @@ def test_quiet_one_shot_consumes_the_variable_before_the_turn(monkeypatch): _run(monkeypatch, json.dumps(AUTHOR), run_conversation) assert seen["env"] is None assert TURN_AUTHOR_ENV not in os.environ + + +def test_quiet_one_shot_resumes_nested_notify_on_this_session_not_parent(monkeypatch, capsys): + """A nested Bot Mode completion keyed to B wakes B even when the parent env still names A. + + ``chat -Q`` used to inherit the dispatcher's HERMES_SESSION_KEY and exit after the + dispatch ack, so C's reply was saved but B never resumed. + """ + from tools.approval_context import get_current_session_key + from tools.process_registry import process_registry + + monkeypatch.delenv("HERMES_KANBAN_GOAL_MODE", raising=False) + monkeypatch.delenv("HERMES_KANBAN_TASK", raising=False) + monkeypatch.setenv("HERMES_SESSION_KEY", "session-A") + calls = [] + + def run_conversation(**kwargs): + calls.append({"key": get_current_session_key(), "msg": kwargs["user_message"]}) + if len(calls) == 1: + process_registry.completion_queue.put({ + "type": "completion", + "session_id": "proc-c", + "session_key": "session-B", + "command": "message_agent C", + "exit_code": 0, + "output": "marker-from-C", + }) + return {"final_response": "sent, finish your turn"} + return {"final_response": "C said marker-from-C"} + + agent = SimpleNamespace(run_conversation=run_conversation, session_id="session-B") + try: + with pytest.raises(SystemExit) as exc: + cli._run_quiet_single_query( + SimpleNamespace(agent=agent, conversation_history=[], session_id="session-B"), + "ask C", + ) + assert exc.value.code == 0 + assert calls[0] == {"key": "session-B", "msg": "ask C"} + assert calls[1]["key"] == "session-B" + assert "marker-from-C" in calls[1]["msg"] + assert capsys.readouterr().out.strip() == "C said marker-from-C" + finally: + while not process_registry.completion_queue.empty(): + process_registry.completion_queue.get_nowait() diff --git a/tests/tools/test_bot_relay.py b/tests/tools/test_bot_relay.py index 270716d46e..19aaa4bbe3 100644 --- a/tests/tools/test_bot_relay.py +++ b/tests/tools/test_bot_relay.py @@ -614,8 +614,14 @@ def test_delivery_env_carries_only_the_given_author(monkeypatch): monkeypatch.setenv("HERMES_RELAY_TEST_MARKER", "kept") monkeypatch.setenv(TURN_AUTHOR_ENV, json.dumps({"id": "bot:previous", "name": "previous", "is_bot": True})) + monkeypatch.setenv("HERMES_SESSION_KEY", "session-A") + monkeypatch.setenv("HERMES_UI_SESSION_ID", "ui-A") + monkeypatch.setenv("HERMES_SESSION_ID", "session-A") assert TURN_AUTHOR_ENV not in bot_relay.delivery_env(None) env = bot_relay.delivery_env(bot_relay.delivery_turn_author("ops", "ops")) assert json.loads(env[TURN_AUTHOR_ENV]) == {"id": "bot:ops", "name": "ops", "is_bot": True} assert env["HERMES_RELAY_TEST_MARKER"] == "kept" + assert "HERMES_SESSION_KEY" not in env + assert "HERMES_UI_SESSION_ID" not in env + assert "HERMES_SESSION_ID" not in env