Runners¶
kew is runner-agnostic. It owns the parts that make autonomous dispatch safe — the queue, worktree isolation, budgets, the security hook, the tamper-evident audit log, and governance — and treats the coding agent itself as a pluggable, supervised subprocess. The same controls apply no matter which agent does the work, so you can route different issues to different agents without giving up the control plane.
Governance that lives inside one vendor's console governs one vendor. kew keeps budgets, audit, approval, and the kill switch outside the runner, so they hold across every agent — cloud or local.
Supported runners¶
| Runner | Use it for | Models | Config section |
|---|---|---|---|
claude-code (default) |
Deep Claude integration with session resume and structured events | Claude | [agent.claude-code] |
opencode |
Multi-provider and local models; GPT/o-series inference remains here | Gemini, GPT/o-series, Codex-branded models, Ollama, OpenRouter | [agent.opencode] |
codex |
Official OpenAI Codex CLI, explicitly selected and host-brokered; supports Switchyard through OpenAI Responses | Authenticated Codex models | [agent.codex] |
pi |
The pi coding agent | Multi-provider | [agent.pi] |
hermes |
Headless OpenRouter-only agent with native usage-file cost | OpenRouter | [agent.hermes] |
lemonade |
kew's local loop over an OpenAI-compatible endpoint | Local models | [agent.lemonade] |
Runner comparison¶
The following table compares the available runners to help you choose the right one for your needs:
| Runner | Provider(s) | Cost | Best for |
|---|---|---|---|
| Claude Code | Anthropic | Metered | Hard work |
| OpenCode | Multi-provider | Metered | Provider-flexible |
| Official Codex | OpenAI direct | API-equivalent included-plan value | Explicit host dispatch |
| pi | Multi-provider | Metered | Minimal terminal agent |
| Hermes | OpenRouter only | Metered | OpenRouter models, native usage-file cost |
| Lemonade | Any local OpenAI-compatible endpoint | $0 | Private/sovereign work |
Each runner is a thin adapter (in kew/runners/) that kew shells out to and supervises. Per-runner options — binary path, extra flags, provider knobs — live in that runner's kew.toml section; see Configuration.
Switchyard transport¶
Claude Code supports the optional Switchyard transport through its native
Anthropic Messages interface. Kew applies the configured endpoint with Claude
Code's documented, child-local ANTHROPIC_BASE_URL override and supplies the
exact configured route through --model. Fresh and resumed sessions use the
same override, and Kew does not write Claude project or user configuration.
Direct mode remains the default and does not change or remove an operator-provided Anthropic endpoint. Switchyard owns upstream provider credentials; endpoint and route configuration contain no credential values.
When the inference transport is switchyard, the official Codex runner uses
the configured route as its exact model and supplies a run-local custom
provider over the OpenAI Responses wire API. The endpoint and provider are
passed only through Codex CLI configuration overrides; kew does not write user
or project Codex configuration. Codex receives the endpoint's /v1 API base;
JSONL events, native resume, reasoning effort, and the existing host
authentication remain unchanged.
Switchyard support is earned per runner; speaking a compatible API is not enough. The v1 rollout matrix is intentionally narrow:
| Runner | Switchyard v1 status | Boundary |
|---|---|---|
codex |
Passthrough-capable | OpenAI Responses; explicit selection and Codex CLI 0.145.0+; native authentication may be presented to the configured endpoint. |
claude-code |
Passthrough-capable | Anthropic Messages; child-local ANTHROPIC_BASE_URL; native authentication may be presented to the configured endpoint. |
opencode, pi, hermes, lemonade |
Refused | No proven isolated v1 override; Kew fails before runner launch. |
Passthrough capability is not rollout approval. Direct remains the default,
and the exact binary, route configuration, runner/model, corpus, canary, and
benchmark evidence require the independent UAT gate
(docs/audit/2026-08-03-switchyard-passthrough-uat.md in the repository —
internal audit packs are not published). Random,
classifier, stage routing, and automatic direct fallback remain disabled.
Runner-reported tokens/cost stay authoritative; process-wide proxy metrics are
diagnostic observations only. See
Switchyard operations
for startup, failure, shutdown, and Rollback procedures.
Running a runner in a sandbox¶
With [sandbox] enabled = true a runner does not run as a host subprocess — it runs inside a container image. The host-side interface to that image is fixed and normative: see the container entrypoint contract. It is also the spec you build a new agent image against — per-runner variation belongs inside the image, not in kew.
Containability is declared per runner
A resolved container runner needs both a mapped image and a nonempty
approved credential declaration. Missing either half fails closed. Official
Codex instead declares runner-native containment in code: it stays on the
host under Codex workspace-write and records posture native; mapping an
image is neither required nor used. Configuration cannot grant another
runner native status.
Do not route a non-Claude runner through the legacy single [sandbox].image;
use an explicit [sandbox.images] mapping and the runner's own declared
credential. No runner borrows the Claude image or credential.
Routing¶
Set a default runner, then optionally route by issue complexity (simple / medium / complex). Each tier can pick its own runner and model:
[routing]
default = "claude-code" # default runner
simple = { runner = "opencode", model = "gemini-2.5-flash" } # cheap model for easy issues
complex = { runner = "claude-code", model = "claude-opus-4-8" } # strongest for hard issues
A tier may be a full { runner, model } table or a bare string shorthand (medium = "claude-code"). kew classifies each issue's complexity (from labels / heuristics) and picks the matching tier, falling back to default.
Inferring the runner from the model¶
If you set only a model, kew infers the runner from the model name, so most setups need no explicit runner:
| Model prefix | Runner |
|---|---|
claude-* |
claude-code |
gemini-*, gpt-*, o1-*, o3-*, o4-*, ollama/* |
opencode |
pi, hermes, and codex are never inferred. Select them explicitly. The
openrouter/* prefix stays mapped to opencode, and GPT/o-series inference
continues to select OpenCode rather than the official Codex runner.
Cost & honesty across runners¶
kew records cost per run from the runner's own usage where it reports one (Claude Code, pi), and prices token usage from its pricing table otherwise. Costs are list-price/API-equivalent, not necessarily your actual bill — see the value-leverage framing in kew report. The per-model scorecard (kew report --models) compares merge rate, review cycles, and cost per merged PR across whichever runners and models your fleet actually used — measured from your own outcomes, not a benchmark.
For runners that emit OpenTelemetry usage (e.g. Claude Code interactive sessions), kew ingest folds that into the same record so dispatched and interactive spend live in one place.
Next¶
- OpenCode runner — provider auth and setup for Gemini / GPT / Ollama / OpenRouter and 70+ others.
- Official Codex runner — official login, native sandbox, and host publication.
- OpenRouter models — hundreds of models behind one key via OpenCode, plus the data-policy settings to configure before dispatching real code.
- Configuration — routing and all
[agent.<runner>]sections.