// Probe (a)+(b): tiny non-streaming chat completion and streaming with usage, per model. import { CHAT_MODELS, client, rawSSE, save, short } from "./lib.ts"; const results: Record = {}; for (const model of CHAT_MODELS) { const r: any = { model }; // (a) non-streaming via OpenAI SDK try { const t0 = Date.now(); const res = await client.chat.completions.create({ model, messages: [ { role: "system", content: "Answer in one short sentence." }, { role: "user", content: "What is 2+2?" }, ], max_completion_tokens: 200, }); r.nonStream = { ms: Date.now() - t0, ...res }; console.log(model, "non-stream OK", res.choices[0].finish_reason, short(res.choices[0].message.content, 80), JSON.stringify(res.usage)); if ((res.choices[0].message as any).reasoning_content) console.log(" has reasoning_content:", short((res.choices[0].message as any).reasoning_content, 100)); } catch (e: any) { r.nonStream = { error: e.status, body: e.error ?? e.message }; console.log(model, "non-stream ERR", e.status, short(e.error ?? e.message)); } // (b) streaming via raw SSE to capture exact chunk shapes const s = await rawSSE("/chat/completions", { model, messages: [{ role: "user", content: "Say hello in French, 5 words max." }], stream: true, stream_options: { include_usage: true }, max_completion_tokens: 200, }); const evs = s.events; const deltaKeys = new Set(); let content = ""; let reasoning = ""; for (const e of evs) { if (e.data === "[DONE]" || !e.data?.choices) continue; const d = e.data.choices[0]?.delta ?? {}; Object.keys(d).forEach((k) => deltaKeys.add(k)); if (d.content) content += d.content; if (d.reasoning_content) reasoning += d.reasoning_content; } const withUsage = evs.filter((e) => e.data?.usage); r.stream = { status: s.status, headers: s.headers, error: (s as any).error, nChunks: evs.length, firstChunk: evs[0]?.data, secondChunk: evs[1]?.data, lastChunks: evs.slice(-3).map((e) => e.data), deltaKeys: [...deltaKeys], content, reasoningLen: reasoning.length, usageChunkCount: withUsage.length, finishReasons: [...new Set(evs.map((e) => e.data?.choices?.[0]?.finish_reason).filter(Boolean))], eventNames: [...new Set(evs.map((e) => e.event).filter(Boolean))], }; console.log(model, "stream", s.status, "chunks", evs.length, "deltaKeys", [...deltaKeys], "usage:", short(withUsage.at(-1)?.data?.usage, 400)); results[model] = r; } save("01-chat-stream.json", results);