Agent Switchboard

Use Claude Code, Codex, Gemini, Antigravity, and VS Code together — without copy-pasting context between them.

Agent Switchboard is a local MCP bridge that lets your AI coding agents hand tasks to each other, review each other's work, run multi-round debates, and share compact project context — a local nervous system where the tools stay separate but coordinate through one local broker.

No API keys. No cloud broker. No extra billing. It uses the local CLIs, IDE bridge routes, and subscriptions you already have where possible.

⭐ If this saves your agent workflow, please star the repo so others can find it!

Why this exists

Modern AI coding workflows are fragmented. You might use Codex or Claude Code as the reasoning brain, Gemini Flash for bounded workhorse tasks, and Antigravity / VS Code for workspace context — but normally they can't talk to each other, so you end up manually copying plans, files, errors, and context from one assistant to another. That's fine for small tasks; it gets messy fast on real projects. Agent Switchboard gives those agents a shared local coordination layer so they cooperate instead of working blind to each other.

Fast Version

  • Ask one assistant to use another - from Codex, ask the Claude frontier to audit; from Claude, ask the Codex frontier to reason; send bounded implementation, search, and preparation work to Gemini Flash/Antigravity.
  • See across chats - pull a compact snapshot of what another agent's session knows; Codex and Claude Code are read on demand from disk, no copy-paste.
  • Run cross-model debate - Codex vs Claude for N rounds, then synthesize a verdict.
  • Keep the selected model as the brain, route labour cheaply - global Codex/Claude/Gemini rules, reader/workhorse roles, and a completion audit are installed and refreshed by the same exe.
  • Use Gemini Flash as an external workhorse - Codex, Claude, and Gemini brains can proactively route bounded cheap labour through the Switchboard MCP route_agent_task tool, without treating Flash as a native child or authoritative brain.
  • Token compaction is built in - compressed handoffs, compact context packs, work memory, and retrievable originals instead of dumping entire transcripts.
  • Keep it local - SQLite state under ~/.agent-broker; no private chat scraping, no cloud broker.
  • Use subscriptions you already pay for - no required API keys or metered orchestration service.
  • Know the truth - doctor reports which routes are full, partial, or app-only on your machine.

Everything user-facing — the agent-switchboard.exe binary, the command, and the MCP server key — is agent-switchboard. Internally, local state stays in ~/.agent-broker and the Python entrypoint is agent_broker_mcp.py.

Built for Antigravity and VS Code users. Antigravity is a VS Code fork, so the same bridge extension installs in both.

Honest scope: only Antigravity has a true programmatic in-app send and a structured reply back to the broker. Claude/Codex are reached through a CLI round-trip or an auto-opened inbox file - see Delivery, honestly. This is a power-user tool for people who already run these assistants; it drives logged-in subscription UIs, so read Terms & risk first.


Requirements

Two supported install paths — pick one:

  • Self-contained agent-switchboard.exe (no Python needed). One file from the Releases page does everything: installs the MCP server into every assistant, installs the bridge extension (the VSIX is embedded), and runs the MCP server itself (agent-switchboard.exe serve). Has a built-in uninstall.
  • Python 3.10+ (run from source). The broker is one dependency-free Python file; agents launch it as python agent_broker_mcp.py.

