Jev Router is now reasoning-router: six classifiers, three harnesses

Why I rewrote Jev Router as reasoning-router, which classifiers, harnesses, and models it supports, and how to move an existing Jev Router config over.

Published

Jev Router is now reasoning-router. It still picks the reasoning effort for each step of a coding session without breaking the prompt cache, and it still uses Jev by default. The difference is that Jev is now one of six classifiers you can choose, and OpenCode is one of three ways to run it. The others are a Pi extension and a local proxy that Codex CLI and other Responses or Messages clients can point at.

Why I renamed it

I released Jev Router as an OpenCode plugin that asked Jev how much reasoning the next step needed. Both halves of the name were assumptions, and within a week of the release neither one held. Cloudflare released Clef, a decision model on Workers AI that takes the same request Jev does. Laya is an open-source model you run yourself that accepts the same request. I also wanted the router in Pi and Codex, which can't load an OpenCode plugin.

Adding those to Jev Router would have left a package named after one vendor and one harness that supported several of each. The router itself never cared about either. It summarizes the recent conversation, asks a classifier for an effort, inserts that effort mid-conversation so the cached prefix still matches (how that works), and streams the response back. Only the classifier call and the hook into the harness are specific to a vendor or a harness, so I split those out and renamed the project after what it does.

Classifiers

Jev is still the default, and it's still the only classifier with evaluation results. The others are wired up and tested against their APIs, but I haven't measured how well any of them picks effort.

ClassifierWhere it runsStatus
JevTypeSafe, or Vercel AI GatewayDefault, evaluated on SWE-bench Verified

Clef

Cloudflare Workers AI (clef or clef-flash)

Effort quality not evaluated
Laya

Your machine, with laya-serve

Effort quality not evaluated
Kev

Your machine, with kev.serve

Effort quality not evaluated

OpenAI Decisions

OpenAI (public beta, gpt-6-luna)

Tested against mocked responses only
CLM

Your machine, with clm-serve and a Qwen3-8B embedding backend

API compatibility only

With Laya, Kev, or CLM, the conversation summary never leaves a server you run.

Harnesses

Each harness gets whatever integration its extension surface allows, which is different for all three.

OpenCode keeps the in-process plugin, which rewrites the request body directly, the same as Jev Router did. It's tested on OpenCode 2.0.18.

Pi needed much less code, because on Claude models it already changes effort mid-conversation without breaking the cache. The extension only picks the effort and lets Pi apply it. On OpenAI models Pi changes effort in a way that does break the cache, so for now the Pi extension supports Claude only. It's tested on Pi 1.0.4, and the Pi findings have the details.

Codex has no plugin or hook that sees the model request, but it lets you add a custom model provider with its own base URL. Pointing that at the local proxy was enough. On Codex CLI 0.159.0, the proxy kept each effort change in place on later turns and after Codex restarted, which is what keeps the cache intact. The Codex findings cover the setup and what's still open. The same proxy works for any client that speaks OpenAI Responses or Anthropic Messages. I also ran Hermes Agent through it with a custom provider, though there's no Hermes-specific setup yet (findings).

Models

Supported models haven't changed since the last Jev Router release. They're GPT-6 Astra, Luna, and Sol, GPT-6.1 Sol, and Claude Fable 5.1, Mythos 5.1, Opus 5.5, Opus 5, and Sonnet 5.5. The router rejects any other model before making a network call.

What's been tested

The routing logic and the evaluation are the same as Jev Router's. On SWE-bench Verified with GPT-6 Astra, Jev-routed effort and fixed high effort each solved 44 of 44 attempts, and Jev used 14% fewer output tokens and finished 9% faster on average. The previous post has the full tables and caveats, and the evaluation write-up has the raw results. A few things are new and unmeasured.

  • None of the five new classifiers has been run on SWE-bench, so I can't say whether any of them picks effort as well as Jev.
  • The Pi extension and the Codex path are checked for wire behavior against fake upstreams, not for token savings on real tasks.
  • ChatGPT and Claude subscription logins still aren't supported. For Codex, the proxy doesn't yet forward the headers the ChatGPT backend needs, and subscription routes may reject configuration_update (details).
  • Everything is alpha, and the proxy is meant for trusted local use only.

Moving from Jev Router

The OpenCode config changes in three places. The package is @reasoning-router/opencode, the Jev settings move into a classifier block, and models show up as reasoning-router/... instead of jev-router/....

{
  "plugins": [
    {
      "package": "@reasoning-router/opencode",
      "options": {
        "classifier": {
          "provider": "jev",
          "apiKey": "{env:REASONING_ROUTER_CLASSIFIER_API_KEY}",
          "baseUrl": "https://ai-gateway.vercel.sh/typesafe",
        },
        "wrap": {
          "openai": ["openai/gpt-6-astra"],
          "anthropic": ["anthropic/claude-opus-5-5"],
        },
      },
    },
  ],
  "model": "reasoning-router/gpt-6-astra",
}

Environment variables moved from JEV_ROUTER_* to REASONING_ROUTER_*, with no compatibility layer. Drop baseUrl if you have a direct TypeSafe key, or switch provider to try another classifier. For Pi, run pi install npm:@reasoning-router/pi and pick a reasoning-router/claude-... model. For Codex, start the proxy with npx @reasoning-router/proxy and add it as a model provider in ~/.codex/config.toml. The README has the setup for every harness and classifier. The design still borrows from jev-codex-router and pi-jev-router.

All writingEmail me