Guide
Guide Jev en Python
Le SDK Python officiel de TypeSafe fonctionne avec ce site sans modification : installez typesafe-sdk, pointez la base URL vers jev-api.org et appelez system_one avec une clé jev-api.org. Ce guide couvre l'installation, la configuration, les trois types de questions, la lecture des réponses et le client async.
Mis à jour
Installation
Le paquet s'appelle typesafe-sdk sur PyPI et requiert Python 3.10 ou plus. Le source est sur github.com/typesafe-ai/typesafe-sdk-python.
pip install typesafe-sdk
# or: uv add typesafe-sdk
# requires Python 3.10+Configurer la clé et la base URL
Le SDK lit deux variables d'environnement. TYPESAFE_API_KEY prend une clé de votre tableau de bord jev-api.org — les clés de la console TypeSafe ne fonctionnent pas ici — et TYPESAFE_BASE_URL doit valoir https://jev-api.org pour que les requêtes atteignent l'endpoint compatible /v1/systemone au lieu d'api.typesafe.ai.
# .env — a key from your jev-api.org dashboard
TYPESAFE_API_KEY=jeva_...
TYPESAFE_BASE_URL=https://jev-api.orgVous pouvez aussi les passer directement : TypeSafeClient(api_key=..., base_url="https://jev-api.org"). Le modèle par défaut est jev-latest ; remplacez-le avec TYPESAFE_DEFAULT_MODEL ou l'argument model. Le timeout par défaut est de 10 secondes.
Premier appel : Noul, Choice et Score
client.system_one prend un state — chaîne, objet ou tableau — et une map questions construite avec les classes Noul, Choice et Score. L'appel ci-dessous revient dans la bande de latence documentée de 70 à 500 ms et utilise 1 crédit sur ce site.
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
with TypeSafeClient() as client: # reads TYPESAFE_API_KEY and TYPESAFE_BASE_URL
response = client.system_one(
state={"document": "I was charged twice. Please fix this ASAP."},
questions={
"billing": Noul(instructions="Is this ticket about billing?"),
"tone": Choice(
instructions="What is the customer's tone?",
criteria={"calm": None, "frustrated": None, "angry": None},
),
"urgency": Score(
instructions="How urgent is this ticket?",
criteria=["can wait", "this week", "today"],
),
},
)
print(response.nouls["billing"].noul) # 0.0 .. 1.0
print(response.choices["tone"].choice) # winning option
print(response.scores["urgency"].score) # fractional levelLire les réponses
La réponse expose des vues typées : response.nouls, response.choices et response.scores, indexées par vos ids de question. Une réponse Noul porte .noul, la probabilité de oui entre 0 et 1. Une Choice porte .choice, .probabilities et .confidence. Une Score porte un .score fractionnaire plus .legend, .probabilities et .confidence.
Utilisez confidence comme signal de relais. Quand il est faible ou que deux options sont proches, envoyez le cas à une personne ou posez une question de suivi plus étroite au lieu de baisser le seuil à l'aveugle. Vous pouvez aussi lire l'objet brut par question via response.answers["id"].
Client async
AsyncTypeSafeClient a la même interface avec des appels awaitables — pratique dans des endpoints FastAPI ou des workers qui traitent plusieurs states en parallèle.
from typesafe_sdk import AsyncTypeSafeClient, Noul
async with AsyncTypeSafeClient() as client:
response = await client.system_one(
state="I was charged twice for my subscription.",
questions={"refund": Noul(instructions="Is the customer asking for money back?")},
)
print(response.answers["refund"])Sans le SDK : requests pur
Si vous ne voulez pas de la dépendance, envoyez vous-même le corps JSON. L'endpoint simple de ce site, /api/v1/decisions, accepte la même forme state+questions avec le modèle jev-1.13 et des limites un peu plus strictes (1 à 6 questions, 2 à 8 options de Choice).
import os
import requests
res = requests.post(
"https://jev-api.org/api/v1/decisions",
headers={"Authorization": f"Bearer {os.environ['JEV_API_KEY']}"},
json={
"model": "jev-1.13",
"state": "I was charged twice for my subscription.",
"questions": {
"refund": {"type": "noul", "instructions": "Is the customer asking for money back?"}
},
},
timeout=30,
)
print(res.json()["answers"]["refund"])Erreurs et timeouts
jev-api.org renvoie des erreurs JSON avec un champ detail. Les codes que vous verrez :
- 401 — clé absente ou rejetée. Vérifiez l'en-tête Authorization: Bearer et que la clé vient de ce site.
- 402 — la clé est valide mais le solde ne couvre pas l'appel. Ajoutez des crédits sur la page des tarifs.
- 422 — le corps a échoué la validation ou le modèle l'a rejeté (par exemple au-delà des limites de 64k/32k tokens). Le message nomme le champ.
- 429 — limite de débit. Reculez et réessayez.
- 502 — le service de décision n'a pas renvoyé de réponses. Aucun crédit n'est utilisé.
FAQ
Puis-je utiliser ma clé de la console TypeSafe ici ?
Non. Les clés ne sont pas interchangeables : celles de TypeSafe fonctionnent sur api.typesafe.ai et celles du tableau de bord jev-api.org fonctionnent ici. Mettez TYPESAFE_API_KEY à une clé jev-api.org et TYPESAFE_BASE_URL à https://jev-api.org.
Quel endpoint le SDK appelle-t-il sur ce site ?
Avec base_url à https://jev-api.org, le SDK poste vers /v1/systemone — l'endpoint compatible TypeSafe, qui accepte l'ensemble complet des questions (jusqu'à 256 questions, 255 options de Choice, instructions structurées) et facture 1 crédit par appel réussi.
Le SDK retente-t-il automatiquement ?
Le SDK TypeSafe embarque une politique de retry par défaut pour les erreurs transitoires comme 429 ; vous pouvez la modifier via l'option retry du client. Les erreurs de validation (422) doivent être corrigées dans le corps, pas retentées.
Quelle version de Python faut-il ?
Python 3.10 ou plus. Le paquet typesafe-sdk contient les clients synchrone (TypeSafeClient) et asynchrone (AsyncTypeSafeClient).
Comment savoir quelle version du modèle a répondu ?
Le champ model de la réponse rapporte toujours l'id versionné qui a servi la requête — aujourd'hui jev-1.13.0 — même si vous avez envoyé un alias comme jev-latest.
Envoyez la première décision
Créez une clé, définissez les deux variables d'environnement et exécutez l'extrait ci-dessus.