TL;DR
- The official Python package is typesafe-sdk and supports sync and async clients.
- Python results are grouped into choices, scores, and nouls.
- Use full distributions and labeled examples when setting automation thresholds.
- Calculate numbers and dates in Python rather than asking Jev to do arithmetic.
The TypeSafe Python SDK offers synchronous and asynchronous clients for Jev. Both send the same state and typed questions. The difference is how they fit into the rest of the application.
This tutorial classifies an incoming request, scores its urgency, and estimates whether it describes a payment problem. The final routing stays in Python so the model never owns the side effect.
Install the Python SDK
The official Python documentation supports uv and pip.
uv add typesafe-sdk
# or
pip install typesafe-sdk
export TYPESAFE_API_KEY="your-api-key"
TypeSafe’s quick start currently specifies Python 3.10 or newer. Keep the API key in a server-side secret store or environment variable.
Make a synchronous Jev request
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
state = {
"message": "My renewal failed and I need access before tonight.",
"customer_tier": "paid",
}
questions = {
"route": Choice(
instructions="Which team should handle `message`?",
criteria={
"billing": "Payment, renewal, or refund problem",
"technical": "Bug or integration problem",
"account": "Login or account-access problem",
"other": "None of the listed categories",
},
),
"urgency": Score(
instructions="How urgent is `message`?",
criteria=["can wait", "needs attention soon", "needs attention today"],
),
"payment_problem": Noul(
instructions="Does `message` describe a payment or renewal failure?"
),
}
with TypeSafeClient() as client:
response = client.system_one(state=state, questions=questions)
route = response.choices["route"]
urgency = response.scores["urgency"]
payment_problem = response.nouls["payment_problem"]
print(route.choice, route.confidence, route.probabilities)
print(urgency.score, urgency.confidence, urgency.probabilities)
print(payment_problem.noul)
The Python client groups answers by primitive. A Choice result sits in response.choices, a Score result in response.scores, and a Noul result in response.nouls.
The Noul value is already the probability of yes, so it does not have the separate confidence property returned for Choice and Score.
Use the async client in a service
An API server should avoid blocking its event loop while waiting on an external request. The async client uses the same question objects.
from typesafe_sdk import AsyncTypeSafeClient
async def evaluate_request(state: dict):
async with AsyncTypeSafeClient() as client:
return await client.system_one(
state=state,
questions=questions,
)
Create clients according to the SDK’s lifecycle guidance for the framework in use. The important product behavior is the fallback. A timeout or exhausted retry should lead to a known state, not an accidental automatic action.
async def route_request(state: dict):
try:
response = await evaluate_request(state)
except Exception as exc:
logger.exception("Jev request failed", exc_info=exc)
return {"queue": "manual_review", "reason": "model_unavailable"}
answer = response.choices["route"]
if answer.confidence < 0.65:
return {"queue": "manual_review", "reason": "uncertain_route"}
return {"queue": answer.choice, "reason": "jev_route"}
The threshold is illustrative. Test it on the distribution of requests the service will actually receive.
Read probabilities, not only the winner
A result can select billing while assigning nearly as much probability to account. The winner alone hides that ambiguity.
Keep the full distribution in evaluation logs, subject to the privacy rules for the underlying state. Useful review fields include:
- model version
- question version or code revision
- selected choice or score
- full probability distribution
- confidence where available
- action taken by the application
- corrected label when a person reviews the case
That record makes it possible to compare a new model version, spot taxonomy overlap, and find thresholds that automate safe cases without burying reviewers.
Keep calculations in Python
TypeSafe’s Jev 1.13 jaggedness page says the model is not reliable for counting, exact arithmetic, or date comparison. Python already handles those operations precisely.
from datetime import UTC, datetime
trial_ends_at = datetime.fromisoformat(state["trial_ends_at"])
is_expired = trial_ends_at < datetime.now(UTC)
Pass is_expired into the state if the semantic question needs that fact. Do not ask the model to infer it from two date strings.
The same rule applies to business eligibility. Check plan, geography, account balance, inventory, and deadlines with deterministic systems. Use Jev for the remaining judgment, such as whether a message is asking to cancel or whether a passage supports a claim.
Separate broad policies into questions
Suppose a product manager asks for an automatic save-offer workflow. One large Noul question such as “Should we give this customer an offer?” hides too much.
A more inspectable design might ask Jev whether the message expresses price concern and whether it contains a product complaint. Python can then combine those signals with exact eligibility data, offer limits, and account history.
This has two benefits. The semantic questions can be evaluated independently, and the commercial policy remains visible in code. When the offer rule changes, the team changes the policy rather than hoping a rewritten prompt preserves every old boundary.
Evaluate before automating
Create a labeled fixture set before the first production action.
CASES = [
{
"state": {"message": "I was billed after cancelling."},
"expected_route": "billing",
},
{
"state": {"message": "The app crashes when I upload a photo."},
"expected_route": "technical",
},
]
A useful evaluation reports more than total accuracy. Break errors down by class, confidence range, and the action that would have followed. A wrong low-risk route and a wrong irreversible decision should not be treated as equivalent.
For the production design behind that test, read Jev confidence and threshold routing. Developers using Node can follow the separate Jev TypeScript quickstart.
Sources
FAQ
- How do I install Jev for Python?
- Install the official client with pip install typesafe-sdk or uv add typesafe-sdk, then set TYPESAFE_API_KEY.
- Does TypeSafe have an asynchronous Python client?
- Yes. The package provides AsyncTypeSafeClient as well as the synchronous TypeSafeClient.
- Where are Jev answers stored in Python?
- The Python response groups results by primitive in response.choices, response.scores, and response.nouls.