At a glance
- Does
- Asks Jev one binary question and takes Yes, No or Unsure
- Emits
- jev.noul, jev.outlet, jev.model, jev.usage.inputTokens
- Needs
- A Jev account, an OpenRouter provider, or Watchflows Sparks
Set it up
Jev is TypeSafe AI's System One model. It never writes text — it returns the probability that the answer is yes, and the node turns that number straight into the outlet that fires. Reach for it instead of an AI Prompt when the decision is genuinely binary: it is far faster and far cheaper than a chat turn plus a Condition.

Leave State empty to send the whole payload as an object — Jev prefers objects. A single {{path}} that resolves to an object or array is sent structured, never as stringified JSON. Narrow it anyway: unrelated context costs accuracy.
What counts as Yes and What counts as No are sent as the definitions of each answer, not as examples to match. Fill both in when the question is subtle and Jev draws the line where you would.
The Certainty slider has two thumbs. The right one is where Yes starts, the left one where No ends, and everything between is Unsure. They move independently — left never passes right — so "No at or below 0.10, Yes at or above 0.30" is one drag each. Leave the left thumb alone and it mirrors the right. Drag them together and the Unsure band disappears.
A fourth outlet, Failure, is the recovery path. It carries error and errorType when the call itself throws — TypeSafe down, the rate limit exhausted, a question it refuses. Leave it unwired and a thrown call stops the run as it always has; wire it and the run carries on down that branch instead.
Three things can pay for a Jev question, and Account is where you pick: a Jev account connected in Settings → Integrations, any OpenRouter provider you have added in Settings → AI Providers, or Watchflows Sparks if you have any. OpenRouter hosts the same model at the same price, so the answer, the outlets and your thresholds are identical whichever you choose — Sparks run these nodes with nothing to paste — the free 2,000 Sparks included. The Jev nodes stay out of the palette only while you have none of the three.
Configure
| Field | Default | What it does |
|---|---|---|
| Account | — | Who pays: a connected Jev account, OpenRouter — <provider>, or Watchflows Sparks. Left unset it uses whichever one you have — the row says which. |
| Model | jev-latest | jev-latest, jev-preview, or a dated release like jev-1.13.0 to pin a flow whose thresholds must not drift. On OpenRouter and Sparks a dated release is sent without its patch number — jev-1.13.0 asks for jev-1.13, the same release — and jev-preview is not offered at all, so a node pinned to it says so instead of running. |
| State | — | What Jev evaluates. Empty sends the whole payload. |
| Question | — | One atomic judgement, in plain words. |
| What counts as Yes | — | Optional. Where the Yes boundary sits. |
| What counts as No | — | Optional. Where the No boundary sits. |
| Certainty | Yes 0.8 | The right thumb: at or above this, Yes fires. |
| No at or below | mirrors Yes | The left thumb: at or below this, No fires. |
Output
Every key is available downstream as {{key}}, and jev arrives as real structure, not a JSON string.
| Key | Type | Value |
|---|---|---|
jev.noul | Number | Probability the answer is yes, 0–1 — near 0.5 means genuinely unsure |
jev.outlet | String | The branch taken: Yes, No or Unsure |
jev.model | String | The Jev release that answered, e.g. jev-1.13.0 |
jev.provider | String | Which route answered: typesafe, openrouter or sparks |
jev.usage.inputTokens | Number | Input tokens billed for this call; output is free |
error | String | Failure outlet only: the human-readable message |
errorType | String | Failure outlet only: the category — apiError for a refused call, invalidConfiguration for a node that is not set up, sparksExhausted when a Sparks-paid question runs out of credit, sparksSettling while Watchflows AI gets this Mac ready (a few minutes) |
Example: escalate only the messages that need a person
A support message arrives. Jev is asked whether the customer is asking for a human. Yes goes to a notification; No and Unsure go nowhere.

Paste this into the Flow Builder to get the same flow:
Ask Jev whether an incoming support message is asking for a human agent, and notify me only when it is.
Good to know
Jev is literal, and it is not a calculator. It answers the question you wrote, not the one you meant. Ask one thing per node, do arithmetic upstream in a Math step, and remember it reads dates as text — "is this overdue" needs the date comparison done before it gets here.
Thresholds are domain-specific. The cost of a wrong Yes and a wrong No is rarely the same, which is why the two cuts move separately. Start conservative and tune against real traffic.
Treat untrusted text as untrusted. Like any step that reads text from outside, Jev can be steered by instructions hidden in the state.