Jev is TypeSafe's judgment model. It doesn't write text; it answers yes/no, label and rating questions with calibrated probabilities. Use it for the functions that only decide something.
The jev backend is in thunc 0.1.3 and later. It needs no extra Python packages.
pip install --upgrade thunc
Create one in the TypeSafe console. You'll paste it into jev login in step 4, and nowhere else.
jev CLIOn a Mac with Apple Silicon, use TypeSafe's Homebrew tap. Homebrew asks you to trust a tap's formulas before it installs them; trusting only jev is enough.
brew tap model-clis/packages brew trust --formula model-clis/packages/jev brew install jev
On Linux, or a Mac without Homebrew, the install script checks the download's SHA-256 and puts jev in ~/.local/bin. For Windows and other options, see the jev README.
curl -fsSL https://raw.githubusercontent.com/model-clis/jev/main/scripts/install.sh | sh
jev login asks for your key, checks it with TypeSafe and stores it in ~/.model-clis/jev/credentials.json, readable only by you.
jev login
In CI or a container, set JEV_API_KEY instead. It takes precedence over the stored login. thunc never sends configure(api_key=...) to Jev, because that is usually the key of another backend.
One call costs a fraction of a cent. A probability near 1 means the login works.
jev noul "Is the sky blue?" --state "A clear summer day"
{"answers":{"q":{"noul":0.95,"type":"noul"}},"latency_ms":265,"model":"jev-1.13.0","ok":true,...}Pick Jev for one function with backend="jev", or for everything with thunc.configure(backend="jev") or THUNC_BACKEND=jev. thunc never picks it on its own.
from typing import Literal import thunc @thunc.function(backend="jev") def team(ticket: str) -> Literal["bug", "billing", "feature-request", "other"]: """Which team should handle this customer support ticket?""" ... team("I was charged twice this month.") # -> "billing"
Jev picks from answers you define, so only these return types work. Any other type raises ThuncError before a request is sent.
| Return type | Jev question | You get |
|---|---|---|
bool | yes/no (noul) | True when a yes is at least as likely as a no |
Literal["bug", "billing", ...] | choice, up to 255 labels | The label Jev chose |
Literal[1, 2, 3, 4, 5] | score, levels lowest first | The most likely level, as an int |
str, int, float, list, dict, dataclasses, T | None | none | ThuncError; use another backend |
For a rating, use Literal[1, 2, 3, 4, 5] instead of int with ensure=.
Jev can't write text, so most programs use it for the decisions and another backend for the writing. Each function picks its own backend. Here Jev filters every message, and Claude drafts a reply only for the ones that need one.
thunc.configure(backend="anthropic") # the default, for text @thunc.function(backend="jev") def needs_reply(message: str) -> bool: """Does this message ask a question or report a problem we should answer?""" ... @thunc.function def draft_reply(message: str) -> str: """Write a short first reply to this message. Never promise a refund.""" ... for message in inbox: if needs_reply(message): # ~0.3 s, fractions of a cent print(draft_reply(message))
jev-latest, which the cache and trace record.ThuncError at once. Asking again would get the same answer.From a clone of the repository, after step 4:
python3 -m examples.jev_hello # a yes/no, a label and a rating python3 -m examples.jev_inbox # 8 tickets, 24 calls, about 1 s python3 -m examples.jev_with_claude # Jev decides, Claude Code writes the replies
To run thunc's live tests on Jev: THUNC_BACKEND=jev pytest live_tests. Tests that need text answers are skipped.
| You see | What to do |
|---|---|
`jev` was not found on PATH. | Install the CLI (step 3). If you used the install script, add ~/.local/bin to your PATH. |
Refusing to load formula model-clis/packages/jev from untrusted tap | Run brew trust --formula model-clis/packages/jev, then brew install jev again. |
jev exited 1: Error: API rejected the credentials | Run jev login again. If JEV_API_KEY is set, it wins over the login, so check or unset it. |
The jev backend answers bool, Literal of strings ... | The function's return type isn't one Jev can answer. Use Literal[...], or give that function another backend. |
Unknown backend 'jev' | Your thunc is older than 0.1.3: pip install --upgrade thunc. |