← BACK TO CASE INDEX

CODEX ROUTING / COMMUNITY CASE

jev-codex-router

Per-call model and reasoning routing for Codex: Jev picks the capability tier and thinking depth for every model call, tool continuations included.

270 GITHUB STARSREPOSITORY OWNER 0xNatoshiARCHIVED

The author archived this repository on September 24, 2026. This case documents its routing design and source. Compatibility with current Codex releases has not been independently tested by JevCases.

VIEW ON GITHUB Stars are a verified snapshot · 2026-09-25
Repository preview of the jev-codex-router repository
Repository preview · 0xNatoshi / jev-codex-router
OVERVIEWCODEX ROUTING

Codex work alternates between short mechanical edits and turns that need real reasoning. Treating every turn the same means either overspending on simple work or under-serving the hard parts.

jev-codex-router sits between Codex and the model API and decides, per model call, which model should answer and how much thinking it should spend. It is a self-contained monorepo: a Codex Router fork is embedded under router/, with the Jev policy, relay and reports in server/.

The default direction is native-first. Native models answer every healthy turn, a local fallback is reached only when the ChatGPT usage window is actually exhausted, and the local provider inventory is never sent to the decision model.

WHAT JEV DECIDESJUDGMENT

Jev answers four independent Choice questions in a single request: whether the next call falls under the mandatory-Astra policy, the least expensive sufficient capability tier, the minimum sufficient thinking depth, and the scope of the route lease. Ordinary code, not Jev, enforces the policy and applies the answer to the request.

How a routed request flowsARCHITECTURE

Codex keeps talking to a local router instead of the model API directly. Only the jev/auto route is diverted: the call is handed to a local Jev server, which returns a model and a reasoning effort, and the request is then executed against a local caller edge that shares the native session.

Responses go in and Responses come out. The SSE stream is relayed verbatim, so tool calls, reasoning and compaction behave as they would natively. The router changes which model answers a call, not the shape of the exchange.

Request path, as drawn in the repository README
Codex ──▶ Codex Router (:4202)
            ├─ native models ──────────────▶ ChatGPT backend (your plan)
            └─ "jev/auto" ─▶ LiteLLM ─▶ API forwarder
                                     │
                                     ▼
                          jev_server.py (127.0.0.1:4319)
                            ├─ compact decision state ─▶ Jev
                            │                           └─ model + effort
                            │
                            └─ canonical Codex replay + decision
                               └─▶ local caller edge (shared native session)
                                    └─▶ luna / terra / sol / astra

What Jev sees, and what the executing model seesTWO PROJECTIONS

The decision model and the executing model do not receive the same material. Jev sees only a bounded decision dossier: the active task, the step type, and where relevant a short assistant-intent tail, a tool name, a tool-output tail or an image flag.

The model that ends up executing the call receives the complete canonical request held by Codex — instructions, history or compaction handoff, tool calls and tool results. Only the selected model, reasoning effort, service tier and required streaming flag change.

  • The embedded router exempts the jev/auto route from conversation windowing and tool-result aging, because those optimisations would remove context before the Jev server could relay it.
  • Context continuity is unconditional: returning to a previously used model can increase processed input on a cache miss, but it cannot remove conversation facts. Requests using automatic truncation or compaction items fall back to a request-level effort.
  • A short context-dependent ask such as "continue" also receives one bounded active-task summary, so the decision is not made from a blind last message.

Capability tiers and the policy behind the routeROUTING POLICY

The native ladder runs Luna, then Terra, Sol and Astra, with thinking depth selectable from low through max. Terra is the routing prior for bounded implementation with clear requirements — small local features, known-cause fixes, straightforward tests. Sol covers complex implementation and cross-file reasoning. The repository describes both as capability priors, not calibrated success rates.

Policy split-v11-native-first-fallback judges the remaining work rather than inheriting the category of a review that already finished. Astra is reserved by an explicit policy choice: project architecture, an independent final code review, and risk-focused review covering security, authentication and permissions, concurrency, migrations, public API compatibility or material performance risk.

  • The word "review" on its own does not force Astra; routine in-progress checkpoints use ordinary capability routing.
  • There is no target distribution, no keyword-to-model rule, no low-confidence fallback to Sol and no mechanical-step exception.
  • A close pair of tier and effort decisions is applied unchanged rather than rounded up.
  • Jev's confidence is not a code-quality score, and a favourable quality score never cancels a required final review.

Fail-open, kill switch and quota fallbackFAILURE PATHS

Three mechanisms keep a turn alive when something goes wrong, and they are logged separately because they mean different things. Failures do not end the turn: a missing or invalid Jev response, a provider error or a timeout keeps it running on a safe fallback route — Astra at medium effort. A sentinel file is the manual kill switch and routes without Jev instantly.

Quota fallback is narrower than it sounds. Native models answer every healthy turn, and provider discovery is not even run. Only observed native quota exhaustion activates a locally discovered, capability-compatible route: either a manual sentinel file, or an automatic flip on a 429 or usage-limit response, which also retries the failed call. The flip clears itself on the first successful native call, while the manual sentinel is never cleared automatically.

  • At most two fallback candidates are derived from the models this machine has configured, enabled and exposed. The jev/auto route is always excluded, to prevent recursion.
  • An Ollama model is eligible only while its runtime answers and its persisted real-Codex check reports agentCapable=true. LM Studio additionally has to report that exact model from its live /models endpoint.
  • The decided thinking depth travels with the call and is clamped onto the fallback ladder's three rungs, where the native ladder exposes five.
  • Each fallback attempt is an exact route, so the parent failover cannot loop back through Jev; a retryable failure is retained only while a distinct sibling attempt remains.

