feat(swe-auto): cost-aware router skill (#123) - #131
Conversation
Adds /swe-auto, the first slice of docs/vision.md: a router skill where the developer does not pick the model. It triages a task into a tier (budget/workhorse/frontier), consults the measured cost/quality Pareto frontier, selects the cheapest non-dominated model that clears the tier's band, runs /swe3 via the in-repo headless runner, optionally judges it, and escalates one tier on shortfall (bounded by max_escalations), writing routing.json. Design: the frontier is the selectable universe; model_execution is a thin how-to-launch layer with built-in Bedrock recipes (self-hosted needs an endpoint). The runner is used in place (monorepo, Option B) rather than packaged. Task inputs (repo/ref/problem-or-issue-URL) are always user args; routing knobs live in swe-auto.yaml. Components: benchmarks/scripts/swe_auto_router.py (pure decision core), swe_auto_run.py (executor + escalation loop + preflight), .claude/skills/swe-auto/ (SKILL.md, triage-examples.md, swe-auto.example.yaml), docs/swe-auto.md. Tests: 43 new unit tests (unittest); full suite 283 pass; ruff/mypy/bandit clean. Smoke-tested end to end on hello-world (budget->haiku, 6/6 artifacts). Default harness: pi.
…ntier is consulted
…GENTS.md/CLAUDE.md
|
Closing in favour of #161, which reworks this into a model router: an advisory skill that recommends a model instead of routing and running the task itself. The idea here was right — use the measured Pareto frontier to pick a model rather than guessing — but two things about this design did not survive contact with the newer data and a clearer product framing. It only works inside this repository. It routes on the wrong signal. This design triages a task into a tier and maps that tier to a quality band. On the v2 dataset, complexity explains 6% of the variance in the per-task gap between Nothing here is wasted. The frontier parsing, the band-and-select logic and the tests are the starting point for #161, and the branch stays put if we want to pull from it. Follow the work in #161. |
Summary
Implements
/swe-auto(issue #123), the first concrete slice of docs/vision.md: a router skill where the developer does not pick the model. Given a repo, a ref, and a problem (a description or a GitHub issue link), it triages the task into a tier (budget / workhorse / frontier), consults the measured cost/quality Pareto frontier, selects the cheapest non-dominated model that clears that tier's band, runs/swe3through the in-repo headless runner with that model, optionally judges it, and escalates one tier on shortfall (bounded bymax_escalations), writing arouting.json.Follows the sequence diagram in vision.md end to end.
Design decisions
run-swe-headless.pyin place; no packaged/pinned installable and no vendored copy (a copy would drift, which is wrong for a benchmark repo). Standalone/external use is a follow-up./swe-autowrites a synthetic single-task dataset and invokes it with--dataset/--tasks/--model/--agent/--skill swe3.model_executionis a thin "how to launch" layer, not a model catalog: Bedrock recipes are built in (self-hosted needs an endpoint), so the router never picks a model it cannot run.swe_auto_router.pyis the pure, deterministic decision core (frontier parse, tier->band, cheapest-clearing select, reliability gating, escalation);swe_auto_run.pyorchestrates (ephemeral dataset, executor, judge, escalation loop, preflight, routing.json). The one model-driven step (triage) lives in the skill.pi.Components
benchmarks/scripts/swe_auto_router.py- decision core.benchmarks/scripts/swe_auto_run.py- executor + escalation loop + preflight, with--dry-runand--preflight..claude/skills/swe-auto/-SKILL.md,triage-examples.md,swe-auto.example.yaml.docs/swe-auto.md- user guide; linked fromdocs/vision.md.Testing
unittest); full suite 283 pass; ruff / mypy / bandit clean.routing.jsonwritten).Scope / follow-ups (out of v1)
router_model(v1 triages with the active session model; both are recorded).Closes #123.