Guide TypeScript
OpenAI Decisions API en TypeScript
OpenAI n'a pas publié de SDK pour sa Decisions API — il n'y a pas de client.decisions.create à copier. Cette page montre du TypeScript fonctionnel et entièrement typé pour l'endpoint de ce site — une alternative appelable à l'OpenAI Decisions API qui sert decisions-1 et suit le même motif de décision contrainte.
Mis à jour
Définir le contrat
Typez la requête une fois et réutilisez-la partout. model est une union de littéraux, l'id épinglé ne peut pas dériver en coquille. questions est un record indexé par vos ids, chacun de type noul, choice ou score.
Typez les réponses comme une union discriminée par type — c'est ce qui rend le traitement sûr : une réponse noul a un champ noul, une choice a choice et probabilities — le filtrage par type vous donne les bons champs.
TypeScript
interface DecisionQuestion {
type: 'noul' | 'choice' | 'score'
instructions: string
criteria?: Record<string, string> | string[]
}
interface DecisionRequest {
model: 'decisions-1' | 'decisions-latest'
state: string | Record<string, unknown> | unknown[]
questions: Record<string, DecisionQuestion>
}
interface DecisionAnswers {
[questionId: string]:
| { type: 'noul'; noul: number }
| { type: 'choice'; choice: string; probabilities: Record<string, number>; confidence: number }
| { type: 'score'; score: number; legend: string[]; probabilities: Record<string, number>; confidence: number }
}Faire l'appel
Un seul POST avec une clé Bearer. satisfies DecisionRequest vérifie le corps à la compilation ; AbortSignal.timeout empêche les appels bloqués de figer le pipeline. Filtrez answers par le champ type avant de les lire.
TypeScript
const res = await fetch('https://decisions-api.net/api/v1/decisions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.DECISIONS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(request satisfies DecisionRequest),
signal: AbortSignal.timeout(30000),
})
const { answers } = (await res.json()) as { answers: DecisionAnswers }
const team = answers.team
if (team.type === 'choice' && team.confidence >= 0.7) {
routeTo(team.choice)
}Timeouts et retries
429 et 502 méritent un retry court avec backoff — les appels échoués ne sont pas facturés. 402 signifie solde vide : rechargez, ne réessayez pas. 422 est une erreur de validation ; le message nomme le champ, corrigez donc le corps plutôt que de réessayer.
TypeScript
async function decide(body: DecisionRequest, attempts = 3): Promise<DecisionAnswers> {
for (let i = 0; i < attempts; i++) {
const res = await fetch('https://decisions-api.net/api/v1/decisions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.DECISIONS_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
signal: AbortSignal.timeout(30000),
})
if (res.status === 429 || res.status === 502) {
await new Promise(r => setTimeout(r, 2 ** i * 1000))
continue
}
if (res.status === 402) throw new Error('out of credits')
if (!res.ok) throw new Error(`decision call failed: ${res.status}`)
return (await res.json() as { answers: DecisionAnswers }).answers
}
throw new Error('decision call failed')
}Encapsulez l'appel dans un helper
L'appelant doit voir une fonction qui prend du texte et renvoie une étiquette — pas les détails HTTP. Mettez le timeout, le test du 402 et la boucle de retry dans decide() une fois, et chaque point d'appel reste propre.
TypeScript
// Keep the call behind one typed function — timeouts, 402s,
// and retries live inside it, not at every call site.
export async function routeTicket(text: string): Promise<string> {
const answers = await decide({
model: 'decisions-1',
state: text,
questions: {
team: {
type: 'choice',
instructions: 'Which team should own this ticket?',
criteria: {
payments: 'Checkout or billing.',
frontend: 'Rendering or browser behavior.',
account: 'Login or permissions.',
},
},
},
})
const team = answers.team
return team.type === 'choice' && team.confidence >= 0.7 ? team.choice : 'triage'
}FAQ
Existe-t-il un exemple officiel du SDK OpenAI pour la Decisions API ?
Non. OpenAI n'a publié ni méthodes SDK ni schéma de requête pour sa Decisions API — tout code montrant client.decisions.create est inventé. Cette page utilise du HTTP simple.
Ai-je besoin d'un générateur de code pour les types ?
Non — les interfaces de cette page couvrent tout le contrat. Copiez-les dans votre projet ; elles sont assez petites pour être auditées et versionnées avec votre code.
Comment envoyer un contexte structuré ?
state accepte un objet JSON ou un tableau, pas seulement une chaîne — passez des dicts directement dans le corps json et le modèle les lit comme contexte.
Lancez une décision depuis le navigateur
Aucune configuration — exécutez un vrai appel dans le bac à sable avec 1 crédit offert aux nouveaux visiteurs.