How we reviewed this: in python:3.12-slim on four CPU cores with no GPU. We ran its suite the way its README installs it, probed and drove a local embedding recipe with a real 0.6B model, then pointed the unmodified official typesafe-sdk at a jevify serve process. We made no Jev calls; jevify owns no weights and this is our own run of a model we supplied.
What it does
You bring a model — behind an OpenAI-compatible endpoint, or in-process — and jevify asks it typed questions about a state, reading the answer off the model’s own distribution rather than parsing generated text. The result comes back in the shape of TypeSafe’s response, so code written for Jev works against it. Three pieces carry the design: a recipe says how a given model is asked, a probe establishes what that deployment can actually do, and a scorecard records how it did, with the command and hashes that produced each number.
Setup
pip install -e . and one recipe file; the repository ships seven, from llama.cpp and vLLM endpoints to in-process encoders. We used recipes/qwen3-embedding-0.6b.local.yaml, which pulls Qwen3-Embedding-0.6B and runs it in-process on CPU.
jevify probe is the step worth keeping. It reports what it found rather than what the recipe hoped for:
notes: "embedding dimension 1024", "transport local",
"choice questions only; cosine similarity, labeled similarity"
token_ids_verified: false prefill_honored: null cache: null fanout: null
Using it
A choice question against that recipe answers as you would expect, and the envelope around the answer is the interesting part:
"dept": {"type": "choice", "choice": "billing", "confidence": 0.21,
"probabilities": {"billing": 0.473, "support": 0.377, "sales": 0.150},
"x_jevify": {"semantics": "similarity", "rung": "native", "degraded": false,
"off_menu_mass": null, "permutation": "none", "calls": 2}}
semantics: "similarity" is jevify telling you that this probability came from cosine distance between embeddings, not from a model’s own answer distribution — so it is a ranking, not a calibrated belief. rung names which readout it used, degraded says whether it had to fall back, and calls counts the requests it made. Every response also carries recipe_hash and a state_id, so an answer can be traced to the exact configuration that produced it.
It refuses rather than degrades. Ask that same embedding recipe for a noul or a score and it stops:
jevify: the embedding kind answers choice questions only;
a noul or score question needs a readout-capable or rerank recipe
That is the behaviour we keep wishing for in this category. A wrapper that wants to look Jev-shaped could have returned a number here; this one names the rung its backend does not have.
The compatibility claim holds, and we checked it ourselves rather than through their fixtures. jevify serve with the local recipe, then the unmodified typesafe-sdk 0.7.1 pointed at it with a base URL:
official SDK -> model='qwen3-embedding-0.6b'
answers={'dept': ChoiceAnswer(type='choice', choice='billing', confidence=0.571,
probabilities={'billing': 0.714, 'support': 0.145, 'sales': 0.141})}
The SDK parsed it into its own ChoiceAnswer type without a patch. The project’s own acceptance test does the same thing against a scripted backend and passes once the SDK is installed; it skips cleanly when it is not, which is the right guard rather than a hidden failure.
Permissions and data
Whatever you send goes to the backend your recipe names, and nowhere else — with a local recipe, nothing leaves the machine. jevify serve binds 127.0.0.1 by default and prints its own security posture at startup:
{"serving": "qwen3-embedding-0.6b", "recipe_hash": "1e80584…", "url": "http://127.0.0.1:8130/v1/systemone", "api_key_checked": false}
api_key_checked is false until you set the environment variable named by --api-key-env. Saying so in the startup line is better than the silence most local servers keep, but it is still an open endpoint by default: if you move it off loopback, set the key in the same change.
One quirk: on the embedding path usage reports input_tokens: 0, output_tokens: 1, because there are no tokens to count. Do not wire that field to a cost estimate.
Maintenance
MIT, published on PyPI, Python 3.12+, with CI. The suite is 133 tests that run offline in a container with no GPU, plus marked sets for the pieces that need more: encoder for the in-process models, sdk for the official-SDK round trip, live for a real backend named in an environment variable. All the ones we could run, passed.
Verdict
The most careful of the “make your model answer like Jev” wrappers we have run, and the care is in the refusals: a probe that reports what your deployment cannot do, an error instead of a fabricated noul, and a semantics field that tells the caller when a probability is a similarity score. Use it when you already run a model and want typed answers from it without inventing a protocol.
If you want the model as well as the protocol, see JevForge for training your own and JevK5 for published weights; for the same idea against an OpenAI-compatible endpoint with a different readout, jevper.
See how it compares with other tools in Best Jev tools, tested hands-on.
Review updated Sep 25, 2026. Numbers quoted from the project are its author's own; we don't publish our own measurements of Jev.