Best Open Source Jev Alternatives: 5 Self-Hosted Decision Models

Most of the decisions software asks a model to make are small and repetitive: route this ticket, flag this message, rate this severity. Those calls never needed prose, and paying a frontier model to generate a sentence you immediately parse back into an if statement has always been the wrong shape for the job.
TypeSafe shipped Jev on September 15, 2026 to do exactly that job and nothing else, then kept it closed, hosted and behind a waitlist. The first open reimplementations appeared within about 24 hours, AINews counted six clones in two days on September 19, and the awesome-jev list now tracks more than a dozen. The largest has 19,301 GitHub stars, and it added over 5,000 of them in the last day alone.
Below are the five worth your time, ranked by GitHub stars pulled from the API on September 23, 2026. Two of them I ran on an Apple M3 Pro while writing this.
Summary
The open field reproduces Jev’s interface well and its accuracy only partly.
- Laya (19,301 stars, Apache-2.0): 421M on ModernBERT-large,
pip install laya, 32.8-39.5 ms per question on a T4. Its base checkpoints score near chance zero-shot, so it is a base to fine-tune, not a drop-in. - Kev (5,385 stars, Apache-2.0): LoRA adapters on Qwen3.5 at 0.8B, 4B and 9B, serving TypeSafe’s
/v1/systemonecontract so the official SDK works unchanged. Its new MLX backend answered in 47 ms on my Mac. - SemIf (4,023 stars, MIT) trains no model: it reads option logits off a frozen Qwen3.5-4B, measuring 1.023 s against 5.332 s for the same 21 decisions via generated JSON.
- NanoJev (2,086 stars, MIT) is a 0.6B model for real-time control loops, beating Jev 128/128 to 56/128 on ViZDoom Basic. Not a general classifier.
- jevlike (1,255 stars, MIT) ships a trainer, not a model: bring labelled options and train an option-attention head on a laptop.
- The caveat: on the independent 49-task classifier benchmark, Jev scores 0.966 macro accuracy against 0.704 for the best open entrant. These projects win on latency, price and control, not out-of-the-box accuracy.
Why a dozen clones appeared in a week
A System One model is narrow, and that is what made it easy to copy. You hand it a block of state plus questions with declared answer types - a Choice over up to 255 options, a Score on an ordered scale, a Noul yes/no probability - and it fills every answer in one parallel pass instead of decoding tokens. Nothing to parse, nothing to repair.
That interface is public in TypeSafe’s API docs; the model and training data are not. Reproducing the contract takes a weekend, because reading option logits off any open-weight model gives the same shape of answer. Reproducing the quality is a research problem, and a week is not long enough.
Comparison table
| Project | Stars | License | What it runs | Best for |
|---|---|---|---|---|
| Laya | 19,301 | Apache-2.0 | ModernBERT-large 421M, mmBERT-base 322M | CPU-friendly triage, 100+ languages |
| Kev | 5,385 | Apache-2.0 | Qwen3.5 0.8B / 4B / 9B + LoRA | Swapping out a hosted Jev call |
| SemIf | 4,023 | MIT | Frozen Qwen3.5-4B (no fine-tune) | Reusing a model you already host |
| NanoJev | 2,086 | MIT | Qwen3-0.6B + decision heads | Real-time control loops |
| jevlike | 1,255 | MIT | Byte encoder or any frozen HF encoder | Training on your own label set |
1. Laya: the one everybody starred

Laya is the flagship by a wide margin, and the only one of the five you install with a single pip install laya. Convai Innovations released it on September 18 under Apache 2.0, and its 421M parameters sit on a ModernBERT-large backbone with a decision head on top. A 322M multilingual checkpoint covers 100+ languages, and a Router picks between them by detecting the script in under a millisecond.
Published speed is 39.5 ms per question on a Tesla T4, or 7.2 ms with ten batched. I ran the README’s quickstart on an M3 Pro with no GPU acceleration and measured 66 ms median over 20 runs for all three questions in one pass:
import laya
agent = laya.load("convaiinnovations/laya")
state = {
"subject": "Duplicate charge on invoice #4411",
"body": "We were billed twice for March. Please refund the duplicate today or we will cancel our plan.",
}
questions = {
"department": {"type": "choice", "instructions": "Which department should handle this request?",
"criteria": {"billing": "invoices, payments, refunds",
"technical": "bugs, outages, system errors",
"sales": "pricing, new contracts"}},
"urgency": {"type": "score", "instructions": "How urgent is this request?",
"criteria": ["not urgent", "soon", "critical deadline or blocking issue"]},
"churn_risk": {"type": "noul", "instructions": "Does the user threaten to cancel or leave?"},
}
res = agent.predict(state, questions)["answers"]
print(res["department"]["choice"], res["department"]["confidence"]) # billing 0.827
print(res["urgency"]["score"], res["churn_risk"]["noul"]) # 1.49 0.741Version 0.3.7 cut checkpoint loading roughly tenfold, taking laya.load() on this machine from 28 seconds to about 4, and added laya-serve, a FastAPI server on the same POST /v1/systemone protocol as Jev.
Now the part the star count hides. Laya’s README is unusually candid: its base checkpoints score 0.362 and 0.342 on the typed-decisions benchmark against a 0.318 random baseline and a 0.461 majority-class baseline. The headline 0.766, which beats Jev’s published 0.727, comes from laya-typed-decisions, fine-tuned on that benchmark’s own training split. Treat Laya as a fast base you specialise on your own data, not a zero-shot replacement. It is also weak on large option sets: 0.425 against Jev’s 0.870 on Banking77’s 77 labels, because the options share a fixed 192 to 256 token budget and each label gets three or four tokens.
2. Kev: the drop-in with the honest evals

