When your script asks a user a basic yes-or-no question, they might type yes, Y, no!, or yeah. As a programmer, you have to guess every way they might answer, so your Python script needs to account for that. With the newly released Jev AI model, you can ease the load on your if statements and try to make sense of all human replies.
You’ll start with a small train station script that only accepts an uppercase Y or N. Then you’ll hand the station visitor’s answer to Jev, and finally ask three questions in one request to find out where each visitor should go:

To follow along, you should be comfortable with reading user input from the keyboard and Python dictionaries. If you’ve worked with an AI model through the OpenRouter API before, then you’ll recognize the setup steps. But that’s not a requirement.
Get Your Code: Click here to download the free sample code you’ll use to connect a Python script to Jev with the TypeSafe SDK and OpenRouter.
Take the Quiz: Test your knowledge with our interactive “How to Get Started With Jev in Python” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
How to Get Started With Jev in PythonCheck your understanding of the Jev AI model in Python, from OpenRouter setup and Noul cutoffs to Choice and Score answers.
Prerequisites
Jev is a model by TypeSafe AI, and like many AI companies, TypeSafe AI publishes a Python SDK for its model. Instead of sending a prompt and getting prose back, as you do with LLMs like Claude or ChatGPT, Jev answers every question in a typed format. You get a number or a key from a set of options, which you can conveniently parse in your Python code.
Your project needs at least Python 3.10 and the TypeSafe SDK. You’ll manage both with uv because uv installs the right Python version for you and reads your dependencies from pyproject.toml.
Note: If you don’t have uv yet, then follow the installation instructions for your operating system. Check that uv --version works in your terminal before you continue.
You also need an API key to talk to Jev. You can get one straight from TypeSafe AI, but for this tutorial, you’ll use OpenRouter. OpenRouter is a good place to try out a model without creating a separate account and entering your credit card details with every provider.
The OpenRouter video course covers the platform in depth. For now, all you need is an OpenRouter account with a few dollars of credit on it and an API key from the keys page of your account. Jev is cheap, but not free, so a request from an empty account fails.
You don’t need to pick a model version. The SDK asks for jev-latest by default, which OpenRouter resolves to the newest Jev release. If you’d rather pin a version so that your results stay reproducible, then you can pass an argument like model="jev-1.13" when you create the client later on.
Step 1: Set Up Your Jev Python Project
To get a feel for when Jev can come in handy, it’s a good idea to start with a script that doesn’t use any AI at all. The scenario takes place at a train station. A visitor walks up to the counter, and your script asks if they lost something.
Create a new folder called jev-python/, head over to it in your terminal, and add a file named plain_python.py:
plain_python.py
1def respond(lost_something):
2 if lost_something:
3 print("You can find the lost and found counter on the right.")
4 else:
5 print("What can I help you with?")
6
7def ask():
8 while True:
9 answer = input("Did you lose something? (Y/N) ")
10 if answer == "Y":
11 return True
12 if answer == "N":
13 return False
14 print("Please answer with Y or N.")
15
16def main():
17 lost_something = ask()
18 respond(lost_something)
19
20if __name__ == "__main__":
21 main()
In line 9, you ask the visitor if they lost something, and you want a clear answer. If the input is an uppercase Y or N, then ask() returns True or False. Otherwise, you stay in the while loop until you get one of the two letters.
Run the script with uv run, which picks a suitable Python interpreter for you:
$ uv run plain_python.py
Did you lose something? (Y/N) y
Please answer with Y or N.
Did you lose something? (Y/N) Y
You can find the lost and found counter on the right.
Even a lowercase y doesn’t count. You could add .upper() to the answer, so that lowercase input works, too. But now imagine that the visitor says, “Yeah, I’ve lost something.” Where does this stop? Every phrasing that a real person could come up with is another case that your script would need to handle.
That’s where Jev comes into the picture. To work with Jev in Python, you need the TypeSafe SDK. Create a pyproject.toml file next to your script and declare the dependency:
pyproject.toml
[project]
name = "jev-python"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
"typesafe-sdk==0.7.1",
]
The dependencies list is the most important part of this file. When you run a script with uv run inside this folder, uv reads your pyproject.toml file. It creates a virtual environment and installs typesafe-sdk before your script starts.
Next, create a file named .env and paste the API key from your OpenRouter account into it:
.env
OPENROUTER_API_KEY=your-openrouter-api-key
The variable name must be OPENROUTER_API_KEY in uppercase because that’s the name your script will look up in a moment.
Note: Keep this file to yourself. If you’re working with Git, then add .env to your .gitignore file before your first commit. That way, your key stays out of your repository. It’s still on your screen, though, so hide the file before you record a video or share your desktop.
You now have a working script, a project file that knows about the TypeSafe SDK, and a secret key. In the next step, you’ll connect the three.
Step 2: Ask Jev a Yes-or-No Question With Noul
The code that talks to Jev isn’t that different from your plain Python script, which is why you’ll enhance what you have rather than start from scratch. Copy plain_python.py to a new file named jev_noul.py. Noul is the name of the first Jev primitive that you’ll use, and it’s the one that answers yes-or-no questions.
Connect Your Script to Jev
Open jev_noul.py and connect it to Jev through OpenRouter:
jev_noul.py
1import os
2
3from typesafe_sdk import Noul, TypeSafeClient
4
5client = TypeSafeClient(
6 api_key=os.environ["OPENROUTER_API_KEY"],
7 base_url="https://openrouter.ai/api",
8)
9
10def respond(lost_something):
11 if lost_something:
12 print("You can find the lost and found counter on the right.")
13 else:
14 print("What can I help you with?")
15
16def ask():
17 while True:
18 answer = input("Did you lose something? ")
19 r = client.system_one(
20 state=answer,
21 questions={
22 "lost_something": Noul(
23 instructions="Is the answer from the user affirmative?"
24 ),
25 },
26 )
27 lost_something = r.answers["lost_something"].noul
28 if lost_something > 0.8:
29 return True
30 if lost_something < 0.2:
31 return False
32 print("Sorry, I didn't get that.")
33
34def main():
35 lost_something = ask()
36 respond(lost_something)
37
38if __name__ == "__main__":
39 main()
In line 3, you import Noul and TypeSafeClient from the SDK. Then, in lines 5 to 8, you create your client as an instance of TypeSafeClient. The API key comes from the environment variable you defined in .env, and the base_url points to the OpenRouter API. If you had an API key from TypeSafe AI directly, then you’d store it in a TYPESAFE_API_KEY variable and leave out both arguments.
In line 18, you only ask “Did you lose something?” and don’t mention Y or N anymore. The visitor’s answer then goes into client.system_one() in line 19, and you store the reply in r, which is short for response. The method takes two arguments. The state is the text that Jev should look at, and questions is a dictionary of the questions that you want Jev to answer about that text.
The questions dictionary in lines 21 to 25 has one item. You can pick any key you like, and "lost_something" is what you’ll use to look up the answer later. The value is your Noul object with instructions that tell Jev which lens to look through when it reads the state.
In line 27, you look up your question in r.answers by its key and read its .noul attribute. That’s a float between 0 and 1. You can think of it as a Boolean on a sliding scale, where 1 means a clear yes and 0 a clear no.
You pick the cutoffs in lines 28 and 30 yourself. If the value is above 0.8, then ask() returns True. If it’s below 0.2, then ask() returns False.
Anything in between means that Jev isn’t sure, and you ask again. Lower the bar, and you accept more mumbled answers. Raise it, and you ask visitors to repeat themselves more often.
Drag the two cutoffs below to see where the Noul scores of a few typical replies end up: