Skip to content
MrJev

AgentJev

A 0.6B decision model on a Qwen3 backbone with weights on Hugging Face: state in, a distribution over your options out, nothing decoded.

View on GitHub →

Hands-on review

An open 0.6B decision model with a strict request contract, a loopback-only server and a checkpoint hash in /health — and one unit test that cannot import.

Good for

  • Typed decisions on a machine with no GPU and no account
  • A service that states its checkpoint hash and refuses to truncate your input
  • Reading a contract that keeps transport identifiers out of the model input

Watch out for

  • The repository's only unit test imports a package that is not in the tree
  • The practical-test script prints a latency claim it did not measure
  • The checkpoint is loaded with `weights_only=False`, which is not needed

Tested Sep 24, 2026 at a965ca8ff06c · python:3.12-slim in Docker on 4 CPU cores, no GPU, --network none with both checkpoints from a local cache: its HTTP service, its own client, its practical-test script and its unit test

How we reviewed this: on four CPU cores in python:3.12-slim with no GPU anywhere, --network none, with the published weights and the Qwen3-0.6B backbone from a local cache. We ran its HTTP service, its own client, the practical-test script it ships, and its unit test; we planted canaries in the request to see what reaches the model. This is an open model, so everything below is our own run of their model — no Jev calls, and no measurement of Jev.

What it does

A 0.6B decision head on a Qwen3 backbone: a state and typed questions go in, a probability per option comes back, and nothing is decoded. Three primitives — boolean, choice over 2 to 255 candidates, and score over 2 to 10 ordered levels. The weights are on Hugging Face, the code is here, and the two are deliberately separate: the README has you wrap the published model.safetensors into the .pt the server wants, in four lines.

Setup

It is a research tree, and the defaults show it — --checkpoint /root/agentjev/runs/phase4/final.pt, --model-path /root/agentjev/models/Qwen3-0.6B-Base, --device cuda:0. The README’s own invocation overrides all three, and --device cpu is enough to run the whole thing on a laptop:

{"event": "ready", "port": 8149, "model": "AgentJev-0.6B",
 "checkpoint_sha256": "f91b276b81f8c865e056eb9cb1a8c6ada4d8baa660aee60a4402bdf0fda6ceda",
 "max_choice_candidates": 255, "output_token_decoding": false,
 "temperatures": {"boolean": 1.0718, "choice": 1.0353, "score": 1.0718},
 "probability_semantics": "model distribution; domain calibration is not guaranteed"}

Two things in that line are rarer than they should be. The service hashes the checkpoint it loaded and publishes the digest, so you can tell two servers apart. And it says in its own health output that the probabilities are a model distribution rather than a calibrated one — while still shipping temperatures.json, which carries the fitted temperature, the number of calibration cases and the soft cross-entropy behind each primitive.

Using it

All three primitives answered on CPU through its own client: a boolean on whether a suite passed, a choice over four next actions, a score over three risk levels. Each returns the full distribution, and choice also returns the margin over the runner-up. Its own run_practical_test.py completes two longer scenarios end to end against the same server.

The contract is the strongest part, and it is strict in the right direction. Every malformed request we sent came back 400 with a sentence naming the rule:

300 options              400 choice requires 2..255 candidates
one option               400 choice requires 2..255 candidates
duplicate question id    400 question IDs must be unique nonempty strings within a state
two identical options    400 candidate descriptions must be distinct
type: "mystery"          400 type must be boolean, choice or score
empty state              400 state must be nonempty text, an object or an array
NaN in the JSON          400 nonfinite JSON
3,016 tokens of state    400 needs 3016 tokens; limit 2048. Shorten the input; nothing was truncated.

That last one is the one to notice: over the limit it refuses, and says it refused, instead of quietly cutting the state in half.

Permissions and data

Nothing leaves the machine. There is no API key, no outbound call, and the service binds loopback only — which we checked rather than read. Running it in a container with the port published, a request from the host is reset while the container’s own loopback request returns 200.

The contract’s claim that “transport IDs never enter semantic model input” also holds. We put distinct canaries in the question id, the option keys, the state, the question text and an option description, then decoded the token paths the model actually sees: the state, the question and the description are there; the question id and the option keys are not.

Maintenance

MIT, weights on Hugging Face, active this week. There are no CI workflows, and the testing situation is the weak spot. The repository’s one unit test cannot be collected on a fresh clone:

jev_service/candidate_v8.py:7: from typed_decisions.agent_completion_v8_run02.canonical import canonicalize
E   ModuleNotFoundError: No module named 'typed_decisions.agent_completion_v8_run02'

Only agent_completion_v9 is in the tree; the v8 package the import names is not, and typed_decisions/agent_completion_v9/prepare_mbpp.py imports it too. Someone else reported this the day before we ran it, at the same commit, so it is known and open rather than new. Two other scripts still hardcode C:\Users\ASUS\agentjev_staging\typed_decisions.

The scripts that do run have a smaller problem of the same kind. run_practical_test.py prints its own per-decision timings and then closes with a hardcoded line claiming every decision took 40–80 ms. On our four cores those same decisions took 4.7 to 5.3 seconds, and the summary line would have said 40–80 ms either way, because it is a print rather than a measurement.

One more, for anyone sharing checkpoints: engine.py calls torch.load(..., weights_only=False), which executes pickle from the file. The published checkpoint does not need it — we loaded it with weights_only=True and got all 343 tensors — so the safe flag costs nothing here.

Verdict

The best-behaved open decision service we have run on a laptop: it refuses bad input in a sentence you can act on, never truncates silently, keeps your option keys out of the model, and tells you which checkpoint answered. Use it when you want typed decisions with no account and no GPU, and pin the checkpoint hash it reports.

Treat the repository as the research tree it is: one import short of a working test suite, and one print away from a latency claim it did not make. For the same shape with a server that already speaks the TypeSafe request format, see SemIf and JevForge; for the multilingual end, Laya.

See how it compares with other tools in Best Jev tools, tested hands-on.

Review updated Sep 24, 2026. Numbers quoted from the project are its author's own; we don't publish our own measurements of Jev.

More in Open Models & Reproductions

Laya

★ 25k▲ 10k

NandhaKishorM/laya

Non-autoregressive decision engine over 100+ languages: three checkpoints and a router that detects the script and dispatches per request. Its benchmarks end with a limits section naming the datasets it does not generalise to and the headline figure that came from a training split.

PythonReviewed

kev

★ 7.1k▲ 6.7k

jaredpalmer/kev

Jev-style decision models from 0.5B to 8B, built as LoRA adapters on Qwen and served behind a Jev-compatible /v1/systemone API.

PythonReviewed

SemIf

★ 4.3k▲ 2.5k

TheoLeeCJ/SemIf-OpenJev

Jev-style decisions from a frozen 4B model on a single RTX 3090, with a browser demo. Formerly OpenJev.

PythonReviewed

Get new Jev projects every week

New Jev releases, pricing changes, and the best new projects, once a week. No spam; unsubscribe anytime.

Powered by Buttondown. See our privacy policy.