A fresh user turn gets one Jev call. Tool continuations, retries and follow-up model calls reuse the pinned decision.
Why turn-pinned
Switching models inside a tool loop is the expensive way to route.
A new model has to rebuild the prompt prefix. Keeping the model fixed through the tool loop limits rebuilds to turn boundaries.
Same model, same prefix: effort can move without paying a prefix rebuild. That is the cache-safe lever for routine turns.
The flow
New turn → Jev once → policy gate → pinned model → tool loop.
jev-codex launches the real Codex CLI and exposes a virtual
jev-auto model. The local proxy recognizes a fresh user turn, asks
TypeSafe Jev once, applies
deterministic gates, then writes the real model into the request.
The rest of the turn stays stable: the same model handles every tool continuation. The next user turn is the first opportunity to choose again.
Open full diagram ↗
The control loop
Four decisions: pick, gate, run, learn.
Jev proposes model and effort; local policy decides whether the switch is allowed. Price break-even, cache warmth, session state and upgrade triggers all enter the same deterministic gate.
After the turn, usage updates cache warmth, failures can trigger an upgrade, and the session is persisted. Compaction resets cache evidence and effort provenance.
Open full diagram ↗
Guardrails
Jev proposes. Code decides.
Compare the target model's rebuild cost with the per-turn saving over remaining turns.
Read cached_tokens from response usage. A cold cache makes a downgrade cheaper to try.
Lock after a turn budget, cap switches, cooldown between changes, and persist across resume.
Upgrade only on failure, high complexity or an explicit user request — not every Jev suggestion.
A compacted prefix invalidates cache evidence and effort anchors. Start clean.
Per-turn effort is capped at high by default, with a defined fallback.
The trade-off
Effort first. Model second. Never per call.
Per-call routing
- Model can change on every model call.
- Prefix cache is rebuilt repeatedly.
- Tool loop behavior is less stable.
- Best case: better per-call fit.
Turn-pinned + effort
- One model per user turn.
- Tool loop reuses the same model.
- Effort can move with
configuration_update. - Best case: fewer rebuilds, less reasoning on routine work.
CODEX APP
The same model, now in the app.
The same local provider also powers the Codex app. Run jev-codex setup-app, fully restart the app, create a new task, and select Jev Auto Router in the model picker.
Evidence
What is proven — and what is not.
Turn detection, tool-loop pinning, retry dedupe, price gates, session guards, effort anchors, compaction reset and the session store. 60 tests.
Live GPT cache-hit rate, quality non-inferiority, output-token reduction and end-to-end latency still need a paired evaluation.
Quickstart
Build from source. Keep the first run small.
Node.js 22+, a signed-in Codex CLI and a TypeSafe Jev key are required. The npm registry release is still pending; source install is the current path.
git clone https://github.com/miniLV/Jev-Auto-Router.git
cd Jev-Auto-Router
npm ci
npm run build
export JEV_API_KEY="<your-typesafe-key>"
node bin/jev-codex.mjs
Effort routing is off by default. To try the new loop on a small task:
export JEV_CODEX_EFFORT_ROUTING=turn
export JEV_CODEX_EFFORT_CAP=high
node bin/jev-codex.mjs
The Codex app uses the same local provider:
jev-codex setup-app