Try it
Copy the code ↓- Data source
- Decision schema
- Model inference
- Structured result
2 Decision schema 3 typed questions
addressed_tochoicegame_commandside_conversationthinking_aloudunclearmovechoiceupdownleftrightnonefor_the_gamenoulprobability 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": "App: voice-steered maze. Accepted commands: up, down, left, right.\nRoom: player at the desk, a colleague on a phone call nearby.\n\nTurn transcript (end of turn):\n \"Yeah, take a left after the bank and I'\''ll call you back.\"\n\nTask: addressed_to, move, for_the_game.",
"questions": {
"addressed_to": {
"type": "choice",
"instructions": "A voice-controlled maze game is listening in a shared room. Who or what was this finished turn of speech meant for?",
"criteria": {
"game_command": "The speaker is directing the game, for example asking it to move, turn, stop or go back",
"side_conversation": "The speaker is talking to another person or on a phone call; the words are not meant for the game even if they contain direction words",
"thinking_aloud": "Filler, hesitation or self-talk such as \"hmm\", \"wait\" or \"let me think\" with no instruction for the game",
"unclear": "It could be meant for the game but the request is too vague or garbled to act on"
}
},
"move": {
"type": "choice",
"instructions": "If the turn is a command for the maze game, which move does it ask for? Answer none when it is not a game command.",
"criteria": {
"up": "Move up or forward",
"down": "Move down or back",
"left": "Turn or move left",
"right": "Turn or move right",
"none": "No game move is being asked for"
}
},
"for_the_game": {
"type": "noul",
"instructions": "The speaker intends the game to act on this turn right now."
}
}
}'// Node.js 18+ (built-in fetch). Run: FLATKEY_API_KEY=... node jev.mjs
const body = {
"model": "typesafe/jev-1.13",
"state": "App: voice-steered maze. Accepted commands: up, down, left, right.\nRoom: player at the desk, a colleague on a phone call nearby.\n\nTurn transcript (end of turn):\n \"Yeah, take a left after the bank and I'll call you back.\"\n\nTask: addressed_to, move, for_the_game.",
"questions": {
"addressed_to": {
"type": "choice",
"instructions": "A voice-controlled maze game is listening in a shared room. Who or what was this finished turn of speech meant for?",
"criteria": {
"game_command": "The speaker is directing the game, for example asking it to move, turn, stop or go back",
"side_conversation": "The speaker is talking to another person or on a phone call; the words are not meant for the game even if they contain direction words",
"thinking_aloud": "Filler, hesitation or self-talk such as \"hmm\", \"wait\" or \"let me think\" with no instruction for the game",
"unclear": "It could be meant for the game but the request is too vague or garbled to act on"
}
},
"move": {
"type": "choice",
"instructions": "If the turn is a command for the maze game, which move does it ask for? Answer none when it is not a game command.",
"criteria": {
"up": "Move up or forward",
"down": "Move down or back",
"left": "Turn or move left",
"right": "Turn or move right",
"none": "No game move is being asked for"
}
},
"for_the_game": {
"type": "noul",
"instructions": "The speaker intends the game to act on this turn right now."
}
}
};
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": "App: voice-steered maze. Accepted commands: up, down, left, right.\nRoom: player at the desk, a colleague on a phone call nearby.\n\nTurn transcript (end of turn):\n \"Yeah, take a left after the bank and I'll call you back.\"\n\nTask: addressed_to, move, for_the_game.",
"questions": {
"addressed_to": {
"type": "choice",
"instructions": "A voice-controlled maze game is listening in a shared room. Who or what was this finished turn of speech meant for?",
"criteria": {
"game_command": "The speaker is directing the game, for example asking it to move, turn, stop or go back",
"side_conversation": "The speaker is talking to another person or on a phone call; the words are not meant for the game even if they contain direction words",
"thinking_aloud": "Filler, hesitation or self-talk such as \"hmm\", \"wait\" or \"let me think\" with no instruction for the game",
"unclear": "It could be meant for the game but the request is too vague or garbled to act on"
}
},
"move": {
"type": "choice",
"instructions": "If the turn is a command for the maze game, which move does it ask for? Answer none when it is not a game command.",
"criteria": {
"up": "Move up or forward",
"down": "Move down or back",
"left": "Turn or move left",
"right": "Turn or move right",
"none": "No game move is being asked for"
}
},
"for_the_game": {
"type": "noul",
"instructions": "The speaker intends the game to act on this turn right now."
}
}
}""")
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
- builders of voice-controlled games, kiosks and desktop tools used in shared rooms
- voice-agent teams on Deepgram Flux, Pipecat or LiveKit who see false commands from background speech
- hands-free app makers who want a cheap relevance check before any action fires
- prototype builders who need an explicit "none of these" answer instead of a forced guess
Triggers
- speech-to-text fires an end-of-turn event on someone else's phone call
- the player thinks out loud ("hmm, wait") and the app treats it as a command
- a keyword matcher hears "left" inside "I left it on your desk" and moves
- sending every turn to a chat model adds a round trip before the app can react
The workflow
- 01Turn transcriptEnd-of-turn text from your STT plus the commands the app accepts right nowInput
- 02For the app?Command, side conversation, thinking aloud or unclearJev
- 03Which move?up / down / left / right / none, plus a yes/no on intentJev
- 04Code gateMove only on a confident command at the final end of turn; else ignore or askYour code
Question shape
{
"addressed_to": {
"type": "choice",
"instructions": "A voice-controlled maze game is listening in a shared room. Who or what was this finished turn of speech meant for?",
"criteria": {
"game_command": "The speaker is directing the game, for example asking it to move, turn, stop or go back",
"side_conversation": "The speaker is talking to another person or on a phone call; the words are not meant for the game even if they contain direction words",
"thinking_aloud": "Filler, hesitation or self-talk such as \"hmm\", \"wait\" or \"let me think\" with no instruction for the game",
"unclear": "It could be meant for the game but the request is too vague or garbled to act on"
}
},
"move": {
"type": "choice",
"instructions": "If the turn is a command for the maze game, which move does it ask for? Answer none when it is not a game command.",
"criteria": {
"up": "Move up or forward",
"down": "Move down or back",
"left": "Turn or move left",
"right": "Turn or move right",
"none": "No game move is being asked for"
}
},
"for_the_game": {
"type": "noul",
"instructions": "The speaker intends the game to act on this turn right now."
}
}Gate policy
≥ 0.90
If addressed_to is game_command and move is not none, run the move in code when the final end-of-turn arrives; if it is side_conversation or thinking_aloud, ignore the turn silently.
0.65–0.90
Do nothing yet: keep the result, wait for the next turn, and only act if the player repeats or confirms the command.
< 0.65
Treat as unclear: show a short on-screen prompt ("Which way?") instead of moving, and log the transcript for tuning.
Failure modes
Pre-launch checks before you trust auto-routing:
- Keyword matching on direction words, so "take a left after the bank" on someone's phone call moves the player;
- Forcing every turn into a command with no none option, so filler and side talk always become some move;
- Acting on an early, provisional end-of-turn guess instead of waiting for the final one, so a player who keeps talking gets the wrong move;
- Routing every turn through a chat model, adding a full round trip before the game reacts;
- Letting Jev drive the game directly; it only answers who the speech was for and which move, while movement, collisions and timers stay in code;
FAQ
Why isn't turn detection enough?
Turn detection tells you when someone stopped talking. It does not tell you whether they were talking to your app. In a shared room most finished turns are not commands at all, so you need a second, meaning-level check before anything moves.
Why ask for addressed_to and move separately?
They fail differently. A phone call can contain a clear direction word ("take a left") that is not for the game, and a real command can be vague. Two answers let code ignore side talk confidently and ask a follow-up only when the player really meant the game.
Why include a none option?
Without it the model has to pick a move for every turn, and background speech becomes random movement. An explicit none (and side_conversation / thinking_aloud categories) gives Jev a correct answer for the common case where nothing should happen.
Can I call Jev before the speaker has finished?
Yes, if your speech-to-text emits an early end-of-turn signal. Ask Jev on the early transcript so the answer is ready, drop it if the speaker resumes, and only act when the final end-of-turn arrives with the same text.
Does this work beyond games?
Yes. The same shape fits any hands-free app in a shared space: kiosks, cockpit or kitchen tools, desktop voice shortcuts. Change the instructions to describe your app and replace the move options with your command list.
What does the Flatkey call look like?
POST https://router.flatkey.ai/api/alpha/decisions with Authorization: Bearer …, Content-Type: application/json, and a body of state, model (typesafe/jev-1.13), and questions (choice / score / noul). This is not an OpenAI-compatible /v1 chat endpoint.
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
I built a maze you steer by voice while my wife takes calls the desk over. Flux says when my turn ended, Jev says whether it was even for the maze at all, and at $0.00016 the system can ask before I'm done talking
— @samgutentag View the post on X →
Wire this gate with your own key
Bring your own key through Flatkey / OpenRouter. Keep exact checks in code.