1import OpenAI from 'openai';
2import { z } from 'zod';
3import { zodResponseFormat } from 'openai/helpers/zod';
4
5const openai = new OpenAI();
6
7// 1. Output contract as Zod schema
8const Triage = z.object({
9 category: z.enum(['bug', 'feature', 'support']),
10 severity: z.enum(['low', 'medium', 'high']),
11 summary: z.string().max(120),
12 reasoning: z.string(),
13});
14
15// 2. Few-shot examples
16const examples = [
17 { in: 'Site is down for everyone', out: { category: 'bug', severity: 'high', summary: 'Outage', reasoning: 'All users affected' } },
18 { in: 'Add dark mode', out: { category: 'feature', severity: 'low', summary: 'Dark mode request', reasoning: 'Quality-of-life UX' } },
19];
20
21export async function triage(ticket: string) {
22 // 3. Structured response with schema enforcement
23 const res = await openai.chat.completions.parse({
24 model: 'gpt-4o-mini',
25 messages: [
26 { role: 'system', content: 'You are a triage bot. Classify support tickets. If unsure, return reasoning explaining doubt.' },
27 ...examples.flatMap(e => [
28 { role: 'user' as const, content: e.in },
29 { role: 'assistant' as const, content: JSON.stringify(e.out) },
30 ]),
31 { role: 'user', content: ticket },
32 ],
33 response_format: zodResponseFormat(Triage, 'triage'),
34 });
35
36 // 4. Type-safe parsed output
37 return res.choices[0].message.parsed!;
38}