Decision models.
A decision model replaces the if inside your agent, not the agent — and teams that miss the difference hand it arithmetic, dates and whole transcripts, then ship branches that are wrong without ever raising an error. Let code compute; send the model only the judgment, and treat its answer as a probability distribution you must threshold, not a verdict. Jev, from TypeSafe AI, and its fast followers sell exactly that judgment, cheaply.
Step 1Four primitives, and three of them are control flow.
TypeSafe calls Jev a "System One" model: it does not write text, it answers typed questions about a piece of content. A request carries a state (the content) and a map of questions, each keyed by a name you choose and each one of four types. On Hacker News, an account identifying itself as the company's CEO mapped three of them to the statement they stand in for — the most useful way to hold the product in your head:
noulis anif. Short for Bernoulli: one condition, and the answer is the probability it holds.choiceis amatch. You supply the options and a description for each, up to 255 of them; you get a probability per option.scoreis a sort key. You supply an ordered ladder of 2 to 10 level descriptions; you get a distribution over levels and a probability-weighted position on the ladder.boxis the outlier. Added in Jev 1.14 (preview only, as of October 2026), it locates one region in an image. TypeSafe itself calls it its first type "not purely meant for smart-if statements".
Notice what the model never chooses: the labels. Every option, every level, every condition is text you write at call time. No training run, no fixed taxonomy: changing a branch is editing a string. Here is the documented quick-start, trimmed to two questions:
# POST https://api.typesafe.ai/v1/systemone (Jev quick start, trimmed to two questions) { "state": "Our API integration started returning 500 errors on every request about 20 minutes ago, and we can't process any customer orders until this is fixed.", "model": "jev-latest", "questions": { "department": { "type": "choice", "instructions": "Which team should handle this", "criteria": { "billing": "Payment or subscription issues", "technical": "Bugs or integration problems", "sales": "Pricing or account questions" } }, "is_urgent": { "type": "noul", "instructions": "The message conveys urgency or time-sensitivity" } } } # response (docs example; values can change between Jev releases) "department": { "type": "choice", "choice": "technical", "confidence": 1.0, "probabilities": { "technical": 1.0, "billing": 0.0, "sales": 0.0 } }, "is_urgent": { "type": "noul", "noul": 0.99 }
Read the response as code would: department is the arm of a match, is_urgent is the input to an if. The model filled in two conditions. What happens next is still yours.
Step 2The type safety is not new. The distribution is.
The headline claim at launch was that Jev cannot produce a malformed answer, and that is true: the answer is always one of your labels or a number in range. But TypeSafe's own launch post labels its 0% type-error rate "not empirical" — it is guaranteed by the schema, which is exactly the guarantee constrained decoding already gives any LLM with structured outputs. The objection that ran through the launch thread is the right one: it cannot emit an invalid type, but it can still emit a completely wrong valid value.
What a constrained LLM does not hand you is a first-class distribution over your labels, returned on every call. That is the actual product: a branch can now have three outcomes — act, ask, escalate — chosen by how the probability mass is spread. Two documented details matter:
confidenceis not a second opinion. It is a deterministic function ofprobabilities; for a choice it is(n·p_max − 1)/(n − 1), so it only sees the top option. Thresholding both is thresholding one thing twice.noulreturns no confidence field at all. The probability is the whole answer; a value near 0.5 is the model saying it is unsure, and the docs suggestabs(p − 0.5) × 2if you want a margin.
"Calibrated" is the vendor's claim, and as of October 2026 no in-distribution calibration numbers had been published. The only published figures come from an off-label academic test, Jev grading another model's answers: ECE 0.133, and AUROC 0.666 against 0.868 for a trained calibrator. So the thresholds are your job, set on your own labelled data — the method is in uncertainty & calibration, and the operating procedure in decision-model thresholds.
The failure mode is silent by construction. A wrong answer from a decision model is a valid label with a plausible probability, so your agent takes the wrong branch and logs nothing unusual. No parse error, no exception. Unless you log the distribution beside the branch and sample it against human labels, you will not find out.
Step 3Its weak spots are exactly where code is strong.
TypeSafe's "jaggedness" page for Jev 1.13 (last reviewed 2 October 2026) lists where it fails. Almost every entry is something an ordinary program does perfectly.
- Counting and arithmetic. "Jev is not a calculator" — it "recognizes the shape of an answer rather than tallying". Count, sum and compare in code.
- Dates and times. It "reads dates as text, not as ordered quantities". Parse the dates, compare them in code, and ask the model only about what the comparison means.
- Indirection. Double negatives and property-of-a-property questions. Resolve the lookup in code and point the question at the one field that matters.
- Large, noisy state. Accuracy falls as irrelevant detail piles up. Filter first; send only what the question needs.
- Option order. Choice "leans toward the option that comes first". Shuffle the options in code and check the answer holds.
- Adversarial state. State is data, and the model does not treat it as hostile. HiddenLayer showed an injected on-page ad hijacking a browser agent's checkout decision; a separate study found injected text shifts the probabilities but rarely flips the top answer (attack success rose from 1.8% to 3.5% under adaptive attack). Either way, this is prompt injection, and the defence lives outside the model.
That gives the design rule: code computes, the model judges. Before a question goes out, every count, date comparison, lookup and filter that can be done deterministically has been done, and what remains is a judgment no rule captures well — is this message frustrated, is this passage useful, is this command risky. A question that still contains arithmetic is a bug in the caller.
Step 4Where it sits in an agent, and who else now sells one.
Because it replaces a branch, a decision model belongs at the branch points of an agent, never in the loop that plans and writes:
- Routing. Which handler, which queue, which model — the static switch from model routing with a probability attached, so low-margin cases can go to the expensive path.
- Tool-call guards. LangChain's experimental
AutoModeMiddlewareuses Jev to flag risky pending tool calls (such asbash) and block them before they execute. - Context filtering. GPT-Researcher v3.7.0 (26 September 2026) scores every scraped passage for usefulness to the question and keeps only the ones that help — and falls back to BM25 keyword ranking when there is no key or a Jev call fails. That fallback is the pattern to copy.
- Trace checks. Yes/no questions over a step of an agent's trace: did the tool result answer the request, did the reply follow the policy. Use them to filter for human review, not as graders — the off-label result above is exactly this use.
Jev launched on 15 September 2026, and within three weeks it was a category. Cloudflare released Clef (1 October) with open weights, describing it as "fully Jev-API compatible"; Perplexity published pplx-decider-v1-27b, also open-weight; OpenAI's Decisions API, with predicate, choice and score types, entered public beta on 6 October. The interesting split is the request shape: Jev's state plus keyed questions is becoming a de facto standard others copy, while OpenAI chose an array of named questions and its own vocabulary. A thin adapter around the shape keeps switching vendor a config change. The head-to-head comparison puts the four side by side.
Pick one existing if in your agent that today calls an LLM and parses "yes" or "no". Move every count, date and lookup it depends on into code, ask the model only the remaining judgment, and log the full distribution next to the branch taken. Label a few hundred real cases, set act/ask/escalate thresholds from them, and pin the versioned model ID rather than jev-latest, because the alias moves to each new release on the vendor's schedule and your thresholds do not move with it.
Related: observability for logging the decision, guardrails for where tool-call guards fit, and small & local models for the fine-tuned alternative.