A CLI wizard that analyzes your agentic codebase and helps you adopt BitRouter to cut LLM cost. It reads your code (read-only), then produces three artifacts:
bitrouter.yaml— an MVP routing policy to try with BitRouter.bitrouter-audit.md— an audit of your LLM usage + a savings estimate..bitrouter/analysis.json— the machine-readable analysis.
It is built on the pi coding-agent SDK and routes its own LLM calls through BitRouter. It never modifies your source — it only writes the artifacts above.
Once you've adopted BitRouter and it has metered some real traffic, the tool upgrades from a cold-start rate card to observed dollars (see Optimizer below).
Status: in development. See
SPEC.mdfor the v1 build plan.
npx @bitrouter/agent # analyze + generate all three artifacts
npx @bitrouter/agent audit # audit + estimate only (no policy file)
npx @bitrouter/agent estimate # estimate only (.bitrouter/analysis.json)
npx @bitrouter/agent optimize # tighten the policy from real metered trafficFlags: --out-dir <dir>, --model <id>, --target <local|cloud>, --offline,
--yes, --debug, plus observed-mode flags --db <path|url>, --since <days>,
--min-requests <n>.
By default the analysis is done by a pi agent routed through BitRouter (with a
consent prompt before any code is sent). Pass --offline — or if the router is
unreachable, the tool falls back automatically — to run a fully local static
analysis instead: nothing leaves your machine, and no LLM is required.
Cold-start numbers are a rate-card scenario, not a bill — with no traffic there
are no real dollars. Once BitRouter is running as your gateway it meters every
request into a local bitrouter.db. The optimizer reads that DB (read-only) and
upgrades the estimate to observed spend:
bitrouter-optimizer.md— real $ spent per model/provider, the rate you actually paid ($/Mtok), error rates, and a projected monthly saving.bitrouter.optimized.yaml— a proposed tightened policy, written to a new file (your ownbitrouter.yamlis never touched).- the
observedblock merged into.bitrouter/analysis.json.
npx @bitrouter/agent optimize # read bitrouter.db, propose a tighter policy
npx @bitrouter/agent optimize --since 7 # use only the last 7 days of trafficoptimize uses the model (via BitRouter) to draft the policy diff, with a
deterministic offline fallback. The numbers are always computed locally. init
also performs this upgrade silently when it finds a populated bitrouter.db
— it "just knows" you have traffic. When there isn't enough yet, both degrade to
the cold-start rate card and tell you why.
Reading the metering DB uses Node's built-in node:sqlite. It works out of the
box on Node ≥ 24; on Node 22–23 run with --experimental-sqlite (otherwise the
optimizer cleanly falls back to the cold-start rate card).
The explicit Smithers mode supervises a strong baseline, one-key economy exploration, terminal eval reward, frozen candidate export, and a fresh holdout. It accepts the YAML only when quality, critical-case, cost-per-success, and byte-determinism gates all pass; it never publishes or edits the active policy.
npx @bitrouter/agent optimize \
--smithers-workflow eval/workflow.tsx \
--smithers-cases eval/cases.jsonl \
--bitrouter-config bitrouter.yaml \
--bitrouter-bin ./target/release/bitrouter \
--out-dir artifacts \
--yesSee Smithers reward-supervised policy optimization for the policy prerequisites, acceptance contract, artifacts, and production limitations. The first real SWE-EVO run is documented in the 2026-07-23 experiment report: reward attribution, persistence, and deterministic export worked, but the candidate was rejected after a 3/4 holdout and a 27.6% cost-per-success regression. A post-run audit also found that v7 had disabled exploration without fully disabling holdout learning; the branch now fixes that contract for the next untouched experiment.
local(default) — routes through a BitRouter daemon athttp://127.0.0.1:4356. Runbitrouter startfirst.cloud— routes through BitRouter Cloud. Runbitrouter auth loginfirst.
Running bitrouter (instead of pi) starts a BitRouter-branded, read-only
chat session: it can inspect your codebase and run the estimate / audit /
optimize tools and the /bitrouter command, but it cannot edit files or run
shell commands. Its identity, tool set, and skills are locked to BitRouter, and
its config lives under ~/.bitrouter/agent rather than pi's ~/.pi.
By default the session loads only BitRouter-family skills — every skill
whose front-matter name is bitrouter or bitrouter-<thing> (e.g. the bundled
bitrouter analysis skill and the provider's bitrouter-pi setup skill). pi's
usual skill auto-discovery (~/.agents/skills, ancestor .agents/skills, …) is
otherwise disabled, so unrelated skills don't leak into the appliance.
Naming convention. To have a skill auto-load, name it bitrouter or
bitrouter-<thing>. The launcher discovers it by declared name (not by
directory name), de-duplicates by name (the bundled copy wins over a stray
~/.agents/skills copy), and loads it alongside the rest — no launcher change
needed. Distinct names like bitrouter and bitrouter-pi coexist without
colliding.
Loading other skills explicitly. Skills outside the family don't load by default, but you can opt any in:
-
Per invocation, by path or by bare name:
bitrouter --skill ~/.agents/skills/paseo # by path bitrouter --skill paseo # by name (searched in the skill roots)
-
Persistently, via a
bitrouter.skillsarray in~/.bitrouter/agent/settings.json(each entry a name or a path):{ "bitrouter": { "skills": ["paseo", "/abs/path/to/team-skill"] } }We namespace it under
bitrouteron purpose — pi reads the top-levelskillskey as auto-discovery patterns, so the opt-in list lives underbitrouter.
pnpm install
pnpm build # bundle to dist/
pnpm typecheck
pnpm lint
pnpm testApache-2.0