// (a) tiny non-streaming completion (default thinking), (b) streaming with include_usage, per model. import { client, MODELS, rawSSE, save, errInfo } from "./lib.ts"; const out: Record = {}; for (const model of MODELS) { const t0 = Date.now(); try { const r = await client.chat.completions.create({ model, messages: [{ role: "user", content: "What is 2+2? Answer in one short sentence." }], max_tokens: 200, }); out[`${model}:nonstream`] = { ms: Date.now() - t0, response: r }; console.log(model, "nonstream", Date.now() - t0, "ms", JSON.stringify(r.usage), "finish", r.choices[0].finish_reason, "reasoning?", !!(r.choices[0].message as any).reasoning_content); } catch (e) { out[`${model}:nonstream`] = errInfo(e); console.log(model, "nonstream ERR", JSON.stringify(errInfo(e))); } const t1 = Date.now(); const s = await rawSSE("/chat/completions", { model, messages: [{ role: "user", content: "Say hello in French, 5 words max." }], max_tokens: 200, stream: true, stream_options: { include_usage: true }, }); const deltaKeys = new Set(); let firstReasoningMs: number | null = null, firstContentMs: number | null = null; for (const ev of s.events) { if (ev === "[DONE]") continue; const d = ev.choices?.[0]?.delta; if (d) for (const k of Object.keys(d)) { deltaKeys.add(k); if (d.reasoning_content && firstReasoningMs === null) firstReasoningMs = 0; if (d.content && firstContentMs === null) firstContentMs = 0; } } out[`${model}:stream`] = { ms: Date.now() - t1, status: s.status, headers: s.headers, comments: s.comments, nEvents: s.events.length, deltaKeys: [...deltaKeys], first3: s.events.slice(0, 3), last4: s.events.slice(-4) }; console.log(model, "stream", s.status, Date.now() - t1, "ms", s.events.length, "events; delta keys", [...deltaKeys], "comments", s.comments.length); } save("01-chat-stream.json", out);