Kev is a family of rank-16 LoRA adapters plus a small pointer head on Qwen3.5 bases at 0.8B, 4B and 9B, from Jared Palmer. It serves TypeSafe’s own POST /v1/systemone contract, so the official typesafe-sdk works against it by changing a base URL. Its Hacker News thread pulled 438 points, much of it arguing about whether any of this beats a fine-tuned BERT. Standing it up and querying it looks like this, run here on the M3 Pro:
git clone https://github.com/jaredpalmer/kev.git && cd kev
uv sync --extra serve
KEV_DTYPE=bf16 uv run --extra serve python -m kev.serve --run jaredpalmer/kev-0.8b --port 8009curl -s localhost:8009/v1/systemone -H 'content-type: application/json' -d '{
"state": "Shoes arrived two weeks late and in the wrong size. Also I see two charges on my card.",
"model": "kev-latest",
"questions": {
"department": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"returns": "Exchanges, refunds, wrong or damaged items",
"shipping": "Delivery status, delays, lost packages",
"billing": "Charges, invoices, payment problems"}},
"escalate": {"type": "noul", "instructions": "Does this need urgent human attention?"},
"frustration":{"type": "score", "instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]}
}}'That returned returns at 0.39 probability with shipping at 0.38 and billing at 0.24, the right spread for a ticket that mentions all three. Kev shipped an MLX backend on September 22, and on a Mac it is a large difference: the same request went from 213 ms on the old PyTorch MPS path to 77 ms on a fresh state and 47 ms on a repeated one, after a 3.2 s first call.
Kev publishes the most careful evaluation of the group, including where it loses. Kev-9B scores 0.822 on held-out new sources against Jev’s 0.857, its confident-error rate is 4.0% against 3.7%, and the share of decisions you could automate at a 5% error budget is 0.45 to 0.57 against Jev’s 0.70. Knowledge questions are the big gap - MMLU 0.74 against 0.90 - and that is the base model, not the adapter.
3. SemIf: no new model, just read the logits

SemIf, formerly called OpenJev, does not pretend to have reproduced Jev’s model. It reproduces the pattern: take a frozen open-weight model you already host, declare your options, and read their probabilities off the logits without sampling a single answer token.
The case for it runs on one RTX 3090 with a frozen Qwen3.5-4B, one state and 21 binary criteria. Direct typed logits: 1.023 s, zero output tokens. An autoregressive JSON array of the same 21 answers: 5.332 s and 111 output tokens, 5.21x longer. Reusing one long state across many criteria pushes throughput from 2.33 decisions per second to 20.03.
On quality, the 4B baseline reaches 0.845 modal agreement with TypeSafe’s published results on a 102-row aligned subset against Jev’s 0.883, and a quantized Qwen3.8-27B bridge hits 0.958 balanced accuracy on 144 authored decisions. Fixtures, prompt hashes and raw timings are all committed. It wants a GPU that holds a 4B model in BF16, but there is a llama.cpp CPU backend, MLX and MPS for Apple Silicon, and a WebGPU demo in a browser tab.
4. NanoJev: 0.6B for real-time loops

