<p align="center">
  <a href="https://z.ai/subscribe?ic=ROK78RJKNW">
    <img src="https://img.shields.io/badge/Z.AI-10%25_OFF_Coding_Plans-6366f1?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiPgogIDxwYXRoIGQ9Ik0xMiAyTDIgN2wxMCA1IDEwLTV6Ii8+CiAgPHBhdGggZD0iTTIgMTdsMTAgNSAxMC01Ii8+CiAgPHBhdGggZD0iTTIgMTJsMTAgNSAxMC01Ii8+Cjwvc3ZnPg==&labelColor=4f46e5" alt="Z.AI 10% OFF" />
  </a>
</p>

<p align="center">
  <strong>Get 10% OFF Z.AI coding plans</strong><br/>
  <a href="https://z.ai/subscribe?ic=ROK78RJKNW">z.ai/subscribe</a>
</p>

---

<h1 align="center">Codex Launcher — Any AI Provider</h1>

<p align="center">
  <strong>Run OpenAI Codex CLI &amp; Desktop with <em>any</em> AI provider.</strong><br/>
  Google Antigravity &bull; Gemini CLI &bull; OpenCode &bull; Z.AI &bull; Anthropic &bull; Command Code &bull; Codebuff &bull; OpenRouter &bull; Crof.ai &bull; NVIDIA NIM &bull; OpenAdapter &bull; Kilo.ai &bull; DeepSeek &bull; and more
</p>

<p align="center">
  <img src="https://img.shields.io/badge/Python-3.8+-blue?logo=python&logoColor=white" alt="Python 3.8+" />
  <img src="https://img.shields.io/badge/GTK-3.0-green?logo=gtk&logoColor=white" alt="GTK 3.0" />
  <img src="https://img.shields.io/badge/License-MIT-yellow" alt="MIT License" />
  <img src="https://img.shields.io/badge/Zero_Pip_Dependencies-✓-brightgreen" alt="Zero pip dependencies" />
</p>

<p align="center">
  <img src="https://img.shields.io/badge/Responses_API-✓-success" /> 
  <img src="https://img.shields.io/badge/Chat_Completions-✓-success" /> 
  <img src="https://img.shields.io/badge/Anthropic_Messages-✓-success" /> 
  <img src="https://img.shields.io/badge/Command_Code-✓-success" /> 
  <img src="https://img.shields.io/badge/Streaming_SSE-✓-success" />
  <img src="https://img.shields.io/badge/Tool_Calls-✓-success" />
  <img src="https://img.shields.io/badge/AI_Assist-✓-success" />
  <img src="https://img.shields.io/badge/Intelligence_Routing-✓-success" />
  <img src="https://img.shields.io/badge/AI_Monitoring-✓-success" />
  <img src="https://img.shields.io/badge/Self_Revive_Watchdog-✓-success" />
</p>

---

## The Problem

OpenAI's Codex CLI v2.0+ exclusively uses the **Responses API** — a protocol that is incompatible with virtually every other AI provider:

| Provider | API | Works with Codex? |
|----------|-----|:-:|
| OpenAI | Responses API | ✅ |
| Google Antigravity (OAuth) | Code Assist / Gemini Native | ✅ |
| Gemini CLI OAuth | Code Assist | ✅ |
| Z.AI | Chat Completions | ✅ |
| OpenCode | Chat Completions | ✅ |
| Anthropic | Messages API | ✅ |
| Command Code | Custom `/alpha/generate` | ✅ |
| Ollama | Chat Completions | ✅ |
| OpenRouter | Chat Completions | ✅ |
| NVIDIA NIM | Chat Completions | ✅ |
| Crof.ai | Chat Completions | ✅ |

The protocols differ in **endpoint paths**, **message formats**, **tool-call structures**, **streaming events**, and **completion semantics**. You can't just swap a base URL.

## The Solution

A three-component system:

1. **Translation Proxy** — translates Responses API ↔ Chat Completions / Anthropic Messages in real-time
2. **Config Engine** — generates Codex config files on-the-fly per provider, with backup/restore
3. **GTK Launcher** — manages endpoints, launches Desktop or CLI, handles the full lifecycle

```
┌─────────────────────────────────────────────────────────────────────┐
│                         Codex Launcher GUI                          │
│              (endpoint management + AI Assist + lifecycle)          │
└──────────┬─────────────────┬──────────────────┬────────────────────┘
           │                 │                  │
    ┌──────▼──────┐  ┌──────▼──────┐  ┌────────▼─────────┐
    │  Codex      │  │  Native     │  │  Translation     │
    │  Default    │  │  OpenAI     │  │  Proxy           │
    │  (remove    │  │  (direct    │  │  (auto-revive)   │
    │  config)    │  │  URL)       │  │                  │
    └──────┬──────┘  └──────┬──────┘  └────────┬─────────┘
           │                │                   │
           ▼                ▼          ┌────────┴────────┐
    ┌──────────────┐ ┌───────────┐    │                 │
    │ Built-in     │ │ config.   │    ▼                 ▼
    │ Codex OAuth  │ │ toml      │ ┌────────────┐ ┌───────────┐ ┌──────────┐
    └──────────────┘ └───────────┘ │ OpenAI     │ │ Anthropic │ │ Command  │
                                   │ Chat Comp. │ │ Messages  │ │ Code     │
                                   └────────────┘ └───────────┘ └──────────┘
```

---

## Features

### Multi-Provider Support
- **Native OpenAI** — direct connection, no proxy needed
- **OpenAI-compatible** — Z.AI, OpenCode Zen/Go, Crof.ai, NVIDIA NIM, Kilo.ai, OpenRouter, Ollama, Together, Groq, and any provider with a Chat Completions endpoint
- **Anthropic** — Claude models via the Messages API
- **Command Code** — 20 models (DeepSeek, Claude, GPT, Kimi, GLM, Qwen, etc.) via Command Code's `/alpha/generate` API with configurable client version
- **Codex Default** — built-in Codex OAuth with official models, zero config

### Translation Proxy (`translate-proxy.py`)
- Full Responses API ↔ Chat Completions / Anthropic Messages / Command Code API bidirectional translation
- **Streaming SSE** support with proper event sequencing (`response.created` → `response.output_text.delta` → `response.completed`)
- **Tool calls** — full function calling support including parallel tool calls
- **Reasoning content** — forwards `reasoning_content` fields from providers that support it
- **Browser UA injection** — bypasses Cloudflare bot detection for providers like OpenCode
- **Smart URL construction** — prevents double-path bugs (`/v1/chat/completions/chat/completions`)
- **Header forwarding** — preserves client identity headers while filtering hop-by-hop headers
- **Connection pooling** — persistent HTTPS connections per host, eliminates TLS handshake overhead per request
- **Stream idle timeout** — kills stalled upstream connections after 5 minutes of silence
- **Retry-After support** — respects upstream `Retry-After` headers on 429/502/503 responses
- **Response store TTL** — evicts stored responses older than 10 minutes, prevents memory leaks
- **Bounded stream buffers** — 8MB cap prevents OOM on pathological responses
- **Dual logging** — all proxy messages written to both stderr and `~/.cache/codex-proxy/proxy.log`
- Zero dependencies — pure Python stdlib

### Command Code Adapter
- **Multi-format tool-call parser** — handles all known CC model output formats in a cascading chain:
  - DSML tags (`<｜｜DSML｜｜invoke>`) — current model format
  - `<bash>...</bash>` blocks with metadata extraction
  - `<explore_agent>` blocks converted to real `exec_command`
  - `<tool_call type="bash">` HTML-like blocks
  - XML `<function=` patterns
  - Raw JSON `{"cmd":"..."}` embedded in text
  - Fallback regex for unrecognized tool-call signals
- **Three-tier argument parser** — handles double-wrapped, escaped, and unicode-escaped arguments
- **Recursive unwrapping** — handles double/triple-wrapped `cmd` values
- **Post-extraction sanitizer** — validates every tool call has valid name + args before forwarding to Codex
- **ErrorAnalyzer** — learns from 4xx errors, retries with adjusted parameters (max 2 retries)
- **Schema cache** with 24h staleness TTL for provider capabilities

### Intelligence Routing (v3.7.0)
- **Three-layer self-healing system** — the agent loop never stalls, even when the model speaks gibberish
- **Layer 1 — Deep URL Extraction**: When `<explore_agent>` hides URLs inside nested JSON (`messages: [{"content": "https://..."}]`), the parser drills into the JSON structure to find them. Module-level `_build_explore_cmd()` is reused across parser + stream path.
- **Layer 2 — Escalation Auto-Proceed**: `<require_escalation>` and `<request_escalation_permission>` blocks are detected and auto-resolved — the model doesn't get stuck waiting for permissions that don't exist.
- **Layer 3 — Intent-Based Command Synthesis**: When ALL parsers fail, 5 heuristics analyze the model's plain-text output and synthesize a working command:
  1. URL detected → `curl` it
  2. File path mentioned → `cat` or `ls` it
  3. Shell command in quotes → extract and run it
  4. "explore"/"fetch" intent → use the last URL the user mentioned
  5. "I need to"/"let me" intent → echo a diagnostic so the loop continues
- **Session URL memory** — `_last_user_urls` deque (20 entries) tracks URLs from user messages across the session, giving the synthesizer context to work with
- **54 self-test patterns** — comprehensive coverage of all three layers

### AI Monitoring (v3.8.0)
- **Self-healing watchdog** — the proxy auto-recovers from crashes, the model getting stuck, upstream failures, and more
- **Three-tier response system**: Tier 1 = rule-based (< 1s), Tier 2 = pattern lookup (< 100ms), Tier 3 = AI diagnostic agent (2-5s)
- **HealthWatcher thread** — pings proxy `/health` every 5 seconds, auto-restarts on crash
- **LogAnalyzer thread** — tails debug logs for 18 failure signal patterns in real-time
- **14 Tier 1 rules** — restart proxy, clear schema cache, kill stale processes, retry with backoff, rate limit handling
- **Incident pattern store** — learns from every resolved incident, looks up known fixes by success rate
- **AI diagnostic agent** — user-configurable provider/model (e.g., Gemini Flash, GPT-4o-mini, local Ollama) for diagnosing novel failures
- **30 fault types** catalogued across 5 categories: proxy failures (A), upstream errors (B), parser failures (C), Codex process failures (D), config/state failures (E)
- **Safety guards** — rate-limited AI calls, restart caps (5/10min), cooldown per pattern, monthly budget cap
- **GUI panel** — ON/OFF toggle, provider/model/API key selector, health check interval, auto-restart toggle, incident log viewer
- **Enhanced `/health`** — returns `uptime_s`, `memory_mb`, `requests_total` for monitoring

### GTK Launcher (`codex-launcher-gui`)
- **Endpoint manager** — add, edit, delete, set default providers
- **Provider presets** — one-click setup for 15+ providers with pre-filled URLs and model lists
- **Model auto-fetch** — pulls available models directly from provider APIs
- **Bulk model import** — paste a comma/newline-separated list of model IDs
- **Launch Desktop** — starts Codex Desktop with the selected provider and model
- **Launch CLI** — opens Codex CLI in a terminal with the selected provider
- **Codex Default** — launch with built-in OAuth, no proxy or custom config
- **AI Assist** — integrated AI-powered configuration assistance and troubleshooting
- **Usage Dashboard** — per-provider tracking with dark theme, KPI strip, model bars, status pills
- **Profile backup/import** — export and import endpoint configurations as portable JSON bundles
- **Threaded operations** — model refresh runs in background, UI stays responsive
- **Process lifecycle** — stall detection, kill/cleanup, config backup/restore around sessions
- **Config normalization** — automatically strips stale API path suffixes from URLs
- **Reasoning controls** — per-provider reasoning toggle with effort level selection

### Process Management
- Kills stale electron/webview/app-server processes from previous sessions
- Removes stale PID files and sockets
- Manages proxy lifecycle (start, health-check, stop)
- Config backup before launch, automatic restore after exit

---

## Technology Stack

| Component | Technology | Why |
|-----------|-----------|-----|
| Translation Proxy | Python 3 stdlib (`http.server`, `urllib`, `json`) | Zero dependencies, runs anywhere |
| GUI Launcher | Python 3 + GTK 3.0 (`PyGObject/gi`) | Native Linux desktop integration |
| Config Engine | Python 3 (`toml` generation, `json` catalogs) | Dynamic, no hardcoded configs |
| Process Mgmt | bash + `os.setsid`/`os.killpg` | Unix process group lifecycle |
| Streaming | Server-Sent Events (SSE) | Required by Codex Responses API |
| API Translation | Responses API ↔ Chat Completions / Anthropic Messages | Protocol bridging |

**Zero pip dependencies.** Everything uses Python stdlib + system GTK bindings.

---

## Quick Start

### Prerequisites

- **Codex CLI** ≥ 2.0 (`npm install -g @openai/codex` or bundled with Codex Desktop)
- **Codex Desktop** installed at `/opt/codex-desktop/` (optional, for Desktop mode)
- **Python 3.8+** (stdlib only)
- **python3-gi** for GTK (`sudo apt install python3-gi`)
- bash, curl, lsof

### Install

```bash
git clone https://github.rommark.dev/admin/Codex-Launcher---Any-AI-Porovider.git
cd Codex-Launcher---Any-AI-Porovider
./install.sh
```

### Run

Open **Codex Launcher** from your app grid, or:

```bash
codex-launcher-gui
```

### First Launch

1. Click **Manage Endpoints** → **Add**
2. Select a provider preset (e.g., "OpenCode Zen (OpenAI-compatible)")
3. Enter your API key
4. Click **Fetch from API** to auto-discover models, or add them manually
5. Click **Save**
6. Select the endpoint and model from the dropdowns
7. Click **Launch Desktop** or **Launch CLI**

---

## Development Journey

### Phase 1: The Z.AI Proxy — Protocol Reverse Engineering

**Problem:** Codex CLI v2.0 switched exclusively to the Responses API. Z.AI (and every other provider) uses Chat Completions. They are fundamentally incompatible.

**Approach:**
1. Captured Codex's HTTP traffic to understand the exact Responses API request/response shape
2. Mapped the protocol differences:
   - `/v1/responses` → `/chat/completions` (endpoint)
   - `input` array with typed items → `messages` array with role/content (message format)
   - `function_call` items → `tool_calls` array on assistant messages (tool format)
   - SSE `response.output_text.delta` events → `delta.content` chunks (streaming)
3. Built the initial `zai-proxy.py` — a 200-line HTTP server that translates in both directions
4. Hit a critical bug: Codex hung in "thinking" state. Discovered that merely emitting `response.done` is insufficient — the `response.completed` event **must** contain the full output item array
5. Added streaming SSE with proper event sequencing — this was the breakthrough that made it work

**Testing:** Manual end-to-end testing with `curl`, Codex CLI `--profile zai`, and Codex Desktop. Verified streaming, tool calls, and reasoning content.

### Phase 2: Multi-Provider Architecture — The Unified Proxy

**Problem:** Maintaining separate proxies for each provider (Z.AI, Anthropic, OpenRouter, etc.) was unmaintainable.

**Approach:**
1. Abstracted the translation into a backend plugin architecture:
   - `openai-compat` backend: translates Responses → Chat Completions (works for any OpenAI-compatible API)
   - `anthropic` backend: translates Responses → Anthropic Messages API
2. Unified config loading: JSON config file, CLI arguments, and environment variables
3. Shared HTTP server, model serving, and SSE framework
4. Per-backend: message conversion, tool conversion, response conversion, stream conversion

**Key design decisions:**
- Pure Python stdlib — no Flask, no aiohttp, no pip dependencies. The proxy must work on any system with Python 3.
- `http.server.BaseHTTPRequestHandler` — simple, synchronous, but sufficient for single-user desktop use
- Config via JSON file — the launcher writes a proxy config to `~/.cache/codex-proxy/` for each endpoint

### Phase 3: The GTK Launcher — Desktop Integration

**Problem:** Users had to manage config files, start proxies manually, and remember which wrapper script to use.

**Approach:**
1. Built a GTK 3.0 GUI with three layers: main window, endpoint manager dialog, edit endpoint dialog
2. Implemented dynamic config generation: for each launch, generate `config.toml` with the right provider definition, profile, and model catalog
3. Model catalog generation with dual field naming (`slug` + `model`, `supported_reasoning_levels` + `supportedReasoningEfforts`) — required because Codex CLI and Codex Desktop use different field names
4. Process lifecycle: backup config → cleanup stale processes → start proxy → write config → launch Codex → wait → restore config → stop proxy

**Threading challenges:**
- GTK requires all UI updates on the main loop. Used `GLib.idle_add()` for all cross-thread communication
- Model refresh was blocking the UI — moved to a background thread with idle_add completion callbacks
- Proxy startup waits up to 15 seconds with health checks before proceeding

### Phase 4: Endpoint Management & Provider Presets

**Approach:**
1. JSON-based endpoint storage (`~/.codex/endpoints.json`)
2. Provider presets with pre-filled URLs and model lists for common providers
3. Auto-fetch models from provider `/v1/models` endpoints
4. Bulk model import (paste comma/newline-separated model IDs)
5. Profile backup/import — portable JSON bundles with endpoints + config

**URL normalization:** Discovered that saved URLs sometimes had `/chat/completions` appended from manual entry. Added `normalize_base_url()` that strips trailing API path suffixes to prevent double-path bugs.

### Phase 5: Cloudflare Bot Detection — The OpenCode 403 Saga

**Problem:** OpenCode Zen/Go returned 403 (Cloudflare error 1010) for all requests.

**Investigation:**
1. Tested direct `curl` requests — all returned 403 regardless of auth header type (Bearer, x-api-key, both, none)
2. Examined Codex logs — found `turn.has_metadata_header=true` and `error code: 1010`
3. Error 1010 is Cloudflare's "Access denied" — bot detection based on User-Agent and browser headers
4. Python's `urllib` sends `User-Agent: Python-urllib/3.x` which triggers the block

**Solution:**
1. Added `_BROWSER_HEADERS` — a set of Chrome-like headers (User-Agent, Sec-Ch-Ua, Sec-Fetch-*)
2. `forwarded_headers()` with `browser_ua=True` — injects browser headers while preserving incoming client headers and filtering hop-by-hop headers
3. Applied only to `openai-compat` backend where Cloudflare is common
4. This resolved the 403 — upstream now returns 401 (auth) instead of 403 (bot block), confirming the headers work

### Phase 6: Codex Default Mode — OAuth Without Config

**Problem:** Users wanted to quickly switch back to built-in Codex OAuth without maintaining a separate endpoint.

**Approach:**
1. Added "Codex Default (Desktop)" and "Codex Default (CLI)" buttons
2. On launch: backup config → **delete** `config.toml` entirely → start Codex → restore config after exit
3. Key insight: writing empty strings (`model = ""`, `model_provider = ""`) causes Codex to error with "Model provider `` not found". The config must not exist at all for Codex to fall back to built-in defaults.

### Phase 7: Command Code Multi-Format Parser — The 17-Fix Odyssey

**Problem:** Command Code provider's tool calls were silently dropped, causing the Codex agent loop to stop after the first response. The CC model returns tool calls as inline text in wildly varying formats that change between sessions and model versions.

**Root Cause Analysis:**
1. CC's `/alpha/generate` API uses a proprietary protocol — not Chat Completions, not Anthropic Messages
2. Tool calls appear as inline text within `text-delta` SSE events, not as structured JSON
3. The model output format is **non-deterministic** — observed 6+ distinct formats:
   - Raw JSON: `{"cmd":"mkdir -p /foo","type":"tool-call"}`
   - XML: `<function name="exec_command"><parameter name="cmd">...</parameter></function>`
   - HTML-like: `<tool_call type="bash">\n{"command":"..."}`
   - Bash blocks: `<bash>\nprefix_rule: ...\n{"command":"..."}</bash>`
   - Explore blocks: `<explore_agent>...</explore_agent>`
   - DSML tags: `<｜｜DSML｜｜invoke name="exec"><｜｜DSML｜｜parameter name="command">...</parameter></invoke>`
4. Additional complications: double-wrapped arguments, unescaped quotes, unicode escapes, missing fields

**The Fix — 17 Incremental Patches:**
Built a cascading parser chain (`DSML → bash → explore → tool_call → XML → raw JSON → fallback regex`) that tries each format in order. Each patch addressed a specific format observed in production:

- **FIX 1–4**: Foundation — string-only content, version headers, cache clearing, streaming error handling
- **FIX 5–8**: Core parsing — raw JSON extraction, three-tier argument parser, field extraction, permission normalization
- **FIX 9–10**: Cleanup — removed dead code, added documentation
- **FIX 11–11c**: Robustness — recursive unwrapping of nested cmd values, post-extraction sanitizer, XML regex fix
- **FIX 12**: Self-revive watchdog — proxy auto-restarts on crash instead of dying silently
- **FIX 13–17**: New format support — fallback extraction, HTML-like blocks, explore blocks, bash blocks, DSML tags

**Key Design Decision:** Field-level regex extraction instead of JSON parsing. Standard JSON parsers fail on unescaped quotes in shell commands (e.g., `echo "hello world"` breaks JSON). The regex approach tolerates malformed JSON by extracting individual fields.

**Verification:** `--self-test` flag runs 19 automated tests covering all edge cases. Debug logging to `~/.cache/codex-proxy/cc-debug.log` captures every parser decision for troubleshooting.

### Phase 8: Intelligence Routing — When the Model Refuses to Speak Machine

**Problem:** The 17-fix parser chain from Phase 7 was powerful — it could handle DSML, XML, JSON, bash blocks, explore tags, you name it. But there was one edge case it couldn't crack: **when the model doesn't produce a parseable tool-call format at all**.

In production, `deepseek/deepseek-v4-flash` via Command Code kept doing things like:

```
<explore_agent>
messages: [{"content": "Understand the Z.AI-Chat-for-Android repo at https://..."}]
</explore_agent>
```

or:

```
<require_escalation>
I need elevated permissions to access the repository.
</require_escalation>
```

or just plain English: *"I need to fetch the README from the repository to understand the app structure."*

In every case, `parsed_tool_calls=0`. No tool to execute. The Codex agent loop ground to a halt. The user saw "thinking..." forever.

**The insight:** The model is trying to communicate *intent*, just not in a format we can parse. Instead of adding more regex patterns, what if we could **read the model's mind** — understand what it *wants* to do, and synthesize the command for it?

**Intelligence Routing — Three Layers of Escalation:**

```
Layer 1: "Fix the input"     — Can we extract more from what the model gave us?
Layer 2: "Handle the intent" — Is the model asking for something we can auto-resolve?
Layer 3: "Read the mind"     — What is the model trying to do? Just do it for it.
```

**Layer 1 — Deep URL Extraction (FIX 23):**

The `<explore_agent>` handler had a URL regex, but the URL was trapped inside `{"content": "https://..."}` — the trailing `"` broke matching. The fix: after the initial regex fails, `json.loads()` the entire block, walk the JSON tree, and pull URLs out of `content` fields. The `_build_explore_cmd()` function was extracted to module level so both the parser and the stream handler could use it.

```python
# Before: regex fails, URL lost
# After: json.loads -> iterate items -> extract content -> find URL
```

**Layer 2 — Escalation Auto-Proceed (FIX 24):**

`<require_escalation>` blocks are the model's way of saying "I need more permissions." The CC adapter doesn't have an escalation mechanism — these blocks were silently dropped. The fix: detect them (both closed `<tag>...</tag>` and bare `<tag />` forms), extract any URL inside them, and auto-proceed with an explore command or a diagnostic echo.

```python
# Model: <require_escalation>Please let me run curl</require_escalation>
# Proxy: Okay, here's your curl command → exec_command synthesized
```

**Layer 3 — Intent-Based Command Synthesis (FIX 25):**

The crown jewel. When ALL parsers return empty — no DSML, no XML, no JSON, no fallback regex matches — the system doesn't give up. It analyzes the model's raw text through **5 heuristic lenses** in priority order:

| Priority | Signal | Synthesized Command |
|:--------:|--------|---------------------|
| 1 | URL in text | `curl` to fetch it |
| 2 | File path reference | `cat` or `ls` the file |
| 3 | Shell command in backticks/quotes | Extract and run it |
| 4 | "explore"/"fetch" + last user URL | Full explore command |
| 5 | "I need to"/"let me" intent | Echo diagnostic |

The system also maintains a **session URL memory** (`_last_user_urls`, a deque of the last 20 URLs from user messages) so heuristic 4 always has a URL to work with, even when the model's text doesn't contain one.

```python
# Model: "I should explore the repository to understand its structure."
# Parser: empty (no parseable format)
# Layer 3 heuristic 4: "explore" detected, pulling URL from session memory...
# Result: exec_command with full curl pipeline
```

**The result:** Before Intelligence Routing, `parsed_tool_calls=0` meant **game over** — the agent loop stalled permanently. After Intelligence Routing, `parsed_tool_calls=0` triggers the self-healing chain and the loop **always** gets a tool call to execute. The model can speak in tongues and the system still works.

**Test coverage:** 54 self-test patterns (up from 41), with 13 new tests specifically for Intelligence Routing layers.

### Phase 9: AI Monitoring — The Watchman That Never Sleeps

**Problem:** Intelligence Routing (Phase 8) handles failures *inside a single request*. But it can't detect a dead proxy process, reconnect Codex to a restarted proxy, switch to a backup provider when the primary is down, or clear corrupt caches. When the proxy crashes at 3 AM, the user wakes up to a broken Codex session and has to manually restart everything.

**The insight:** We needed a separate watchdog process that runs *outside* the proxy — monitoring it from the outside, like a night watchman patrolling a building. But a dumb watchdog that just restarts on crash is crude. What if the watchdog could *think* — diagnose *why* the proxy crashed and take the right corrective action?

**The Three-Tier Response System:**

```
Failure Detected
      │
      ├── Tier 1: Known pattern? → Rule-based fix (< 1 second)
      │             "proxy dead" → restart_proxy
      │             "429 rate limit" → wait_retry_after
      │             "schema corrupt" → delete_provider_caps
      │
      ├── Tier 2: Seen this before? → Incident store lookup (< 100ms)
      │             85% success rate → reuse the fix that worked last time
      │
      └── Tier 3: Novel failure? → AI diagnostic agent (2-5 seconds)
                    Feed context to cheap LLM → get recommended action
                    Learn from result for next time
```

**What makes this different from existing solutions:**

Existing proxy tools (ccLoad, cc-proxy, codex-pool) all focus on routing and failover at the *request* level. None have an AI-powered diagnostic agent that analyzes failure context and recommends corrective actions. ccLoad has health checks and cooldowns, but it's purely rule-based. AI Monitoring adds the *intelligence* layer on top — the Tier 3 agent can diagnose novel failures that no rule covers.

**How it works:**

Two threads run in the GUI process:
1. `HealthWatcher` — pings `/health` every 5 seconds. On 3 consecutive failures, triggers Tier 1 `restart_proxy`.
2. `LogAnalyzer` — tails the debug log file, watching for 18 signal patterns. Counts consecutive failures per category. When a threshold is hit (e.g., 5x stuck recovery, 3x server error), triggers the appropriate tier.

The AI diagnostic agent (Tier 3) is fully configurable — the user picks any provider and model. A cheap model like Gemini Flash (~$0.0002/call) or a free local Ollama instance works perfectly. The agent receives a structured incident report (proxy health, upstream status, recent errors, parser state) and responds with one JSON action.

**Learning over time:** Every resolved incident is stored in `incident-store.json` with pattern → fix → success rate. Over time, the system shifts from Tier 3 (expensive AI calls) to Tier 2 (instant pattern lookup). A failure seen 10 times with 90% success rate will never reach the AI again.

**Catalogued 30 fault types** across 5 categories based on analysis of 42 production `parsed_tool_calls=0` events, 13 stuck recoveries, and 11 sanitizer flags from our actual debug logs. The system knows exactly what to look for.

---

## Architecture Deep Dive

### Request Flow (OpenAI-compatible provider)

```
Codex CLI/Desktop
    │
    │ POST /responses (Responses API)
    │ Body: { model: "glm-5.1", input: [...], stream: true }
    ▼
┌─────────────────────────────────┐
│  translate-proxy.py (port 8080) │
│                                 │
│  1. Parse Responses API body    │
│  2. Convert input → messages    │
│  3. Convert tools format        │
│  4. Inject browser UA headers   │
│                                 │
│  POST /v1/chat/completions      │──→  Upstream Provider
│  Body: { model, messages, ... }│      (opencode.ai, z.ai, etc.)
│                                 │
│  5. Receive Chat Comp. response │  ←── SSE stream or JSON
│  6. Convert response format     │
│  7. Emit Responses API SSE      │
│                                 │
└─────────────────────────────────┘
    │
    │ SSE: response.created
    │ SSE: response.output_text.delta  (streamed tokens)
    │ SSE: response.output_text.done
    │ SSE: response.completed
    ▼
Codex CLI/Desktop (receives Responses API events)
```

### Config Lifecycle

```
┌─────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌─────────┐
│ Backup   │───→│ Cleanup  │───→│ Generate │───→│ Launch   │───→│ Restore │
│ config   │    │ stale    │    │ config   │    │ Codex    │    │ config  │
│ .toml    │    │ processes│    │ + models │    │ process  │    │ from    │
│          │    │          │    │          │    │          │    │ backup  │
└─────────┘    └──────────┘    └──────────┘    └──────────┘    └─────────┘
```

### Model Catalog Format

The launcher generates model catalog JSON with dual field naming to satisfy both Codex CLI and Codex Desktop:

```json
{
  "models": [{
    "slug": "glm-5.1",          // CLI reads this
    "model": "glm-5.1",         // Desktop reads this
    "supported_reasoning_levels": [...],  // CLI
    "supportedReasoningEfforts": [...],   // Desktop
    ...
  }]
}
```

---

## Gemini Antigravity State Continuity

Codex Launcher includes special handling for Gemini 3 / Antigravity OAuth:

- **Thought signature preservation**: Captures `thoughtSignature` from Gemini responses
  and reattaches them on follow-up requests to maintain tool-call continuity.
- **Edit-intent detection**: When follow-up requests contain edit keywords, a tool-use
  nudge is injected to prevent text-only responses.
- **User instruction enforcement**: The latest user message is guaranteed to be the
  final content turn sent to Gemini, even after compaction.
- **Smart compaction**: Old tool outputs capped at 3000 chars, recent 6 at 20000 chars.

---

## Multi-Account Rotation

Codex Launcher supports **multiple accounts per provider** with automatic rotation
when one account is rate-limited.

### Codebuff (Multiple Accounts)

Register additional free accounts at [codebuff.com](https://www.codebuff.com), then
add them to `~/.config/manicode/credentials.json`:

```json
{
  "default": { "authToken": "token-primary", "email": "you+1@gmail.com" },
  "accounts": [
    { "authToken": "token-secondary", "email": "you+2@gmail.com" },
    { "authToken": "token-tertiary", "email": "you+3@gmail.com" }
  ]
}
```

Each account gets 5 free requests/day. With 3 accounts = **15 requests/day**.

### Google OAuth (Multiple Projects)

Add additional Google Cloud token files:

```
~/.cache/codex-proxy/google-antigravity-oauth-token.json     # primary
~/.cache/codex-proxy/google-antigravity-oauth-token-1.json   # extra project 1
~/.cache/codex-proxy/google-antigravity-oauth-token-2.json   # extra project 2
```

### API Keys (Comma-Separated)

For any OpenAI-compatible provider:
```json
{ "api_key": "sk-key1,sk-key2,sk-key3" }
```

### Account Status Endpoint

```bash
curl http://127.0.0.1:PORT/v1/accounts
```

---

## Provider Presets

| Preset | Backend | Base URL |
|--------|---------|----------|
| OpenAI | Native | `https://api.openai.com/v1` |
| Anthropic | Anthropic | `https://api.anthropic.com/v1` |
| OpenCode Zen | OpenAI-compat | `https://opencode.ai/zen/v1` |
| OpenCode Go | OpenAI-compat | `https://opencode.ai/zen/go/v1` |
| Command Code | Command Code | `https://api.commandcode.ai` |
| **Codebuff** | **Codebuff** | `https://codebuff.com` *(free DeepSeek/Kimi — OAuth login built-in)* |
| Crof.ai | OpenAI-compat | `https://crof.ai/v1` |
| OpenAdapter | OpenAI-compat | `https://api.openadapter.in/v1` |
| Z.ai Coding | OpenAI-compat | `https://api.z.ai/api/coding/paas/v4` |
| NVIDIA NIM | OpenAI-compat | `https://integrate.api.nvidia.com/v1` |
| Kilo.ai | OpenAI-compat | `https://api.kilo.ai/api/gateway` |
| OpenRouter | OpenAI-compat | `https://openrouter.ai/api/v1` |
| Z.AI | OpenAI-compat | `https://api.z.ai/api/coding/paas/v4` |
| Google Gemini (API Key) | OpenAI-compat | `https://generativelanguage.googleapis.com/v1beta/openai` |
| Google Gemini (OAuth) | Gemini OAuth | `cloudcode-pa.googleapis.com` |
| Google Antigravity (OAuth) | Antigravity OAuth | `daily-cloudcode-pa.sandbox.googleapis.com` |
| Custom | Any | User-defined |

### Free Models (via Codebuff)
Codebuff provides free access to these models — no API key needed:
- **DeepSeek V4 Pro** — Smartest model
- **DeepSeek V4 Flash** — Most efficient
- **Kimi K2.6** — Balanced
- **MiniMax M2.7** — Fastest

*Requires: `codebuff login` via GUI OAuth button, or `npm install -g codebuff && codebuff login` (GitHub OAuth)*

---

## File Structure

```
src/
├── translate-proxy.py            # Translation proxy (openai-compat + anthropic + command-code)
├── codex-launcher-gui            # GTK launcher GUI
├── cleanup-codex-stale.sh        # Stale process cleanup
└── codex-launcher.desktop.template  # Desktop entry template

install.sh                        # One-command installer
README.md                         # This file
```

### Installed Locations

```
/usr/bin/translate-proxy.py               # Proxy (from .deb)
/usr/bin/codex-launcher-gui               # Launcher (from .deb)
/usr/bin/cleanup-codex-stale.sh           # Cleanup (from .deb)
/usr/share/applications/codex-launcher.desktop  # App grid entry
~/.codex/endpoints.json                   # Endpoint storage
~/.codex/config.toml                      # Codex config (auto-generated)
~/.cache/codex-proxy/                     # Proxy configs + model catalogs
~/.cache/codex-proxy/cc-debug.log         # Debug log (per-request)
```

---

### Phase 10: Codebuff Integration — Free AI for Everyone (v3.8.1)

**Problem:** Users want access to powerful models like DeepSeek V4 Pro without paying API fees. Codebuff (by CodebuffAI) offers free access to premium models through their server, but it's a CLI tool — not an API you can plug into Codex Launcher.

**The insight:** Codebuff's backend is a Next.js app with an OpenAI-compatible `/api/v1/chat/completions` endpoint. It uses agent-run lifecycle management and model-specific routing. If we replicate the agent run protocol in our proxy, we can tap into codebuff's free tier.

**How Codebuff works internally:**
1. User logs in via GitHub OAuth → session token stored in `~/.config/manicode/credentials.json`
2. Each request creates an **agent run** via `POST /api/v1/agent-runs`
3. Chat completions sent with `codebuff_metadata: {run_id, cost_mode: "free"}`
4. Server routes to the correct upstream provider using its own API keys
5. Agent run finished when request completes

**What we built:**

```
Codex Request
     │
     ▼
┌─────────────────────────────────┐
│  translate-proxy.py              │
│  _handle_codebuff()             │
│                                  │
│  1. Read token from credentials  │
│  2. POST /api/v1/agent-runs      │──→  {action: "START", agentId}
│  3. POST /api/v1/chat/completions │──→  {model, messages,
│                                        codebuff_metadata: {
│                                          run_id, cost_mode: "free"}}
│  4. Stream response back to Codex   │←──  SSE events
│  5. POST /api/v1/agent-runs       │──→  {action: "FINISH"}
└─────────────────────────────────┘
```

**Free models available:**
| Model | Agent ID | Notes |
|-------|----------|-------|
| DeepSeek V4 Pro | `base2-free-deepseek` | Smartest |
| DeepSeek V4 Flash | `base2-free-deepseek-flash` | Most efficient |
| Kimi K2.6 | `base2-free-kimi` | Balanced |
| MiniMax M2.7 | `base2-free` | Fastest |

**Bonus fix:** While investigating this, we discovered that `endpoints.json` had been overwritten with only 4 AG X entries, losing all 17+ provider presets. Restored all presets from proxy cache files.

---

## Troubleshooting

| Issue | Cause | Fix |
|-------|-------|-----|
| Window opens then disappears | Stale processes from previous session | Click **Kill && Cleanup** |
| Window never opens | Startup freeze | Kill && Cleanup, then retry |
| "Model provider `` not found" | Empty strings in config | V2 deletes config entirely for Default mode |
| 403 Forbidden from OpenCode | Cloudflare bot detection | Proxy injects browser UA headers |
| 401 Unauthorized from OpenCode | Invalid key or no credits | Check API key and billing |
| Double path in URL | Stale `/chat/completions` in base URL | `normalize_base_url()` strips suffixes |
| Proxy stops when terminal closes | SIGHUP to subprocess | Launcher uses `os.setsid` process groups |
| Models not showing in picker | Wrong model catalog format | Must have both `slug` + `model` fields |
| Codex hangs in "thinking" | Missing `response.completed` | Proxy emits full SSE event sequence |
| Stops after first tool call (Crof) | `previous_response_id` not resolved | V2.1.2 stores and chains responses for multi-turn |
| CC agent stops after first response | Tool calls not parsed from model text | V3.5 multi-format parser handles all CC output formats |
| CC tool calls have wrong args | Double-wrapped arguments | V3.5 three-tier parser + recursive unwrapping |
| Proxy crashes mid-session | Unhandled streaming error | V3.5 self-revive watchdog auto-restarts |
| CC 403 upgrade_required | Missing version header | V3.5 always sends `x-command-code-version` |
| CC explore_agent can't find URL | URL hidden inside JSON messages | V3.7 Layer 1 drills into JSON to extract URLs |
| CC agent stalls on escalation blocks | `<require_escalation>` not handled | V3.7 Layer 2 auto-proceeds past escalation requests |
| CC agent stalls — no tool calls at all | Model output format unrecognized | V3.7 Layer 3 synthesizes command from text intent |
| Proxy crashes mid-session | Unhandled streaming error | V3.8 AI Monitor auto-restarts proxy |
| Proxy port conflict on restart | Stale process holding port | V3.8 AI Monitor kills stale + restarts |
| Schema cache corruption | ErrorAnalyzer learned wrong schema | V3.8 AI Monitor auto-clears provider-caps.json |
| Upstream 500 repeatedly | Provider having issues | V3.8 AI Monitor detects pattern + alerts/switches |

---

## Adding a New Provider

1. Click **Manage Endpoints** → **Add**
2. Choose a preset or set **Custom**
3. Set backend type: `OpenAI-compatible`, `Anthropic`, or `Native`
4. Enter base URL and API key
5. Click **Fetch from API** or add models manually
6. Save and launch

For providers behind Cloudflare, the proxy automatically injects browser headers. For providers with non-standard APIs, add a new backend module to `translate-proxy.py` following the `oa_*` / `an_*` pattern.

---

## Manual Proxy Usage

```bash
# Start proxy for any OpenAI-compatible provider
python3 src/translate-proxy.py \
  --backend openai-compat \
  --target-url https://api.your-provider.com/v1 \
  --api-key YOUR_KEY \
  --port 8080

# Or use a JSON config
python3 src/translate-proxy.py --config my-proxy-config.json

# Then run Codex
codex --profile my-profile -c model=my-model
```

---

## Requirements

- Python ≥ 3.8
- python3-gi (`sudo apt install python3-gi`)
- Codex CLI ≥ 2.0
- Codex Desktop (optional, for Desktop mode)
- bash, curl, lsof

**No pip dependencies.** Zero. Pure stdlib + system GTK.

---

## License

MIT

---

<p align="center">
  <strong>Get 10% OFF Z.AI coding plans</strong><br/>
  <a href="https://z.ai/subscribe?ic=ROK78RJKNW">
    <img src="https://img.shields.io/badge/Claim_Your_Discount-10%25_OFF-6366f1?style=for-the-badge&labelColor=4f46e5" alt="Z.AI 10% OFF" />
  </a>
</p>
