# 🗺️ Multi-Agent Mux (MAM): New Agent Types Extension Roadmap & Architecture Analysis

- **Author**: Creator Agent (`creator-agy-01`)
- **Date**: 2026-08-26
- **Status**: Complete / Ready for Review
- **Document Purpose**: Provide a comprehensive architectural review of recent layout enhancements and an actionable implementation blueprint for onboarding new agent backends (e.g., `codex`, `grok-build`, `opencode`, `kimi`, `cursor`).

---

## 1. Review of Recent Commit Changes

### 1.1 Layout Engine Refinements (`lib_py/layout.py` & `lib.sh:432`)
- **Constraint Relaxation**:
  - `MAM_MIN_PANE_COLS` default was lowered from `60` -> `40` -> `15`. This allows dense multi-pane tiling in compact terminal environments (e.g. 80x24 standard terminals with 54x23 content areas) without prematurely triggering `column_width_overflow`.
  - `MAM_MIN_PANE_ROWS` default was set to `0`. Vertical height constraints were removed because terminal panes support native scrollback buffers, allowing 2-row splitting even in constrained heights.
- **Single-Workspace 2×K Multi-Pane Tiling**:
  - Standard viewports (e.g. 54×23 content area in 80×24 window, or 90–100 col windows) cleanly progress through:
    1. **1 Pane** $\rightarrow$ split down $\rightarrow$ **2 Panes** (top/bottom)
    2. **2 Panes** $\rightarrow$ split right $\rightarrow$ **3 Panes** (starts column 2)
    3. **3 Panes** $\rightarrow$ fill singleton down $\rightarrow$ **4 Panes** (2×2 balanced grid)
    4. **4 Panes** $\rightarrow$ 5th pane overflows to a dedicated fresh workspace when column width $< 15$ cols.
- **Verification & Test Suite**:
  - `tests/test_layout.py` (27 unit tests) and `tests/test_tier1_unit.py` (59 unit tests) assert default `min_cols=15` and verify boundary conditions (e.g. 30 cols split vs 29 cols overflow; 54×23 compact window tiling).
  - All 371 tests across the 18 test suites pass with 0 failures.

---

## 2. Architecture & Contract for Adding New Agent Types

MAM's architecture isolates agent-specific quirks into clean, pluggable Python adapters backed by a shared CLI bridge (`lib_py.agents`). 

```
                                    ┌──────────────────────────────────────────────────────────┐
                                    │                     Herdr Runtime                        │
                                    │  (herdr agent start <name> --kind <kind> -- <cmd>)       │
                                    └────────────────────────────┬─────────────────────────────┘
                                                                 │
                                                                 ▼
                                    ┌──────────────────────────────────────────────────────────┐
                                    │                  lib.sh (Shell Runtime)                  │
                                    │   • resolve_agent_type_from_registry()                   │
                                    │   • wait_for_tui_ready() (via MAM_READY_TOKENS)          │
                                    │   • send_keys_safe() / stop_session.sh                   │
                                    └────────────────────────────┬─────────────────────────────┘
                                                                 │
                                                    eval $(python -m lib_py.agents facts <agent>)
                                                                 │
                                                                 ▼
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│                                                        lib_py.agents Framework                                                           │
│                                                                                                                                          │
│   ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐   │
│   │                                                        BaseAgentAdapter                                                          │   │
│   │   • name, own_key, ready_tokens, exit_key, delegate_agent_key, identity_cache_fields                                               │   │
│   │   • input_prompt, input_placeholder, input_rule_pattern                                                                          │   │
│   │   • artifact_path(), verify_artifact(), purge_artifacts()                                                                        │   │
│   │   • spawn_spec(), resume_spec(), auth_ok(), discover()                                                                           │   │
│   └────────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────┘   │
│                                                                    │                                                                     │
│               ┌────────────────────┬───────────────────────────────┼───────────────────────────────┬─────────────────────┐               │
│               ▼                    ▼                               ▼                               ▼                     ▼               │
│      ClaudeAgentAdapter    AgyAgentAdapter                 ClineAgentAdapter              HermesAgentAdapter     [NewAgentAdapter]       │
│         (Claude Code)        (Antigravity)                      (Cline)                        (Hermes)        (Codex / OpenCode / ...)  │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
```

---