Measuring what the router servedCOST AND LATENCY

The router writes one JSON line per decision to a local log and never publishes it. A reporting script turns that log into the table a third party can reproduce on their own machine.

Reproducing the report locally
python3 server/report_routing.py --days 7 --policy current   # current policy only
python3 server/report_routing.py --days 30 --json             # all versions, JSON
  • The report prints the served model distribution (luna, terra, sol, astra, plus any Codex-dry external fallback), the share of turns served by the cheapest tier, the share held below the confidence gate, and the gates encountered.
  • It also prints median latency end-to-end alongside Jev's own decision time, observed prompt-cache reads by model and hashed session, and an estimate of real cost against two counterfactuals: every turn on gpt-6-astra, and every turn on gpt-5.6-sol.
  • Usage counters are kept only when the provider reports them. Unknown usage is not counted as zero, retries are retained, and reasoning tokens are already included in output.

The headline saving cited for this project is a historical simulation: roughly −60% against an all-Astra baseline over 237 turns, measured under the previous policy. The repository states directly that this is not measured Codex quota saved and not evidence for the current policy. Credit figures in the report are estimates from published rates rather than observed account debits, and counterfactual token volumes and task quality have not been experimentally measured.

Requirements and installationSETUP

The documented prerequisites are macOS with the Codex desktop app, Node.js 22.19 or newer, Python 3.11 or newer, and a TypeSafe API key for Jev. No separate Codex Router checkout is needed, because the fork is embedded in the repository.

Documented quickstart
echo 'TYPESAFE_API_KEY=your-key' >> ~/.hermes/.env
./install.sh
bin/jev-codex-router router status
bin/jev-codex-router report --days 7
  • The installer uses router/ as the service source, preserves configured providers, idempotently adds the jev/auto route, provisions a protected loopback credential, installs both launchd services and runs a smoke check.
  • Codex has to be quit and reopened, then the Jev Codex Router entry picked in the model picker. The repository warns that a catalog entry or provider declaration alone does not select the local transport.
  • The server binds 127.0.0.1 only and talks to the local Codex Router. The repository contains no secrets; the key is read from an env file or the process environment, and local decision logs are git-ignored.

Stated status and limitationsLIMITS

  • The repository was archived on September 24, 2026. Its README records the author’s setup at that time; present-day Codex compatibility has not been verified here.
  • The split routing policy still needs outcome calibration on real usage; the decision and attempt logs provide observations, not quality labels.
  • Every route currently uses standard speed, overriding an incoming Fast setting, including retries and bypass modes.
  • Code comments are in French for the current author's working language.
  • Licence: MIT.

FAQ7 QUESTIONS

Is jev-codex-router still maintained?

GitHub marks the original repository as archived and read-only as of September 24, 2026. The source remains available for studying the architecture. JevCases has not verified compatibility with current Codex releases.

What is jev-codex-router?

An open-source Codex router that decides the model and the reasoning effort for each model call, including continuations after a tool. It is driven by Jev and shipped as a self-contained monorepo with the Codex Router fork embedded, under an MIT licence.

Which models does it route between?

The native ladder is Luna, Terra, Sol and Astra, with thinking depth from low through max and standard speed on every route. Terra and Sol are described as routing priors for bounded implementation and for complex cross-file work; Astra is reserved by an explicit policy choice for architecture and for independent final or risk-focused review.

Does it reduce ChatGPT quota usage?

The repository reports a roughly −60% historical simulation against an all-Astra baseline over 237 turns, but states plainly that this is not measured quota saved and not evidence for the current policy. What it does ship is a local decision log and a reporting script, so the served distribution, latency and cache reads can be reproduced on your own machine. Counterfactual token volumes and task quality have not been experimentally measured.

What happens when Jev fails or the network drops?

The turn continues. Any Jev error keeps the call alive on a separately logged fail-open route, Astra at medium effort. A sentinel file routes without Jev instantly, and native quota exhaustion activates a locally discovered compatible route, retrying after an automatic flip on a 429 or usage-limit response.

Is the whole conversation sent to the decision model?

No. Jev receives a bounded decision dossier — the active task, the step type, and where relevant a short intent tail, tool name, tool-output tail or image flag. The executing model receives the complete canonical request, so a cache miss can increase processed input but cannot remove conversation facts.

How do I see which model answered a turn?

Every routed turn is written to a local JSON log, and the picked model appears in the thread as a routed tag carrying one glyph per route: luna, sol, astra or terra. The reporting script summarises the same log over a chosen number of days.

RELATED CASESINSIDE JEVCASES

Read the full projecthttps://github.com/0xNatoshi/jev-codex-router
VIEW ON GITHUB

Case notes by JevCases. Sources checked .

Case notes are based on the archived repository documentation. JevCases has not independently run the current setup or reproduced its cost estimates. The documented routes use standard speed.

← RETURN TO THE CASE INDEX