Other notes:

  • Windows 10/11 for the installer, bridge auto-select, and shortcut patching (the broker itself is cross-platform; the installer/CDP layer is Windows-first today).
  • Antigravity CLI (agy) is required for the default headless Antigravity route. Install it from the official Antigravity CLI docs; without it, Switchboard falls back to the existing in-app bridge/inbox.
  • Node.js on PATH is needed only for the CDP helpers (Antigravity model auto-select, Codex/Claude webview submit).
  • Optional: pip install tiktoken for exact token accounting (a chars/4 estimate is used if it's absent; the exe bundles it).

Quick Start (Windows)

  1. Close Antigravity and VS Code. The installer refuses to run while either IDE is open, so extensions and debug flags can't be left half-updated.

  2. Install one of two ways:

    A — Self-contained exe (no Python): download agent-switchboard.exe from the Releases page and run it. Pick Install from the menu (or agent-switchboard.exe install).

    B — From source (Python 3.10+):

    powershell -NoProfile -ExecutionPolicy Bypass -File .\install-agent-broker.ps1
    

    Either way the installer detects which assistants you have (Codex, Claude Code, Antigravity, VS Code), registers the MCP server with each, installs the bridge extension (VSIX embedded in the exe; auto-built/located from source), and writes config. If Antigravity is installed, it then offers (default Yes) to enable automated in-app model selection — press Enter to accept (it patches the Antigravity launcher to open a local debug port) or decline to skip. Every config it edits is backed up first.

  3. Open Antigravity / VS Code again so the Agent Switchboard Bridge extension activates.

  4. Try it. In any registered assistant: "Use Agent Switchboard to ask Claude Opus to audit this function."

  5. Check what actually works on your machine: run agent-switchboard.exe doctor (or python agent_broker_mcp.py bridge doctor). It's read-only and tells you, per assistant, whether a CLI/extension is present, which delivery route you'll get, and whether a headless debate can run — see Diagnostics: doctor.

Uninstall / rollback (both paths): run agent-switchboard.exe uninstall (or python setup.py uninstall), or pick Uninstall from the menu. It reverses MCP registration in all four hosts, removes the bridge extension, and removes the installed broker exe. Add --remove-data to also delete ~/.agent-broker. The broker uses whatever subscriptions your assistants are already logged into.


What It Does

Goal
Let Codex, Claude Code, and Antigravity consult each other
Use existing subscriptions — no API keys, no extra billing
Keep all shared state local (SQLite), never scrape private chat history
Token compaction so cross-agent calls don't burn context ✅ compressed handoffs + compact context packs with a locally-stored, retrievable original (Headroom-style retrieval, not a reversible codec)
Keep a short per-topic work memory so the next model sees what changed, where, why, checks, risks, and next step
Peek at another open chat — fetch a compact snapshot of what another agent's session knows, on request (opt-in, local, never silent scraping) ✅ active context snapshots; Codex & Claude Code read on disk, with Antigravity local task/log/activity fallback (request_context_snapshotget_latest_context_snapshot)
Cross-model debate — two assistants debate N rounds headless on your subscriptions, then a synthesis judge writes a verdict ✅ (agent-switchboard debate)
Route Codex, Claude, and Antigravity to their headless CLIs by default; use the in-app chat/inbox only when asked or as fallback
Select Antigravity CLI models naturally (gemini flash for the moving workhorse, or an exact version pin) and discover future models from live agy models output
Let Codex/Claude proactively use newest live Flash High as a cheap external workhorse, with native fallback and independent-package concurrency rules
Fall back to the in-app extension / app automatically when a CLI isn't installed ✅ (see caveats in the docs)
Send a prompt straight into Antigravity's chat panel + get a structured reply back ✅ (antigravity.sendPromptToAgentPanel, the only full in-app round-trip)
Pick the Antigravity model automatically Offered at install (default on) when Antigravity is detected — patches the launcher to open a local CDP debug port so the broker auto-selects the model in-app; just decline at the prompt to skip

How It Works

The broker is a dependency-free Python MCP server. Each assistant talks to it over stdio JSON-RPC; the broker keeps shared state in one local SQLite file (WAL mode, so multiple hosts can poll it concurrently) and routes work to the right place.

Routing priority:

  1. Surface — Codex, Claude, and Antigravity default to the headless CLI (reliable, model-switchable, answer returned inline). For Antigravity, that means the standalone agy executable, not the IDE's antigravity chat launcher. Say "in app" / "inbox", pass surface: extension / surface: inbox, or set use_inbox: true to force the bridge panel. If agy is absent, an automatic Antigravity route falls back to that bridge/inbox.
  2. Model — vague Codex requests resolve from live codex debug models metadata; Claude frontier consults use the moving fable alias and fall back to the moving opus alias only on an explicit availability/entitlement error. Bare Antigravity and "Gemini Flash" select the newest exact stable gemini-<numeric>-flash-high slug advertised by live agy models, using numeric version order; the bundled static slug is offline fallback only. Explicit version pins remain exact, and preview/nonconforming SKUs are never auto-promoted. Gemini Flash is a useful non-authoritative workhorse-level adviser: a higher version does not promote it above Sol/Fable or make it automatically authoritative.
  3. External workhorse lane — Codex, Claude, and Gemini brains should proactively consider newest live Flash High through Agent Switchboard for bounded search/read/extraction/summaries/drafting, low-risk implementation/tests from an approved plan, and independent parallel packages. Flash is not a native child agent. Each call carries exactly one package and schema-enforced output; implementation requires a package id, a 1-5-file allowlist, and explicit acceptance criteria. Flash cannot receive danger-full-access or live production work. If agy/Flash is missing, quota-limited, times out, mismatches, returns malformed/contradictory output, or fails, use the host's native cheap reader/workhorse and record the fallback. The brain independently verifies cited lines, the actual diff, and checks before accepting or sending another package.
  4. Token budget — every routed task carries a task contract (implementation_plan, co_audit, debate, review, …) with a word budget, and a compressed context pack instead of raw history. If a caller inlines a bloated prompt (over a soft token limit), the broker stashes the full text as a retrievable context_ref and returns a prompt_notice nudging it to send a short instruction + ref next time — so token discipline is enforced by the system, not left to each agent.

Use the Switchboard MCP tool route_agent_task with target_agent: "antigravity", surface: "cli", target_model: "gemini flash", and effort: "high". The sender brain must not run agy directly; surface: "cli" tells Switchboard to invoke its internal CLI backend. Set mode: "plan" for read-only work. For implementation, set mode: "accept-edits" and include work_package_id, 1-5 exact allowed_files, and acceptance_criteria; Switchboard rejects an incomplete or whole-plan handoff.


See what another chat knows (active context snapshots)

Working in one assistant but need the current state another open chat is holding? Ask for a context snapshot — a COMPACT continuation state (objective, plan, touched files, checks, risks, next step), not a full transcript, and never silent scraping (it's opt-in and local).

  • request_context_snapshot(project, topic, target_agent) asks the best available open surface for that compact state.
  • Codex & Claude Code fast path (on disk): the broker reads the live session transcript on disk — Codex from ~/.codex, Claude Code from ~/.claude/projects — redacted + truncated and scoped to the session whose cwd matches the project (no cross-project leak), returning immediately with no agent cooperation or CDP needed. The two CLIs are symmetric.
  • Antigravity fallback: when no live bridge snapshot is available, the broker can read local Antigravity task/log/activity files (~/.gemini/antigravity-ide/brain plus workspace/file history) and return a bounded, clearly low/medium-confidence continuation snapshot. This is not guaranteed to be the visible chat transcript, but it prevents dead-end "cannot find context" failures.
  • Other surfaces: the request is queued for a capable bridge host (claim_context_snapshot_request / complete_context_snapshot_request, race-safe + idempotent, with a stale-claim reaper), or picked up from a .agent-broker/context-snapshots/ fallback file. If no live surface is heartbeating and no local fallback exists, the request reports no_live_surface (with guidance) instead of queuing forever with no claimer.
  • Honest limit: a surface feeds the nerve system only if it's readable on disk (Codex/Claude Code), a live heartbeating bridge (Antigravity/VS Code), or it proactively records. A disconnected helper — e.g. the Claude desktop app (Electron + server-side history, not on disk) — can be registered to push context, but cannot be read on demand. doctor shows exactly which surfaces can contribute, so blind spots are visible, not surprising.
  • Read it back with get_latest_context_snapshot — it also folds into get_context_pack ("Latest Context Snapshots") and get_topic_status, so the next model picks it up automatically. Live-host routing uses record_surface_heartbeat / list_live_surfaces.

This is the cross-chat "peek" layer: agents and IDEs can see what another agent's session currently knows and fetch it on request, without copy-pasting transcripts.


Delivery, honestly

There is a real difference between delivered (a file/prompt reached the surface), auto-opened (the bridge opened it for you), submitted (it was actually sent into a chat), and completed back to broker state (a model-tagged reply landed in the broker). Antigravity is still the only true structured in-app round-trip; queued Codex requests also get a broker-owned CLI worker when the Codex CLI is available.

Target Mechanism How far it gets
Antigravity CLI (default) agy --print <prompt> --model … --effort … --output-format json --json-schema … (direct argument-array invocation, no shell) reported, pending brain verification — schema-enforced headless round-trip; plan is sandboxed, while bounded implementation uses accept-edits
Antigravity (in-app Gemini/Claude) antigravity.sendPromptToAgentPanel (+ optional CDP model select) delivered → submitted → completed back to broker (complete_antigravity_request) — the only structured round-trip
Claude extension claude-inbox markdown, auto-opened + best-effort CDP auto-submit delivered → auto-opened → (often) submitted → recorded back to broker: the request now has a durable claude_requests row, so a reply via respond_to_request lands on it, or a file written to claude-responses/ is ingested by bridge claude-responses
Claude CLI claude -p headless (prompt via stdin) completed — full headless round-trip
Codex extension / inbox codex-inbox markdown, auto-opened, plus bounded Codex CLI worker when available delivered → auto-opened for visibility; the worker records completed/failed back to broker state so polling does not hang forever. Extension-only/no-CLI installs remain manual via respond_to_request
Codex CLI codex exec headless completed — full headless round-trip
Gemini gemini CLI (-m <model> honored) or GEMINI_API_KEY completed via CLI; the API path is an off-by-default escape hatch

Answer return-path: any surface without a native completion API closes the loop by calling respond_to_request(request_id, response) — the broker records the answer + timing on the request and refreshes a per-topic ledger.md (get_request_ledger). Codex inbox requests now also start a bounded CLI worker by default, so request_result returns an answer or a terminal error instead of staying delivered forever.

Model enforcement, honestly: the broker can only switch the answering model programmatically on Antigravity (CDP UI automation, best-effort) and the CLIs (--model/-m flag). Codex/Claude CLI responses are attested from runtime metadata and fail closed when metadata is missing or mismatched. agy receives the exact dynamically resolved Flash slug and returns a conversation id, but currently does not expose independent actual-model attestation, so the result labels the requested route without claiming stronger proof. Answer prose and usage summaries are never accepted as model proof. The broker cannot drive the Codex- or Claude-extension model picker, so those surfaces still receive a strict guard plus a notification to select the requested model.

Model + effort on the CLIs: model and reasoning effort are separate inputs, never folded together. Pass effort and the broker sets the CLI's own effort flag. A bare family request defaults to the live Codex frontier at max, Claude's moving fable alias at max (then opus only when unavailable), or Antigravity's dynamically selected latest stable Gemini Flash High workhorse at high. Explicit cheap_read and balanced policies select dynamically discovered Codex reader/workhorse models or Claude haiku/sonnet; prompt keywords never guess. Flash remains a non-authoritative external workhorse regardless of version. If Claude's frontier is unavailable, Flash supplies a degraded advisory second opinion; for routine bounded labour, both Codex and Claude may proactively use it with the failure/concurrency safeguards above. The selected main-session model is never rewritten. Flash permission bypass is prohibited; production deployment remains with the brain.

The broker is target-driven when a target is named. If a Codex/Claude caller leaves the target completely empty, Switchboard uses the caller only as a fallback: Codex defaults to Claude, and Claude defaults to Codex. A named target or prompt phrase like "consult with Claude" still wins.


Diagnostics: doctor

Because "what works" depends on what you have installed, the broker ships a read-only doctor that probes this machine and tells you the truth — no state is changed.

agent-switchboard.exe doctor          # rendered report
agent-switchboard.exe doctor --json   # machine-readable
# from source:  python agent_broker_mcp.py bridge doctor

For each assistant it reports: whether the CLI is found (and a live --version smoke test), whether the extension is installed, the CDP port, the delivery route you'll actually get, the reply path, and whether a headless debate can run. It also prints a nerve-system view — which surfaces can feed request_context_snapshot (on-disk fast-path vs live bridge vs push-only), so a blind spot like a disconnected desktop app is visible. It flags broker/bridge version drift and prints actionable next steps.

What each install combination gets you (this is what doctor checks):

You have… Codex / Claude result
CLI on PATH full headless round-trip (best); answer returns inline
Extension only, no CLI the broker still delivers into the extension (auto-opened inbox + best-effort CDP auto-submit), but it's semi-manual and not a silent headless round-trip. doctor reports this as partial / delivery-only
Desktop app only clipboard hand-off only — no programmatic return path
Neither doctor tells you exactly what to install

Headless debate (running both sides automatically) needs both the Codex and Claude CLIs present — doctor reports headless autonomous debate runnable: YES/no before you try. Extension-only setups can still get a one-shot second opinion, just not an autonomous multi-round run.


Changelog

v1.0.33 (managed Gemini hierarchy + MCP-only sender boundary)

  • Install/repair now manages the same checksum-protected hierarchy in ~/.gemini/GEMINI.md. It narrowly replaces the known obsolete global Pine-v6 persona, while preserving unrelated user-authored Gemini content and refusing tampered managed blocks.
  • Sender brains must enter cross-vendor and Flash labour through Switchboard MCP route_agent_task. "Through CLI" means surface: "cli" on that tool; only Switchboard may start agy, and the installed Codex/Claude pre-tool hooks deny sender-side direct invocation.
  • A Switchboard-launched Flash session is explicitly the non-authoritative worker for one schema-enforced package, never the brain/router and never an autonomous whole-plan executor.

v1.0.32 (fail-closed Gemini Flash work packages)

  • Every Antigravity Flash CLI call now uses --output-format json --json-schema .... Switchboard validates the structured result locally and rejects missing fields, malformed output, contradictory completion, out-of-scope file changes, and unsupported claims that a defect is intentional/by design.
  • Flash implementation is limited to one package per call and requires work_package_id, 1-5 exact allowed_files, and explicit acceptance_criteria. Whole-plan execution, continuation to another package, danger-full-access, production SSH, live credentials, destructive operations, migrations, and live deployment are prohibited.
  • A valid Flash result returns brain_verification: pending and accepted: false. The Codex or Claude sender must independently inspect cited primary lines, the actual diff, and check output before accepting the package or dispatching the next one; ambiguity and failure fall back to the native reader/workhorse.

v1.0.31 (dynamic Gemini Flash external workhorse routing)

  • Bare Antigravity and gemini flash requests now select the newest exact stable gemini-<numeric>-flash-high slug advertised by live agy models, including its current tabular output. Numeric version ordering handles future releases automatically, while preview/nonconforming models are excluded, the bundled 3.6 slug remains an offline fallback, and explicit version pins remain exact.
  • Gemini Flash High is classified as a proactive external workhorse for bounded search, reading, extraction, summaries, drafting, and approved low-risk implementation/tests. It remains non-authoritative regardless of version and cannot replace the Sol/Fable frontier brain; when Claude's Fable-to-Opus chain is unavailable, Flash is only a degraded advisory second opinion and the Codex brain retains judgment.
  • Missing, quota-limited, timed-out, mismatched, or failed agy/Flash work falls back to the host's native cheap reader/workhorse and records the fallback. Flash and native workers may run concurrently only on independent packages: reads may be parallel, while writes remain serial unless demonstrably isolated, with the brain reviewing evidence and actual diffs.

v1.0.30 (Windows-safe Claude hook execution)

  • Claude Code routing hooks now use executable-plus-argument-array form, preventing /usr/bin/bash from stripping backslashes out of Windows executable paths. Install/repair migrates legacy string-form Switchboard hooks without changing other user hooks; Codex hooks keep their existing command-string format.
  • Completion now requires every Claude-managed background Bash, PowerShell, or Monitor job started by a package to reach a terminal result or be stopped. Launching or detaching background work does not count as verification.

v1.0.29 (strict native pre-labour enforcement)

  • The installed PreToolUse gate now atomically allows one bounded block of direct brain labour, then denies the next eligible read, search, evidence, test, documentation, or mechanical call until a same-vendor native reader/workhorse starts or a package-specific brain override is registered.
  • Native-agent relief is bounded rather than permanent: each cheap-role start opens only the next block, while completed planning work cannot disable later implementation enforcement. Switchboard consultation controls remain available, but ordinary research MCP calls count as evidence labour.
  • Direct-labour counts are captured before tool execution, resist parallel-call and retry bypasses, and set a floor that the final routing audit cannot under-report. Managed native roles are also instructed to cap their return at 8,000 characters so cheap-agent transcripts do not flood the brain context.

v1.0.28 (bounded context ingress and complete routing audits)

  • Oversized MCP verification payloads are quarantined outside the brain context by the installed PostToolUse hook. The brain receives a compact evidence reference and must request an explicit field projection or output cap instead of ingesting the raw response.
  • Decision premises are explicit: readers locate candidate evidence and distinguish fact from interpretation; the brain adjudicates only the minimum primary evidence whose truth could change a decision.
  • Completion audits now cover unplanned as well as planned work and include a direct-brain labour census for reads, searches, evidence queries, tests, documentation, and other routine work.
  • agent-switchboard.exe --version (plus version and -v) reports the packaged release, so an installed binary can be verified directly.

v1.0.27 (native-first labour routing)

  • Same-vendor labour now uses native subagents first: Codex explorer/Luna-low and worker/Terra-medium, or Claude Explore/Haiku and economy-worker/Sonnet-medium. That same-vendor restriction remains; the current policy also permits the distinct external Antigravity Flash workhorse lane documented above.
  • Plans now carry a portable semantic lane plus execution mechanism and executor-resolved exact model/effort. A Claude-authored Sonnet/Haiku package is re-resolved to Codex's current native worker/reader when Codex executes it, and vice versa.
  • The completion gate records host-issued SubagentStart/SubagentStop ids and accepts mixed native:<agent-id> and broker:<uuid> receipts. Bare brain overrides no longer bypass the whole audit; retained work uses a package-specific override: brain - <WP-ID>: <specific reason>.
  • A one-shot native-first checkpoint fires after ten mutating operations without a completed cheap native agent. Dirty-worktree or deployment ownership no longer excuses read-only, test, evidence, documentation, or isolated mechanical labour.
  • Dynamic Codex role selection excludes the frontier brain from cheaper roles when alternatives exist. A transient catalog failure keeps the last-known managed native roles instead of installing stale hard-coded model ids.

v1.0.26 (future-proof brain/labour hierarchy)

  • The install/repair flow now owns checksum-marked global Codex and Claude hierarchy blocks, cheap reader/workhorse role files, and merge-safe prompt/tool/stop hooks. It preserves existing hooks and main model/effort settings; the same refresh runs whenever the installed MCP server starts.
  • Codex brain/worker/reader roles are selected from live codex debug models priority/visibility/description metadata. Claude uses moving family aliases: Fable/max for the peer brain, Opus/max only on an explicit Fable availability failure, Sonnet/medium for workhorse implementation, and Haiku for read-only labour.
  • Queued Claude jobs now preserve their requested permission mode instead of hardcoding plan, so approved routine implementation can execute on the workhorse. Direct and async results report requested, attempted, and runtime-attested actual models.
  • A bounded completion gate observes mutating tool use and requests a broker-verified routing audit (or an explicit brain override) before an implementation can claim completion. It fails open when the broker ledger is unavailable and blocks at most once per turn.

v1.0.25 (exact Haiku pin + tighter delegation contracts + codex discovery order)

  • CLAUDE_CHEAP_MODEL now pins the exact claude-haiku-4-5-20251001 model id instead of the floating haiku alias; the static Claude catalog entry was updated to match while keeping all existing Haiku aliases (haiku, claude haiku, haiku 4.5) resolvable.
  • Implementation-plan and implementation task contracts, and the cost-aware routing rules, now require each work package to state Route | exact model/effort | deliverable | verification | escalation, require workers to record an override: brain - <reason> line when deviating from the assigned route, reclassify risk/difficulty at each work-package boundary, return the first ambiguity or failed fix to the brain before delegating the deterministic remainder, default to parallel reads / serial writes, and require the final routing audit to cross-check the broker's actual-model ledger rather than a worker's self-report.
  • discover_codex (broker) and setup.py's config writer/repair now resolve Codex CLI path in the same order: a valid configured codex_path, then a valid CODEX_CLI_PATH marker from ~/.codex/config.toml, then PATH.
  • Direct and asynchronous Codex/Claude CLI calls now record the runtime-reported model (and Codex effort), label missing evidence unverified, and fail closed on a requested-model mismatch. Claude trusts only the main assistant event; Codex trusts the persisted turn_context tied to the emitted thread id.
  • Codex request rows now preserve read-only, workspace-write, or danger-full-access through the detached worker instead of silently forcing every worker to read-only. Native Windows sandbox failures still escalate to the brain; the broker never weakens the requested sandbox automatically.

v1.0.24 (cost-aware frontier brain + worker routing)

  • Bare serious consultations now use the current frontier brain at maximum effort: Codex Sol/max and Claude Fable/max.
  • Explicit model_policy="cheap_read" routes read/extract/summarize labor to Luna/low or Haiku (without an unsupported Haiku effort flag).
  • Explicit model_policy="balanced" routes bounded implementation/testing from an approved plan to Terra/medium or Sonnet/medium. Prompt keywords never silently downshift a serious request.
  • The routing guide now documents both families and the evidence/escalation contract remains in the shared ground rules.

v1.0.23 (cross-agent output discipline)

  • Shared task contracts now lead with the result, describe failures concretely, avoid invented estimates, and prefer plain language.
  • Review/audit/bug-hunt contracts report every substantiated in-scope finding, keep unrelated observations separate, and identify residual verification gaps when no finding is confirmed.

v1.0.22 (Antigravity CLI-first routing)

  • Antigravity now defaults to the standalone agy CLI, matching Codex and Claude's CLI-first behavior. Calls return stdout directly; if agy is missing, automatic routing falls back to the existing in-app bridge/inbox.
  • Explicit surface intent always wins. surface="extension" / "inbox" or use_inbox=true forces the in-app bridge; surface="cli" requires the headless CLI.
  • Model selection uses stable, live CLI slugs. "flash high 3.6" resolves to gemini-3.6-flash-high, and list_agent_models merges agy models output so newly released models become available without hardcoding another broker release.
  • Execution mode follows task intent. Consult/review defaults to sandboxed plan; task_kind="implementation" defaults to accept-edits; bypassing permission prompts remains an explicit danger-full-access choice.
  • Added consult_antigravity, antigravity_cli_path, doctor reporting for agy, installer detection, and CLI/inbox fallback guidance.

v1.0.21 (limits are advisory — stop force-shrinking data between sessions)

  • Inline consult responses: default 5k → 20k chars, hard ceiling 40k → 200k (AGENT_BROKER_CONSULT_RESPONSE_CHARS / _MAX). Full responses were always preserved (history + request row + response_ref), but the small inline cap force-shrank what the calling session actually saw.
  • Truncation no longer mangles structure. The old path collapsed all newlines/indentation (destroying code blocks and diffs). The rare over-ceiling cut is now a clean tail-cut at a line boundary with an explicit [... truncated inline; FULL response preserved — see response_ref] marker.
  • Word budgets are now explicitly ADVISORY in the task contract, ground-rules file, and the prompt-size notice: aim lean, avoid redundant content (re-pasted files the receiver can read itself), but never omit unique data needed for a correct/complete answer. The prompt notice now states the prompt was delivered in full.
  • Audited the full transfer path: prompts (MCP → DB → stdin → CLI) and responses (CLI pipe → DB → request_result) move untruncated; only display excerpts (history, event log) are shortened.

v1.0.20 (no stray Claude tabs — worker requests skip the UI inbox)

  • Worker-handled Claude requests no longer open a new Claude tab. v1.0.19 wrote the inbox .md and started the CLI worker, so the bridge also delivered the prompt into the IDE — a stray tab popped up while the worker answered headless. Inbox files are now written only when no CLI worker took the request (UI fallback path), and the worker deletes any leftover inbox copies when it finalizes (covers rows queued by older servers).

v1.0.19 (Claude/Fable requests get the CLI worker too)

  • Queued Claude consults no longer sit "queued" forever. A Claude inbox request (e.g. Opus consulting Fable) used to depend entirely on an interactive session or the bridge picking the inbox file up — in a headless environment nothing ever did. Queueing now also starts a detached Claude CLI worker (claude -p --model fable/opus/sonnet/haiku --effort …, same machinery as the Codex worker: atomic claim, 1800s cap, rowcount-gated side effects, no console window) that records the answer; collect it with request_result(request_id, wait_seconds=180). The inbox file stays as the UI fallback. Disable via AGENT_BROKER_CLAUDE_QUEUE_AUTORUN=0.
  • Targets that aren't CLI-runnable (e.g. Antigravity panel models) keep the UI delivery path, and now expire with a clear error after ~35 min instead of hanging forever; stale-expiry covers claude_requests like it covers codex_requests.
  • Schema: claude_requests gained effort, cli_model, worker_pid, worker_started_at, worker_completed_at (auto-migrated).

v1.0.18 (max-effort headroom + honest wait expectations)

  • Worker cap raised 900s → 1800s. A max-effort Sol consult on a real design prompt commonly runs 5-15 minutes (live-measured: 8m21s); the old cap risked killing legitimate long runs. Override via AGENT_BROKER_CODEX_ASYNC_TIMEOUT_SECONDS.
  • Pending/running responses now state the real ETA. The pending payload carries typical_wait: "5-15 minutes at max/xhigh effort" and retry_after_seconds: 120 (was a hammer-inducing 20), and request_result reports elapsed_seconds plus a "this is normal, not a hang" note for max/xhigh — so callers stop reading a 8-minute run as stuck.

v1.0.17 (consult is always Sol/max — no silent downgrade)

  • Removed the prompt-keyword "cheap read" guesser. It was silently routing real consults to gpt-5.6-luna at low effort whenever the prompt mentioned reading/lines/deleting — producing hedged, untrustworthy answers. Luna now runs only when the caller explicitly sets model_policy='cheap_read' or names a Luna model.
  • A serious consult on Sol is forced to max. Even if the caller passes high/medium, a consult/plan/audit/review/debate is clamped up to max (unless it explicitly opted into a cheaper tier). Safe now that max routes async instead of hanging — so the earlier hang fix no longer costs you effort.

v1.0.16 (no more stray cmd windows)

  • Consults no longer pop an empty cmd.exe window on Windows. The detached async worker runs without a console of its own, so the Codex/Claude CLI (and git/powershell helpers) it spawned were getting a fresh console window that lingered on screen. Every child process now spawns with CREATE_NO_WINDOW, so all consultation work happens silently in the background.

v1.0.15 (highest-effort default + effort-based async routing)

  • Consults/plans default to gpt-5.6-sol at max again (v1.0.14 had dropped this to high). Quality is the default; latency is handled by routing, not by lowering effort.
  • max/xhigh consults route async up front. Instead of blocking the 240s sync window and then reporting pending, an effort that doesn't fit the window returns a pending request_id immediately while the detached worker finishes it — collect with request_result(request_id, wait_seconds=180). Efforts that fit (high/medium/low) still return inline.
  • Reading/labour stays on Luna. model_policy='cheap_read' (and cheap/reader-shaped requests) run gpt-5.6-luna at low and return inline.
  • Defaults only — the caller always overrides. An explicit effort, target_model, or model_policy wins: request Luna for a consult, or Sol/max for anything, as the task needs.

v1.0.14 (Codex consult no longer hangs / times out)

  • Direct consult_codex no longer times out and discards the work. A consult now runs through the same ledger+worker path as queued requests: it returns the answer inline when it finishes inside the sync window, otherwise it returns a status: "pending" payload with a request_id — the detached worker keeps running to its own cap and records the answer, so nothing is lost. Collect a pending answer with request_result(request_id, wait_seconds=120).
  • Consults default to high effort, not max. At max, gpt-5.6-sol routinely overran the 240s sync window and the timeout threw the work away. high finishes inline for typical consults; the sync path no longer clamps serious consults up to max (the async routing paths still do). Pass effort: "max" explicitly when you want it — that request just returns a pending id.
  • request_result / request_status gained wait_seconds long-poll. One call blocks (bounded to the MCP window) until the request reaches a terminal state, the reliable way for a turn-based caller to collect a pending consult.
  • Worker hardening. Atomic single-writer claim (no duplicate workers on a simultaneous start); post-completion history/events are skipped when a worker loses the finalize race; lone UTF-16 surrogates in CLI output are scrubbed before the DB write (previously crashed store_consultation after a successful consult, discarding the answer).

v1.0.13 (Codex inbox async worker)

  • Claude -> Codex inbox requests no longer stay delivered forever. Queued Codex requests now start a bounded headless Codex CLI worker that writes the