Preserve agent cwd through Codex app server
This commit is contained in:
@@ -204,14 +204,16 @@ prompt_delivery = "exec" # {kickoff}=prompt file, {session}=session name,
|
||||
|
||||
For an `"arg"` backend the flag *templates* are configurable (so you can point at a non-claude
|
||||
CLI): `resume_flag` (default `--resume '{id}'`), `model_flag` (default `--model '{model}'`),
|
||||
`remote_control_flag` (default `--remote-control '{session}'`), and `remote_addr_flag` (default
|
||||
`--remote '{addr}'`). A backend that sets `process_name`
|
||||
`remote_control_flag` (default `--remote-control '{session}'`), `remote_addr_flag` (default
|
||||
`--remote '{addr}'`), and `remote_cwd_flag` (default `-C {dir}` whenever `remote_addr` is set).
|
||||
A backend that sets `process_name`
|
||||
participates in backend-mismatch healing; one that doesn't (e.g. `demo`) never does.
|
||||
An optional `preamble` runs first and must succeed before the TUI starts; it supports `{bin}`,
|
||||
`{session}`, `{model}`, and `{dir}` templates. The Codex backend uses it to idempotently start the
|
||||
shared Remote Control daemon, then uses `remote_addr = "unix://"` to connect each tmux-hosted Codex
|
||||
TUI to that daemon. This keeps the app-server as the sole thread-store writer while local and
|
||||
Remote clients share the session.
|
||||
TUI to that daemon. The accompanying `-C` is required because the daemon's process directory is
|
||||
independent of the agent's. This keeps the app-server as the sole thread-store writer while local
|
||||
and Remote clients share the session in the configured project directory.
|
||||
For an unattended TUI with a deterministic first-run gate, `startup_prompt_re` opts into one
|
||||
screen check after `startup_prompt_delay` seconds; on a match, the harness types the explicitly
|
||||
configured `startup_prompt_response` and `submit_key`. Codex uses this to trust the agent's
|
||||
|
||||
@@ -350,10 +350,15 @@ def start_agent(cfg, agent, *, force=False):
|
||||
parts.append(_render_template(backend.get("remote_control_flag",
|
||||
"--remote-control '{session}'"), {"session": session}))
|
||||
if backend.get("remote_addr"):
|
||||
parts.append(_render_template(backend.get("remote_addr_flag", "--remote '{addr}'"), {
|
||||
remote_values = {
|
||||
"addr": backend["remote_addr"], "session": session, "model": model,
|
||||
"dir": shlex.quote(cwd),
|
||||
}))
|
||||
}
|
||||
parts.append(_render_template(
|
||||
backend.get("remote_addr_flag", "--remote '{addr}'"), remote_values))
|
||||
remote_cwd_flag = backend.get("remote_cwd_flag", "-C {dir}")
|
||||
if remote_cwd_flag:
|
||||
parts.append(_render_template(remote_cwd_flag, remote_values))
|
||||
if model:
|
||||
parts.append(_render_template(backend.get("model_flag", "--model '{model}'"), {"model": model}))
|
||||
if backend.get("flags"):
|
||||
|
||||
@@ -96,6 +96,12 @@ else
|
||||
fail "Codex probe did not complete (cmd=${cmd}); tail: $(echo "$pane" | grep -vE '^\s*$' | tail -5)"
|
||||
fi
|
||||
|
||||
if echo "$pane" | grep -Fq "$REPO"; then
|
||||
pass "daemon-created Codex thread uses the requested project directory"
|
||||
else
|
||||
fail "Codex thread did not use requested directory $REPO"
|
||||
fi
|
||||
|
||||
if python3 "$REPO/agents.py" --config "$CFG" status \
|
||||
| grep -E '^\s*probe\b' | grep -q RUNNING; then
|
||||
pass "agents.py status reports probe RUNNING"
|
||||
|
||||
+2
-1
@@ -279,8 +279,9 @@ class TestExampleConfig(unittest.TestCase):
|
||||
cmd = launched[0]
|
||||
self.assertTrue(cmd.startswith(
|
||||
"codex remote-control start --json >/dev/null && "
|
||||
"codex --remote 'unix://' --model 'gpt-test' "))
|
||||
"codex --remote 'unix://' -C "))
|
||||
self.assertEqual(cmd.count("--remote 'unix://'"), 1)
|
||||
self.assertIn(f"-C {agents.shlex.quote(cfg['agents']['cx']['dir'])}", cmd)
|
||||
self.assertIn("--model 'gpt-test'", cmd)
|
||||
self.assertIn(
|
||||
"--dangerously-bypass-approvals-and-sandbox --dangerously-bypass-hook-trust --no-alt-screen",
|
||||
|
||||
Reference in New Issue
Block a user