Skip to main content

JEV Router — the right Claude model for every turn

CI PyPI MIT License Python 3.11 | 3.12 Zero dependencies Claude Code supported Status: beta

Quick start · How it works · User guide · Architecture · Contributing


JEV Router picks the Claude model for each new turn of your Claude Code session. Renaming a variable doesn't need Opus; debugging a race condition does. JEV Router asks TypeSafe's Jev — a fast decision model — which of your models fits the turn, then runs it there. Claude Code keeps working exactly as usual: same UI, tools, permissions, sessions and streaming.

pip install jev-model-router
jev-claude          # that's it — Claude Code, with per-turn routing

✨ Features

  • Per-turn routing — every new message is judged on its own, so a session can move from Haiku to Opus and back as the work changes.
  • Native Claude Code — a local proxy in front of Claude Code's API; nothing to configure in Claude Code, no fork, no plugin. /resume, permissions, tools and streaming are untouched.
  • You stay in control — pick a model in /model and routing steps aside; pick JEV Router again to resume. Say "use opus" in a prompt to force it for one turn.
  • Tool loops stay on one model — Jev is asked once per turn; every file read, edit and command in that turn reuses the chosen model.
  • Fails open — no key, a Jev timeout or an error never blocks you; Claude Code carries on with a safe model within ~3 seconds.
  • Explainable — a status-line readout of every decision, jev-explain for the full reasoning, and a one-line log per turn.
  • Private by design — your key and prompts are never logged; local files are owner-only.
  • Zero dependencies — pure Python standard library.

🎬 Demo

The /model picker with the JEV Router row A rename task routed to Haiku

Left: "JEV Router" in Claude Code's own /model picker. Right: a rename routed to Haiku — the status line shows the model Jev picked.

More screenshots — hard turn on Opus, manual override, jev-explain, decision log

A harder turn moves up to Opus — Jev is asked again on the next message:

A design question routed to Opus

Picking a model yourself pauses routing — the status line shows ⏸ manual:

Manual model selection bypasses Jev

jev-explain shows why a turn got its model:

jev-explain report

One safe log line per turn — no prompt, no keys:

Decision log

Captured from a real Claude Code 2.1.282 session through jev-claude; Jev's answers came from the local stand-in scripts/fake_jev.py.

🚀 Quick start

Requirements: Python 3.11+, Claude Code installed and logged in (a claude.ai subscription or an API key — no extra Anthropic key needed), and a TypeSafe API key.

1. Install

pip install jev-model-router

Latest development version: pip install git+https://github.com/himanshu231204/jev_model_routers

2. Add your TypeSafe key — TYPESAFE_API_KEY, the name TypeSafe's docs and SDK use:

echo "TYPESAFE_API_KEY=your_key" > ~/.jev-router.env        # or: export TYPESAFE_API_KEY=...

Windows PowerShell: Set-Content "$HOME.jev-router.env" "TYPESAFE_API_KEY=your_key"

3. Run

jev-claude                          # interactive, routing each new turn
jev-claude -p "fix the failing test"   # every Claude Code argument is passed through
jev-claude --resume                 # sessions work as usual

The session starts on JEV Router. Watch the status line — e.g. claude-haiku-4-5-20251001 (p=0.97) — to see which model each turn got. The full guide, with troubleshooting, is in docs/quickstart.md.

🧠 How it works

flowchart LR
    A["Claude Code"] -->|"model = jev-router"| B["JEV Router<br/>(local proxy)"]
    B -->|"new turn: ask Jev"| J["Jev<br/>(TypeSafe System One)"]
    J -->|"best model + confidence"| B
    B -->|"model = claude-haiku / sonnet / opus"| C["Anthropic API"]
    C -->|"streamed back, unchanged"| B --> A
  1. jev-claude starts Claude Code with a local proxy as its API endpoint and a JEV Router entry in /model.
  2. When you send a message, the proxy asks Jev which of your account's models — newest Haiku, Sonnet or Opus — can handle it, with a confidence score.
  3. A small local policy makes the final call: explicit choices win, low confidence never downgrades, and a long conversation isn't downgraded (switching would re-read it all).
  4. Only the request's model is rewritten; Claude's response streams straight back.
  5. Tool calls, retries and Claude Code's background requests in the same turn reuse that model.

