A primitive is one of the small pieces a language gives you for free: if, while, ==, sort. Everything else is built out of them.
I keep coming back to one thought about AI. Loop engineering, where you put an agent on repeat until a goal is met, is a while loop with a model inside. And decision models like Jev are an if.
Jev came out in September from a startup called TypeSafe. You send it some text and a typed question, and it sends back a choice with probabilities. Within weeks OpenAI and AWS had their own versions. Its whole job is to be a branch in your code.
If while and if have models now, what about the rest of the language?
Most primitives already have a model
Take a support inbox with a few hundred emails a day. Some are complaints, some ask the same question as yesterday, a few are urgent. Each step of handling them is a primitive, and most steps already have a model.
| Primitive | Question in the inbox | Model that answers it |
|---|---|---|
if | Is this email a complaint? | decision models like Jev |
switch | Should a cheap or an expensive LLM write the reply? | routers like RouteLLM |
== | Is this the same question as one we already answered? | embedding similarity |
sort | Which ticket goes first? | rerankers |
cast | What's the order number in this message? | extraction models like NuExtract |
assert | Is the reply safe to send? | guard models like Llama Guard |
break | Is the agent writing the reply going in circles? | stop models like StopLoss, out this month |
| memoization | Can we reuse the answer we gave yesterday? | semantic caching |
Most of these models are small, and most are older than Jev. What Jev changed is how it's sold: as a general primitive, typed and cheap, instead of a tool for one job.
The functional version is even cleaner
A yes/no question to Jev is a predicate, so it can go straight into a filter:
filter(emails, decide("is this a complaint?"))
Sorting works the same way. A reranker scores each ticket against a question, and you sort by that score:
sortBy(tickets, rank("how urgent is this?"))
Jev's multiple choice does the job of pattern matching. And libraries like LOTUS already let you run map, filter and reduce with a model doing the work inside.
Equality has the biggest knock-on effect. In the inbox, "the same question" now means "close enough", decided by an embedding and a threshold. So the cache will sometimes hand back the answer to a slightly different question. In one study a few percent of cache hits were wrong. Dedup, joins and sorting inherit the same looseness.
What's still missing
The gaps in the inbox look like the next models to arrive:
try/catch: the reply fails to send, and a model reads the error and picks the recovery. Agents are trained to recover from errors, but nobody ships this as its own model yet.- An optional return, like
nullorOptional: some emails can't be classified. A model whose only job is to say "I don't know" would return nothing instead of a guess. - A result type, like Rust's
Result: the model returns either an answer or a clear error, so a wrong answer never slips through looking like a right one. - Higher-order functions: a model that returns a function, like writing the prompt or the code for the next step.
If decision models are any guide, these will arrive as small, typed models you call from ordinary code.
What changes when a primitive is a model
Ask decide whether an email is a complaint and it might say 0.83. Whether that counts as a complaint depends on your threshold. Set it at 0.7 and the email goes to the complaints queue. Set it at 0.9 and it doesn't. Every model-made primitive has a number like this. It's the new magic constant in your code.
Testing changes with it. One email proves nothing about the filter. You need a few hundred labeled emails, and you check calibration: when the model says 80%, is it right about 80% of the time? The test suite becomes a dataset.
Purity goes too. Send the same email twice and you can get a different branch, even with a fixed seed. That's fixable at the inference level, but it isn't the default.
Where I'd stop
Some decisions shouldn't be a model call at all. A risk assessment generated from a codebase only sees the code. You also need the developers, the business people and whoever owns security. The uncertainty is in the problem itself, so context and output matter as much as input.
Models will take over primitives where a messy question has a small set of answers. Where the answer depends on people, they stay out of the branch.
I can see decide becoming a keyword like any other, and while (!decide("is the task done?", state)) reading as normal as while (i < n). while and if got their models first. The open question is which keyword is next.
Sources
- IBM, What Is Loop Engineering?
- OpenRouter, What Is Jev? TypeSafe's Decision Model Explained for Developers (2026)
- Fortune, Jev, an AI for making quick decisions, has been a viral hit. But OpenAI is hot on its heels (2026)
- TechCrunch, Amazon releases its own Jev clone as decision models flood the web (2026)
- Isaac Ong et al., RouteLLM: Learning to Route LLMs with Preference Data (2024)
- Meta AI, Llama Guard: LLM-based Input-Output Safeguard for Human-AI Conversations (2023)
- NuMind, NuExtract: A Foundation Model for Structured Extraction (2024)
- Jiarong Liang et al., StopLoss: Teaching Agents to Predict Failure and Stop Early (2026)
- ZeroEntropy, Open-source alternatives to Cohere Rerank in 2026
- Sajal Regmi and Chetan Phakami Pun, GPT Semantic Cache (2024)
- LOTUS semantic operators, documentation
- Bingbing Wen et al., Know Your Limits: A Survey of Abstention in Large Language Models (2025)
- André F. Cruz, Moritz Hardt and Celestine Mendler-Dünner, Evaluating language models as risk scores (2024)
- Simon Willison, on Thinking Machines' "Defeating Nondeterminism in LLM Inference" (2025)