feat(agent): add full codex agent support (v4.2.0)

- Implement CodexAdapter in lib_py/agents/adapters/codex.py with safe flags and TUI readiness
- Extend create_session, resume_session, stop_session, and reconcile for codex CLI
- Support codex agent delegation and loop integration across all multi-agent skills
- Add unit, component, and contract test suites for codex integration
- Verify all 462 tests passing cleanly
This commit is contained in:
Godopu committed 2026-09-05 23:02:29 +09:00
1 parent de0a9c2e81
commit 76f10b2096
45 files changed
+2045 -276

No files matched your search

+50
View File
@@ -1276,3 +1276,53 @@ def test_comp_opencode_create_and_reconcile_and_stop(mam_sandbox, mock_herdr, mo
assert s_stopped["resumable"] is True
def test_comp_codex_create_and_reconcile_and_stop(mam_sandbox, mock_herdr, mock_agents):
"""Verify create_session -> reconcile drift-C materialization -> stop flow for codex."""
create_script = mam_sandbox / ".agents" / "skills" / "multi-agent-mux-create" / "scripts" / "create_session.sh"
res = subprocess.run([
"bash", str(create_script),
"--workspace", str(mam_sandbox),
"--agent", "codex",
"--role", "creator"
], capture_output=True, text=True, cwd=str(mam_sandbox))
assert res.returncode == 0, res.stderr
yaml_path = mam_sandbox / ".mam" / "agent-sessions.yaml"
import yaml
with open(yaml_path) as f:
data = yaml.safe_load(f)
sessions = data.get("herdr_sessions", [])
assert len(sessions) == 1
s = sessions[0]
session_name = s["name"]
assert s["status"] == "running"
assert s["codex_session_id_own"] is None
assert s["session_id_source"] == "pending-discovery"
# Run reconcile.sh to trigger drift-C materialization
reconcile_script = mam_sandbox / ".agents" / "skills" / "multi-agent-mux-monitor" / "scripts" / "reconcile.sh"
res_rec = subprocess.run(["bash", str(reconcile_script), "--once", "--emit-diff"], capture_output=True, text=True, cwd=str(mam_sandbox), env={**os.environ, "WORKSPACE_ROOT": str(mam_sandbox)})
assert res_rec.returncode == 0, res_rec.stderr
with open(yaml_path) as f:
data_after = yaml.safe_load(f)
s_after = [x for x in data_after.get("herdr_sessions", []) if x.get("name") == session_name][0]
assert s_after.get("codex_session_id_own") is not None
assert s_after.get("last_visible_status") in ("pinned", "resume_verified")
# Stop session
stop_script = mam_sandbox / ".agents" / "skills" / "multi-agent-mux-stop" / "scripts" / "stop_session.sh"
res_stop = subprocess.run([
"bash", str(stop_script),
"--session", session_name,
"--agent", "codex"
], capture_output=True, text=True, cwd=str(mam_sandbox))
assert res_stop.returncode == 0, res_stop.stderr
with open(yaml_path) as f:
data_stopped = yaml.safe_load(f)
s_stopped = [x for x in data_stopped.get("herdr_sessions", []) if x.get("name") == session_name][0]
assert s_stopped["status"] == "stopped"
assert s_stopped["resumable"] is True