Jev doesn't write code — Claude does. Jev answers one quick structured question per turn, the kind of "route this to one of a fixed set of destinations, and know how confident you are" decision it is built for. Design details: ARCHITECTURE.md.

⚙️ Configuration

Everything works with just the key. Optional environment variables:

Variable Effect
TYPESAFE_API_KEY TypeSafe key for Jev. Required for routing; without it jev-claude runs plain Claude Code.
JEV_ALLOW_FABLE=1 Also offer Fable (bills extra usage credits).
JEV_NO_STATUSLINE=1 Don't add the routing status line (your own status line is never overridden).
JEV_DEBUG=1 Request-level tracing in ~/.jev-claude.log, including prompt excerpts.
JEV_CLIENT=sdk Call Jev through the official typesafe-sdk (pip install "jev-model-router[typesafe]").

Routing thresholds (confidence floor, cache protection, timeouts) live in one file: src/jev_router_live/config.py.

🧰 Commands

Command What it does
jev-claude [claude args…] Run Claude Code with per-turn routing.
jev-codex [codex args…] Run OpenAI Codex with per-turn routing (experimental).
jev-explain <session-id> Show why the last turn got its model.

❓ FAQ

Does it replace Claude?

No. Claude still does all the work. Jev only chooses which Claude model handles each turn.

What happens if Jev is down or my key is wrong?

Routing fails open: the turn runs on a safe model (Opus on the first turn, otherwise the model already in use) within about three seconds, and the reason is logged. Claude Code never stops.

What does Jev see?

The prompt of each new turn (with Claude Code's injected system context removed), the current model, a rough context size, and the list of models to choose from. Not your files, tool output or conversation history.

Will it change my Claude Code settings?

No. "JEV Router" is selected for the session only and never saved as your default; if Claude Code persists it anyway, jev-claude restores your previous default on exit. Plain claude is unaffected.

Claude Code prints [claude-code:unrecognized_model] {"model":"jev-router"} at startup.

Harmless — it's Claude Code noting the extra "JEV Router" entry. Requests are still routed.

📍 Project status

Beta. Verified end to end against Claude Code 2.1.282 (interactive and -p): the picker entry, per-turn routing, tool-loop pinning, manual override, fail-open and streaming, with 94 automated tests on Python 3.11 and 3.12. OpenAI Codex support (jev-codex) is experimental. Known limitations are listed in ARCHITECTURE.md.

🤝 Contributing

Contributions are welcome — see CONTRIBUTING.md for setup and conventions and AGENTS.md for the invariants a change must keep. Please report security issues privately as described in SECURITY.md.

git clone https://github.com/himanshu231204/jev_model_routers.git && cd jev_model_routers
pip install -e ".[test]"
python -m pytest -q

📄 License

MIT © 2026 Himanshu Kumar

JEV Router is an independent open-source project and is not affiliated with Anthropic or TypeSafe. Claude and Claude Code are products of Anthropic; Jev is a model by TypeSafe.

Release files for jev-model-router 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jev-model-router 0.1.0
File Size Uploaded
jev_model_router-0.1.0.tar.gz 34.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jev-model-router 0.1.0
File Interpreter ABI Platform
jev_model_router-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 76.9 kB

Release files / jev_model_router-0.1.0.tar.gz

Download URL jev_model_router-0.1.0.tar.gz
Size 34.9 kB
Tags Source
SHA-256 checksum
How to use checksums
38d12e4df0affcd685b59c742c37ce30da21d09eb5bb5adb587799d45e160b6a
BLAKE2b-256 checksum
How to use checksums
3abd255d741aaf28385ec2e979ad9a260538a9d3d3aebaf38a27d9078a333420
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / jev_model_router-0.1.0-py3-none-any.whl

Download URL jev_model_router-0.1.0-py3-none-any.whl
Size 42.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
31eeee10f1e94792150055fb21d8cddec344efaaf1535baa02343bd9cfe54432
BLAKE2b-256 checksum
How to use checksums
af1fa5cd9406b945569843b9a705bb20b9d935170942178c2e5b4af0995a813b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page