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,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# resolve_session_id.sh — multi-agent-mux-resume 의 부속 스크립트
|
||||
# Usage:
|
||||
# bash resolve_session_id.sh --workspace <path> --agent <claude|agy|hermes|grok|opencode>
|
||||
# bash resolve_session_id.sh --workspace <path> --agent <claude|agy|hermes|grok|opencode|codex>
|
||||
# 출력: stdout 으로 UUID 한 줄 (없으면 빈 줄 + exit 0)
|
||||
#
|
||||
# P0-C: 전역 agent_identities 를 즉시 반환하지 않는다. lib.sh::find_workspace_uuid
|
||||
@@ -13,7 +13,7 @@ source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib.sh"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 --workspace <path> --agent <claude|agy|hermes|grok|opencode> [--session <name>]
|
||||
Usage: $0 --workspace <path> --agent <claude|agy|hermes|grok|opencode|codex> [--session <name>]
|
||||
Outputs the resolved UUID on stdout (empty if not found).
|
||||
--session prefers that registry row's recorded id; falls back to workspace-wide discovery if it does not verify.
|
||||
EOF
|
||||
@@ -36,8 +36,8 @@ done
|
||||
[ -n "$WORKSPACE" ] || { echo "ERROR: --workspace required" >&2; exit 2; }
|
||||
[ -n "$AGENT" ] || { echo "ERROR: --agent required" >&2; exit 2; }
|
||||
case "$AGENT" in
|
||||
claude|agy|hermes|grok|opencode) ;;
|
||||
*) echo "ERROR: --agent must be claude, agy, hermes, grok, or opencode" >&2; exit 2 ;;
|
||||
claude|agy|hermes|grok|opencode|codex) ;;
|
||||
*) echo "ERROR: --agent must be claude, agy, hermes, grok, opencode, or codex" >&2; exit 2 ;;
|
||||
esac
|
||||
|
||||
find_workspace_uuid "$WORKSPACE" "$AGENT" "$SESSION_NAME"
|
||||
@@ -9,7 +9,7 @@ source "$LIB_SH"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 --workspace <path> --agent <claude|agy|hermes|grok|opencode> --session <name> [options]
|
||||
Usage: $0 --workspace <path> --agent <claude|agy|hermes|grok|opencode|codex> --session <name> [options]
|
||||
|
||||
Options:
|
||||
--herdr-session NAME specify isolated herdr session name (alias: --herdr-server)
|
||||
@@ -42,7 +42,7 @@ done
|
||||
[ -n "$WORKSPACE" ] || { echo "ERROR: --workspace required" >&2; exit 2; }
|
||||
[ -n "$AGENT" ] || { echo "ERROR: --agent required" >&2; exit 2; }
|
||||
case "$AGENT" in
|
||||
claude|agy|hermes|grok|opencode) ;;
|
||||
claude|agy|hermes|grok|opencode|codex) ;;
|
||||
*) echo "ERROR: unsupported agent: $AGENT" >&2; exit 2 ;;
|
||||
esac
|
||||
[ -n "$SESSION_NAME" ] || { echo "ERROR: --session required" >&2; exit 2; }
|
||||
@@ -62,7 +62,7 @@ UUID=$(bash "$(dirname "${BASH_SOURCE[0]}")/resolve_session_id.sh" \
|
||||
FRESH_SPAWN=0
|
||||
if [ -z "$UUID" ]; then
|
||||
case "$AGENT" in
|
||||
agy|hermes|opencode) FRESH_SPAWN=1 ;;
|
||||
agy|hermes|opencode|codex) FRESH_SPAWN=1 ;;
|
||||
*)
|
||||
echo "ERROR: No saved session for $WORKSPACE ($AGENT). Use multi-agent-mux-create first." >&2
|
||||
exit 1
|
||||
@@ -119,6 +119,7 @@ if [ "$FRESH_SPAWN" = "1" ]; then
|
||||
agy) CMD_FULL="${RESOLVED_BIN} --dangerously-skip-permissions" ;;
|
||||
hermes) CMD_FULL="${RESOLVED_BIN} --yolo --accept-hooks" ;;
|
||||
opencode) CMD_FULL="${RESOLVED_BIN} --auto --agent build" ;;
|
||||
codex) CMD_FULL="${RESOLVED_BIN} --dangerously-bypass-approvals-and-sandbox" ;;
|
||||
esac
|
||||
fi
|
||||
else
|
||||
@@ -130,6 +131,7 @@ else
|
||||
hermes) CMD_FULL="${RESOLVED_BIN} --resume $UUID --no-restore-cwd --yolo --accept-hooks" ;;
|
||||
grok) CMD_FULL="${RESOLVED_BIN} --resume $UUID --permission-mode bypassPermissions" ;;
|
||||
opencode) CMD_FULL="${RESOLVED_BIN} --session $UUID --auto --agent build" ;;
|
||||
codex) CMD_FULL="${RESOLVED_BIN} resume --dangerously-bypass-approvals-and-sandbox $UUID" ;;
|
||||
*) echo "ERROR: unsupported agent: $AGENT" >&2; exit 2 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
# resume UUID 를 per-row own id (claude_session_id_own / agy_conversation_id_own)
|
||||
# 에 박는다 — agent_identities 전역은 더 이상 primary 아님 (cache 로 강등, P0-C/단계 e).
|
||||
#
|
||||
# Usage: bash update_yaml_resumed.sh --session <name> --uuid <id> [--agent claude|agy|hermes|grok|opencode]
|
||||
# Usage: bash update_yaml_resumed.sh --session <name> --uuid <id> [--agent claude|agy|hermes|grok|opencode|codex]
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)/lib.sh"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 --session <name> --uuid <id> [--agent claude|agy|hermes|grok|opencode] [--herdr-session <name>] [--cmd-full <cmd>]
|
||||
Usage: $0 --session <name> --uuid <id> [--agent claude|agy|hermes|grok|opencode|codex] [--herdr-session <name>] [--cmd-full <cmd>]
|
||||
|
||||
--uuid may be empty for an Issue-3 Class A fresh-spawn resume (agy/hermes/
|
||||
opencode 0-turn stopped session, no conversation id ever assigned) - pass
|
||||
opencode/codex 0-turn stopped session, no conversation id ever assigned) - pass
|
||||
--cmd-full so the display command can be recorded without a uuid to embed.
|
||||
EOF
|
||||
}
|
||||
@@ -235,6 +235,16 @@ elif agent == 'opencode':
|
||||
cp = os.environ.get('CHILD_PID', '0')
|
||||
if cp.isdigit() and int(cp) > 0:
|
||||
target['child_pid'] = int(cp)
|
||||
elif agent == 'codex':
|
||||
target['pane']['cmd'] = 'codex'
|
||||
if uuid:
|
||||
target['pane']['cmd_full'] = f'codex resume --dangerously-bypass-approvals-and-sandbox {uuid}'
|
||||
target['codex_session_id_own'] = uuid
|
||||
else:
|
||||
target['pane']['cmd_full'] = os.environ.get('CMD_FULL_OPT', '') or 'codex --dangerously-bypass-approvals-and-sandbox'
|
||||
cp = os.environ.get('CHILD_PID', '0')
|
||||
if cp.isdigit() and int(cp) > 0:
|
||||
target['child_pid'] = int(cp)
|
||||
|
||||
snap = d.setdefault('snapshot', {})
|
||||
snap['taken_at'] = now
|
||||
|
||||
Reference in new issue
Block a user