NanoJev is the outlier, and the only project here that clearly beats Jev at something. It is a Qwen3-0.6B backbone with decision heads trained on four game environments, aimed at the control-loop case behind TypeSafe’s own Doom demo.
On the held-out test set, one shared checkpoint scores 128/128 successes on ViZDoom Basic against Jev’s 56/128, and 27/128 on the harder Predict Position task against Jev’s 11/128. It solves a 50x50 maze in 225 attempts where Jev needs 2,738. Jev still wins the maze test set 7/10 to 4/10, and they tie 8/8 on Snake.
Read that for what it is: a model trained on 18,760 decision questions from four games and evaluated on those same four games, with weights and dataset on Hugging Face under the unified-games-v1 tag. Strong evidence that a 0.6B purpose-trained model can outrun a frontier decision API inside a tight loop, and no evidence it will triage your tickets. The inference script expects CUDA, so there is no Apple Silicon path today.
5. jevlike: train your own from scratch

jevlike is not a model, it is a recipe. The architecture fits in a sentence: each option becomes a query vector, that query attends over the context tokens, a shared dot product scores each option-context pair, and a softmax across the options gives the distribution. The default encoder learns byte embeddings from scratch, or you bolt the head onto any frozen Hugging Face encoder.
Your data is one JSON object per line - {"context": "...", "options": [...], "label": 0} - and the loop is four commands on CPU, MPS or CUDA. Evaluation prints top-1 accuracy, calibration error, and a shuffled-context control that pairs each menu with the wrong context, the kind of baseline most projects skip.
It is the right pick when the options are yours: internal routing categories, a product taxonomy, a set of playbook actions. It is the wrong pick if you need something working this afternoon, and the author is upfront - the shipped chess checkpoint loses 48 of 50 games to Stockfish at level 0, and the default byte encoder truncates context to 192 bytes.
What the independent benchmark says
Every project above benchmarks itself against Jev on a suite it chose, and every one wins on its own suite. The useful number comes from elsewhere. The jabr classifier benchmark runs 49 tasks and 869 cases across compliance, triage, legal, DevOps, linguistics and safety:
| System | v2 macro accuracy (49 tasks) |
|---|---|
| TypeSafe Jev (hosted) | 0.966 |
| Von (395M, open) | 0.704 |
| GLiNER2 (~300M, open) | 0.698 |
| Laya (421M, open) | 0.583 |
That is a 26-point gap on out-of-domain tasks, with a distinct failure mode recorded for each: Von collapses to one mode on unfamiliar domains, GLiNER2 over-triggers on keywords, Laya compresses rating scales. Note that Von (546 stars, Apache-2.0, ModernBERT-Large) leads the open field despite sitting far below Laya on stars, a reminder that stars measure attention, not accuracy. In-domain, after a fine-tune on your own labels, the open models are competitive. Out of domain and zero-shot, they are not close yet.
Testing a local decision server from outside your machine
Kev, SemIf, Von and now Laya all expose an HTTP endpoint bound to your own machine, which is fine until something outside it has to call: a staging app, a webhook feeding the classifier, a teammate checking the routing, or a router sending small decisions to the cheap model. With Kev listening on port 8009, one command gives it a public HTTPS URL using Pinggy:
ssh -p 443 -R0:localhost:8009 free.pinggy.io
That matters during a migration, because the honest way to choose between these models is to shadow real traffic against both: point a copy of production webhooks at the tunnel, log what the open model would have decided, and compare it with Jev’s actual answer. One caution - both servers are open by default, so set KEV_API_KEY or LAYA_API_KEY to require a bearer token before you expose one.
Which one to pick
For the shortest path from a hosted Jev call to a self-hosted one, use Kev: the wire API matches and your code does not change. If you already run an open-weight model, use SemIf and read the logits off what you have. If you want something small and CPU-friendly with multilingual coverage and will fine-tune, use Laya. If your decisions live inside a tight control loop, NanoJev is the only project here with evidence at that latency. If your label set is unusual enough that no pretrained checkpoint helps, jevlike trains one on a laptop.
Three others are worth a bookmark: OpenJev runs DiffusionGemma 26B-A4B and is the only one that answers questions about images, openjev-sglang serves Qwen3.6-35B-A3B on SGLang for B200-class hardware, and Von leads the independent benchmark.
Conclusion
The open ecosystem reproduced Jev’s interface in about a day and has spent the week since trying to reproduce its accuracy. On latency, price and control it already wins outright: a 421M encoder on your own CPU costs nothing per call and answered in 66 ms on the laptop I tested it on. On zero-shot, out-of-domain quality it does not, and 0.966 against 0.704 is the number to remember when someone calls one of these a drop-in replacement.
So pick the one whose deployment story matches yours, fine-tune it on a few hundred of your own labelled examples, refit the confidence temperature, and measure it against what you run today. These projects are barely a week old and move fast enough that a figure goes stale in a day, so treat every published number, the vendor’s included, as a hypothesis rather than a result - the same caution that applies to self-hosting models generally.