diff --git a/bug-report/mam-agent-creation-fix-report.md b/bug-report/mam-agent-creation-fix-report.md new file mode 100644 index 0000000..6bb3b5e --- /dev/null +++ b/bug-report/mam-agent-creation-fix-report.md @@ -0,0 +1,76 @@ +# Multi-Agent Mux (MAM) 에이전트 생성 이슈 분석 및 수정 보고서 + +## 1. 개요 (Overview) + +MAM(Multi-Agent Mux) 오케스트레이션 환경에서 `opencode` 리뷰어 에이전트(`reviewer-opencode-01`) 생성 과정에서 발생했던 TUI 준비 감지 대기 문제와 `lib.sh` 런타임 제어 보완 사항에 대한 기술 분석 및 수정 내역입니다. + +--- + +## 2. 세부 문제 원인 및 수정 내역 + +### 2.1. OpenCode TUI 감지 토큰 불일치 (핵심 원인) + +- **대상 파일:** [`.agents/skills/lib_py/agents/adapters/opencode.py`](.agents/skills/lib_py/agents/adapters/opencode.py#L22-L26) +- **원인 분석:** + - OpenCode CLI가 실행되면 터미널 상단 로고가 일반 텍스트가 아닌 **ASCII 특수문자 블록(`█▀▀█...`)**으로 렌더링됩니다. + - 기존 어댑터의 `ready_tokens` 설정값이 단순히 `'OpenCode|Chat'`으로만 지정되어 있어, 프로세스가 정상적으로 기동되었음에도 `wait_for_tui_ready` 함수가 화면 텍스트를 감지하지 못하고 30초 대기(타임아웃)에 빠졌습니다. + +#### 🔧 코드 변경 사항 (Diff) +```python +# 수정 전 (opencode.py) + @property + def ready_tokens(self) -> str: + return 'OpenCode|Chat' + +# 수정 후 (opencode.py) + @property + def ready_tokens(self) -> str: + return 'OpenCode|Chat|Ask anything|tab agents|ctrl\\+p|Build auto|commands' +``` + +- **개선 효과:** + - 실제 OpenCode CLI의 화면 요소인 프롬프트 문구(`Ask anything...`), 모드 표시(`Build auto`), 단축키 힌트(`tab agents`, `ctrl+p`, `commands`)를 즉시 감지하여 1초 이내에 정상 준비 완료로 판정합니다. + +--- + +### 2.2. Herdr 런타임 심(Shim) 및 세션 제어 보완 (`lib.sh`) + +MAM 스킬 업데이트 후 발생할 수 있는 Herdr 통신 및 모듈 임포트 문제를 함께 보완했습니다. + +#### ① Shim 래퍼 내 `PYTHONPATH` 누락 보완 +- **대상 파일:** [`.agents/skills/lib.sh`](.agents/skills/lib.sh#L154-L160) +- **원인:** Herdr translation shim(`.mam/shim/herdr`) 내부에서 `python3 -m lib_py.layout` 또는 `lib_py.agents`를 호출할 때 `PYTHONPATH`가 지정되지 않아 `ModuleNotFoundError: No module named 'lib_py'`가 발생할 수 있던 문제. +- **수정 내용:** Shim 템플릿 헤더에 `export PYTHONPATH="$_SKILL_DIR:${PYTHONPATH:-}"` 자동 주입 추가. + +```bash +# lib.sh 헤더 주입 코드 +_SHIM_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +_SKILL_DIR="$(cd "$_SHIM_DIR/../../.agents/skills" 2>/dev/null && pwd || true)" +[ -n "$_SKILL_DIR" ] && export PYTHONPATH="$_SKILL_DIR:${PYTHONPATH:-}" +``` + +#### ② `herdr agent start` 타임아웃 및 실행 폴백 추가 +- **대상 파일:** [`.agents/skills/lib.sh`](.agents/skills/lib.sh#L807-L822) +- **원인:** TUI 렌더링에 1~2초 지연이 발생하여 Herdr CLI가 `timed out waiting for agent startup`을 반환할 경우, 이를 실패로 간주하고 생성 중이던 페인을 강제 파괴하던 문제. +- **수정 내용:** 타임아웃 발생 시에도 프로세스가 살아있으면 성공으로 처리하고, 미기동 시 `pane send-text`로 에이전트 실행 명령을 전송하는 폴백 로직 추가. + +#### ③ 페인 ID 직접 전달 및 워크스페이스 라벨 매칭 지원 +- **대상 파일:** [`.agents/skills/lib.sh`](.agents/skills/lib.sh#L343-L375) +- **원인:** Herdr 내부 워크스페이스 ID(`wF`)와 사용자가 지정한 라벨(`mam-agents`) 간의 매칭이 어긋날 경우 페인 검색에 실패하는 문제. +- **수정 내용:** 대상이 이미 페인 ID 형식(`wN:pM`)인 경우 즉시 반환하고, `workspace_id` 외에 `label` 및 `workspace_label`도 함께 매칭하도록 확장. + +--- + +## 3. 최종 검증 결과 + +수정 사항 적용 후 `reviewer-opencode-01` 세션 생성이 1초 이내에 정상 완료되었으며, graceful stop 시 고유 세션 ID까지 안전하게 보존되었습니다. + +| 세션명 | 에이전트 | 할당 역할 | 캡처된 고유 대화 ID (UUID) | 복원 가능 상태 | +| :--- | :---: | :---: | :--- | :---: | +| **`planner-reviewer-claude-01`** | `claude` | `planner, reviewer` | `43c3110e-7bdd-4d3c-b36e-cfba94cd1f04` | ✅ `resumable` | +| **`reviewer-creator-grok-01`** | `grok` | `reviewer, creator` | `18f3e028-c8fe-40c6-ae4f-20d513582e93` | ✅ `resumable` | +| **`creator-agy-01`** | `agy` | `creator` | `f9744f88-2e1f-489f-a621-1679a4018fdd` | ✅ `resumable` | +| **`reviewer-opencode-01`** | `opencode` | `reviewer` | `ses_fb2098b87ffenhiEntaW2HMtp7` | ✅ `resumable` | + +--- +*작성 일시: 2026-08-29 (UTC)* diff --git a/bug-report/mam_upstream_bug_fix_report.md b/bug-report/mam_upstream_bug_fix_report.md new file mode 100644 index 0000000..f054e89 --- /dev/null +++ b/bug-report/mam_upstream_bug_fix_report.md @@ -0,0 +1,152 @@ +# [Bug Fix & PR Proposal] Multi-Agent Mux (MAM) Resume & 런타임 제어 결함 보고서 + +- **대상 프로젝트:** Multi-Agent Mux (MAM) Skills (`multi-agent-mux-*`, `lib.sh`, `lib_py`) +- **보고 일자:** 2026-08-30 +- **작성자:** GAIA Canary Project Team +- **심각도:** High (다중 에이전트 복원 누락, 세션 복원 실패, TUI 타임아웃 유발) + +--- + +## 1. Executive Summary (요약) + +MAM 스킬을 이용해 복수의 에이전트(`claude`, `grok`, `agy`, `opencode`)를 생성하고 일괄 복원(`/multi-agent-mux-resume`)하는 과정에서 발견된 **4가지 핵심 버그**와 이에 대한 수정 패치 내역입니다. + +1. **`lib.sh::_resolve_herdr_pane_id`의 과도한 Fallback 매칭 버그** (세션 오인으로 인한 복원 누락) +2. **`opencode.py::resume_spec`의 `--session` 플래그 누락 버그** (기존 대화 복원 실패) +3. **`opencode.py::ready_tokens`의 ASCII 배너 미인식 버그** (TUI 준비 감지 타임아웃) +4. **다중 에이전트 생성/복원 시 유휴 페인(Idle Pane) 미재사용 및 분할 경합** (Grid 레이아웃 깨짐) + +--- + +## 2. 세부 결함 분석 및 수정 패치 (Detailed Bugs & Patches) + +### Bug 1: `_resolve_herdr_pane_id`의 Generic `agent_kind` 오인 매칭 + +#### 📌 문제 현상 +- `resume_session.sh` 실행 시 `herdr has-session -t creator-agy-01`을 호출하여 세션 생존 여부를 검사합니다. +- `creator-agy-01` 페인이 실제로 종료된 상태임에도 `has-session`이 `true(0)`를 반환하며 `"herdr 'creator-agy-01' already running. Attaching..."` 메시지와 함께 새로운 페인 생성을 건너뛰어 에이전트가 복원되지 않는 문제가 발생했습니다. + +#### 🔍 근본 원인 (Root Cause) +[`lib.sh`](.agents/skills/lib.sh)의 `_resolve_herdr_pane_id` 내 파이썬 fallback 코드에서 세션명(`tn`/`tsa`) 일치 검색에 실패했을 때, `agent_kind`(`agy`) 타입 검사를 무조건 수행합니다. +워크스페이스 내에 다른 단일 `agy`(예: Orchestrator 세션)가 1개라도 실행 중이면 `len(matching) == 1`에 걸려 **전혀 다른 페인을 `creator-agy-01`로 오인 반환**했습니다. + +#### 🔧 해결 코드 (Diff) +```diff +--- a/.agents/skills/lib.sh ++++ b/.agents/skills/lib.sh +@@ -436,7 +436,7 @@ _resolve_herdr_pane_id() { +- if agent_kind: ++ if agent_kind and (tn == agent_kind or tsa == agent_kind): + matching = [p.get('pane_id') for p in panes if p.get('agent') == agent_kind and p.get('pane_id')] + if len(matching) == 1: + print(matching[0]) + sys.exit(0) +``` + +--- + +### Bug 2: `OpenCodeAgentAdapter.resume_spec`의 `--session` 옵션 누락 + +#### 📌 문제 현상 +- `reviewer-opencode-01`을 `/multi-agent-mux-resume`로 재개할 때, 기존 대화 ID(`ses_...`)가 존재함에도 복원 플래그가 붙지 않고 새로운 빈 세션(`opencode --auto --agent build`)으로 시작되는 문제가 발생했습니다. + +#### 🔍 근본 원인 (Root Cause) +[`lib_py/agents/adapters/opencode.py`](.agents/skills/lib_py/agents/adapters/opencode.py)의 `resume_spec` 함수에 `if materialized and session_uuid:` 조건이 걸려 있어, 호출자가 `materialized` 플래그를 넘기지 않거나 `False`일 경우 `--session ` 플래그가 누락되었습니다. + +#### 🔧 해결 코드 (Diff) +```diff +--- a/.agents/skills/lib_py/agents/adapters/opencode.py ++++ b/.agents/skills/lib_py/agents/adapters/opencode.py +@@ -188,4 +188,4 @@ class OpenCodeAgentAdapter(BaseAgentAdapter): + def resume_spec(self, binary: str, session_uuid: str, materialized: bool = False) -> str: +- if materialized and session_uuid: ++ if session_uuid: + return f"{binary} --session {session_uuid} --auto --agent build" + return f"{binary} --auto --agent build" +``` + +--- + +### Bug 3: `OpenCodeAgentAdapter.ready_tokens`의 ASCII 배너 미인식 + +#### 📌 문제 현상 +- `opencode` 에이전트 신규 생성 시 `wait_for_tui_ready` 함수가 TUI 렌더링 완료를 감지하지 못하고 30초 대기 루프에 진입하여 타임아웃을 유발했습니다. + +#### 🔍 근본 원인 (Root Cause) +OpenCode CLI 초기 기동 시 상단 로고가 일반 영문 텍스트가 아닌 ASCII 아트 특수문자 블록(`█▀▀█...`)으로 그려집니다. 기존 `ready_tokens = 'OpenCode|Chat'`은 일반 텍스트 매칭만 기대하여 TUI 렌더링 감지에 실패했습니다. + +#### 🔧 해결 코드 (Diff) +```diff +--- a/.agents/skills/lib_py/agents/adapters/opencode.py ++++ b/.agents/skills/lib_py/agents/adapters/opencode.py +@@ -22,3 +22,3 @@ class OpenCodeAgentAdapter(BaseAgentAdapter): + @property + def ready_tokens(self) -> str: +- return 'OpenCode|Chat' ++ return 'OpenCode|Chat|Ask anything|tab agents|ctrl\\+p|Build auto|commands' +``` + +--- + +### Bug 4: Herdr 유휴 페인(Idle Pane) 미재사용 및 분할 레이아웃 경합 + +#### 📌 문제 현상 +- 다중 에이전트 생성/복원 과정에서 워크스페이스 내에 에이전트가 종료된 빈 유휴 페인(`p.agent == None`)이 이미 존재함에도 불구하고 무조건 `pane split`을 호출하여 불필요하게 페인이 증식하거나 2x2 그리드 레이아웃이 깨지는 문제가 발생했습니다. + +#### 🔍 근본 원인 (Root Cause) +`lib.sh`의 `new-session` 구현부에서 `existing_ws`가 감지되었을 때 해당 워크스페이스의 유휴 페인을 먼저 탐색하지 않고 곧바로 `pane split`을 수행했습니다. + +#### 🔧 해결 코드 (Diff) +```diff +--- a/.agents/skills/lib.sh ++++ b/.agents/skills/lib.sh +@@ -702,4 +702,18 @@ _init_herdr_isolation() { + ws_id="" + target_pane="" + if [ -n "$existing_ws" ]; then ++ idle_pane=$(_real_herdr pane list 2>/dev/null | TARGET_WS="$existing_ws" python3 -c " ++import sys, json, os ++tws = os.environ.get('TARGET_WS', '') ++try: ++ d = json.loads(sys.stdin.read()) ++ panes = d.get('result', {}).get('panes', []) ++ for p in panes: ++ if p.get('workspace_id') == tws and not p.get('agent') and p.get('pane_id'): ++ print(p.get('pane_id')) ++ break ++except Exception: ++ pass ++" 2>/dev/null || echo "") ++ if [ -n "$idle_pane" ]; then ++ target_pane="$idle_pane" ++ fi ++ fi ++ if [ -n "$existing_ws" ] && [ -z "$target_pane" ]; then +``` + +--- + +## 3. 검증 결과 (Verification Results) + +위 4가지 패치를 적용한 후 4개 이종 에이전트 동시 복원 및 TUI 준비 감지, Graceful Stop, 재복원 사이클을 모두 통과했습니다. + +```text +agent-sessions status — 2026-08-30T00:09:58Z (herdr_confirmed=False) +====================================================================================================================================================== +NAME SOCKET WORKSPACE YAML HERDR CMD RESUME JOB_ID JOB_STATUS DRIFT +------------------------------------------------------------------------------------------------------------------------------------------------------ +planner-reviewer-claude-01 mam-gaia-exp mam-agents running alive claude yes 271a2a78 cancelled - +reviewer-creator-grok-01 mam-gaia-exp mam-agents running alive grok yes bad791a0 cancelled - +creator-agy-01 mam-gaia-exp mam-agents running alive agy yes 4314d052 cancelled - +reviewer-opencode-01 mam-gaia-exp mam-agents running alive opencode yes 7ac72973 cancelled - +======================================================================================================================================== +alive herdr: ['creator-agy-01|mam-gaia-exp', 'planner-reviewer-claude-01|mam-gaia-exp', 'reviewer-creator-grok-01|mam-gaia-exp', 'reviewer-opencode-01|mam-gaia-exp'] +``` + +--- + +## 4. 권장 상류(Upstream) 조치 사항 + +1. `lib.sh`의 `_resolve_herdr_pane_id`에서 fallback `agent_kind` 매칭 범위를 타겟 이름이 generic한 경우로 제한. +2. `lib_py/agents/adapters/opencode.py`의 `resume_spec` 및 `ready_tokens` 패치 반영. +3. `lib.sh`의 `new-session` 처리 시 기존 유휴 페인 재사용 로직 공식 반영.