Direct answer: JevJevA small AI model from TypeSafe that decides what happens to each chat: reply, skip, flag for the team, or remove from follow-up. Jev writes no replies.How Jev picks the chats to answer 1.14 is the version of the TypeSafe Jev decision model that was released on 14 October 2026. On OpenRouter, its ID is typesafe/jev-1.14, it costs USD 0.042 per 1 million input tokens, and output tokens are free. The model accepts provider.zdr: true, but openai/gpt-6-luna-decisions refuses the same request with code 404.
Main condition: you use a decision model for closed questions, for example yes or no, or 1 option from your list. Limit: in our public test, Jev 1.14 was not more accurate than Jev 1.13 or GPT-6 Luna Decisions. All 3 were correct on 40 of 40 messages, and the differences are in thresholds, price, and data rules.
We read the OpenRouter model pages, the TypeSafe documentation, and the Jev 1.14 release post on 2 November 2026. On the same date, we sent 40 messages that we wrote for this article to 3 models, 2 rounds per model. This test uses no customer data.
The problem: your old threshold does not move with you
A change of decision model looks like a change of 1 string, but the threshold in your code was set for the old model. Jev returns a probability, and your code compares it with a fixed number, for example 0.8. The basics are in our explanation of what Jev is.
A different model spreads its scores in a different way. One model gives 0.99 for a clear message, and another model gives 0.76 for the same message. A 0.8 threshold that is safe on the first model misses that message on the second model.
TypeSafe writes this rule on its Models page: if you tune thresholds on 1 version, send that version ID, not the alias. The jev-latest alias now points to Jev 1.14, so code that uses the alias already moved to a new model with no code change.
What changed in Jev 1.14
TypeSafe calls Jev 1.14 a set of small improvements across the board, and it expects the largest gain in languages other than English. Source: the Jev 1.14 release post, 14 October 2026.
Small improvements with a language focus
The release post gives no quality numbers for Jev 1.14 against Jev 1.13. TypeSafe only writes that most things became a little better. The Models page also writes that English is the primary training language, and that you must test other languages on your own content.
Three "danger zone" features
TypeSafe opens 3 experimental features through APIAPIThe official door 2 systems use to exchange data, without anybody copying it by hand.Open the glossary headers, and it writes that it does not yet vouch for them in production:
- Images with the header
TypeSafe-Danger-Zone-Images: true. This feature also works on Jev 1.13. - The
boxtype, which returns 1 bounding box on an image. This type is only on Jev 1.14. - Long context with the header
TypeSafe-Danger-Zone-Long-Context: true. The limit goes from 64k per request to 262k tokens, but TypeSafe writes that this mode is slower and less accurate.
Alias and version schedule
Jev 1.14 was released first under jev-preview, and then TypeSafe moved jev-latest to this version. TypeSafe plans to give 60 days of warning before Jev 1.13 stops, and 30 days for Jev 1.14.
Jev 1.14, Jev 1.13, and GPT-6 Luna Decisions
Jev 1.14 and Jev 1.13 have the same price on OpenRouter, but GPT-6 Luna Decisions costs more and has no ZDR endpoint. We read the table data from the OpenRouter Models API and each model page on 2 November 2026.
| Item | Jev 1.14 | Jev 1.13 | GPT-6 Luna Decisions |
|---|---|---|---|
| Version ID | typesafe/jev-1.14-20261014 | typesafe/jev-1.13-20260917 | openai/gpt-6-luna-decisions-20261006 |
| Release on OpenRouter | 14 October 2026 | 18 September 2026 | 6 October 2026 |
| Input token price | USD 0.042 per 1 million | USD 0.042 per 1 million | USD 0.10 per 1 million |
| Output token price | Free | Free | Free |
| Context on OpenRouter | 262,144 tokens | 262,144 tokens | 1,050,000 tokens |
| ZDR endpoint | Yes | Yes | No |
| P50 latency on OpenRouter | 0.10 seconds | 0.08 seconds | 0.25 seconds |
| Question limit | No count limit, if the request fits the context | No count limit, if the request fits the context | Up to 200 per request |
Per token, Luna Decisions costs 2.4 times the price of Jev. In our test, the same text counted as 573 tokens on average for Jev and 472 tokens for Luna, so the cost gap per call is about 2 times. The method to calculate the cost per decision is in our Jev pricing article.
One note about context. The TypeSafe Models page gives a default limit of 64k per request and 32k per question on the TypeSafe API. OpenRouter shows 262,144 tokens. Test your own long state before you rely on the larger number.
How to compare 2 decision models fairly
A fair test uses the same cases, the same threshold in the first round, 2 rounds, and then a new threshold for each model. This sequence keeps 2 questions apart: which model is more accurate, and which threshold fits each model.

Two rounds show stability. If the same score moves far between rounds, no threshold is reliable. A threshold sweep per model shows the safe range, which is the range of thresholds with 0 errors on your set.
What you need
This test needs 1 account, 1 case file, and usual command-line tools.
- An OpenRouter account and 1 API key for tests only, with a small credit limit.
- A balance of a few US cents. At list prices, 240 calls of this size cost less than 1 US cent.
- curl and jq, or Node.js 20 or later.
- 1 file of made-up labeled cases in JSON or CSV.
- 1 results sheet for the scores of each model and each round.
Step 1: Write 1 decision as typed questions
Pick 1 decision that repeats often, and write it as a noul or choice question with criteria that do not overlap. We used a made-up shoe shop with 2 questions: does the customer ask for the money back, and which team handles the message.
"questions": {
"minta_uang_kembali": {
"type": "noul",
"instructions": "Apakah pelanggan meminta uangnya dikembalikan pada pesan ini?",
"criteria": {
"true": "Pelanggan meminta refund, meminta dana dikembalikan, atau menagih pengembalian dana yang sedang berjalan.",
"false": "Pelanggan bertanya, mengeluh, meminta tukar barang, meminta kirim ulang, atau hanya bertanya kebijakan."
}
},
"tim": {
"type": "choice",
"instructions": "Tim mana yang harus menangani pesan pelanggan ini?",
"criteria": {
"pengiriman": "Paket, resi, kurir, alamat, keterlambatan, paket hilang, dan kirim ulang.",
"pembayaran": "Transfer, kode bayar, status pembayaran, invoice, dan dana yang belum masuk.",
"produk": "Ukuran, warna, cacat, stok, tukar barang, dan keluhan atas barang.",
"lainnya": "Lowongan, kerja sama, ucapan terima kasih, dan hal lain di luar pesanan."
}
}
}
We kept the question text in Indonesian because the test messages are in Indonesian and its regional languages.
Check: each option of tim has criteria that cannot both be true for 1 usual message.
Step 2: Write made-up cases and their labels first
Write 30 to 50 made-up messages, and write their labels before you run any model. Labels that you write after you see a model answer lean toward that model.
Our set has 24 basic messages and 16 hard messages. The hard messages use Javanese, Sundanese, and Minang, abbreviations, mixed English, negation, sarcasm, and 1 long message with details that do not matter.
| No | Made-up message (English meaning) | Asks for money back | Team |
|---|---|---|---|
| 9 | The photo shows black, a grey one came. I want to swap for the black one, not a refund. | No | produk (product) |
| 24 | Do not return the money, just send the lost item again. | No | pengiriman (delivery) |
| 26 | Javanese: the item never came, it has been a week. Just give my money back. | Yes | pengiriman (delivery) |
| 27 | Sundanese: excuse me, I already paid but there is no confirmation yet. What now? | No | pembayaran (payment) |
| 28 | Abbreviated: the item came but the sole fell off, can I get a refund? | Yes | produk (product) |
| 29 | Sarcasm: great, my parcel has toured Java for 2 weeks. Just send it again. | No | pengiriman (delivery) |
| 35 | Minang: the shoes I bought have not arrived. It has been a week. | No | pengiriman (delivery) |
| 39 | Javanese: why is my refund money not in yet? You promised 3 days. | Yes | pembayaran (payment) |
Check: ask 1 other person to label the cases without your labels. Fix the criteria if your labels differ on more than 2 cases.
Step 3: Check ZDR before real data goes in
Zero Data Retention (ZDR) means that the provider does not keep your data. With provider.zdr: true, OpenRouter sends the request only to ZDR endpoints, as the OpenRouter ZDR documentation says.
curl -s https://openrouter.ai/api/v1/endpoints/zdr \
| jq -r '.data[].model_id' | grep -E 'jev-1.14|luna-decisions'
On 2 November 2026, this command printed only typesafe/jev-1.14. Luna Decisions did not show.

Check: a Jev 1.14 request with provider.zdr: true returns status 200. The same request to Luna Decisions returns 404 with the message No endpoints found matching your data policy (Zero data retention).
Step 4: Run 2 rounds with a 0.5 threshold
Send each case to each model 2 times, and keep the raw scores, not only pass or fail. The endpoint on the OpenRouter model pages is the Decisions API.
curl -s https://openrouter.ai/api/alpha/decisions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "typesafe/jev-1.14",
"provider": { "zdr": true },
"state": "Dana refund-ku kok durung mlebu yo? Janjine 3 dino.",
"questions": { ... }
}'
Keep 5 values from each response: answers.minta_uang_kembali.noul, answers.tim.choice, answers.tim.confidence, usage.input_tokens, and model. The model field names the version that actually answered.
Check: the model field holds typesafe/jev-1.14-20261014, and the number of responses equals the number of cases times 2.
Step 5: Sweep thresholds for each model
Count the correct answers at several thresholds for each model, and write down the range of thresholds with 0 errors. The code below does this for 1 noul question.
// hasil: [{ id, noul }] dari 1 model, label: Map id ke true atau false
for (let i = 1; i < 20; i += 1) {
const t = i / 20;
const benar = hasil.filter((r) => (r.noul >= t) === label.get(r.id)).length;
console.log(t, benar, 'dari', hasil.length);
}

Check: write down the safe range of each model, and pick a threshold in the middle of that range, not at its edge.
Step 6: Lock the version and test again when the version changes
Use the version ID typesafe/jev-1.14 in production code, not the alias ~typesafe/jev-latest. The alias moves when TypeSafe releases a new version, and your threshold does not move with it.
Log the model field of each response. When a new version comes out, run the same case set on it, sweep its thresholds, and then move with the new threshold.
Check: grep your code for the word latest in model names. The correct result is no match.
Public test results, 2 November 2026
On 40 made-up messages, all 3 models were correct on 40 of 40 at a 0.5 threshold, so accuracy does not pick the winner. The table below is a simulation with made-up data, not customer data.
| Item | Jev 1.14 | Jev 1.13 | Luna Decisions |
|---|---|---|---|
| Correct, refund question, 0.5 threshold | 40 of 40 | 40 of 40 | 40 of 40 |
| Correct, team choice | 40 of 40 | 40 of 40 | 40 of 40 |
| Team choice changed between rounds | 0 | 0 | 0 |
| Largest refund score change between rounds | 0.05 | 0.05 | 0.00 |
| Threshold range with 0 errors | above 0.25 up to 0.60 | above 0.25 up to 0.74 | above 0.07 up to 0.82 |
| Correct at a 0.8 threshold | 38 of 40 | 39 of 40 | 40 of 40 |
| Average input tokens | 573 | 573 | 472 |
| Cost per 1,000 calls, list price | USD 0.024 | USD 0.024 | USD 0.047 |
| P50 and P90 latency, 1 test server | 457 and 820 ms | 443 and 495 ms | 516 and 610 ms |
The differences come from regional-language and abbreviated messages. The table below gives the refund score, then the confidence of the team choice, in round 1.
| No | Label | Jev 1.14 | Jev 1.13 | Luna Decisions |
|---|---|---|---|---|
| 26 (Javanese) | refund, delivery | 0.98 and 0.76 | 0.97 and 0.55 | 1.00 and 0.81 |
| 27 (Sundanese) | no refund, payment | 0.21 and 0.41 | 0.20 and 0.96 | 0.00 and 1.00 |
| 28 (abbreviated) | refund, product | 0.60 and 1.00 | 0.74 and 1.00 | 1.00 and 1.00 |
| 35 (Minang) | no refund, delivery | 0.12 and 0.97 | 0.23 and 0.91 | 0.00 and 0.99 |
| 39 (Javanese) | refund, payment | 0.76 and 1.00 | 0.80 and 1.00 | 0.99 and 0.95 |
We read 3 points from this table:
- Luna Decisions gives almost binary scores. In round 1, 37 of 40 refund scores were exactly 0 or 1. Jev gave no score of exactly 0 or 1, so Jev leaves room for a human review lane.
- A 0.8 threshold from Luna is not safe for Jev 1.14. Messages 28 and 39 ask for a refund, but Jev 1.14 gave them 0.60 and 0.76. Both pass without a catch.
- The language gain does not show on a set this small. On Sundanese message 27, Jev 1.14 still picked the correct team, but its confidence was 0.41. Jev 1.13 gave 0.96 for the same message.
We measured latency from 1 test server, so the numbers include the network path to OpenRouter. The OpenRouter model pages show a P50 of 0.10 seconds for Jev 1.14 and 0.25 seconds for Luna Decisions.
Checklist before you move to Jev 1.14
Use this list before you change the decision model in a production flow.
- Write 30 to 50 made-up labeled cases. Owner: process owner. Evidence: a dated case file.
- Check the ZDR list for the target model. Owner: engineer. Evidence: a 200 response with
provider.zdr: true. - Run 2 rounds on the old model and the new model. Owner: engineer. Evidence: JSON results for each call.
- Sweep thresholds for each model and write down the safe range. Owner: engineer. Evidence: a table of correct answers per threshold.
- Pick a threshold in the middle of the safe range. Owner: process owner. Evidence: a dated decision note.
- Send choices with confidence below 0.8 to a human queue. Owner: engineer. Evidence: a routing log.
- Lock the version ID and log the
modelfield. Owner: engineer. Evidence: log lines with the version. - Stop if the new model is wrong on a case that the old model got right, or if its safe range is empty. Owner: process owner. Evidence: the comparison table.
Where Jev 1.14 sits among other decision models
OpenRouter listed 33 decision model entries on 2 November 2026, and 23 models have a ZDR endpoint. The table below shows 7 models from that list. We tested only 3 models for this article.
| Model | Input price per 1 million tokens | Context | ZDR endpoint |
|---|---|---|---|
| Perplexity Decider Flash V1.2 | USD 0.01 | 262,144 | Yes |
| LiquidAI d1.1 | USD 0.02 | 65,536 | Yes |
| TypeSafe Jev 1.14 | USD 0.042 | 262,144 | Yes |
| Microsoft-Decision-1 | USD 0.042 | 32,768 | Yes |
| Nace.AI Drex Max | USD 0.06 | 262,144 | Yes |
| OpenAI GPT-6 Luna Decisions | USD 0.10 | 1,050,000 | No |
| Cloudflare Clef | USD 0.24 | 65,536 | Yes |
Rama Digital recommendation: pick Jev 1.14 when your data rules require ZDR, your state is below 262,144 tokens, and you want a low price per token. Pick GPT-6 Luna Decisions when your state is longer, ZDR is not required, and a test on your cases shows that Luna is more accurate. For tasks that still need text, read Jev against generative LLMs.
Questions and answers
Is Jev 1.14 more accurate than Jev 1.13?
TypeSafe writes about small improvements across the board, mostly in languages other than English. On our 40 made-up messages, both were correct on 40 of 40. Test on cases from your own domain.
Did the price of Jev 1.14 go up from Jev 1.13?
No. On 2 November 2026, both cost USD 0.042 per 1 million input tokens on OpenRouter, and output tokens are free.
What happens if a model has no ZDR endpoint?
OpenRouter refuses the request with 404 and a data policy message. The OpenRouter ZDR page also notes a plan to screen all requests for CSAM from 27 October 2026, ZDR traffic included.
Do I need to set my thresholds again when I change versions?
Yes. In our test, the safe threshold range of Jev 1.14 ends at 0.60, and the range of Jev 1.13 ends at 0.74. A threshold that is safe for 1 version can miss cases on another version.
How many cases do I need for a test?
A set of 30 to 50 cases catches large gaps and shows the threshold range. Our 40-case set did not separate the accuracy of the 3 models, so small gaps need hundreds of cases.
Can Jev 1.14 read images?
OpenRouter lists text and images as input. TypeSafe marks images as a danger zone feature that it does not yet vouch for in production, so test it before you use it.
Next step
The limit that still applies: this public test uses 40 made-up messages and 2 questions, so its results do not represent your domain. More decisions that you can give to a decision model are in Jev use cases.
If you want us to map your decision points and build a test set for your flow, open AI Diagnostic. To talk about it first, pick a time for an AI Diagnostic session.
Sources
- TypeSafe: Jev, For the Builders and Dreamers (14 October 2026)
- TypeSafe: Models, aliases, context, and language
- OpenRouter: TypeSafe Jev 1.14
- OpenRouter: TypeSafe Jev 1.13
- OpenRouter: OpenAI GPT-6 Luna Decisions
- OpenRouter Models API, decisions filter
- OpenRouter: Zero Data Retention
- OpenRouter: ZDR endpoint list
- OpenRouter: Decisions API
- OpenRouter: Provider routing




