mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-23 10:42:00 +00:00
fix(codex): seed app-server sessions with configured cwd
This commit is contained in:
parent
745c4db235
commit
c11ae8261b
4 changed files with 84 additions and 1 deletions
|
|
@ -617,6 +617,10 @@ class SessionManager:
|
|||
|
||||
_register_task_cwd(session_id, cwd)
|
||||
agent = AIAgent(**kwargs)
|
||||
# Codex app-server sessions are spawned lazily on the first turn. Stamp
|
||||
# the ACP workspace onto the agent so the Codex runtime starts from the
|
||||
# editor/session cwd instead of the Hermes daemon's process cwd.
|
||||
agent.session_cwd = cwd
|
||||
# ACP stdio transport requires stdout to remain protocol-only JSON-RPC.
|
||||
# Route any incidental human-readable agent output to stderr instead.
|
||||
agent._print_fn = _acp_stderr_print
|
||||
|
|
|
|||
|
|
@ -250,7 +250,9 @@ def run_codex_app_server_turn(
|
|||
# Spawned on first turn, reused across turns, closed at AIAgent
|
||||
# shutdown (see _cleanup hook).
|
||||
if not hasattr(agent, "_codex_session") or agent._codex_session is None:
|
||||
cwd = getattr(agent, "session_cwd", None) or os.getcwd()
|
||||
from agent.runtime_cwd import resolve_agent_cwd
|
||||
|
||||
cwd = getattr(agent, "session_cwd", None) or str(resolve_agent_cwd())
|
||||
# Approval callback: defer to Hermes' standard prompt flow if a
|
||||
# CLI thread has installed one. Gateway / cron contexts get the
|
||||
# codex-side fail-closed default.
|
||||
|
|
|
|||
|
|
@ -77,6 +77,50 @@ class TestCreateSession:
|
|||
def test_get_nonexistent_session_returns_none(self, manager):
|
||||
assert manager.get_session("does-not-exist") is None
|
||||
|
||||
def test_make_agent_stamps_session_cwd_for_codex_runtime(self, monkeypatch):
|
||||
class FakeAgent:
|
||||
model = "fake-model"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.kwargs = kwargs
|
||||
|
||||
monkeypatch.setattr("run_agent.AIAgent", FakeAgent)
|
||||
monkeypatch.setattr(
|
||||
"acp_adapter.session.load_config",
|
||||
lambda: {
|
||||
"model": {
|
||||
"default": "fake-model",
|
||||
"provider": "fake-provider",
|
||||
},
|
||||
"mcp_servers": {},
|
||||
},
|
||||
raising=False,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.config.load_config",
|
||||
lambda: {
|
||||
"model": {
|
||||
"default": "fake-model",
|
||||
"provider": "fake-provider",
|
||||
},
|
||||
"mcp_servers": {},
|
||||
},
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"hermes_cli.runtime_provider.resolve_runtime_provider",
|
||||
lambda requested=None: {
|
||||
"provider": requested,
|
||||
"api_mode": "codex_app_server",
|
||||
"base_url": "https://example.invalid",
|
||||
"api_key": "test-key",
|
||||
},
|
||||
)
|
||||
monkeypatch.setattr("acp_adapter.session._register_task_cwd", lambda task_id, cwd: None)
|
||||
|
||||
state = SessionManager(db=None).create_session(cwd="/tmp/project")
|
||||
|
||||
assert state.agent.session_cwd == "/tmp/project"
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -293,6 +293,39 @@ class TestRunConversationCodexPath:
|
|||
agent.run_conversation("hi")
|
||||
assert not client_mock.chat.completions.create.called
|
||||
|
||||
def test_gateway_terminal_cwd_seeds_codex_thread_cwd(self, monkeypatch, tmp_path):
|
||||
"""Gateway sessions set TERMINAL_CWD without stamping agent.session_cwd.
|
||||
Codex app-server must still start in that configured workspace instead
|
||||
of falling back to the Hermes daemon process cwd."""
|
||||
from agent.transports.codex_app_server_session import (
|
||||
CodexAppServerSession, TurnResult,
|
||||
)
|
||||
|
||||
captured: dict[str, str] = {}
|
||||
|
||||
def fake_init(self, **kwargs):
|
||||
captured["cwd"] = kwargs["cwd"]
|
||||
self._thread_id = "thread-stub-1"
|
||||
|
||||
def fake_run_turn(self, user_input: str, **kwargs):
|
||||
return TurnResult(
|
||||
final_text="ok",
|
||||
projected_messages=[{"role": "assistant", "content": "ok"}],
|
||||
turn_id="turn-stub-1",
|
||||
thread_id="thread-stub-1",
|
||||
)
|
||||
|
||||
monkeypatch.setenv("TERMINAL_CWD", str(tmp_path))
|
||||
monkeypatch.setattr(CodexAppServerSession, "__init__", fake_init)
|
||||
monkeypatch.setattr(CodexAppServerSession, "run_turn", fake_run_turn)
|
||||
|
||||
agent = _make_codex_agent()
|
||||
assert not hasattr(agent, "session_cwd")
|
||||
with patch.object(agent, "_spawn_background_review", return_value=None):
|
||||
agent.run_conversation("hi")
|
||||
|
||||
assert captured["cwd"] == str(tmp_path)
|
||||
|
||||
|
||||
class TestReviewForkApiModeDowngrade:
|
||||
"""When the parent agent runs on codex_app_server, the background
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue