From b442e03f54f8eb02a2fea2eefe6bee0d891e518d Mon Sep 17 00:00:00 2001 From: Kulvir Date: Tue, 21 Jul 2026 12:28:34 -0700 Subject: [PATCH] chore: switch external model harness from Kilo to pi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fix how the panel tracks a running pi model, drop CodeRabbit, and stop gating non-OpenRouter pi models on an OpenRouter key. **Tracking.** `pi` buffers ALL output until the process exits — verified for `--mode text`, `--mode json` and `--mode rpc`, and the session file is not created until completion either, so there is no incremental channel to watch. The polling protocol treated output-file growth as the health signal and declared a model "stuck" after 10 minutes of no growth. Since the file sits at 0 bytes for the entire run, that rule fires on healthy reviews: a genuine 40+ minute review is indistinguishable from a hung one and gets abandoned. Track the process instead: - Launch each model in a subshell that records a pid file and, on completion, an exit sentinel (`{model}.exit`). - Poll `kill -0 $(cat {model}.pid)` for liveness. ALIVE means working, regardless of output size. - Treat a model as failed only when the process is GONE **and** the sentinel is non-zero or the output is empty. GONE + exit 0 + non-empty output is a success awaiting its SendMessage. - Call out explicitly that file size must not be used as a health signal, so the heuristic does not get reintroduced. Verified with a real pi run: ALIVE at 0 bytes for 32s+, then GONE with exit=0 and non-empty output, correctly classified as success. This also caught a real failure — a review that died silently and produced nothing was previously indistinguishable from one still working. **Preflight.** The check required `OPENROUTER_API_KEY` for every command starting with `pi `, but a model configured as `pi --provider altimate-azure` does not use OpenRouter at all. A missing OpenRouter key would therefore skip a perfectly working model and then abort on quorum, while never validating the credential that model actually needs. The required credential is now derived from each model's own `--provider`. **CodeRabbit removed.** Its invocation used `coderabbit review --plain`, and the CLI has since removed `--plain` (plain text is the default). Combined with the "if it fails, continue without it" fallback, CodeRabbit was silently skipped on every run. Rather than carry a supplementary reviewer that quietly does nothing, drop it: availability check, invocation, collection/reporting lines, comparison table column, attribution footer, the skill-reference section, and the plugin keywords. --- .claude-plugin/marketplace.json | 2 +- CHANGELOG.md | 15 +++ README.md | 22 ++--- plugins/consensus/.claude-plugin/plugin.json | 4 +- plugins/consensus/.codex-plugin/plugin.json | 5 +- plugins/consensus/commands/code-review.md | 98 ++++++++++--------- plugins/consensus/commands/consensus-setup.md | 48 ++++----- plugins/consensus/commands/plan-review.md | 62 ++++++++---- plugins/consensus/commands/review.md | 60 ++++++++---- plugins/consensus/consensus.codex.config.json | 20 ++-- plugins/consensus/consensus.config.json | 26 ++--- .../references/command.md | 16 +-- .../references/command.md | 15 +-- .../consensus-setup/references/command.md | 32 +++--- 14 files changed, 246 insertions(+), 179 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 76ff5a2..2271892 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -6,7 +6,7 @@ }, "metadata": { "description": "Configurable multi-model consensus code review, plan review, and general review for Claude Code and Codex", - "version": "1.7.0" + "version": "1.8.0" }, "plugins": [ { diff --git a/CHANGELOG.md b/CHANGELOG.md index a9e1b89..6270128 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +## [1.8.0] - 2026-07-21 + +### Changed + +- **External model harness switched from Kilo to the [pi coding agent](https://pi.dev).** All OpenRouter-hosted model entries now run `pi --provider openrouter --model -p` instead of `kilo run -m openrouter/ --auto`. Resume/convergence keeps `resume_flag: "-c"` (pi's `--continue`). Native `codex`/`agy`/`qwen` entries are unchanged. +- Setup CLI-detection, provider prompts, harness tables, and preflight checks now reference `pi` (`command -v pi`) instead of `kilo`. +- Fixed stale/invalid model ids that no longer resolve on OpenRouter: `openai/gpt-5.4-codex` → `openai/gpt-5.3-codex`, `x-ai/grok-4.20-beta` → `x-ai/grok-4.3`, `xiaomi/mimo-v2-pro` → `xiaomi/mimo-v2.5-pro` (display names aligned). Verified every default model id against pi's live OpenRouter catalog. +- **GLM now routes through OpenRouter** (`z-ai/glm-5.1`) instead of the Z.ai coding-plan direct provider (`zai-coding-plan/glm-5.1`) — pi has no Z.ai-direct provider. This changes GLM billing from a Z.ai coding-plan subscription to OpenRouter usage; Z.ai coding-plan users who want the direct route should register a pi custom provider (see below). +- Convergence isolates each panelist's pi session with `--session-dir "$SESSION_DIR/pi-"` so the `-c`/`--continue` resume can't cross-wire parallel panelists (pi resumes the most-recent session *per working directory*). +- Plugin metadata bumped to v1.8.0. + +### Note + +- Private/self-hosted endpoints (e.g. Azure OpenAI) are supported by registering a pi custom provider via an extension in `~/.pi/agent/extensions/` — see the pi custom-provider docs. + ## [1.7.0] - 2026-05-20 ### Changed diff --git a/README.md b/README.md index 7f38da0..9715681 100644 --- a/README.md +++ b/README.md @@ -61,8 +61,8 @@ Alias skills are also provided for `code-review`, `plan-review`, `plan-reviwe`, | Requirement | Required? | Notes | |-------------|-----------|-------| | Claude Code or Codex | Yes | The host environment determines the lead reviewer | -| Kilo CLI | Recommended | Routes OpenRouter models with one API key | -| OpenRouter API key | Recommended | Required for Kilo/OpenRouter models | +| pi CLI | Recommended | Routes OpenRouter models with one API key | +| OpenRouter API key | Recommended | Required for pi/OpenRouter models | | Native CLIs | Optional | Claude supports `codex`, Antigravity CLI (`agy`), and `qwen`; Codex supports non-Codex native CLIs | | CodeRabbit CLI | Optional | Supplementary static analysis for code reviews | @@ -73,15 +73,15 @@ Alias skills are also provided for `code-review`, `plan-review`, `plan-reviwe`, | Model | Provider | OpenRouter ID | Claude native | Codex external | |-------|----------|---------------|---------------|----------------| | Claude | Anthropic | built-in | lead | not used | -| Codex / GPT | OpenAI | `openai/gpt-5.4-codex` | `codex` | lead, not external | +| Codex / GPT | OpenAI | `openai/gpt-5.3-codex` | `codex` | lead, not external | | Gemini 3.1 Pro | Google | `google/gemini-3.1-pro-preview` | Antigravity CLI (`agy`) | Antigravity CLI (`agy`) | -| Kimi K2.6 | Moonshot | `moonshotai/kimi-k2.6` | Kilo | Kilo | -| Grok 4.20 | xAI | `x-ai/grok-4.20-beta` | Kilo | Kilo, disabled by default | -| MiniMax M2.7 | MiniMax | `minimax/minimax-m2.7` | Kilo | Kilo | -| GLM-5.1 | Zhipu AI | `zai-coding-plan/glm-5.1` | Kilo | Kilo | -| Qwen 3.6 Plus | Alibaba | `qwen/qwen3.6-plus` | `qwen` or Kilo | Kilo by default | -| MiMo V2 Pro | Xiaomi | `xiaomi/mimo-v2-pro` | Kilo | Kilo | -| DeepSeek V4 Pro | DeepSeek | `deepseek/deepseek-v4-pro` | Kilo | Kilo | +| Kimi K2.6 | Moonshot | `moonshotai/kimi-k2.6` | pi | pi | +| Grok 4.3 | xAI | `x-ai/grok-4.3` | pi | pi, disabled by default | +| MiniMax M2.7 | MiniMax | `minimax/minimax-m2.7` | pi | pi | +| GLM-5.1 | Zhipu AI | `z-ai/glm-5.1` | pi | pi | +| Qwen 3.6 Plus | Alibaba | `qwen/qwen3.6-plus` | `qwen` or pi | pi by default | +| MiMo V2.5 Pro | Xiaomi | `xiaomi/mimo-v2.5-pro` | pi | pi | +| DeepSeek V4 Pro | DeepSeek | `deepseek/deepseek-v4-pro` | pi | pi | Codex intentionally excludes Codex/GPT from the external panel because Codex is already the lead reviewer. @@ -115,7 +115,7 @@ Example Codex config: { "id": "kimi", "name": "Kimi K2.6", - "command": "kilo run -m openrouter/moonshotai/kimi-k2.6 --auto", + "command": "pi --provider openrouter --model moonshotai/kimi-k2.6 -p", "resume_flag": "-c", "enabled": true } diff --git a/plugins/consensus/.claude-plugin/plugin.json b/plugins/consensus/.claude-plugin/plugin.json index eb67532..ca550a4 100644 --- a/plugins/consensus/.claude-plugin/plugin.json +++ b/plugins/consensus/.claude-plugin/plugin.json @@ -1,11 +1,11 @@ { "name": "consensus", - "version": "1.7.0", + "version": "1.8.0", "description": "Configurable multi-model code review, plan review, and general review with consensus convergence for Claude Code", "author": { "name": "AltimateAI" }, "repository": "https://github.com/AltimateAI/claude-consensus", "license": "MIT", - "keywords": ["code-review", "plan-review", "review", "multi-model", "consensus", "configurable", "coderabbit"] + "keywords": ["code-review", "plan-review", "review", "multi-model", "consensus", "configurable"] } diff --git a/plugins/consensus/.codex-plugin/plugin.json b/plugins/consensus/.codex-plugin/plugin.json index 4c63a38..ca2ce6f 100644 --- a/plugins/consensus/.codex-plugin/plugin.json +++ b/plugins/consensus/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "consensus", - "version": "1.7.0", + "version": "1.8.0", "description": "Codex-led multi-model code review, plan review, and general review with consensus convergence", "author": { "name": "AltimateAI", @@ -16,8 +16,7 @@ "review", "multi-model", "consensus", - "configurable", - "coderabbit" + "configurable" ], "skills": "./skills/", "interface": { diff --git a/plugins/consensus/commands/code-review.md b/plugins/consensus/commands/code-review.md index c95bc1f..a5aa560 100644 --- a/plugins/consensus/commands/code-review.md +++ b/plugins/consensus/commands/code-review.md @@ -89,7 +89,11 @@ Source the API key (targeted — only export `OPENROUTER_API_KEY`): ``` For each model in `MODELS`, verify CLI availability: -- Commands starting with `kilo` -> check: `command -v kilo` AND `[ -n "$OPENROUTER_API_KEY" ]` +- Commands starting with `pi ` (the pi CLI, not `pip`/`pixi`) -> check `command -v pi`, then derive + the required credential from that model's own `--provider`: + * `--provider openrouter` -> also require `[ -n "$OPENROUTER_API_KEY" ]` + * any other provider (e.g. `altimate-azure`) -> configured as a pi provider/extension, so it + needs NO OpenRouter key. Do NOT skip it for a missing `OPENROUTER_API_KEY`. - Commands starting with `codex` -> check: `command -v codex` - Commands starting with `agy` -> check: `command -v agy` - Commands starting with `gemini` -> legacy config; check `command -v agy`, run through the `agy` path below, and warn the user to rerun `/consensus-setup` @@ -97,23 +101,17 @@ For each model in `MODELS`, verify CLI availability: Run all checks in parallel. Remove unavailable models from `MODELS` with a warning for each: ``` -Warning: Skipping {model.name} — {reason: "kilo CLI not found" / "OPENROUTER_API_KEY not set" / "codex CLI not found" / "Antigravity CLI not found"} +Warning: Skipping {model.name} — {reason: "pi CLI not found" / "OPENROUTER_API_KEY not set" / "codex CLI not found" / "Antigravity CLI not found"} ``` -**Check CodeRabbit availability:** -```bash -command -v coderabbit && echo "CODERABBIT_OK" -``` -If available, set `CODERABBIT_AVAILABLE=true`. CodeRabbit is a supplementary static analysis reviewer — it does NOT count toward quorum and does NOT participate in convergence. Its findings are incorporated during synthesis. +Count available models + 1 (Claude) = `TOTAL_PARTICIPANTS`. -Count available models + 1 (Claude) = `TOTAL_PARTICIPANTS`. If CodeRabbit is available, add 1 to `TOTAL_PARTICIPANTS` for reporting (but NOT for quorum calculation). - -If `TOTAL_PARTICIPANTS (excluding CodeRabbit) < MIN_QUORUM`: +If `TOTAL_PARTICIPANTS < MIN_QUORUM`: **ABORT**: "Only {TOTAL_PARTICIPANTS} models available but quorum requires {MIN_QUORUM}. Run `/consensus-setup` to reconfigure." Report: ``` -Panel: Claude + {comma-separated list of available model names}{+ CodeRabbit if available} ({TOTAL_PARTICIPANTS} total, quorum={MIN_QUORUM}) +Panel: Claude + {comma-separated list of available model names} ({TOTAL_PARTICIPANTS} total, quorum={MIN_QUORUM}) ``` ## Step 1: Create Session Directory & Write Prompt @@ -194,19 +192,10 @@ Task: prompt: ``` -**While teammates work**, do two things in parallel: - -1. **Run CodeRabbit** (if `CODERABBIT_AVAILABLE`): - ```bash - coderabbit review --plain --base {BASE_BRANCH or BASE_COMMIT} > $SESSION_DIR/coderabbit.md 2>&1 - ``` - - Use the same base reference as the review target (e.g., `--base main` for branch diffs, `--base-commit HEAD~N` for commit ranges) - - CodeRabbit runs fast (typically 30-60 seconds) and writes structured findings directly - - If it fails or returns empty output, set `CODERABBIT_AVAILABLE=false` and continue without it +**While teammates work**, write Claude's own review using codebase knowledge — Read the changed +files, related tests, understand patterns. Write your review to `$SESSION_DIR/claude.md`. -2. **Write Claude's own review** using codebase knowledge — Read the changed files, related tests, understand patterns. Write your review to `$SESSION_DIR/claude.md`. - -**Do not wait for teammates before starting Claude's review or CodeRabbit.** Work in parallel. +**Do not wait for teammates before starting Claude's review.** Work in parallel. **Expected duration:** External CLI models typically take 3-10 minutes to explore the codebase and produce output. Some models may take longer on complex codebases. This is completely normal — these models almost never fail. Do NOT check on teammates, send messages, or assume failure. Just wait for their SendMessage. @@ -218,7 +207,7 @@ For each model, substitute `{MODEL_ID}`, `{MODEL_NAME}`, `{MODEL_COMMAND}`, `{MO - For commands starting with `codex`: `--add-dir /path1 --add-dir /path2` (one `--add-dir` per directory) - For commands starting with `agy` or legacy `gemini`: `--add-dir /path1 --add-dir /path2` (one `--add-dir` per directory) - For commands starting with `qwen`: `--include-directories /path1,/path2` (comma-separated) -- For commands starting with `kilo`: empty string (kilo has no flag — the paths are already in the prompt) +- For commands starting with `pi `: empty string (pi takes no extra-dirs flag — the paths are already in the prompt) If `EXTRA_DIRS` is empty, `{EXTRA_DIRS_FLAGS}` is an empty string for all CLIs. @@ -243,8 +232,15 @@ SESSION_DIR={SESSION_DIR} **If `{MODEL_COMMAND}` starts with `qwen`:** qwen {EXTRA_DIRS_FLAGS} --approval-mode plan -p "$(cat $SESSION_DIR/prompt.md)" -o text > $SESSION_DIR/{MODEL_ID}.md 2>&1 - **Otherwise (Kilo/OpenRouter — default):** - {MODEL_COMMAND} "$(cat $SESSION_DIR/prompt.md)" > $SESSION_DIR/{MODEL_ID}.md 2>&1 + **Otherwise (pi/OpenRouter — default):** + # pi buffers ALL output until it exits (verified for --mode text, json and + # rpc — nothing is written mid-run, and the session file is not created + # until completion either). So progress is NOT observable from the output + # file; liveness must come from the process. Launch it with a pid file and + # an exit sentinel so the lead can distinguish "still working" from "done". + ( {MODEL_COMMAND} --session-dir "$SESSION_DIR/pi-{MODEL_ID}" "$(cat $SESSION_DIR/prompt.md)" > $SESSION_DIR/{MODEL_ID}.md 2>&1; echo $? > $SESSION_DIR/{MODEL_ID}.exit ) & + echo $! > $SESSION_DIR/{MODEL_ID}.pid + wait $(cat $SESSION_DIR/{MODEL_ID}.pid) If it fails or produces empty output, retry ONCE. @@ -269,8 +265,10 @@ After sending the review, WAIT. The lead will send you a convergence prompt. Whe **If `{MODEL_COMMAND}` starts with `qwen`:** qwen -c -p "$(cat $SESSION_DIR/convergence-prompt-{MODEL_ID}.md)" -o text > $SESSION_DIR/{MODEL_ID}-convergence.md 2>&1 - **Otherwise (Kilo/OpenRouter — default):** - {MODEL_COMMAND} {MODEL_RESUME_FLAG} "$(cat $SESSION_DIR/convergence-prompt-{MODEL_ID}.md)" > $SESSION_DIR/{MODEL_ID}-convergence.md 2>&1 + **Otherwise (pi/OpenRouter — default):** + ( {MODEL_COMMAND} {MODEL_RESUME_FLAG} --session-dir "$SESSION_DIR/pi-{MODEL_ID}" "$(cat $SESSION_DIR/convergence-prompt-{MODEL_ID}.md)" > $SESSION_DIR/{MODEL_ID}-convergence.md 2>&1; echo $? > $SESSION_DIR/{MODEL_ID}-convergence.exit ) & + echo $! > $SESSION_DIR/{MODEL_ID}-convergence.pid + wait $(cat $SESSION_DIR/{MODEL_ID}-convergence.pid) 3. Read the output, clean it 4. Send it to the lead via SendMessage. The response should start with APPROVE or CHANGES NEEDED. @@ -286,15 +284,25 @@ Wait for a shutdown_request from the lead before exiting. Complete Claude's review. Then use the following polling protocol to wait for all teammates: **Polling-based wait loop:** -1. Every ~1 minute, check each pending teammate's output file size: - `wc -c < $SESSION_DIR/{model.id}.md 2>/dev/null || echo 0` -2. Track the file size. If it's growing (or the file doesn't exist yet because the model is still exploring) — the model is working. Keep waiting. -3. A teammate is ONLY considered stuck if: - - Their output file exists AND - - Its size has not changed for 10 consecutive checks (10 minutes) -4. If a teammate appears stuck after 10 minutes of no file growth, send them a check-in message: "Are you still working? Send me your current output if you have any." -5. Wait another 3 minutes after check-in before giving up on that teammate. -6. DO NOT proceed to Step 5 until every teammate has either sent their result via SendMessage or been declared stuck per the above protocol. + +> ⚠ Do NOT use output-file growth as a health signal. `pi` buffers everything +> until it exits, so `{model.id}.md` stays at **0 bytes for the entire run** — +> a healthy 40-minute review looks identical to a hung one. Judging by file +> size will make you abandon working reviews. + +1. Every ~1 minute, check whether each pending model's PROCESS is still alive: + `kill -0 $(cat $SESSION_DIR/{model.id}.pid 2>/dev/null) 2>/dev/null && echo ALIVE || echo GONE` +2. `ALIVE` = the model is working, regardless of output size. Keep waiting. +3. Completion is signalled by the exit sentinel, not by file size: + `cat $SESSION_DIR/{model.id}.exit 2>/dev/null` — `0` means success, any other + value means the CLI failed (retry ONCE, per the teammate template). +4. A teammate is only treated as failed when its process is `GONE` **and** either + the `.exit` sentinel is non-zero or `{model.id}.md` is empty. A `GONE` process + with a `0` sentinel and non-empty output is a SUCCESS — wait for its SendMessage. +5. If a process is `GONE` with no sentinel at all (killed/crashed), send a check-in + message, then give up on that teammate after 3 minutes. +6. DO NOT proceed to Step 5 until every teammate has either sent their result via + SendMessage or been declared failed per the above protocol. Report to user (dynamically built from `MODELS`): @@ -302,7 +310,6 @@ Report to user (dynamically built from `MODELS`): ## Review Collection: {N}/{TOTAL_PARTICIPANTS} Reviews Received - Claude: done/failed -- CodeRabbit: done/skipped/failed (only if CODERABBIT_AVAILABLE) - {model.name}: done/failed (reason) - ... (one line per model in MODELS) ``` @@ -311,9 +318,7 @@ Report to user (dynamically built from `MODELS`): ## Step 5: Analyze & Compare -Read all available reviews — including CodeRabbit's output at `$SESSION_DIR/coderabbit.md` if it ran — and present a structured comparison. - -**CodeRabbit findings**: CodeRabbit produces structured findings with file paths, line numbers, types (potential_issue, refactor_suggestion), and suggested fixes. Parse these and include them alongside the AI model reviews. CodeRabbit findings are treated as an additional signal — they carry weight like any other reviewer but CodeRabbit does NOT participate in convergence rounds. +Read all available reviews and present a structured comparison. ``` ## Review Results ({N}/{TOTAL_PARTICIPANTS} Reviews Received) @@ -339,7 +344,7 @@ Read all available reviews — including CodeRabbit's output at `$SESSION_DIR/co | Overall verdict | {pass/fail} | ... | ... | ... | ``` -Build the comparison table columns dynamically from `["Claude"] + (["CodeRabbit"] if CODERABBIT_AVAILABLE) + [m.name for m in MODELS]`. +Build the comparison table columns dynamically from `["Claude"] + [m.name for m in MODELS]`. ## Step 6: Draft Synthesized Review @@ -460,7 +465,7 @@ Include a **finding attribution table** (dynamically built from participating mo | {specific issue from the review} | {model name(s)} | Consensus / Unique / Convergence fix | | {another issue} | {model name(s)} | ... | -*Reviewed by {TOTAL_PARTICIPANTS} participants: Claude, {comma-separated model names from MODELS}{, CodeRabbit (static analysis) if it ran}. Convergence: {N} round(s). {any user overrides noted}* +*Reviewed by {TOTAL_PARTICIPANTS} participants: Claude, {comma-separated model names from MODELS}. Convergence: {N} round(s). {any user overrides noted}* ``` **Rules for the attribution table:** @@ -494,8 +499,11 @@ On failure: preserve `$SESSION_DIR` for debugging and tell the user where files 8. **Dynamic quorum.** Use `MIN_QUORUM` from config. Abort if fewer than `MIN_QUORUM` reviews available (including Claude). 9. **Convergence through messaging.** Lead sends draft to teammates, they run their model and report back. Max 2 rounds. 10. **No plan mode.** Code reviews are presented directly, not written to plan files. -11. **Be patient with teammates — they almost never fail.** External CLI models (Codex, Antigravity, Kilo) take time to explore the codebase but almost always finish successfully. Follow this activity-based patience protocol: - - **Poll output files** every ~1 minute using `wc -c < $SESSION_DIR/{model.id}.md 2>/dev/null || echo 0` to check file size. +11. **Be patient with teammates — they almost never fail.** External CLI models (Codex, Antigravity, pi) take time to explore the codebase but almost always finish successfully. Follow this activity-based patience protocol: + - **Poll the process, not the file** every ~1 minute: + `kill -0 $(cat $SESSION_DIR/{model.id}.pid) 2>/dev/null && echo ALIVE || echo GONE`. + `pi` buffers all output until exit, so the output file is 0 bytes for the + whole run and its size says nothing about health. - **Growing file (or no file yet)** = the model is working. Keep waiting. - **A teammate is ONLY considered stuck if**: their output file exists AND its size has not changed for **10 consecutive checks** (10 minutes of zero growth). - If stuck after 10 minutes, send a check-in message: "Are you still working? Send me your current output if you have any." Wait another 3 minutes before giving up on that teammate. diff --git a/plugins/consensus/commands/consensus-setup.md b/plugins/consensus/commands/consensus-setup.md index edcb6d4..d1129ae 100644 --- a/plugins/consensus/commands/consensus-setup.md +++ b/plugins/consensus/commands/consensus-setup.md @@ -31,7 +31,7 @@ If user chooses "Keep current", print the current config summary and stop. Run all of these checks in parallel via Bash: ```bash -command -v kilo && echo "KILO_OK" || echo "KILO_MISSING" +command -v pi && echo "PI_OK" || echo "PI_MISSING" ``` ```bash @@ -57,7 +57,7 @@ Report findings to the user: ``` ## CLI Detection Results -- Kilo CLI: {installed / not found} +- pi CLI: {installed / not found} - Codex CLI: {installed / not found} - Antigravity CLI (`agy`): {installed / not found} - Qwen CLI: {installed / not found} @@ -72,11 +72,11 @@ AskUserQuestion: header: "Provider" options: - label: "OpenRouter (Recommended)" - description: "1 API key, all 9 models via Kilo CLI. Simplest setup." + description: "1 API key, all 9 models via pi. Simplest setup." - label: "Native CLIs" description: "Use codex, Antigravity (`agy`), and qwen CLIs directly where available. Requires each CLI installed separately." - label: "Both" - description: "Mix and match — use native CLIs where available, OpenRouter/Kilo for the rest." + description: "Mix and match — use native CLIs where available, OpenRouter/pi for the rest." ``` ## Step 4: API Key Setup @@ -119,24 +119,24 @@ Build the model list based on provider choice and detected CLIs. The 9 supported models and their CLI mappings: -| Model ID | Name | OpenRouter (Kilo) | Native CLI | +| Model ID | Name | OpenRouter (pi) | Native CLI | |----------|------|-------------------|------------| -| `gpt` | GPT 5.4 Codex | `kilo run -m openrouter/openai/gpt-5.4-codex --auto` | `codex` (if codex CLI installed — note: native codex uses whatever model your `~/.codex/config.toml` specifies, e.g. `gpt-5.5`) | -| `gemini` | Gemini via Antigravity | `kilo run -m openrouter/google/gemini-3.1-pro-preview --auto` | `agy` (if Antigravity CLI installed) | -| `kimi` | Kimi K2.6 | `kilo run -m openrouter/moonshotai/kimi-k2.6 --auto` | OpenRouter only | -| `grok` | Grok 4.20 | `kilo run -m openrouter/x-ai/grok-4.20-beta --auto` | OpenRouter only | -| `minimax` | MiniMax M2.7 | `kilo run -m openrouter/minimax/minimax-m2.7 --auto` | OpenRouter only | -| `glm5` | GLM-5.1 | `kilo run -m zai-coding-plan/glm-5.1 --auto` | Z.ai direct only | -| `qwen` | Qwen 3.6 Plus | `kilo run -m openrouter/qwen/qwen3.6-plus --auto` | `qwen` (if qwen CLI installed) | -| `mimo` | MiMo V2 Pro | `kilo run -m openrouter/xiaomi/mimo-v2-pro --auto` | OpenRouter only | -| `deepseek` | DeepSeek V4 Pro | `kilo run -m openrouter/deepseek/deepseek-v4-pro --auto` | OpenRouter only | +| `gpt` | GPT 5.3 Codex | `pi --provider openrouter --model openai/gpt-5.3-codex -p` | `codex` (if codex CLI installed — note: native codex uses whatever model your `~/.codex/config.toml` specifies, e.g. `gpt-5.5`) | +| `gemini` | Gemini via Antigravity | `pi --provider openrouter --model google/gemini-3.1-pro-preview -p` | `agy` (if Antigravity CLI installed) | +| `kimi` | Kimi K2.6 | `pi --provider openrouter --model moonshotai/kimi-k2.6 -p` | OpenRouter only | +| `grok` | Grok 4.3 | `pi --provider openrouter --model x-ai/grok-4.3 -p` | OpenRouter only | +| `minimax` | MiniMax M2.7 | `pi --provider openrouter --model minimax/minimax-m2.7 -p` | OpenRouter only | +| `glm5` | GLM-5.1 | `pi --provider openrouter --model z-ai/glm-5.1 -p` | OpenRouter only | +| `qwen` | Qwen 3.6 Plus | `pi --provider openrouter --model qwen/qwen3.6-plus -p` | `qwen` (if qwen CLI installed) | +| `mimo` | MiMo V2.5 Pro | `pi --provider openrouter --model xiaomi/mimo-v2.5-pro -p` | OpenRouter only | +| `deepseek` | DeepSeek V4 Pro | `pi --provider openrouter --model deepseek/deepseek-v4-pro -p` | OpenRouter only | **Note on native CLIs**: For `codex`, `agy`, and `qwen`, set the config's `command` field to just `codex`, `agy`, or `qwen`. The teammate template in the review/plan commands detects these and uses the correct native invocation patterns automatically (e.g., `codex exec -s read-only` for reviews, `codex exec resume --last` for convergence, `agy --sandbox -p` for reviews and convergence prompts, `qwen --approval-mode plan -p` with `-o text` for reviews, `qwen -c -p` for convergence). The `resume_flag` field is ignored for native CLIs. If an existing config still contains `command: "gemini"`, treat it as legacy and migrate it to `agy` during reconfiguration. Determine which models are available: -- **OpenRouter path**: All 9 available if `kilo` installed + API key set +- **OpenRouter path**: All 9 available if `pi` installed + API key set - **Native path**: Only `gpt` (if codex installed), `gemini` (if `agy` installed), and `qwen` (if qwen installed) -- **Both path**: Native CLI where available, OpenRouter/Kilo for the rest +- **Both path**: Native CLI where available, OpenRouter/pi for the rest ``` AskUserQuestion: @@ -144,21 +144,21 @@ AskUserQuestion: header: "Models" multiSelect: true options: - - label: "GPT 5.4 Codex" + - label: "GPT 5.3 Codex" description: "{available via OpenRouter / available via codex CLI / not available}" - label: "Gemini 3.1 Pro" description: "{available via OpenRouter / available via Antigravity CLI / not available}" - label: "Kimi K2.6" description: "{available via OpenRouter / not available}" - - label: "Grok 4.20" + - label: "Grok 4.3" description: "{available via OpenRouter / not available}" - label: "MiniMax M2.7" description: "{available via OpenRouter / not available}" - label: "GLM-5.1" - description: "{available via Z.ai coding plan / not available}" + description: "{available via OpenRouter / not available}" - label: "Qwen 3.6 Plus" description: "{available via OpenRouter / available via qwen CLI / not available}" - - label: "MiMo V2 Pro" + - label: "MiMo V2.5 Pro" description: "{available via OpenRouter / not available}" - label: "DeepSeek V4 Pro" description: "{available via OpenRouter / not available}" @@ -202,7 +202,7 @@ For each of the 9 models: For enabled models: - If user chose "Native CLIs" or "Both" AND the native CLI is detected, use the native command + native resume flag -- Otherwise use the OpenRouter/Kilo command + `-c` resume flag +- Otherwise use the OpenRouter/pi command + `-c` resume flag Write the config to `~/.claude/consensus.json` using the Write tool: @@ -244,7 +244,7 @@ Use the command pattern for the configured CLI: - `codex`: `printf '%s\n' "Reply with exactly: PONG" | codex exec -s read-only - 2>&1 | head -20` - `agy` or legacy `gemini`: `agy --sandbox -p "Reply with exactly: PONG" 2>&1 | head -20` - `qwen`: `qwen --approval-mode plan -p "Reply with exactly: PONG" -o text 2>&1 | head -20` -- Kilo/OpenRouter: `{model.command} "Reply with exactly: PONG" 2>&1 | head -20` +- pi/OpenRouter: `{model.command} "Reply with exactly: PONG" 2>&1 | head -20` Check if the output contains "PONG" (case-insensitive). @@ -256,7 +256,7 @@ Report results: ``` ## Smoke Test Results -- GPT 5.4 Codex: PASS +- GPT 5.3 Codex: PASS - Gemini 3.1 Pro: PASS - Kimi K2.6: FAIL — {error or empty output} - ... @@ -298,7 +298,7 @@ Print the final summary: 1. **9 fixed models only.** Do not offer custom model configuration. The wizard supports exactly the 9 models listed above. 2. **Idempotent .env updates.** When writing API keys, preserve all existing keys in the file. Only add/update the `OPENROUTER_API_KEY` line. -3. **Native CLI support for codex, agy, and qwen.** When a user selects native CLIs, set the config's `command` field to `codex`, `agy`, or `qwen`. The teammate template in the review/plan commands handles the full invocation patterns automatically. All other models use OpenRouter/Kilo only. Bare `gemini` is a legacy config value; migrate it to `agy` when rewriting the config. +3. **Native CLI support for codex, agy, and qwen.** When a user selects native CLIs, set the config's `command` field to `codex`, `agy`, or `qwen`. The teammate template in the review/plan commands handles the full invocation patterns automatically. All other models use OpenRouter/pi only. Bare `gemini` is a legacy config value; migrate it to `agy` when rewriting the config. 4. **OpenRouter is the recommended path.** 1 key = 9 models. Emphasize this as the simplest setup. 5. **Enforce minimum 1 external model.** Claude alone is not a consensus. 6. **Hard-stop on quorum failure.** Never finalize a config that can't meet its own quorum. diff --git a/plugins/consensus/commands/plan-review.md b/plugins/consensus/commands/plan-review.md index 633b90e..76e7b22 100644 --- a/plugins/consensus/commands/plan-review.md +++ b/plugins/consensus/commands/plan-review.md @@ -89,7 +89,11 @@ Source the API key (targeted — only export `OPENROUTER_API_KEY`): ``` For each model in `MODELS`, verify CLI availability: -- Commands starting with `kilo` -> check: `command -v kilo` AND `[ -n "$OPENROUTER_API_KEY" ]` +- Commands starting with `pi ` (the pi CLI, not `pip`/`pixi`) -> check `command -v pi`, then derive + the required credential from that model's own `--provider`: + * `--provider openrouter` -> also require `[ -n "$OPENROUTER_API_KEY" ]` + * any other provider (e.g. `altimate-azure`) -> configured as a pi provider/extension, so it + needs NO OpenRouter key. Do NOT skip it for a missing `OPENROUTER_API_KEY`. - Commands starting with `codex` -> check: `command -v codex` - Commands starting with `agy` -> check: `command -v agy` - Commands starting with `gemini` -> legacy config; check `command -v agy`, run through the `agy` path below, and warn the user to rerun `/consensus-setup` @@ -97,7 +101,7 @@ For each model in `MODELS`, verify CLI availability: Run all checks in parallel. Remove unavailable models from `MODELS` with a warning for each: ``` -Warning: Skipping {model.name} — {reason: "kilo CLI not found" / "OPENROUTER_API_KEY not set" / "codex CLI not found" / "Antigravity CLI not found"} +Warning: Skipping {model.name} — {reason: "pi CLI not found" / "OPENROUTER_API_KEY not set" / "codex CLI not found" / "Antigravity CLI not found"} ``` Count available models + 1 (Claude) = `TOTAL_PARTICIPANTS`. @@ -231,7 +235,7 @@ For each model, substitute `{MODEL_ID}`, `{MODEL_NAME}`, `{MODEL_COMMAND}`, `{MO - For commands starting with `codex`: `--add-dir /path1 --add-dir /path2` (one `--add-dir` per directory) - For commands starting with `agy` or legacy `gemini`: `--add-dir /path1 --add-dir /path2` (one `--add-dir` per directory) - For commands starting with `qwen`: `--include-directories /path1,/path2` (comma-separated) -- For commands starting with `kilo`: empty string (kilo has no flag — the paths are already in the prompt) +- For commands starting with `pi `: empty string (pi takes no extra-dirs flag — the paths are already in the prompt) If `EXTRA_DIRS` is empty, `{EXTRA_DIRS_FLAGS}` is an empty string for all CLIs. @@ -256,8 +260,15 @@ SESSION_DIR={SESSION_DIR} **If `{MODEL_COMMAND}` starts with `qwen`:** qwen {EXTRA_DIRS_FLAGS} --approval-mode plan -p "$(cat $SESSION_DIR/prompt.md)" -o text > $SESSION_DIR/{MODEL_ID}.md 2>&1 - **Otherwise (Kilo/OpenRouter — default):** - {MODEL_COMMAND} "$(cat $SESSION_DIR/prompt.md)" > $SESSION_DIR/{MODEL_ID}.md 2>&1 + **Otherwise (pi/OpenRouter — default):** + # pi buffers ALL output until it exits (verified for --mode text, json and + # rpc — nothing is written mid-run, and the session file is not created + # until completion either). So progress is NOT observable from the output + # file; liveness must come from the process. Launch it with a pid file and + # an exit sentinel so the lead can distinguish "still working" from "done". + ( {MODEL_COMMAND} --session-dir "$SESSION_DIR/pi-{MODEL_ID}" "$(cat $SESSION_DIR/prompt.md)" > $SESSION_DIR/{MODEL_ID}.md 2>&1; echo $? > $SESSION_DIR/{MODEL_ID}.exit ) & + echo $! > $SESSION_DIR/{MODEL_ID}.pid + wait $(cat $SESSION_DIR/{MODEL_ID}.pid) If it fails or produces empty output, retry ONCE. @@ -282,8 +293,10 @@ After sending the plan, WAIT. The lead will send you a convergence prompt. When **If `{MODEL_COMMAND}` starts with `qwen`:** qwen -c -p "$(cat $SESSION_DIR/convergence-prompt-{MODEL_ID}.md)" -o text > $SESSION_DIR/{MODEL_ID}-convergence.md 2>&1 - **Otherwise (Kilo/OpenRouter — default):** - {MODEL_COMMAND} {MODEL_RESUME_FLAG} "$(cat $SESSION_DIR/convergence-prompt-{MODEL_ID}.md)" > $SESSION_DIR/{MODEL_ID}-convergence.md 2>&1 + **Otherwise (pi/OpenRouter — default):** + ( {MODEL_COMMAND} {MODEL_RESUME_FLAG} --session-dir "$SESSION_DIR/pi-{MODEL_ID}" "$(cat $SESSION_DIR/convergence-prompt-{MODEL_ID}.md)" > $SESSION_DIR/{MODEL_ID}-convergence.md 2>&1; echo $? > $SESSION_DIR/{MODEL_ID}-convergence.exit ) & + echo $! > $SESSION_DIR/{MODEL_ID}-convergence.pid + wait $(cat $SESSION_DIR/{MODEL_ID}-convergence.pid) 3. Read the output, clean it 4. Send it to the lead via SendMessage. The response should start with APPROVE or CHANGES NEEDED. @@ -299,15 +312,25 @@ Wait for a shutdown_request from the lead before exiting. Complete Claude's plan. Then use the following polling protocol to wait for all teammates: **Polling-based wait loop:** -1. Every ~1 minute, check each pending teammate's output file size: - `wc -c < $SESSION_DIR/{model.id}.md 2>/dev/null || echo 0` -2. Track the file size. If it's growing (or the file doesn't exist yet because the model is still exploring) — the model is working. Keep waiting. -3. A teammate is ONLY considered stuck if: - - Their output file exists AND - - Its size has not changed for 10 consecutive checks (10 minutes) -4. If a teammate appears stuck after 10 minutes of no file growth, send them a check-in message: "Are you still working? Send me your current output if you have any." -5. Wait another 3 minutes after check-in before giving up on that teammate. -6. DO NOT proceed to Step 5 until every teammate has either sent their result via SendMessage or been declared stuck per the above protocol. + +> ⚠ Do NOT use output-file growth as a health signal. `pi` buffers everything +> until it exits, so `{model.id}.md` stays at **0 bytes for the entire run** — +> a healthy 40-minute review looks identical to a hung one. Judging by file +> size will make you abandon working reviews. + +1. Every ~1 minute, check whether each pending model's PROCESS is still alive: + `kill -0 $(cat $SESSION_DIR/{model.id}.pid 2>/dev/null) 2>/dev/null && echo ALIVE || echo GONE` +2. `ALIVE` = the model is working, regardless of output size. Keep waiting. +3. Completion is signalled by the exit sentinel, not by file size: + `cat $SESSION_DIR/{model.id}.exit 2>/dev/null` — `0` means success, any other + value means the CLI failed (retry ONCE, per the teammate template). +4. A teammate is only treated as failed when its process is `GONE` **and** either + the `.exit` sentinel is non-zero or `{model.id}.md` is empty. A `GONE` process + with a `0` sentinel and non-empty output is a SUCCESS — wait for its SendMessage. +5. If a process is `GONE` with no sentinel at all (killed/crashed), send a check-in + message, then give up on that teammate after 3 minutes. +6. DO NOT proceed to Step 5 until every teammate has either sent their result via + SendMessage or been declared failed per the above protocol. Report to user (dynamically built from `MODELS`): @@ -477,8 +500,11 @@ On failure: preserve `$SESSION_DIR` for debugging and tell the user where files 8. **Dynamic quorum.** Use `MIN_QUORUM` from config. Abort if fewer than `MIN_QUORUM` plans available (including Claude). 9. **Return to plan mode.** After final plan + cleanup, call `EnterPlanMode` for user review (with fallback to direct presentation). 10. **Convergence through messaging.** Lead sends draft to teammates, they run their model and report back. Max 2 rounds. -11. **Be patient with teammates — they almost never fail.** External CLI models (Codex, Antigravity, Kilo) take time to explore the codebase but almost always finish successfully. Follow this activity-based patience protocol: - - **Poll output files** every ~1 minute using `wc -c < $SESSION_DIR/{model.id}.md 2>/dev/null || echo 0` to check file size. +11. **Be patient with teammates — they almost never fail.** External CLI models (Codex, Antigravity, pi) take time to explore the codebase but almost always finish successfully. Follow this activity-based patience protocol: + - **Poll the process, not the file** every ~1 minute: + `kill -0 $(cat $SESSION_DIR/{model.id}.pid) 2>/dev/null && echo ALIVE || echo GONE`. + `pi` buffers all output until exit, so the output file is 0 bytes for the + whole run and its size says nothing about health. - **Growing file (or no file yet)** = the model is working. Keep waiting. - **A teammate is ONLY considered stuck if**: their output file exists AND its size has not changed for **10 consecutive checks** (10 minutes of zero growth). - If stuck after 10 minutes, send a check-in message: "Are you still working? Send me your current output if you have any." Wait another 3 minutes before giving up on that teammate. diff --git a/plugins/consensus/commands/review.md b/plugins/consensus/commands/review.md index 0ec0aac..d607f49 100644 --- a/plugins/consensus/commands/review.md +++ b/plugins/consensus/commands/review.md @@ -97,7 +97,11 @@ Source the API key (targeted — only export `OPENROUTER_API_KEY`): ``` For each model in `MODELS`, verify CLI availability: -- Commands starting with `kilo` -> check: `command -v kilo` AND `[ -n "$OPENROUTER_API_KEY" ]` +- Commands starting with `pi ` (the pi CLI, not `pip`/`pixi`) -> check `command -v pi`, then derive + the required credential from that model's own `--provider`: + * `--provider openrouter` -> also require `[ -n "$OPENROUTER_API_KEY" ]` + * any other provider (e.g. `altimate-azure`) -> configured as a pi provider/extension, so it + needs NO OpenRouter key. Do NOT skip it for a missing `OPENROUTER_API_KEY`. - Commands starting with `codex` -> check: `command -v codex` - Commands starting with `agy` -> check: `command -v agy` - Commands starting with `gemini` -> legacy config; check `command -v agy`, run through the `agy` path below, and warn the user to rerun `/consensus-setup` @@ -105,7 +109,7 @@ For each model in `MODELS`, verify CLI availability: Run all checks in parallel. Remove unavailable models from `MODELS` with a warning for each: ``` -Warning: Skipping {model.name} — {reason: "kilo CLI not found" / "OPENROUTER_API_KEY not set" / "codex CLI not found" / "Antigravity CLI not found"} +Warning: Skipping {model.name} — {reason: "pi CLI not found" / "OPENROUTER_API_KEY not set" / "codex CLI not found" / "Antigravity CLI not found"} ``` Count available models + 1 (Claude) = `TOTAL_PARTICIPANTS`. @@ -267,8 +271,15 @@ SESSION_DIR={SESSION_DIR} **If `{MODEL_COMMAND}` starts with `qwen`:** qwen --approval-mode plan -p "$(cat $SESSION_DIR/prompt.md)" -o text > $SESSION_DIR/{MODEL_ID}.md 2>&1 - **Otherwise (Kilo/OpenRouter — default):** - {MODEL_COMMAND} "$(cat $SESSION_DIR/prompt.md)" > $SESSION_DIR/{MODEL_ID}.md 2>&1 + **Otherwise (pi/OpenRouter — default):** + # pi buffers ALL output until it exits (verified for --mode text, json and + # rpc — nothing is written mid-run, and the session file is not created + # until completion either). So progress is NOT observable from the output + # file; liveness must come from the process. Launch it with a pid file and + # an exit sentinel so the lead can distinguish "still working" from "done". + ( {MODEL_COMMAND} --session-dir "$SESSION_DIR/pi-{MODEL_ID}" "$(cat $SESSION_DIR/prompt.md)" > $SESSION_DIR/{MODEL_ID}.md 2>&1; echo $? > $SESSION_DIR/{MODEL_ID}.exit ) & + echo $! > $SESSION_DIR/{MODEL_ID}.pid + wait $(cat $SESSION_DIR/{MODEL_ID}.pid) If it fails or produces empty output, retry ONCE. @@ -293,8 +304,10 @@ After sending the review, WAIT. The lead will send you a convergence prompt. Whe **If `{MODEL_COMMAND}` starts with `qwen`:** qwen -c -p "$(cat $SESSION_DIR/convergence-prompt-{MODEL_ID}.md)" -o text > $SESSION_DIR/{MODEL_ID}-convergence.md 2>&1 - **Otherwise (Kilo/OpenRouter — default):** - {MODEL_COMMAND} {MODEL_RESUME_FLAG} "$(cat $SESSION_DIR/convergence-prompt-{MODEL_ID}.md)" > $SESSION_DIR/{MODEL_ID}-convergence.md 2>&1 + **Otherwise (pi/OpenRouter — default):** + ( {MODEL_COMMAND} {MODEL_RESUME_FLAG} --session-dir "$SESSION_DIR/pi-{MODEL_ID}" "$(cat $SESSION_DIR/convergence-prompt-{MODEL_ID}.md)" > $SESSION_DIR/{MODEL_ID}-convergence.md 2>&1; echo $? > $SESSION_DIR/{MODEL_ID}-convergence.exit ) & + echo $! > $SESSION_DIR/{MODEL_ID}-convergence.pid + wait $(cat $SESSION_DIR/{MODEL_ID}-convergence.pid) 3. Read the output, clean it 4. Send it to the lead via SendMessage. The response should start with APPROVE or CHANGES NEEDED. @@ -310,15 +323,25 @@ Wait for a shutdown_request from the lead before exiting. Complete Claude's review. Then use the following polling protocol to wait for all teammates: **Polling-based wait loop:** -1. Every ~1 minute, check each pending teammate's output file size: - `wc -c < $SESSION_DIR/{model.id}.md 2>/dev/null || echo 0` -2. Track the file size. If it's growing (or the file doesn't exist yet because the model is still exploring) — the model is working. Keep waiting. -3. A teammate is ONLY considered stuck if: - - Their output file exists AND - - Its size has not changed for 10 consecutive checks (10 minutes) -4. If a teammate appears stuck after 10 minutes of no file growth, send them a check-in message: "Are you still working? Send me your current output if you have any." -5. Wait another 3 minutes after check-in before giving up on that teammate. -6. DO NOT proceed to Step 5 until every teammate has either sent their result via SendMessage or been declared stuck per the above protocol. + +> ⚠ Do NOT use output-file growth as a health signal. `pi` buffers everything +> until it exits, so `{model.id}.md` stays at **0 bytes for the entire run** — +> a healthy 40-minute review looks identical to a hung one. Judging by file +> size will make you abandon working reviews. + +1. Every ~1 minute, check whether each pending model's PROCESS is still alive: + `kill -0 $(cat $SESSION_DIR/{model.id}.pid 2>/dev/null) 2>/dev/null && echo ALIVE || echo GONE` +2. `ALIVE` = the model is working, regardless of output size. Keep waiting. +3. Completion is signalled by the exit sentinel, not by file size: + `cat $SESSION_DIR/{model.id}.exit 2>/dev/null` — `0` means success, any other + value means the CLI failed (retry ONCE, per the teammate template). +4. A teammate is only treated as failed when its process is `GONE` **and** either + the `.exit` sentinel is non-zero or `{model.id}.md` is empty. A `GONE` process + with a `0` sentinel and non-empty output is a SUCCESS — wait for its SendMessage. +5. If a process is `GONE` with no sentinel at all (killed/crashed), send a check-in + message, then give up on that teammate after 3 minutes. +6. DO NOT proceed to Step 5 until every teammate has either sent their result via + SendMessage or been declared failed per the above protocol. Report to user (dynamically built from `MODELS`): @@ -569,8 +592,11 @@ On failure: preserve `$SESSION_DIR` for debugging and tell the user where files 8. **Dynamic quorum.** Use `MIN_QUORUM` from config. Abort if fewer than `MIN_QUORUM` reviews available (including Claude). 9. **Convergence through messaging.** Lead sends draft to teammates, they run their model and report back. Max 2 rounds. 10. **No plan mode.** Reviews are presented directly, not written to plan files. -11. **Be patient with teammates — they almost never fail.** External CLI models (Codex, Antigravity, Kilo) take time to explore the codebase but almost always finish successfully. Follow this activity-based patience protocol: - - **Poll output files** every ~1 minute using `wc -c < $SESSION_DIR/{model.id}.md 2>/dev/null || echo 0` to check file size. +11. **Be patient with teammates — they almost never fail.** External CLI models (Codex, Antigravity, pi) take time to explore the codebase but almost always finish successfully. Follow this activity-based patience protocol: + - **Poll the process, not the file** every ~1 minute: + `kill -0 $(cat $SESSION_DIR/{model.id}.pid) 2>/dev/null && echo ALIVE || echo GONE`. + `pi` buffers all output until exit, so the output file is 0 bytes for the + whole run and its size says nothing about health. - **Growing file (or no file yet)** = the model is working. Keep waiting. - **A teammate is ONLY considered stuck if**: their output file exists AND its size has not changed for **10 consecutive checks** (10 minutes of zero growth). - If stuck after 10 minutes, send a check-in message: "Are you still working? Send me your current output if you have any." Wait another 3 minutes before giving up on that teammate. diff --git a/plugins/consensus/consensus.codex.config.json b/plugins/consensus/consensus.codex.config.json index 0a39bf3..0b9ae53 100644 --- a/plugins/consensus/consensus.codex.config.json +++ b/plugins/consensus/consensus.codex.config.json @@ -1,5 +1,5 @@ { - "version": "1.7.0", + "version": "1.8.0", "lead": { "id": "codex", "name": "Codex", @@ -20,49 +20,49 @@ { "id": "kimi", "name": "Kimi K2.6", - "command": "kilo run -m openrouter/moonshotai/kimi-k2.6 --auto", + "command": "pi --provider openrouter --model moonshotai/kimi-k2.6 -p", "resume_flag": "-c", "enabled": true }, { "id": "grok", - "name": "Grok 4.20", - "command": "kilo run -m openrouter/x-ai/grok-4.20-beta --auto", + "name": "Grok 4.3", + "command": "pi --provider openrouter --model x-ai/grok-4.3 -p", "resume_flag": "-c", "enabled": false }, { "id": "minimax", "name": "MiniMax M2.7", - "command": "kilo run -m openrouter/minimax/minimax-m2.7 --auto", + "command": "pi --provider openrouter --model minimax/minimax-m2.7 -p", "resume_flag": "-c", "enabled": true }, { "id": "glm5", "name": "GLM-5.1", - "command": "kilo run -m zai-coding-plan/glm-5.1 --auto", + "command": "pi --provider openrouter --model z-ai/glm-5.1 -p", "resume_flag": "-c", "enabled": true }, { "id": "qwen", "name": "Qwen 3.6 Plus", - "command": "kilo run -m openrouter/qwen/qwen3.6-plus --auto", + "command": "pi --provider openrouter --model qwen/qwen3.6-plus -p", "resume_flag": "-c", "enabled": true }, { "id": "mimo", - "name": "MiMo V2 Pro", - "command": "kilo run -m openrouter/xiaomi/mimo-v2-pro --auto", + "name": "MiMo V2.5 Pro", + "command": "pi --provider openrouter --model xiaomi/mimo-v2.5-pro -p", "resume_flag": "-c", "enabled": true }, { "id": "deepseek", "name": "DeepSeek V4 Pro", - "command": "kilo run -m openrouter/deepseek/deepseek-v4-pro --auto", + "command": "pi --provider openrouter --model deepseek/deepseek-v4-pro -p", "resume_flag": "-c", "enabled": true } diff --git a/plugins/consensus/consensus.config.json b/plugins/consensus/consensus.config.json index dfa50a0..ece9ce9 100644 --- a/plugins/consensus/consensus.config.json +++ b/plugins/consensus/consensus.config.json @@ -1,66 +1,66 @@ { - "version": "1.7.0", + "version": "1.8.0", "models": [ { "id": "gpt", - "name": "GPT 5.4 Codex", - "command": "kilo run -m openrouter/openai/gpt-5.4-codex --auto", + "name": "GPT 5.3 Codex", + "command": "pi --provider openrouter --model openai/gpt-5.3-codex -p", "resume_flag": "-c", "enabled": true }, { "id": "gemini", "name": "Gemini 3.1 Pro", - "command": "kilo run -m openrouter/google/gemini-3.1-pro-preview --auto", + "command": "pi --provider openrouter --model google/gemini-3.1-pro-preview -p", "resume_flag": "-c", "enabled": true }, { "id": "kimi", "name": "Kimi K2.6", - "command": "kilo run -m openrouter/moonshotai/kimi-k2.6 --auto", + "command": "pi --provider openrouter --model moonshotai/kimi-k2.6 -p", "resume_flag": "-c", "enabled": true }, { "id": "grok", - "name": "Grok 4.20", - "command": "kilo run -m openrouter/x-ai/grok-4.20-beta --auto", + "name": "Grok 4.3", + "command": "pi --provider openrouter --model x-ai/grok-4.3 -p", "resume_flag": "-c", "enabled": true }, { "id": "minimax", "name": "MiniMax M2.7", - "command": "kilo run -m openrouter/minimax/minimax-m2.7 --auto", + "command": "pi --provider openrouter --model minimax/minimax-m2.7 -p", "resume_flag": "-c", "enabled": true }, { "id": "glm5", "name": "GLM-5.1", - "command": "kilo run -m zai-coding-plan/glm-5.1 --auto", + "command": "pi --provider openrouter --model z-ai/glm-5.1 -p", "resume_flag": "-c", "enabled": true }, { "id": "qwen", "name": "Qwen 3.6 Plus", - "command": "kilo run -m openrouter/qwen/qwen3.6-plus --auto", + "command": "pi --provider openrouter --model qwen/qwen3.6-plus -p", "resume_flag": "-c", "enabled": true }, { "id": "mimo", - "name": "MiMo V2 Pro", - "command": "kilo run -m openrouter/xiaomi/mimo-v2-pro --auto", + "name": "MiMo V2.5 Pro", + "command": "pi --provider openrouter --model xiaomi/mimo-v2.5-pro -p", "resume_flag": "-c", "enabled": true }, { "id": "deepseek", "name": "DeepSeek V4 Pro", - "command": "kilo run -m openrouter/deepseek/deepseek-v4-pro --auto", + "command": "pi --provider openrouter --model deepseek/deepseek-v4-pro -p", "resume_flag": "-c", "enabled": true } diff --git a/plugins/consensus/skills/consensus-code-review/references/command.md b/plugins/consensus/skills/consensus-code-review/references/command.md index d7cb2cd..9c31902 100644 --- a/plugins/consensus/skills/consensus-code-review/references/command.md +++ b/plugins/consensus/skills/consensus-code-review/references/command.md @@ -33,16 +33,6 @@ Resolve common targets: Support `--dirs /path/a,/path/b` exactly like plan review. -## CodeRabbit - -If `command -v coderabbit` succeeds, run CodeRabbit as a supplementary static-analysis reviewer: - -```bash -coderabbit review --plain > "$SESSION_DIR/coderabbit.md" 2>&1 -``` - -Include CodeRabbit findings in comparison and synthesis, but do not count CodeRabbit toward quorum and do not include it in convergence rounds. - ## Shared Prompt Write `$SESSION_DIR/prompt.md`: @@ -95,7 +85,7 @@ Use the standard code-review stance: ## Compare And Synthesize -Read `codex.md`, each external model file, and `coderabbit.md` if present. +Read `codex.md` and each external model file. Show: @@ -104,7 +94,7 @@ Show: - disagreements or false positives - missing tests - unintended consequences -- comparison table with Codex, CodeRabbit if present, and participating models +- comparison table with Codex and participating models The synthesized review should include: @@ -133,4 +123,4 @@ Review this synthesis. Start your response with one of: Only raise issues that materially affect correctness, severity, or usefulness. ``` -Run convergence for external model reviewers only. CodeRabbit does not participate in convergence. +Run convergence for external model reviewers only. diff --git a/plugins/consensus/skills/consensus-plan-review/references/command.md b/plugins/consensus/skills/consensus-plan-review/references/command.md index 9547300..f5c72e5 100644 --- a/plugins/consensus/skills/consensus-plan-review/references/command.md +++ b/plugins/consensus/skills/consensus-plan-review/references/command.md @@ -26,7 +26,7 @@ fi Preflight: -- commands starting with `kilo` require `command -v kilo` and a non-empty `OPENROUTER_API_KEY` +- commands starting with `pi ` require `command -v pi` and a non-empty `OPENROUTER_API_KEY` - commands starting with `agy` require `command -v agy` - commands starting with `gemini` are legacy configs; require `command -v agy`, run through the `agy` path below, and recommend rerunning `consensus-setup` - commands starting with `qwen` require `command -v qwen` @@ -56,7 +56,7 @@ Directory flags: - Antigravity (`agy`) or legacy `gemini`: `--add-dir /path/a --add-dir /path/b` - native Qwen: `--include-directories /path/a,/path/b` -- Kilo/OpenRouter: no CLI flag; include paths in the prompt +- pi/OpenRouter: no CLI flag; include paths in the prompt ## Session @@ -109,10 +109,13 @@ Do not mention model providers or model names in prompts sent to external tools. For every enabled external model, start the CLI in parallel and write output to `$SESSION_DIR/{model.id}.md`. -Kilo/OpenRouter: +pi/OpenRouter: ```bash -{MODEL_COMMAND} "$(cat "$SESSION_DIR/prompt.md")" > "$SESSION_DIR/{MODEL_ID}.md" 2>&1 +# pi buffers all output until exit, so track liveness by process, not file size. +( {MODEL_COMMAND} --session-dir "$SESSION_DIR/pi-{MODEL_ID}" "$(cat "$SESSION_DIR/prompt.md")" > "$SESSION_DIR/{MODEL_ID}.md" 2>&1; echo $? > "$SESSION_DIR/{MODEL_ID}.exit" ) & +echo $! > "$SESSION_DIR/{MODEL_ID}.pid" +wait $(cat "$SESSION_DIR/{MODEL_ID}.pid") ``` Antigravity (`agy`) or legacy `gemini`: @@ -195,10 +198,10 @@ Only raise issues that genuinely affect correctness, feasibility, or quality. Run the convergence prompt against every external model. -Kilo/OpenRouter: +pi/OpenRouter: ```bash -{MODEL_COMMAND} {MODEL_RESUME_FLAG} "$(cat "$SESSION_DIR/convergence-prompt.md")" > "$SESSION_DIR/{MODEL_ID}-convergence.md" 2>&1 +{MODEL_COMMAND} {MODEL_RESUME_FLAG} --session-dir "$SESSION_DIR/pi-{MODEL_ID}" "$(cat "$SESSION_DIR/convergence-prompt.md")" > "$SESSION_DIR/{MODEL_ID}-convergence.md" 2>&1 ``` Antigravity (`agy`) or legacy `gemini`: diff --git a/plugins/consensus/skills/consensus-setup/references/command.md b/plugins/consensus/skills/consensus-setup/references/command.md index bc26784..7da95ec 100644 --- a/plugins/consensus/skills/consensus-setup/references/command.md +++ b/plugins/consensus/skills/consensus-setup/references/command.md @@ -15,7 +15,7 @@ Never write `~/.claude/consensus.json` from this setup command. 1. Codex is the lead reviewer in Codex sessions. 2. Do not include GPT/Codex as an external panelist. 3. For now, do not add Claude as an external panelist. -4. Use Kilo/OpenRouter for OpenRouter-hosted models and native non-Codex CLIs only. +4. Use pi/OpenRouter for OpenRouter-hosted models and native non-Codex CLIs only. 5. Preserve user model preferences unless the user explicitly asks to replace them, but migrate legacy `command: "gemini"` entries to `command: "agy"` whenever rewriting the config. 6. Do not smoke-test live model calls unless the user asks, because that consumes credits. @@ -25,7 +25,7 @@ Check: ```bash test -f ~/.codex/consensus.json && jq . ~/.codex/consensus.json -command -v kilo +command -v pi command -v agy command -v qwen test -f ~/.codex/.env && grep -q '^OPENROUTER_API_KEY=.\+' ~/.codex/.env @@ -37,7 +37,7 @@ Report: - whether `~/.codex/consensus.json` exists and parses - enabled external models - configured quorum -- Kilo, Antigravity (`agy`), and Qwen availability +- pi, Antigravity (`agy`), and Qwen availability - whether an OpenRouter key exists in `~/.codex/.env` or fallback `~/.claude/.env` If the existing config is valid and the user only asked to inspect, stop after the summary. @@ -48,14 +48,14 @@ Use these model mappings: | ID | Name | Default command | Native alternative | |----|------|-----------------|--------------------| -| `gemini` | Gemini via Antigravity | `kilo run -m openrouter/google/gemini-3.1-pro-preview --auto` | `agy` | -| `kimi` | Kimi K2.6 | `kilo run -m openrouter/moonshotai/kimi-k2.6 --auto` | none | -| `grok` | Grok 4.20 | `kilo run -m openrouter/x-ai/grok-4.20-beta --auto` | none | -| `minimax` | MiniMax M2.7 | `kilo run -m openrouter/minimax/minimax-m2.7 --auto` | none | -| `glm5` | GLM-5.1 | `kilo run -m zai-coding-plan/glm-5.1 --auto` | none | -| `qwen` | Qwen 3.6 Plus | `kilo run -m openrouter/qwen/qwen3.6-plus --auto` | optional `qwen`, disabled by default unless user asks | -| `mimo` | MiMo V2 Pro | `kilo run -m openrouter/xiaomi/mimo-v2-pro --auto` | none | -| `deepseek` | DeepSeek V4 Pro | `kilo run -m openrouter/deepseek/deepseek-v4-pro --auto` | none | +| `gemini` | Gemini via Antigravity | `pi --provider openrouter --model google/gemini-3.1-pro-preview -p` | `agy` | +| `kimi` | Kimi K2.6 | `pi --provider openrouter --model moonshotai/kimi-k2.6 -p` | none | +| `grok` | Grok 4.3 | `pi --provider openrouter --model x-ai/grok-4.3 -p` | none | +| `minimax` | MiniMax M2.7 | `pi --provider openrouter --model minimax/minimax-m2.7 -p` | none | +| `glm5` | GLM-5.1 | `pi --provider openrouter --model z-ai/glm-5.1 -p` | none | +| `qwen` | Qwen 3.6 Plus | `pi --provider openrouter --model qwen/qwen3.6-plus -p` | optional `qwen`, disabled by default unless user asks | +| `mimo` | MiMo V2.5 Pro | `pi --provider openrouter --model xiaomi/mimo-v2.5-pro -p` | none | +| `deepseek` | DeepSeek V4 Pro | `pi --provider openrouter --model deepseek/deepseek-v4-pro -p` | none | Codex setup intentionally omits the Claude plugin's `gpt` model because Codex/GPT is the lead in Codex sessions. @@ -64,7 +64,7 @@ Recommended defaults: - enable the current stable non-Codex panel: Gemini via Antigravity, Kimi, MiniMax, GLM-5.1, Qwen, MiMo, and DeepSeek - leave Grok disabled by default unless the user explicitly enables it - use Antigravity CLI when `agy` is installed; review workflows call it with `--sandbox -p` for both initial and convergence prompts -- use Kilo/OpenRouter for the rest +- use pi/OpenRouter for the rest - set quorum to 8 for the default panel, meaning all 7 enabled externals plus Codex must respond For custom panels, keep quorum within these bounds: @@ -77,7 +77,7 @@ maximum = enabled_external_models + 1 ## Step 3: Key Handling -If Kilo/OpenRouter models are selected and no OpenRouter key is found, ask the user for the key or tell them to set it later. +If pi/OpenRouter models are selected and no OpenRouter key is found, ask the user for the key or tell them to set it later. When saving a key, write only to `~/.codex/.env`: @@ -119,11 +119,11 @@ Include all 8 non-Codex external models, with `enabled` reflecting the user's se Use the selected quorum. The default Codex panel uses `min_quorum: 8`. -For enabled Kilo models, use `resume_flag: "-c"`. +For enabled pi models, use `resume_flag: "-c"`. For native Google/Gemini execution, use `command: "agy"` and `resume_flag: ""`. If an existing user config has `command: "gemini"`, report it as legacy and migrate it to `agy` when the user refreshes the config. -For native Qwen, only use `command: "qwen"` if the user explicitly selects native Qwen; otherwise prefer Kilo/OpenRouter. +For native Qwen, only use `command: "qwen"` if the user explicitly selects native Qwen; otherwise prefer pi/OpenRouter. ## Step 5: Optional Smoke Test @@ -141,7 +141,7 @@ For each enabled model, run a tiny prompt asking it to reply `PONG`, using the c - `agy` or legacy `gemini`: `agy --sandbox -p "Reply with exactly: PONG"` - `qwen`: `qwen --approval-mode plan -p "Reply with exactly: PONG" -o text` -- Kilo/OpenRouter: `{model.command} "Reply with exactly: PONG"` +- pi/OpenRouter: `{model.command} "Reply with exactly: PONG"` If a model fails, disable it only after reporting the failure and confirming that quorum still holds. If quorum would fail, leave the prior valid config in place and tell the user what needs to be fixed.