jev-for-all
Jev is TypeSafe's System One decision model. It answers a question in roughly 70 to 500 ms with a typed answer and a confidence score. This repo connects Jev to coding agents so they can ask it which skill to load, which tools a step needs, and how to move in the browser.
For the reasoning behind the design, including where Jev wins and where it loses, see When Jev wins.
Read this first
This project is fully experimental. Do not use it in important or production-grade projects.
It will probably not cause harm. It does not edit your code, your git history or your agent's settings (it adds its own config folder and registers itself as a plugin, and that is all). My concern is a different one: token and context integrity. Parts of this plugin pick a model for you, hand work to a cheaper model, or add text to your agent's context. If a guess is wrong, you can spend more tokens than you save, or a cheap model can get a job it handles badly, and you may not notice.
What you get
- Cheaper sessions for easy work. On 12 small coding tasks, letting Jev pick the model cost 35% less than always using Sonnet, and the results were the same.
- Fewer wasted tokens at the start. For simple tasks that need no skills or MCP servers, a "lean" launch used 37% fewer input tokens with the same results.
- Fast and cheap decisions. About half a second and roughly $0.0001 each. If Jev is slow, down or unsure, the plugin does nothing instead of guessing.
- A paper trail. Every claim here comes from a script in this repo, and the things that failed are written down in WHERE-JEV-WINS.md.
- Easy to remove. See Uninstall.
What can go wrong
- The evidence is thin. The numbers above come from 12 small, single-file tasks, one run each, and I wrote the tasks and the answer keys. Real projects are bigger and messier, so expect the savings to be smaller and the mistakes to be more common.
- The model is chosen once, from your first prompt. If a session starts with an easy request and turns into
hard work, it stays on the cheaper model. Restart with
jev-for-all startor switch with/model. - It sometimes picks wrong. In my own tests it sent about 2 of every 58 ordinary prompts to the cheaper tier when a stronger one was the better fit.
- Hints can cost more than they save. The per-prompt skill and subagent hints add text to your conversation. In one real session they added 18 skill suggestions that were never useful, and in a small test the prompts that got a hint cost 50 to 70 percent more. They are off by default for that reason.
- It has blocked things before. An older version could refuse a slash command such as
/loopbecause it was not in Jev's skill list. That is fixed, but there are probably more bugs like it. - Lean mode turns things off. A lean session has no skills and no MCP servers until you restart it.
- Each decision adds a delay, about half a second, more if hints are on.
- Large parts are not measured at all: the OpenCode tool filtering, subagent hints from start to finish, big multi-file projects, and what any of this does to your Claude plan's usage limit (the costs above are dollar-equivalents reported by Claude Code, not plan usage).
- The cheaper DeepSeek option has not been tested for real. It needs a working OpenCode Go login, and mine was rejected, so I only tested it against a stand-in.
- The free local option (Laya) is much less accurate than Jev. Details in the Laya section below.
- Your text leaves your machine. Decisions are made by Jev through OpenRouter's alpha API, which can change or disappear. Your prompt goes to it, and in the OpenCode plugin so does the recent conversation, including tool output. See Privacy.
If you try it anyway
Use a throwaway project first. Run jev-for-all doctor after installing. Leave the hints off. Keep an eye on
your own token use for a few sessions, and compare it with what you normally spend.
What this is
Jev runs on OpenRouter's alpha Decisions API. It is not an LLM. You pass it state, it returns typed answers with a calibrated confidence for each. The repo connects it to OpenCode, Claude Code, Hermes and pi (senpi) through one shared decision contract, so every harness gets the same answers.
Install
bunx jev-for-all@latest init # or: npx jev-for-all@latest init
jev-for-all doctor # checks every piece and says how to fix what is wrong
Use @latest: bunx and npx cache the first version they ever downloaded, so a bare bunx jev-for-all init can run an old copy that does not know init. (bun pm cache rm clears it.)
init is safe to re-run. It needs bun (the Claude Code hook, the MCP tool and the
launcher run on it) and does four things:
- Creates
~/.config/jev-for-all/config.json(backend: your OpenRouter key or a Laya URL, mode 0600) and~/.config/jev-for-all/models.json(one entry per tier, see below). Existing files are never overwritten. The Claude Code plugin also creates them on its first session if they are missing. - Registers the OpenCode plugin in your OpenCode config (no secret is copied into it).
- Installs the Claude Code plugin from this repo's marketplace.
- Warns if the OpenCode Go login is missing, because the light tier runs on it.
Pass --key sk-or-... (or enter it when asked) to store the key. An exported OPENROUTER_API_KEY works
without storing anything. Other flags: --laya <url>, --no-claude, --no-opencode, --dry-run.
Do it by hand instead:
/plugin marketplace add emirbartu/jev-for-all # inside Claude Code
/plugin install system-one@jev-for-all
// ~/.config/opencode/opencode.jsonc
{ "plugins": [ { "package": "jev-for-all" } ] }
Let your agent install it: point it at https://raw.githubusercontent.com/emirbartu/jev-for-all/main/docs/install.md.
Configuration
~/.config/jev-for-all/models.json is created with the defaults, so it doubles as the example:
{
"light": { "harness": "claude", "model": "haiku", "effort": "max" },
"standard": { "harness": "claude", "model": "sonnet", "effort": "auto" },
"heavy": { "harness": "claude", "model": "sonnet", "effort": "auto", "minEffort": "high" }
}
effort is low, medium, high, xhigh or max, or auto to let Jev choose per request.
harness is claude (model alias or id, run with --effort) or opencode (provider/model, run with
#variant). Delete the file to get the defaults back. Plugin options for the OpenCode side are in
Full configuration.
Results
These are the original numbers from a test set the author wrote, so treat them as best case. See Read this first for what real use looked like.
- Skill routing: 64 real requests against a 22-skill roster, 0 wrong picks and an 85.9% hit rate. A full run costs about $0.005.
- Decision cost: about $0.0001 per decision, so a busy session costs pennies.
- Browser: one live
browser_taskrun, "open this page and click that article", took 2 steps and 3 decisions, cost $0.000199, and finished in 3.7 s on the correct page. - Hermes adapter: the same contract against a 78-skill roster hit 75% with 0 wrong picks (numbers).
What Jev decides
- Which skill to load, one from the whole roster, chosen for each user message. Small mechanical
steps (rename, bump a value, read a file, run one command) are vetoed up front by
gate::mechanical, so they get no skill (skills.mechanicalVeto, default 0.5). - Whether to hand the request to a subagent (Claude Code adapter), and which one. Most requests stay with the main agent; only broad search, independent research or parallel work delegates.
- Which tool subset this step needs, so the agent picks from a smaller catalog.
- Every operation inside
browser_task: given a goal, Jev picks each click, target and typed value.
Pick the model and thinking level, not just the skill
Built for people who split work across cheap subscriptions (a $20 Claude plan plus OpenCode Go).
Three tiers, each a harness, a model and a thinking effort (tierConfig in spec/decisions.json):
jev-for-all start "fix all the eslint errors across the codebase" # light -> claude --model haiku --effort max
jev-for-all start "add input validation to createOrder" # standard -> claude --model sonnet --effort medium
jev-for-all pick "<prompt>" # print the decision and command only
start decides once, from the first prompt, and never switches mid-session (a model change throws away
the prompt cache and the agent's context). One Jev call returns the tier, the effort and whether the
task needs an external service; if it does not and the task is light, a Claude session starts lean
(skills and MCP off). Change any tier in ~/.config/jev-for-all/models.json, for example
{ "heavy": { "model": "opus" }, "light": { "model": "opencode-go/glm-5.3" } }.
The orchestrator and its workers
The model at the top is whatever you started: Claude Code on Sonnet (or OpenCode). It stays in charge and delegates cheap work to the light tier:
- Light on Claude (default).
jev-for-all startlaunches a stronger tier with ajev-lightsubagent (--agents, built frommodels.json, so a config change applies at the next launch), and, with hints on, the hook adds a one-line "use a subagent withmodel: haiku" hint when Jev judges a prompt light. - Light on OpenCode. Set
"light": { "harness": "opencode", "model": "opencode-go/..." }. The plugin then advertises an MCP tool,jev_delegate_light, that runsopencode run --model <model>#max "<task>"in your project and returns the report plusgit status; it advertises nothing when light is on Claude, so it costs no tokens then. Needs a working OpenCode Go login (opencode auth login;jev-for-all doctor --deeptests it). - Broad searches and parallel work to Claude subagents with a Jev-chosen
model: this is the per-prompt hint layer, off by default because Claude already delegates well on its own and the hints cost tokens in our measurements. Turn it on with"hints": trueinconfig.jsonorSYSTEM_ONE_HINTS=1. - OpenCode as the orchestrator:
jev-for-all opencode-agentsprints ajev-lightsubagent pinned to the light model when light is on OpenCode (thevariantfield is unverified against OpenCode's agent schema).
What it measured
bun scripts/bench-claude.ts: 12 small coding tasks, each with a hidden check that a hand-written
reference solution passes, run through headless Claude Code with every plugin off. Costs are the
total_cost_usd Claude Code reports; one run per cell.
Thinking effort barely moves the bill: Sonnet on the same 12 tasks passed 12/12 at both low and high, and high cost 9% more, used 45% more output tokens and took 1.75 times as long, because the roughly 70k tokens of context dominate. Letting Jev choose the effort is a small saving, not a large one.
Read it carefully. These are single-file tasks, so Haiku solving all of them says little about large
multi-file work, and one run per cell is noisy (Sonnet's one failure, lru-ttl, is likely luck).
Tier labels matched mine on 56 of 58 prompts, but I wrote both, and I tuned the light wording on ten of those cases. The default catalog is deliberately
conservative (standard stays on Sonnet); if your tasks look like the benchmark, put Haiku on
standard and keep the 94%. The lean saving is the firmest result: skills and MCP schemas were about
40% of the input for a one-line edit, and it holds on any model.
Self-hosting with Laya (experimental, not recommended yet)
Laya is an open, self-hosted System One model that speaks the
same POST /v1/systemone protocol as Jev, so it plugs in with one variable and no OpenRouter credits:
uv venv --python 3.12 laya-venv && VIRTUAL_ENV=$PWD/laya-venv uv pip install "laya[serve]"
LAYA_DEVICE=cuda LAYA_PRELOAD=1 LAYA_MODELS=english,multilingual LAYA_DEFAULT_MODEL=english laya-venv/bin/laya-serve
export LAYA_BASE_URL=http://127.0.0.1:8000 # every host in this repo now uses it
export LAYA_MODEL=typed-decisions # optional: english | multilingual | typed-decisions
With LAYA_BASE_URL set Laya is used instead of OpenRouter and never falls back to it, so a stopped
server just means no routing. It is much faster (21 ms median on an RTX 3060, against about 450 ms),
but on our decisions the stock checkpoints are much worse than Jev, measured on the same cases:
Laya's own README says the base checkpoints are meant to be fine-tuned, and that its probabilities are flatter and differently calibrated than Jev's, so thresholds tuned for Jev do not transfer. A wrong skill pick is worse than none, so leave this off until a fine-tuned checkpoint beats the table above. The route to get there is to label a few thousand prompts with Jev once (cents of credits) and fine-tune Laya on them; that has not been done.
The other harnesses
Browser tasks
browser_task runs one natural-language goal in a real browser. Jev picks every move, and only a
TYPE_TEXT step calls a text model, so a task costs less than a cent. Prerequisites (uv, a
jev-ultrafast checkout, and a Chromium-family browser over CDP) and the MCP wiring are in
adapters/browser-mcp/README.md.
Privacy and fail-open behavior
Every model dispatch sends the conversation tail, including tool-result bodies up to
tools.stateBudget (6000) characters, plus the tool catalog's names and descriptions, to
OpenRouter's alpha Decisions endpoint. browser_task also sends the current page's text and
controls on every step while it runs. Nothing is sent without an API key. Every Jev call fails
open: a timeout, error, malformed answer or low-confidence decision changes nothing and never
blocks a model call.
Configuration
The useful options, with defaults:
apiKey: OpenRouter key, or setOPENROUTER_API_KEYmodel:~typesafe/jev-latesttimeoutMs:2500, the per-request timeoutskills.enabled,skills.gateThreshold:true,0.3for skill routingtools.enabled,tools.maxTools:true,12for tool-subset routingobserve.enabled,observe.file:false, none, per-message usage JSONLbrowser.enabled,browser.jevDir:false,~/jev-ultrafastcontrol.verify:false, verification-gate hint before a completion claim
Full configuration
{
"plugins": [
{
"package": "/path/to/jev-for-all",
"options": {
"apiKey": "sk-or-...", // or set OPENROUTER_API_KEY
"model": "~typesafe/jev-latest",
"timeoutMs": 2500,
"debug": false,
"agents": ["build"],
"serverURL": "https://openrouter.ai",
"skills": { "enabled": true, "rerank": "auto", "gateThreshold": 0.3,
"rerankAbove": 40, "rerankBelowP": 0.5, "shortlist": 3,
"fitsThreshold": 0.3, "minConfidence": 0.3 },
"tools": { "enabled": true, "maxTools": 12, "minToolProbability": 0.05,
"needsToolThreshold": 0.3, "minConfidence": 0.3,
"alwaysVisible": ["read","write","edit","bash","grep","glob"],
"stateBudget": 6000 },
"observe": { "enabled": false, "file": "/tmp/system-one-usage.jsonl", "retain": 20 },
"browser": { "enabled": false, "jevDir": "~/jev-ultrafast",
"maxSteps": 12, "timeoutMs": 180000 },
"control": { "verify": false }
}
}
]
}
Development
bun run typecheck # type check
OPENROUTER_API_KEY=... bun scripts/jev-probe.ts decisions # live Jev smoke test
Jev is a TypeSafe model; this is an independent integration, and the repo is not affiliated with any other organization or team.