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:
1 parent
de0a9c2e81
commit
76f10b2096
45 files changed
+2045
-276
No files matched your search
@@ -1,14 +1,14 @@
|
||||
---
|
||||
name: multi-agent-mux-status
|
||||
description: "Read-only instant snapshot of all agent herdr sessions — name, YAML status, herdr alive, pane cmd/cwd, resume UUID on disk, and any drift. No mutation. Reuses reconcile.sh --dry-run for the diff logic. Use when you want to know 'what's running RIGHT NOW' without spinning up the monitor loop."
|
||||
version: 4.1.3
|
||||
version: 4.2.0
|
||||
author: godopu
|
||||
license: MIT
|
||||
platforms: [linux, macos]
|
||||
environments: [terminal, herdr]
|
||||
metadata:
|
||||
hermes:
|
||||
tags: [agent, herdr, claude, antigravity, agy, grok, status, read-only, snapshot]
|
||||
tags: [agent, herdr, claude, antigravity, agy, grok, opencode, codex, status, read-only, snapshot]
|
||||
related_skills: [multi-agent-mux-create, multi-agent-mux-resume, multi-agent-mux-stop, multi-agent-mux-monitor]
|
||||
prereq_skills: [multi-agent-mux-create, multi-agent-mux-monitor]
|
||||
---
|
||||
|
||||
@@ -53,12 +53,12 @@ def resume_on_disk(s):
|
||||
name = s.get('name', '')
|
||||
cwd = (s.get('pane') or {}).get('cwd', '')
|
||||
agent = None
|
||||
for a in ('claude', 'agy', 'hermes', 'grok', 'opencode'):
|
||||
for a in ('claude', 'agy', 'hermes', 'grok', 'opencode', 'codex'):
|
||||
if any(name.endswith(f'-{r}-{a}') for r in ('creator', 'planner', 'reviewer')) or name.endswith(f'-{a}'):
|
||||
agent = a
|
||||
break
|
||||
if not agent:
|
||||
for a in ('claude', 'agy', 'hermes', 'grok', 'opencode'):
|
||||
for a in ('claude', 'agy', 'hermes', 'grok', 'opencode', 'codex'):
|
||||
if f"-{a}" in name or f"_{a}" in name:
|
||||
agent = a
|
||||
break
|
||||
@@ -125,6 +125,29 @@ def resume_on_disk(s):
|
||||
except Exception:
|
||||
return 'MISSING'
|
||||
return 'no'
|
||||
if agent == 'codex':
|
||||
u = s.get('codex_session_id_own')
|
||||
if u:
|
||||
codex_home = os.environ.get('CODEX_HOME', f"{home}/.codex")
|
||||
db_matches = glob.glob(f"{codex_home}/state_*.sqlite")
|
||||
if db_matches:
|
||||
db = max(db_matches, key=os.path.getmtime)
|
||||
try:
|
||||
import sqlite3
|
||||
conn = sqlite3.connect(db)
|
||||
r = conn.execute("SELECT rollout_path FROM threads WHERE id=?", (u,)).fetchone()
|
||||
conn.close()
|
||||
if r and r[0] and os.path.exists(r[0]):
|
||||
return 'yes'
|
||||
if r:
|
||||
return 'yes'
|
||||
except Exception:
|
||||
pass
|
||||
m = glob.glob(f"{codex_home}/sessions/*/*/*/rollout-*-{u}.jsonl")
|
||||
if m and os.path.exists(m[0]):
|
||||
return 'yes'
|
||||
return 'MISSING'
|
||||
return 'no'
|
||||
return '?'
|
||||
|
||||
|
||||
@@ -231,12 +254,12 @@ def resume_on_disk(s):
|
||||
name = s.get('name', '')
|
||||
cwd = (s.get('pane') or {}).get('cwd', '')
|
||||
agent = None
|
||||
for a in ('claude', 'agy', 'hermes', 'grok', 'opencode'):
|
||||
for a in ('claude', 'agy', 'hermes', 'grok', 'opencode', 'codex'):
|
||||
if any(name.endswith(f'-{r}-{a}') for r in ('creator', 'planner', 'reviewer')) or name.endswith(f'-{a}'):
|
||||
agent = a
|
||||
break
|
||||
if not agent:
|
||||
for a in ('claude', 'agy', 'hermes', 'grok', 'opencode'):
|
||||
for a in ('claude', 'agy', 'hermes', 'grok', 'opencode', 'codex'):
|
||||
if f"-{a}" in name or f"_{a}" in name:
|
||||
agent = a
|
||||
break
|
||||
@@ -303,6 +326,29 @@ def resume_on_disk(s):
|
||||
except Exception:
|
||||
return 'MISSING'
|
||||
return 'no'
|
||||
if agent == 'codex':
|
||||
u = s.get('codex_session_id_own')
|
||||
if u:
|
||||
codex_home = os.environ.get('CODEX_HOME', f"{home}/.codex")
|
||||
db_matches = glob.glob(f"{codex_home}/state_*.sqlite")
|
||||
if db_matches:
|
||||
db = max(db_matches, key=os.path.getmtime)
|
||||
try:
|
||||
import sqlite3
|
||||
conn = sqlite3.connect(db)
|
||||
r = conn.execute("SELECT rollout_path FROM threads WHERE id=?", (u,)).fetchone()
|
||||
conn.close()
|
||||
if r and r[0] and os.path.exists(r[0]):
|
||||
return 'yes'
|
||||
if r:
|
||||
return 'yes'
|
||||
except Exception:
|
||||
pass
|
||||
m = glob.glob(f"{codex_home}/sessions/*/*/*/rollout-*-{u}.jsonl")
|
||||
if m and os.path.exists(m[0]):
|
||||
return 'yes'
|
||||
return 'MISSING'
|
||||
return 'no'
|
||||
return '?'
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user