Jev 1.14 Release Notes: Box Questions, Image Inputs, Long Context
TL;DR: Jev 1.14 shipped on 2026-10-14 as model ID
jev-1.14.0. The changelog lists exactly four changes: better multilingual support, a new Box question type that returns a bounding box around something in an image, image inputs insidestate/instructions/criteria, and a long-context header that raises both context limits to 262k tokens. Image support and long context also work on 1.13; only Box questions require 1.14. Price is unchanged at $42 per billion input tokens ($0.042 per million) with free output tokens, and the default context limits are still 64k per request and 32k per question. Images and Box are explicitly labelled Dreamer-ready — prototype only, format may change.
This page is the version-tracking entry for 1.14. It exists because two things changed at once: a new primitive appeared, and image input became possible at all. That combination breaks a few assumptions that hold for every text-only Jev page on this site, so the notes below are split accordingly: what the changelog actually says, what the request and response shapes look like for the new pieces, and what you have to touch on a 1.13 deployment.
Every fact here comes from two sources read on 2026-11-04: the official TypeSafe documentation — the model changelog, the models page, the Box page and the images page — and the OpenRouter models API, specifically GET /api/v1/models/typesafe/jev-1.14/endpoints. Where the two disagree, both values are shown and the disagreement is named rather than smoothed over.
What the changelog lists, verbatim in substance
The changelog for 1.14 is four bullets long. That is the whole published change set:
| # | Change | Scope |
|---|---|---|
| 1 | Model ID is jev-1.14.0 | 1.14 only |
| 2 | Better multilingual support | 1.14 only — no per-language numbers published |
| 3 | New Box question type: finds where something is in an image, answers with a bounding box | 1.14 only |
| 4 | Images can go in state, instructions, or criteria | 1.14 and 1.13 |
| 5 | Long context raises both context limits to 262k tokens | 1.14 and 1.13 |
Row 4 and row 5 are the ones people misread. They are not 1.14 features. The changelog says so in the same sentence that announces them: “This also works on Jev 1.13.” If you are pinned to 1.13 and only want image input or longer context, you do not need to move versions at all. The only capability that requires 1.14 is Box.
Where 1.14 is served
Two channels, same model:
- Official API.
POST https://api.typesafe.ai/v1/systemone, withmodelset tojev-1.14.0, or to the aliasjev-latest, which the models page says points atjev-1.14.0. If you have read the API channels guide, this is the TypeSafe-direct channel that the site treats as the authoritative one. - OpenRouter. The versioned slug is
typesafe/jev-1.14. Its model page returns 200, and the endpoints API describes a single TypeSafe-served endpoint namedtypesafe/jev-1.14-20261014.
The OpenRouter entry itself is worth reading closely, because its numbers are not the numbers in the official models table:
| Field (OpenRouter endpoints API, 2026-11-04) | typesafe/jev-1.14 | typesafe/jev-1.13 |
|---|---|---|
| Endpoint name | typesafe/jev-1.14-20261014 | typesafe/jev-1.13-20260917 |
| Provider | TypeSafe | TypeSafe |
context_length | 262144 | 262144 |
max_prompt_tokens | 262144 | 262144 |
max_completion_tokens | 235929 | 235929 |
pricing.prompt (per token) | 0.000000042 | 0.000000042 |
pricing.completion | 0 | 0 |
uptime_last_1d | 100 | 100 |
| Input modality | text + image | text + image |
| Output modality | decisions | decisions |
Converted, pricing.prompt is $0.042 per million prompt tokens, which matches the official “$42 per Btok / $0.042 per Mtok” line exactly. The context figure is the interesting one: OpenRouter reports 262,144 for both versions, while the official models page states 64k per request and 32k per question by default, rising to 262k only when a request carries the long-context header. Both statements can be true if the OpenRouter listing reports the ceiling rather than the default, but that is an inference, not something either source states. The practical instruction is the same either way: size your first request against 64k and add the header deliberately when you need more. Do not plan a 200k-token request on the assumption that the listing is the enforced default.
Change 1: better multilingual support, and what “better” does not tell you
The changelog says “Better multilingual support” and stops there. There is no per-language accuracy table, no sample-size disclosure, no before-and-after comparison, and no list of which languages improved. Anyone publishing a ranked language table for 1.14 is inventing it.
What you can act on is the framing the documentation has used consistently: English is the primary training language and where accuracy is currently best, other languages including CJK scripts are handled but not equally well, and non-English workloads must be tested on your own content. 1.14 changes the first clause only in the direction of “less bad”, and it gives you no way to quantify by how much.
So the only responsible migration step for multilingual traffic is a measurement, not a version bump. The language support guide on this site already lays out that procedure: stratify a sample of your own production items by language, label it with your own domain experts, run the same questions across both model versions, and compare agreement rate and confidence distribution side by side rather than pooling them. If your Chinese moderation queue agreed with human labels on 88% of items under 1.13, the only meaningful question about 1.14 is what that same number is now.
One trap worth naming: confidence is not comparable across versions without a check. If 1.14 reports higher confidence on the same inputs, that is exactly the kind of shift that makes a threshold tuned on 1.13 fire when it should escalate. The confidence-and-fallback guide’s advice to keep the threshold in configuration rather than in code exists for this case.
Change 2: Box questions — the one genuinely new primitive
Box is the first new question type since the three this site has covered from the start. Where a judgment question returns yes/no/unclear, a Choice returns one option, and a Score returns a position on a ladder, a Box returns where something is: four edges of a rectangle around a target in an image.
Request shape
A Box question has two fields and no criteria:
type: the literal string"box".instructions: what to find and in which image. The documentation is explicit that it does not have to be phrased as a question —"the coffee mug in photo"is a complete instruction.
Because there is no criteria, Box is the only primitive with nothing to define beyond the instruction. That makes it cheap to ask and hard to tune: the entire specification of the target lives in one sentence.
Response shape
{
"model": "jev-1.14.0",
"answers": {
"mug": {
"type": "box",
"box": {
"top": 0.25,
"bottom": 0.82,
"left": 0.44,
"right": 0.84
},
"confidence": 0.92
}
},
"usage": { "input_tokens": 290, "output_tokens": 21 }
}
Those four numbers are fractions of the image’s width and height, measured from the top-left corner, not pixels. left/right are fractions of width; top/bottom are fractions of height. The invariant is left < right and top < bottom. This is the detail that breaks naive integrations: a box of {left: 0.44, right: 0.84} on a 1600px-wide photo is x = 704 to x = 1344, and multiplying by the wrong dimension silently gives you a crop of the right shape in the wrong place.
The documentation’s own worked example is a crop: multiply each edge by the image’s width or height, round, and pass the four-pixel tuple to your imaging library. It also shows a useful defensive pattern — pad each edge outward before cropping when the crop must not clip the target, clamped to the 0–1 range.
The failure mode Box cannot express
A Box answer is always a box. There is no “not found” answer. Ask where the mug is in a photo with no mug and you still get four edges, with no field that tells you the target is absent. The documented fix is to ask a Noul in the same request — “Is there a coffee mug in photo?” — and discard the box when the Noul probability is low. Since every question in a request sees the same state and is evaluated independently, this costs one extra question and no extra round trip.
Two more constraints from the page that matter operationally:
- One box per question. Box finds one target and returns one box. To find several different things, ask one Box question per target in the same request. When the image may contain several instances of the same thing, describe the one you want precisely enough that only it fits, or add a Choice with options
none/one/severalnext to the Box and split the image into regions when the answer isseveral. - Crop before looking for small things. A target a few dozen pixels wide in a very large image can be missed. The documented approach is a two-request cascade: locate the region first (for example a Choice whose options are image tiles), then ask the Box question on that tile and convert its edges back to fractions of the full image.
Requirements and staging
Box needs Jev 1.14 and it needs images turned on. Both are gates, not defaults:
- Send
TypeSafe-Danger-Zone-Images: truewith every request that contains an image or a Box question. Without it, the request fails with400. - Send
model: jev-1.14.0(or thejev-latestalias) on the official API, ortypesafe/jev-1.14on OpenRouter. A 1.13 model answering a Box question is not a supported combination.
Change 3: images in state, instructions and criteria
Image support is the broader change, and it is available on both 1.13 and 1.14. An image can go anywhere text can go: in the state, inside one question’s instructions, and in a question’s criteria. Every question type accepts images, not just Box.
The mechanism is an assets map at the top level of the request, keyed by a reference string. You write the reference where the image belongs — as a whole value or inside a longer sentence — and the model receives the image in its place. The documentation’s own three-way example is compact enough to show the whole idea: a doorbell photo as a state value, a badge photo embedded inside a Noul question’s instructions, and a thumbnail as the description of a Choice option in criteria.
Asset fields
| Field | Meaning |
|---|---|
type | "image". Optional; if sent it must be that value. |
part | Name of the multipart file part holding the image. Used instead of data_base64. |
data_base64 | The file, base64-encoded, standard alphabet with = padding, no whitespace, no data: prefix. |
format | "png", "jpg" or "jpeg", lowercase. Required with data_base64. |
Send each image one way. If an asset somehow carries both part and data_base64, the API uses part.
Reference rules that bite
These are stated plainly in the docs and are still the most common source of 400s:
- Every asset must be referenced. An unreferenced asset fails the whole request with
400. There are no partial answers — one bad image kills the entire response. - Each use adds the image again. Upload once, but every place the reference appears adds another copy to what the model reads, and every copy counts against the expanded-request limit.
- References are matched as plain text. A reference like
catwill match insidecategory. The documentation’s recommendation is a fresh UUID per image per request, which is also what the SDKs do for you. - Object keys are not replaced. A Choice option name or question ID stays text; to attach a picture to an option, put the reference in the option’s description.
- Answers repeat the reference, not the image — relevant if a Score’s
legendechoes your criteria back and you were expecting image data there. - Reference keys are capped at 1,024 bytes each, 65,536 bytes for all references in one request.
Limits
| Limit | Value |
|---|---|
| Format | PNG or JPEG, still images only; animated PNGs rejected |
| File size | 16 MiB per image (after base64 decoding) |
| Side length | 280–1568 px each side; below 280 is rejected |
| Total pixels | 78,400–2,458,624 (a 280×280 to 1568×1568 square) |
| Request body | 32 MiB including JSON, base64 text and multipart framing |
| All distinct images | 32 MiB after the API re-encodes them |
| Expanded request | 32 MiB with every reference replaced by its image |
Two consequences worth planning for. First, re-encoding can make an image larger than the file you sent, so a batch of small uploads can still exceed the aggregate limit. Second, there is no resizing to fit — an image outside the range is rejected rather than scaled. The documented recommendation is to scale the longest side to at most 1568 px, rotate the pixels upright (EXIF orientation is stripped, not applied), convert GIF/WebP/HEIC to PNG or JPEG, and prefer baseline JPEG over progressive.
Multipart is the documented better choice over base64: base64 inflates each image by roughly a third, and that inflation counts against the 32 MiB body limit. Image tokens are billed at the same per-token input price as text, and the response’s usage.input_tokens includes them.
Failure codes
| Status | Cause |
|---|---|
400 | Images used without the TypeSafe-Danger-Zone-Images: true header |
400 | An image or asset rejected: wrong format, damaged, animated, below minimum dimension, unreferenced, invalid base64 or format, empty reference |
400 | max_tokens_exceeded — images plus text exceed the request’s context length |
413 | Over a size limit: file, dimension, total pixels, body, all images, expanded request, or reference lengths |
Change 4: long context, 262k behind a header
Long context is off by default and works on both versions. Turning it on means sending TypeSafe-Danger-Zone-Long-Context: true with every request that needs it; with the header, both the per-request and per-question limits become 262k tokens. Without it, the defaults in the models table apply.
The documentation is unusually direct about the trade: long context costs the same per token as any other request, and it is slower and less accurate than staying within the default limits, so it should be turned on per request rather than globally. For a batch pipeline that occasionally ingests a long contract, that means a two-tier path — a default-limit path for ordinary items and a header-carrying path for the tail — rather than one header on every call.
The reason to be careful is the same one that shows up throughout this site’s guidance on state size: accuracy moves as the state grows, and the docs point to their jaggedness page for that. Adding 200k tokens of context to avoid chunking can cost you more in answer quality than the chunking would have.
What did not change
Worth stating explicitly, because version reading tends to over-read:
- Price. $42 per billion input tokens, $0.042 per million, output free — identical for 1.13 and 1.14 on the official page, and identical in the OpenRouter endpoints data for both slugs.
- Default context. 64k per request, 32k per question, unchanged. Long context is opt-in.
- The three text primitives. Choice, Score and Noul keep their request fields and answer shapes.
- The endpoint.
POST /v1/systemonestill serves every model;modelselects which. There is no separate images endpoint and no separate box endpoint. - Output tokens stay free. Cost is entirely a function of how much state and how many questions and images you send.
Migration checklist: 1.13 → 1.14
The order matters, because the cheap steps validate the expensive ones.
- Decide pin versus alias. If you pin
jev-1.13.0, nothing moves until you change the string. If you ridejev-latest, you are already on 1.14 as of this writing, whether or not you noticed. The models page is explicit thatjev-latestpoints atjev-1.14.0and thatjev-previewcurrently points at the same model because no preview build exists. - Log the answering model. Every response carries a
modelfield with the versioned ID that answered. If you have tuned thresholds against 1.13, that field is the only reliable way to tell which version produced which historical row. - Re-run your fixture set before touching production. Freeze 20–30 representative inputs, record answers and confidence ranges on 1.13, run the same set on 1.14, and diff. For multilingual traffic, split the diff by language — a pooled number hides the change you are looking for.
- Recheck thresholds against the new confidence distribution. Keep per-language thresholds separate if you already had them separate. A shift that looks like an improvement in aggregate can be a regression in one language.
- Change the version string in exactly one place. If the slug appears in code, config and a dashboard, consolidate it to one config value first, then flip it. Rolling back should be a one-line change.
- If you adopt images or Box, gate them. Turn on the header in staging only, add the Noul-plus-Box pairing for absent targets, and keep the text-only path intact so a rejected image cannot take down an endpoint that previously worked.
- Watch the 413s and the aggregate limit. Re-encoding inflates hashed images; a request that passed in testing can fail in production purely on payload size.
Honest unknowns
Three things are not published, and this page will not invent them:
- How much multilingual accuracy improved, and in which languages. The changelog says “better” and gives no measurement.
- Whether confidence is calibrated the same way across versions. No calibration data has been published for either release.
- Whether the OpenRouter 262,144 context figure is the enforced default or the long-context ceiling. The official models page says 64k default; the endpoints API reports 262,144; nothing states which reading applies to the OpenRouter path.
Test all three on your own traffic. That has been the standing advice on this site for confidence, thresholds and language quality, and a version bump does not change it.
Where to go next
- Language support — the measurement procedure for the change the changelog does not quantify.
- Three primitives — Choice, Score and Noul, with Box now sitting alongside them.
- Confidence and fallback — thresholds, per-language tuning, and the three fallback paths.
- Troubleshooting — 400/413 triage, which is where most image-related failures will land.
- Cost and latency — what image tokens and extra questions do to a per-item budget.
- Jev 1.13 release notes — the previous snapshot, still the reference for a 1.13-pinned deployment.