Try it
Copy the code ↓- Data source
- Decision schema
- Model inference
- Structured result
2 Decision schema 3 typed questions
call_verdictchoiceexecutefix_argsask_customerblockarg_mismatchscorenoneminormajorneeds_humannoulprobability 0–1
3 Model inference typesafe/jev-1.13
Waiting for a run.
4 Structured result
Raw JSON
Run the demo to see the JSON answers, the highlighted pick and the final action.
FLATKEY_API_KEY and run.curl -sS https://router.flatkey.ai/api/alpha/decisions \
-H "Authorization: Bearer $FLATKEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "typesafe/jev-1.13",
"state": "Customer (German): \"Bitte erstatten Sie mir 0,12 € für Bestellung 4471, der Versand war zu teuer berechnet.\"\nOrder 4471: total €39.90, paid by card, shipping overcharge €0.12 on record\nProposed tool call: refundOrder(orderId=\"4471\", amount=12.00, currency=\"EUR\")\nPolicy: refunds over €10 need agent approval; amount must match the documented overcharge.\nTask: typed verdict for this tool call — execute / fix_args / ask_customer / block (+ arg_mismatch, needs_human).",
"questions": {
"call_verdict": {
"type": "choice",
"instructions": "Decide what the application should do with the proposed refund tool call before it is executed. Compare the tool name and arguments with the customer'\''s request and the order facts provided.",
"criteria": {
"execute": "Tool and arguments match the customer'\''s request and the order facts; safe to run as proposed",
"fix_args": "Intent is clear but an argument is wrong (amount, currency, decimal separator, order id); correct it in code before running",
"ask_customer": "The request is ambiguous or missing information, so the correct arguments cannot be determined yet",
"block": "The call is outside policy, targets an ineligible or unrelated order, or should not happen at all"
}
},
"arg_mismatch": {
"type": "score",
"instructions": "How far do the proposed tool-call arguments diverge from what the customer actually asked for and what the order allows.",
"criteria": [
"none",
"minor",
"major"
]
},
"needs_human": {
"type": "noul",
"instructions": "A support agent must approve this refund before any money moves."
}
}
}'// Node.js 18+ (built-in fetch). Run: FLATKEY_API_KEY=... node jev.mjs
const body = {
"model": "typesafe/jev-1.13",
"state": "Customer (German): \"Bitte erstatten Sie mir 0,12 € für Bestellung 4471, der Versand war zu teuer berechnet.\"\nOrder 4471: total €39.90, paid by card, shipping overcharge €0.12 on record\nProposed tool call: refundOrder(orderId=\"4471\", amount=12.00, currency=\"EUR\")\nPolicy: refunds over €10 need agent approval; amount must match the documented overcharge.\nTask: typed verdict for this tool call — execute / fix_args / ask_customer / block (+ arg_mismatch, needs_human).",
"questions": {
"call_verdict": {
"type": "choice",
"instructions": "Decide what the application should do with the proposed refund tool call before it is executed. Compare the tool name and arguments with the customer's request and the order facts provided.",
"criteria": {
"execute": "Tool and arguments match the customer's request and the order facts; safe to run as proposed",
"fix_args": "Intent is clear but an argument is wrong (amount, currency, decimal separator, order id); correct it in code before running",
"ask_customer": "The request is ambiguous or missing information, so the correct arguments cannot be determined yet",
"block": "The call is outside policy, targets an ineligible or unrelated order, or should not happen at all"
}
},
"arg_mismatch": {
"type": "score",
"instructions": "How far do the proposed tool-call arguments diverge from what the customer actually asked for and what the order allows.",
"criteria": [
"none",
"minor",
"major"
]
},
"needs_human": {
"type": "noul",
"instructions": "A support agent must approve this refund before any money moves."
}
}
};
const res = await fetch("https://router.flatkey.ai/api/alpha/decisions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FLATKEY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (!res.ok) throw new Error(`Jev request failed: ${res.status} ${await res.text()}`);
const { answers, usage } = await res.json();
console.log(JSON.stringify(answers, null, 2), usage);# Python 3.8+ (pip install requests). Run: FLATKEY_API_KEY=... python jev.py
import json, os, requests
body = json.loads(r"""{
"model": "typesafe/jev-1.13",
"state": "Customer (German): \"Bitte erstatten Sie mir 0,12 € für Bestellung 4471, der Versand war zu teuer berechnet.\"\nOrder 4471: total €39.90, paid by card, shipping overcharge €0.12 on record\nProposed tool call: refundOrder(orderId=\"4471\", amount=12.00, currency=\"EUR\")\nPolicy: refunds over €10 need agent approval; amount must match the documented overcharge.\nTask: typed verdict for this tool call — execute / fix_args / ask_customer / block (+ arg_mismatch, needs_human).",
"questions": {
"call_verdict": {
"type": "choice",
"instructions": "Decide what the application should do with the proposed refund tool call before it is executed. Compare the tool name and arguments with the customer's request and the order facts provided.",
"criteria": {
"execute": "Tool and arguments match the customer's request and the order facts; safe to run as proposed",
"fix_args": "Intent is clear but an argument is wrong (amount, currency, decimal separator, order id); correct it in code before running",
"ask_customer": "The request is ambiguous or missing information, so the correct arguments cannot be determined yet",
"block": "The call is outside policy, targets an ineligible or unrelated order, or should not happen at all"
}
},
"arg_mismatch": {
"type": "score",
"instructions": "How far do the proposed tool-call arguments diverge from what the customer actually asked for and what the order allows.",
"criteria": [
"none",
"minor",
"major"
]
},
"needs_human": {
"type": "noul",
"instructions": "A support agent must approve this refund before any money moves."
}
}
}""")
res = requests.post(
"https://router.flatkey.ai/api/alpha/decisions",
headers={"Authorization": f"Bearer {os.environ['FLATKEY_API_KEY']}"},
json=body,
timeout=60,
)
res.raise_for_status()
data = res.json()
print(json.dumps(data["answers"], indent=2), data.get("usage"))
No Flatkey key yet? Get one for Jev 1.13 →
About this use case

Who / when
Audience
- Java and Spring teams using LangChain4j tools that move money or change orders
- support platform builders who let an assistant propose refunds, credits or cancellations
- engineers who want a cheap, typed second check between tool-call proposal and execution
Triggers
- the proposed amount differs from the amount in the customer's message (decimal comma, currency, cents vs euros)
- the order id in the tool call does not match the order the customer referenced
- the request is ambiguous or partial, so the right arguments are not knowable yet
- the call exceeds a refund policy limit or targets an order that is not eligible
The workflow
- 01Request + tool callMessage, order, proposed argsInput
- 02Score arg mismatchnone / minor / majorJev
- 03Call verdictexecute / fix / ask / blockJev
- 04Tool gateRun, correct, ask, or refuseYour code
Question shape
{
"call_verdict": {
"type": "choice",
"instructions": "Decide what the application should do with the proposed refund tool call before it is executed. Compare the tool name and arguments with the customer's request and the order facts provided.",
"criteria": {
"execute": "Tool and arguments match the customer's request and the order facts; safe to run as proposed",
"fix_args": "Intent is clear but an argument is wrong (amount, currency, decimal separator, order id); correct it in code before running",
"ask_customer": "The request is ambiguous or missing information, so the correct arguments cannot be determined yet",
"block": "The call is outside policy, targets an ineligible or unrelated order, or should not happen at all"
}
},
"arg_mismatch": {
"type": "score",
"instructions": "How far do the proposed tool-call arguments diverge from what the customer actually asked for and what the order allows.",
"criteria": [
"none",
"minor",
"major"
]
},
"needs_human": {
"type": "noul",
"instructions": "A support agent must approve this refund before any money moves."
}
}Gate policy
≥ 0.90
Execute only when call_verdict is execute, arg_mismatch is none and needs_human is false. A high-confidence block refuses the call and logs it.
0.65–0.90
Don't run as proposed: fix_args re-derives the argument in code and re-checks; ask_customer sends a clarifying question. No refund yet.
< 0.65
Hold the call and hand the conversation to a support agent with the proposed arguments attached.
Failure modes
Pre-launch checks before you trust auto-routing:
- Executing whatever tool call the assistant proposes because the JSON parsed and the types are right;
- Reading "0,12 €" as 12.00 and refunding a hundred times the request;
- Refunding the customer's most recent order when they named a different one;
- Asking the same model that proposed the call whether its own call is correct;
- Using one global threshold instead of routing mid-confidence calls to fix or clarify;
FAQ
Why check a tool call with Jev instead of trusting LangChain4j's tool execution?
LangChain4j makes the call well-typed, but a well-typed call can still carry the wrong amount or the wrong order. A separate typed Choice (execute / fix_args / ask_customer / block) with calibrated probabilities lets your Java code run only calls that match the request and route the rest.
Where does the check sit in a Java app?
Between the model's tool-call proposal and your tool method. Intercept the proposed tool name and arguments, send them with the customer's message and order facts to Jev, and only invoke the refund method when the gate allows it.
Does Jev replace amount parsing or refund limits?
No. Keep locale-aware parsing, currency, ownership checks and limits in code. Jev adds the fuzzy judgment those rules miss: whether the arguments match what the customer meant and whether the request is clear enough to act on.
Can I bring my own API key?
Yes. Try the free demo above without signing in. To run it live on your own text, sign in with Google and connect a Flatkey or OpenRouter key (a quick test call runs when you save it). Manage or delete it anytime under Dashboard → BYOK. Keys are stored encrypted on the server, used only for runs you trigger, and never sent back to the browser. Need a Flatkey key? Get one for Jev 1.13 on Flatkey.
Is this the official TypeSafe Jev product page?
No. jev-llm.com is an independent research and practice site. Verify pricing, models and terms at the original TypeSafe sources.
Sources
Refunding twelve cents sounds like a fairly simple task. The customer provides an order and an amount, an assistant proposes a tool call, and the application executes it.
— @myfear View the post on X →
Wire this gate with your own key
Bring your own key through Flatkey / OpenRouter. Keep exact checks in code.