## 3. Detailed Task Breakdown per Component

To add a new agent type `<agent>` (e.g. `opencode`, `codex`, `kimi`, `grok`, `cursor`), the following 5 layers must be implemented:

### Step 1: Implement the Agent Adapter (`.agents/skills/lib_py/agents/adapters/<agent>.py`)
Create `<Agent>AgentAdapter` inheriting from `BaseAgentAdapter`:

```python
class NewAgentAdapter(BaseAgentAdapter):
    @property
    def name(self) -> str:
        return 'newagent'

    @property
    def own_key(self) -> str:
        # YAML state key stored under herdr_sessions[]
        return 'newagent_session_id_own'  # or 'newagent_conversation_id_own'

    @property
    def ready_tokens(self) -> str:
        # Regex matching banner / prompt when TUI is fully loaded and ready for input
        return 'NewAgent|Assistant|Chat|Welcome'

    @property
    def exit_key(self) -> str:
        # Graceful exit command sent to TUI (e.g., '/exit', 'Exit', 'quit', or ':q')
        return '/exit'

    @property
    def delegate_agent_key(self) -> str:
        # Canonical target identifier for delegate-job MQTT payloads
        return 'newagent-cli'

    @property
    def identity_cache_fields(self) -> tuple:
        return ('session_id',)

    # Optional TUI Input Region Delimiters (for send_keys_safe visual parsing)
    @property
    def input_prompt(self) -> str:
        return '❯'

    @property
    def input_placeholder(self) -> str:
        return ''

    @property
    def input_rule_pattern(self) -> str:
        return '─{10,}'

    # Artifact & Session Tracking Lifecycle
    def artifact_path(self, uuid: str, ctx: DiscoveryContext) -> str:
        return f"{ctx.home_dir}/.newagent/sessions/{uuid}.json"

    def verify_artifact(self, uuid: str, ctx: DiscoveryContext) -> bool:
        path = self.artifact_path(uuid, ctx)
        if not os.path.exists(path):
            return False
        if ctx.epoch and os.path.getmtime(path) < ctx.epoch:
            return False
        # Validate internal cwd / workspace match if supported by artifact format
        return True

    def purge_artifacts(self, uuid: str, ctx: DiscoveryContext) -> list:
        # Remove on-disk session files when --purge-conversation is invoked
        path = self.artifact_path(uuid, ctx)
        if os.path.exists(path):
            os.remove(path)
            return [path]
        return []

    # Command-Line Invocation Synthesis
    def spawn_spec(self, binary: str, session_uuid: str = "", use_wrapper: bool = False) -> str:
        if session_uuid:
            return f"{binary} --session {session_uuid}"
        return binary

    def resume_spec(self, binary: str, session_uuid: str, materialized: bool = False) -> str:
        if materialized and session_uuid:
            return f"{binary} --resume {session_uuid}"
        return f"{binary} --session {session_uuid}" if session_uuid else binary

    # Authentication & Health Check
    def auth_ok(self, run_cmd: Optional[Any] = None) -> bool:
        # Check config file, token file, or run CLI status command
        return os.path.exists(f"{os.path.expanduser('~')}/.newagent/auth.json")

    # Session Discovery
    def discover(self, ctx: DiscoveryContext) -> list:
        # Scan on-disk session directory for unassigned sessions matching ctx.workspace
        return []
```

### Step 2: Register Adapter in Registry (`.agents/skills/lib_py/agents/registry.py`)
- Import `NewAgentAdapter` in `registry.py`.
- Add `'newagent': NewAgentAdapter()` to the `_ADAPTERS` dictionary.
- Automatic registration immediately enables:
  - `python -m lib_py.agents facts newagent`
  - `python -m lib_py.agents resolve <session_name>`
  - `python -m lib_py.agents spawn-spec newagent ...`
  - `python -m lib_py.agents resume-spec newagent ...`
  - `python -m lib_py.agents exit-key newagent`

### Step 3: Shell Runtime Dispatch in `lib.sh`
1. **Herdr Session Kind Mapping (`lib.sh:358-375`)**:
   - Add `*-creator-newagent|*-planner-newagent|*-reviewer-newagent) kind="newagent" ;;`
   - Add `elif echo "$name" | grep -qi "newagent"; then kind="newagent"` in fallback pattern.
2. **Binary Name Stripping (`lib.sh:385`)**:
   - Add `'newagent'` to the tuple of recognized agent binary names to prevent positional argument duplication when invoking `herdr agent start`.
3. **Session Name Suffix Matching (`lib.sh:resolve_agent_name`)**:
   - Supported automatically via `agent_of_row()` priority resolution.

### Step 4: Herdr CLI Daemon Support
- Confirm whether `herdr agent start <name> --kind <kind>` accepts the new agent kind:
  - Built-in Herdr kinds: `claude`, `hermes`, `cline`, `generic`, etc.
  - If Herdr 0.8.0 requires a known kind enum, either pass `--kind generic` or register the agent kind definition in Herdr's agent profile configuration.

### Step 5: Test Suite & Contract Verification
1. **Tier 1 Adapter Contract (`tests/test_a4_adapter_contract.py`)**:
   - Add `'newagent'` to `test_agent_adapter_registry`.
   - Add expected tuple to `test_adapter_required_properties`:
     `('ready_tokens_regex', '/exit', 'newagent-cli', ('session_id',))`
   - Verify `test_facts_bridge_eval_contract` for `newagent`.
   - Add unit tests for `artifact_path`, `purge_artifacts`, and `discover`.
2. **Tier 2 Lifecycle Tests (`tests/test_tier2_component.py`)**:
   - Test session creation, YAML serialization, `stop_session.sh` graceful shutdown, and `resume_session.sh`.

---

## 4. Work Difficulty & Complexity Assessment Matrix

| Agent Type | Target CLI / Tool | Session Storage Format | Auth Strategy | Ready Tokens Pattern | Complexity Tier | Estimated Effort |
|---|---|---|---|---|:---:|:---:|
| **OpenCode** | `opencode` (CLI / TUI) | JSON files in `~/.opencode/sessions/` | Local token / API key | `OpenCode\|Chat\|Welcome` | **Tier 1 (Low)** | ~0.5 day |
| **Codex CLI** | `codex` / `openai-codex` | JSONL in `~/.codex/projects/` | API Key (`OPENAI_API_KEY`) | `OpenAI Codex\|Assistant\|❯` | **Tier 1 (Low)** | ~0.5 day |
| **Kimi CLI** | `kimi` (Moonshot CLI) | SQLite DB in `~/.kimi/history.db` | API Key in `~/.kimi/config` | `Kimi\|Moonshot\|Chat` | **Tier 1 (Low)** | ~0.5 day |
| **Grok-Build** | `grok` / `grok-build` | JSON in `~/.grok/sessions/` | Token file / Env var | `Grok\|xAI\|Building` | **Tier 1 (Low)** | ~0.5 day |
| **Cursor CLI** | `cursor` (Headless/RPC) | State DB in `~/.cursor/` or RPC port | OAuth / Cookie | `Cursor\|Connected\|Listening` | **Tier 2 (Medium)** | ~1.5 days |
| **Custom Local LLM** | `ollama` / `vllm-cli` | Custom JSONL / stdout | None (Local host) | `>>>\|Send a message` | **Tier 2 (Medium)** | ~1.0 day |

### Complexity Breakdown by Layer:
1. **Tier 1 (Adapter Contract & Facts Bridge)**:
   - *Effort*: Very Low.
   - *Risk*: Zero risk to existing framework. Python `BaseAgentAdapter` interface is strictly decoupled and self-contained.
2. **Tier 2 (Herdr Kind & Shell Lifecycle)**:
   - *Effort*: Low.
   - *Risk*: Standardized via `lib.sh:resolve_agent_type_from_registry` and `_sanitize_herdr_agent_name`.
3. **Tier 3 (TUI Readiness & Input Capture)**:
   - *Effort*: Low to Medium.
   - *Risk*: Depends on whether the agent CLI emits predictable startup banner tokens and supports ANSI raw terminal input.

---

## 5. Reviewer Evaluation Guidelines

When reviewing newly added agent adapters or layout enhancements, reviewers should verify:
1. `BaseAgentAdapter` compliance (all abstract properties and methods implemented).
2. Fail-safe behavior (graceful fallback if session transcript is missing or corrupted).
3. Zero regression across existing test suites (`pytest tests/`).
4. Proper documentation in `AGENTS.md` and `.mam.env.example`.

