import { MODELS, rawPost, rawSSE, save, short } from "./lib.ts"; const results: Record = {}; for (const model of MODELS) { const t0 = Date.now(); // (a) tiny non-streaming const a = await rawPost("/chat/completions", { model, messages: [{ role: "user", content: "What is 2+2? Answer in one short sentence." }], max_tokens: 200, }); const ms = Date.now() - t0; const msg = (a.body as any)?.choices?.[0]?.message; console.log(`\n[${model}] non-stream ${a.status} ${ms}ms finish=${(a.body as any)?.choices?.[0]?.finish_reason}`); console.log(" headers:", JSON.stringify(a.headers)); console.log(" content:", short(msg?.content, 200)); console.log(" reasoning_content:", short(msg?.reasoning_content, 200)); console.log(" usage:", JSON.stringify((a.body as any)?.usage)); console.log(" top-level keys:", Object.keys((a.body as any) ?? {}), "message keys:", Object.keys(msg ?? {})); if (a.status !== 200) console.log(" body:", short(a.body, 600)); // (b) streaming WITHOUT stream_options const s1 = await rawSSE("/chat/completions", { model, messages: [{ role: "user", content: "Say hello in French, 5 words max." }], max_tokens: 200, }); // (b') streaming WITH include_usage const s2 = await rawSSE("/chat/completions", { model, messages: [{ role: "user", content: "Say hello in French, 5 words max." }], max_tokens: 200, stream_options: { include_usage: true }, }); const summarize = (s: typeof s1) => { const deltaKeys = new Set(); let usageChunks = 0; let finish: string | null = null; let emptyChoicesChunks = 0; const eventLines = s.rawLines.filter((l) => l.startsWith("event:")); for (const c of s.chunks) { if (c === "[DONE]") continue; if (c.usage) usageChunks++; if (Array.isArray(c.choices) && c.choices.length === 0) emptyChoicesChunks++; for (const ch of c.choices ?? []) { for (const k of Object.keys(ch.delta ?? {})) deltaKeys.add(k); if (ch.finish_reason) finish = ch.finish_reason; } } return { status: s.status, nChunks: s.chunks.length, deltaKeys: [...deltaKeys], usageChunks, emptyChoicesChunks, finish, eventLines: eventLines.length, hasDone: s.chunks.at(-1) === "[DONE]", error: s.error, headers: s.headers }; }; const sum1 = summarize(s1), sum2 = summarize(s2); console.log(" stream (no include_usage):", JSON.stringify(sum1)); console.log(" stream (include_usage): ", JSON.stringify(sum2)); console.log(" first 3 chunks:", short(s2.chunks.slice(0, 3), 900)); console.log(" last 3 chunks:", short(s2.chunks.slice(-3), 900)); results[model] = { nonStream: a, stream: { noUsage: { summary: sum1, chunks: s1.chunks }, withUsage: { summary: sum2, chunks: s2.chunks } } }; } save("01-chat-stream", results);