Every query gets judged before it gets answered. One cheap, parallel call decides if it's safe to forward, how hard it actually is, and who should handle it — nothing reaches a model the gate hasn't cleared first.
A support queue is mostly noise. “What are your hours” and a multi-step billing dispute cost the same to send to a frontier model, and get the same shot at leaking a system prompt or forwarding someone's card number to a third party. That's not a model problem — it's a routing problem, and it goes unsolved by default because nothing gets a say before the model does.
So I built the gate I'd want in front of my own support stack: one call that decides, before anything else happens, whether a query is safe to forward, how hard it actually is, and which tier should answer it.
One judgment, not three chained models.
Security, intent, and complexity are three separate questions, but they don't need three separate calls — Jev answers all of them in parallel, against the same input, for a fraction of a cent. A gate that's slow or expensive just becomes the next problem it was supposed to solve. Per TypeSafe's own published benchmarks, this beats a comparable general-purpose LLM doing the same classification work by roughly 20 to 200x on speed and 40 to 400x on cost — a vendor number, worth naming as theirs, not mine.
A query comes in. Jev answers three questions on it, and the answers alone decide what happens next. Two failure directions get weighted differently, on purpose: missing a jailbreak or a PII leak costs far more than an unnecessary block, so the security check trips well before the point where the routing logic would still trust its own judgment on anything else.
Pulled straight from the test suite above, not written for this demo — the outcome shown is what this build actually returned when it ran against these queries.
The obvious first draft of this system is a small LLM with a classification prompt in front of everything else. That works, right up until you do the math on what the gate itself costs to run at volume — at that point the guardrail is competing with the thing it's supposed to be protecting you from spending on.
TypeSafe's published pricing, and the gate call itself finishes in roughly 0.2 to 0.4 seconds on this build — measured, not a slide number. A guardrail that adds real latency or real cost just becomes the next bottleneck.
The security check doesn't share a threshold with the routing logic. A missed jailbreak or PII leak is worse than an unnecessary block, so it trips earlier — a tradeoff picked on purpose, not a number copied from a check answering a different question.
No prompt template to maintain, no JSON parsed inside a try/except and a shrug. Three typed questions go in — yes/no, which option, how far along a scale — and a typed, confidence-scored answer comes back. That's the entire interface.
Verbatim from router.py. Highlighted: the security check runs first and on its own threshold, not folded into the routing confidence check below it.
A gate that scores security and routing confidence against the same 0.50 line is making a decision without admitting it made one. Missing a jailbreak costs more than an unnecessary block, so the thresholds are different numbers, named as constants, with the reasoning written down next to them — not a default that happened to ship.
The first version of this pitch had a cost-reduction number and a latency claim before a single benchmark had run. Both got pulled until there was a real 250-query set behind them, weighted toward the traffic mix a support queue actually sees rather than a convenient sample.
An org-scoped API key isn't a workspace-scoped one — needed an explicit workspace header before a single Claude call would succeed.
The first content block in a Claude response isn't always the text — a leading reasoning block broke a naive content[0].text until it filtered for the text block specifically.
Queries hand-labeled “ambiguous” came back from Jev fully confident, twice. The labels were wrong, not the router — fixed by trusting the live result over the assumption.
Local inference isn't automatically fast — a local model ran 7 to 16 seconds a call on this hardware, slower than Claude. Switched the cheap tier to hosted inference once a real timing test caught it.
The routing decision itself — five unit tests, zero API calls — was correct on the first try. Every failure in this build happened one layer out, in the actual wiring to Jev, Groq, and Claude. That's where the field notes above came from, and it's the layer a logic-only test suite would have missed entirely.