Bro, just say true. Your code needs one boolean. Your LLM hands you an essay. Every dev who has wired a model into an if statement has felt this. Jev, from TypeSafe AI, is built for that exact moment: you send it some text and a few typed questions, and it sends back values your code can use directly — no essay, no parsing. We read TypeSafe's docs end to end and ran the idea through two examples side by side: 📧 a spam filter and 🧪 a vibe check for AI-written pull requests. Facts come from TypeSafe's docs and independent write-ups (linked at the end). The PR example is ours, and its numbers are made up to show the shape — we label them every time.
TL;DR
- Jev is TypeSafe's flagship model and, per its docs, the first "System One" model: it reads a state (your text) plus typed questions and returns typed answers with probabilities. It does not write replies, code or explanations.
- Three answer types: Noul (how likely is this true, 0–1), Choice (one option from your list) and Score (a level on your rubric). Mix them in one call.
- Choice and Score come with a confidence number. The docs' playbook: high → act, medium → confirm, low → hand it to a human. Scale the threshold with the risk.
- Pricing on the Models page: $0.042 per million input tokens, output tokens free. Text-only, English works best.
- Speed and cost multipliers on TypeSafe's homepage are vendor claims. A comparison run by the makers of the rival open CLM-8B found Jev had the higher success rate on two tasks but was slower on all four. LLMs for words, Jev for decisions. 🫡
The pain: you asked for a boolean, you got a TED talk
Here's the whole problem in one line of TypeScript. You want a boolean. An LLM gives you text. The compiler is not impressed:
declare function askLLM(prompt: string): Promise<string>;
const isSpam: boolean = await askLLM("Is this email spam? Answer true or false.");
// ❌ Type 'string' is not assignable to type 'boolean'.The yap
01YOU
"is this email spam? just say true or false"
One boolean. That's the whole ask.
02THE LLM
"Well… it depends on the context 🤓"
Oh no. Here it comes.
03STILL THE LLM
a 5-point essay on sender reputation
Plus a disclaimer. Plus a follow-up question.
04YOUR CODE
Type 'string' is not assignable to type 'boolean'
tsc said no.
05YOU, AGAIN
BRUH 💀
It's one bit, bro.
06WHAT YOU WANTED
true
One value. No yapping.
Dramatised, but you've seen it. Even when the model behaves, your code still has to parse text back into a value.
So you add "respond ONLY with JSON", write a parser, write a retry for when the parser fails, and pay for every output token of the model thinking out loud. TypeSafe's docs call it a mismatch: LLMs produce text for humans, so you coerce text generation into a decision, then parse it back. Tiny yes/no, chunky invoice — and your app asks it all day long.
What Jev actually is (it's not a chatbot)
TypeSafe calls Jev its flagship model and the first System One model. The name nods to Daniel Kahneman's Thinking, Fast and Slow: System 1 is fast and intuitive, System 2 is slow and deliberate. Jev is pitched at the fast, focused judgments — the gut-checks a knowledgeable person makes in a few seconds.
You send a state (the text to judge) and typed questions; Jev returns typed answers plus probabilities. No text generation, no parsing. It reads natural language like an LLM — it just never writes any. On its homepage, TypeSafe says it went the opposite way from RLHF-tuned chat models (which it blames for mode dropping, overconfidence and unreliability): a new architecture, a new sampler and a training algorithm called RLCD — Reinforcement Learning for Calibrated Decisions. Per MarkTechPost, Jev entered limited early access on September 15, 2026.
- 01
State
The text to judge: an email, a ticket, a diff. Strings, JSON or arrays of text.
- 02
Questions
Typed asks: Noul, Choice or Score, each with your own id.
- 03
Jev
Evaluates every question against the same state. Writes no text.
- 04
Typed answers + confidence
Values and probabilities, ready for an if statement.
- 05
Your code
Thresholds decide: act, confirm, or hand to a human.
Two lanes: spam vs vibe-coded PRs
Everything below runs in two lanes at once. The spam lane uses shapes and values recorded in TypeSafe's docs wherever they exist. The PR lane is our own example: a merge gate for pull requests your AI agent wrote at 2am. Same model, same three primitives, very different stakes.
📧 Spam lane
state = the email
State: the raw email — sender, subject, body — as one string.
Questions: is it spam? which team owns it? how urgent is it?
🧪 PR vibe-check lane
state = commit message + diff summary
State: the commit message plus a text summary of the diff. Jev is text-only, so no screenshots of your code.
Questions: does it touch payment code? ship it or not? how cursed is the commit message?
Question ids (is_spam, verdict…) are yours: TypeSafe's docs say they aren't sent to the model, so the instruction text carries the meaning.
The three primitives: Noul, Choice, Score
| Type | What you ask | What comes back |
|---|---|---|
| Noul | Is this statement true? | noul: a probability from 0 (no) to 1 (yes) |
| Choice | Which option from my list? | choice, probabilities (sum to 1), confidence |
| Score | Where does this sit on my rubric? | score (probability-weighted level), probabilities, confidence |
Noul: "is this true?" as a number
A Noul returns the probability that the answer is yes. You pick the threshold in code. TypeSafe's docs recorded jev-1.13.0's answers to one question across six customer messages — a nice look at how the number moves:
Messages shortened. "Are you a bot?" lands in the unsure middle — exactly where the docs suggest sending a person. Source: TypeSafe docs — Noul (jev-1.13.0).
View data table
| Category | Noul (0 = no, 1 = yes) |
|---|---|
| "Thanks, that fixed it!" | 0.02 |
| "How do I reset my password?" | 0.07 |
| "I need this sorted today…" | 0.26 |
| "Are you a bot?" | 0.40 |
| "…speak to someone about my invoice?" | 0.84 |
| "…just talk to a real person?" | 0.99 |
The docs' own gate is one line: wants_human = response.answers["is_human_escalation"].noul > 0.9. Their rules of thumb: raise the threshold when a false yes is expensive, lower it when missing a true yes is expensive, ask one yes/no per Noul, and phrase it so high = yes.
📧 Spam lane
is_spam · threshold high
Noul: "The email is spam."
A false yes buries a real invoice in the spam folder, so the bar is high: above 0.9 → spam, below 0.2 → inbox, the middle → a review folder. That three-way split mirrors the docs' routing example (0.8 / 0.2 / review).
spam = r.answers["is_spam"].noul
if spam > 0.9: move_to_spam()
elif spam > 0.2: send_to_review()
else: deliver()🧪 PR vibe-check lane
touches_payments · threshold low
Noul: "The diff changes payment code." Auth gets its own Noul — one yes/no per question.
Here missing a true yes is the expensive mistake, so the bar drops: anything above 0.5 gets a human. Illustrative result: 0.92. 💸
if r.answers["touches_payments"].noul > 0.5:
request_human_review()Thresholds are ours. The PR value is illustrative — we made it up to show the shape.
Choice: one option from your list (and nothing else)
A Choice picks from a fixed set of up to 255 options. You get the winner, a probability for every option (they sum to 1) and a confidence number: flat distribution → low, one clear peak → high. The docs suggest adding an "other" option so the model is never forced into a bad fit.
Off the menu = bounced
01THE TYPE
verdict ∈ { ship_it, needs_review, rewrite }
Written in your code, before the call.
02THE ASK
"is this PR good?"
State: a 40-file diff. Commit message: "fix stuff lol".
03LLM ENERGY
"honestly? kinda mid but the vibes are there 😌"
Cute. Not in the type.
04REJECTED
❌ not in the type
Jev can't return it. There's no string to return.
05JEV
needs_review
Plus a probability for every option and a confidence.
Illustrative. A Choice can only return one of the options you defined — the answer space is fixed before the model reads a word.
📧 Spam lane
team · doc-recorded
In TypeSafe's quick start, a support ticket ("my Stripe integration keeps failing… I'm losing sales") asked "Which team should handle this" came back technical: technical 0.85, billing 0.15, sales 0.0, confidence 0.78.
For a mail triage flow, swap the options for sales / support / other.
🧪 PR vibe-check lane
verdict · illustrative
Options: ship_it, needs_review, rewrite.
Illustrative result: needs_review 0.71, ship_it 0.22, rewrite 0.07. Not a recorded Jev output — numbers made up to show the shape.
Score: a level on your rubric
A Score takes 2–10 ordered levels and returns the probability-weighted average level, so it can land between levels. The docs' big lesson: describe situations, not degrees. On a misaligned-button bug report, numbers-only levels ("0", "1", "2") scored 0.55 with confidence 0.33; descriptive levels ("Cosmetic; no impact to functionality"…) scored 0.0 with confidence 1.0. Same report, way more certain.
📧 Spam lane
frustration · doc-recorded
Levels: "Calm, just stating facts" → "Frustrated but civil" → "Very angry, strong language".
In the quick start, the Stripe ticket scored 1.0 (frustrated but civil) with confidence 1.0. An urgency Score works the same way: describe what "urgent" looks like.
🧪 PR vibe-check lane
cursed-meter · illustrative
Levels: "Says what changed and why" → "Vague: updates, misc fixes" → "Cursed: fix stuff lol, asdf".
Illustrative result for "fix stuff lol": 2.0 — fully cursed. 💀
One state, many questions, no context rot
An LLM writes its answer one token at a time, and a long multi-part prompt can drift. Jev's docs describe something different: every question in a call is evaluated in parallel and in isolation against the same state, so adding questions barely changes response time and one question can't pollute another. Extra questions still cost input tokens, though.
State: the PR
Commit message + diff summary, sent once.
Noul · touches_payments
How likely is it that this diff changes payment code?
Choice · verdict
ship_it, needs_review or rewrite — with probabilities.
Score · cursed
Where the commit message sits on your rubric.
+ your next question
Added in the same call; the docs say response time barely moves.
Your code
Combines the answers and decides: merge queue or human review.
Confidence: act, confirm, or call a human
TypeSafe's Confidence page opens with a line we'd frame: "If an intelligent system, whether human or machine, cannot express honest uncertainty, the system cannot be trusted." Choice and Score return a confidence between 0 and 1, derived from the probability distribution. Noul skips it — with two outcomes, the probability already says it all.
01Is confidence low?
YES → Don't act — route to a human, ask for clarification or fall backNO ↓
02Is it high, and is the action cheap to undo?
YES → Act automaticallyNO ↓
Proceed with caution: confirm, flag or gather more info (risky actions need a higher bar)
The key rule: thresholds scale with risk. The docs' banking example sends anything under 0.5 confidence to a human, lets a low-stakes balance check go straight through, and still asks for confirmation on a transfer unless confidence is above 0.9. Here's that logic as a sketch — the action names are from the docs, the layout is ours:
intent = response.answers["intent"]
if intent.confidence < 0.5:
route_to_human()
elif intent.choice == "check_balance": # low stakes
show_balance()
elif intent.choice == "approve_transfer": # money moves
if intent.confidence > 0.9:
confirm_then_execute()
else:
ask_user_to_confirm()📧 Spam lane
cheap to undo
A wrong spam call is annoying, not fatal: the email is still in a folder.
So a high Noul auto-files it, the middle goes to review, and low-confidence team routing (the docs use under 0.3) goes to manual triage.
🧪 PR vibe-check lane
expensive to undo
A bad merge into payments is the opposite of cheap.
Even a confident ship_it doesn't auto-merge here: it only skips the extra human pass, and CI still runs. A payments diff always gets a person. No exceptions, no vibes.
The docs' advice: start conservative and tune thresholds on your own data.
Atomic questions, composed in code
Jev is built for gut-checks, not essays. So instead of asking "rate this startup pitch", the docs say to ask market size, technical feasibility and differentiation as separate questions and combine them with your own formula. Their composite-scoring example: priority = 0.6 × severity + 0.3 × frustration + 0.1 × report quality (each normalised by its top level), which gave 0.664 on their sample. Want different priorities? Change a coefficient in code instead of rewriting a prompt.
📧 Spam lane
junk risk
Three atomic questions: is_spam (Noul), has_phishing_link (Noul), urgency (Score, 0–2). Fake urgency plus a sketchy link is a classic scam combo.
risk = (0.5 * is_spam
+ 0.4 * has_phishing_link
+ 0.1 * urgency / 2)🧪 PR vibe-check lane
merge risk
touches_payments (Noul), has_tests (Noul), cursed (Score, 0–2).
Illustrative: 0.6 × 0.92 + 0.3 × (1 − 0.10) + 0.1 × 2/2 ≈ 0.92 → human review.
risk = (0.6 * touches_payments
+ 0.3 * (1 - has_tests)
+ 0.1 * cursed / 2)Weights and PR values are ours and illustrative. Only the pattern (weighted, normalised atomic scores) comes from TypeSafe's docs.
PR vibe check (illustrative)
01NEW PR DROPS
40 files, commit message: "fix stuff lol"
Vibe-coded at 2am. Merged by nobody yet.
02NOUL · TOUCHES_PAYMENTS
0.92 💸
Yeah, it's in the checkout code.
03CHOICE · VERDICT
needs_review
Not ship_it. Not today.
04SCORE · CURSED-METER
"fix stuff lol" → cursed 💀
Top of the rubric.
05THE GATE
human review 🛑
touches_payments > 0.5 → a person looks before merge.
Illustrative values — we made these numbers up to show the shape. Run your own diffs in TypeSafe's Playground.
LLMs for words, Jev for decisions
Jev doesn't replace your LLM. It replaces the part where you were forcing an LLM to be an if statement. TypeSafe's use-case map lists the shapes it's for — classification, detection (spam, fraud, urgency, jailbreaks, sensitive data), scoring, routing, verification — and use cases like semantic code linting, LLM guardrails and model routing.
01Reply to a customer?
YES → LLM — the output is wordsNO ↓
02Is this email spam?
YES → Jev — a Noul and a thresholdNO ↓
03Summarise a document?
YES → LLM — needs generated textNO ↓
04Route a ticket to a team?
YES → Jev — a Choice from a fixed listNO ↓
05Is this PR risky?
YES → Jev — atomic checks composed in codeNO ↓
06Write the fix?
YES → LLM / coding agent — Jev doesn't write codeNO ↓
Split it into yes/no, pick-one or rubric questions for Jev — or keep it on an LLM if it needs extended reasoning
Fun detail: TypeSafe's use-case map literally lists Harness Engineering — model routing, semantic context retrieval, LLM error detection and guardrails, reasoning-trace classification. That's the checks-around-the-agent layer we cover in what harness engineering is. A PR vibe check is a harness gate with a typed brain.
Receipts and a reality check
- Price
- $0.042 / MtokInput tokens ($42 per billion). Output tokens are free.
- Context
- 64k tokensPer request; 32k for the state plus the longest question.
- Rate limits
- 1,200 req/minAnd 250,000 tokens/s — TypeSafe says limits adjust dynamically.
Model ID jev-1.13.0; the aliases jev-latest and jev-preview both point to it today. Text only (strings, JSON, arrays of text) — pre-process images or audio to text. English works best; other languages are handled, but not equally well. Pin the versioned ID if you tuned thresholds. Source: TypeSafe docs — Models.
Also on the Models page: no per-customer fine-tuning (same RLCD-trained weights for every account), no training on customer requests or responses, and zero data retention for enterprise. You customise Jev through the state, your instructions and criteria, and how you split questions.
- Headline
- 193.6x / 444.6x"Faster" / "cheaper", based on workflows for System One tasks, per TypeSafe.
- Homepage demo
- 0.114 s vs 8.566 s$0.000081 for TypeSafe vs $0.013880 for LLMs on the demo shown.
- Input price
- 238x lowerTypeSafe's comparison with Claude Fable 5.1's input price.
TypeSafe's own claims. By our arithmetic the demo alone is roughly 75x faster and 171x cheaper, so the headline figures describe TypeSafe's wider workflow comparison. The use-case map adds "real-time speeds (150ms)" and "100x cheaper". Source: typesafe.ai.
For an outside view: Contrastive-LM's open CLM-8B is also a System One model, and its authors benchmarked it against Jev zero-shot, as reported by MarkTechPost and Superpower Daily. In short, Jev had the higher success rate on two of the four tasks, while CLM-8B was faster on all four. The numbers, task by task, are in our full CLM-8B vs Jev benchmarks.
One more receipt: as a best-of-N verifier on held-out subsets (compared against fine-tuned CLM heads), Jev scored below simply taking the first attempt — 71.1% vs a 73.7% pass@1 on DeepSWE, 83.1% vs 84.0% on Terminal-Bench 2.1. Small subsets, not leaderboard runs, but the lesson stands: benchmark your own decisions before trusting anyone's multiplier. Including ours. 👀
Vibe it: set it up in five minutes
The Python SDK needs Python 3.10+ and reads your key from TYPESAFE_API_KEY:
pip install typesafe-sdkTypeSafe also ships an agent skill so your coding agent knows how to write Jev calls. In Claude Code:
claude plugin marketplace add typesafe-ai/skills
claude plugin install typesafe@typesafe-aiAnd the quick start from TypeSafe's docs, verbatim — one call, all three primitives:
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
client = TypeSafeClient()
ticket = "Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. I'm losing sales. Please help ASAP."
response = client.system_one(
state=ticket,
questions={
"department": Choice(
instructions="Which team should handle this",
criteria={
"billing": "Payment or subscription issues",
"technical": "Bugs or integration problems",
"sales": "Pricing or account questions",
},
),
"frustration": Score(
instructions="How frustrated the customer appears",
criteria=[
"Calm, just stating facts",
"Frustrated but civil",
"Very angry, strong language",
],
),
"is_urgent": Noul(
instructions="The message conveys urgency or time-sensitivity",
),
},
)
print(response.answers["department"].choice) # "technical"
print(response.answers["frustration"].score) # 1.0
print(response.answers["is_urgent"].noul) # 1.0The docs' recorded response for that call: technical with confidence 0.78, frustration 1.0, is_urgent 1.0 — and a usage line of 392 input tokens, 65 output. Under the hood it's a single POST to https://api.typesafe.ai/v1/systemone with a bearer key. Here are both lanes as full calls (our code, using the SDK's shapes; no outputs claimed):
📧 Spam lane
our sketch
One call, two questions, then plain Python decides.
r = client.system_one(
state=email_text,
questions={
"is_spam": Noul(instructions="The email is spam"),
"team": Choice(
instructions="Which team should handle this email",
criteria={
"sales": "Pricing, quotes or buying questions",
"support": "Help with an existing account",
"other": "None of the above",
},
),
},
)
spam = r.answers["is_spam"].noul
if spam > 0.9:
move_to_spam()
elif spam > 0.2:
send_to_review()
else:
route_to(r.answers["team"].choice)🧪 PR vibe-check lane
our sketch · illustrative
Run it in CI on every PR. A person only gets pinged when the gate trips.
r = client.system_one(
state=f"{commit_message}\n\n{diff_summary}",
questions={
"touches_payments": Noul(
instructions="The diff changes payment code",
),
"verdict": Choice(
instructions="What should happen to this pull request",
criteria={
"ship_it": "Small, clear, low-risk change",
"needs_review": "Plausible, but a person should check it",
"rewrite": "Unclear or unsafe; start over",
},
),
"cursed": Score(
instructions="How useful the commit message is",
criteria=[
"Says what changed and why",
"Vague: updates, misc fixes",
"Cursed: fix stuff lol, asdf",
],
),
},
)
a = r.answers
if (a["touches_payments"].noul > 0.5
or a["verdict"].choice != "ship_it"
or a["verdict"].confidence < 0.9):
request_human_review()Helper functions (move_to_spam, request_human_review…) are placeholders for your own code. Thresholds are ours — tune them on your own data.
When NOT to use Jev
- Anything whose output is words: customer replies, summaries, explanations. Jev doesn't generate text. Use an LLM.
- Writing or fixing code. Your coding agent writes the code; Jev can judge it.
- Images or audio. Jev is text-only — convert to text first or pick a different tool.
- Non-English-heavy workloads without testing. The docs say other languages, including CJK, are handled, but not as well as English.
- Questions that need extended reasoning. Decompose them into atomic gut-checks — or, if they can't be split, that's a job for an LLM. Not in the type, bro.
The one-line version: LLMs for words, Jev for decisions, your code for the rules in between. No yapping. 🫡
