diff --git a/acp_adapter/server.py b/acp_adapter/server.py index 65241f6978dde..f6e0462ec9d1c 100644 --- a/acp_adapter/server.py +++ b/acp_adapter/server.py @@ -1868,7 +1868,7 @@ class HermesACPAgent(acp.Agent): # model emits absolute paths under ~/.hermes/workspace and the # edit silently lands outside the editor's workspace. session_tokens = set_session_vars( - session_key=session_id, cwd=state.cwd, + session_key=session_id, session_id=session_id, cwd=state.cwd, ) except Exception: session_tokens = None diff --git a/tests/acp/test_server.py b/tests/acp/test_server.py index 8ec168b0f9495..55f9b42ef014d 100644 --- a/tests/acp/test_server.py +++ b/tests/acp/test_server.py @@ -409,6 +409,43 @@ class TestPrompt: assert isinstance(resp, PromptResponse) assert resp.stop_reason == "refusal" + @pytest.mark.asyncio + async def test_prompt_binds_session_id_into_subprocess_env(self, agent, mock_manager): + """The ACP prompt path must bridge the session id into child subprocesses. + + Regression: ``set_session_vars`` was called with ``session_key`` only, + leaving the ``HERMES_SESSION_ID`` ContextVar bound to the explicit "" + default. Once the session-context machinery is engaged, that empty value + is authoritative — so ``_make_run_env`` handed child subprocesses an + empty ``HERMES_SESSION_ID`` instead of the session's own id. + """ + from tools.environments.local import _make_run_env + + resp = await agent.new_session(cwd=".") + state = mock_manager.get_session(resp.session_id) + + captured: dict[str, str | None] = {} + + def _run(*args, **kwargs): + # Runs inside the session context copy set up by prompt(). + captured["child"] = _make_run_env({}).get("HERMES_SESSION_ID") + return {"final_response": "ok", "messages": []} + + state.agent.run_conversation = _run + state.agent.model = "test-model" + state.agent.provider = "openrouter" + + mock_conn = MagicMock(spec=acp.Client) + mock_conn.session_update = AsyncMock() + agent._conn = mock_conn + + await agent.prompt( + prompt=[TextContentBlock(type="text", text="hi")], + session_id=resp.session_id, + ) + + assert captured.get("child") == resp.session_id +