SPB Git forge

spb/polyllm

Public
15commits 1branches 0releases
2.2 MBsize
maindefault branch
13 days agolast push
TypeScript 97.4% SQL 1% JavaScript 0.9% CSS 0.6%
2.5 KB · 64 lines typescript
Raw Blame History
1// Probe (a)+(b): tiny non-streaming chat completion and streaming with usage, per model.2import { CHAT_MODELS, client, rawSSE, save, short } from "./lib.ts";34const results: Record<string, any> = {};5for (const model of CHAT_MODELS) {6  const r: any = { model };7  // (a) non-streaming via OpenAI SDK8  try {9    const t0 = Date.now();10    const res = await client.chat.completions.create({11      model,12      messages: [13        { role: "system", content: "Answer in one short sentence." },14        { role: "user", content: "What is 2+2?" },15      ],16      max_completion_tokens: 200,17    });18    r.nonStream = { ms: Date.now() - t0, ...res };19    console.log(model, "non-stream OK", res.choices[0].finish_reason, short(res.choices[0].message.content, 80), JSON.stringify(res.usage));20    if ((res.choices[0].message as any).reasoning_content) console.log("  has reasoning_content:", short((res.choices[0].message as any).reasoning_content, 100));21  } catch (e: any) {22    r.nonStream = { error: e.status, body: e.error ?? e.message };23    console.log(model, "non-stream ERR", e.status, short(e.error ?? e.message));24  }25  // (b) streaming via raw SSE to capture exact chunk shapes26  const s = await rawSSE("/chat/completions", {27    model,28    messages: [{ role: "user", content: "Say hello in French, 5 words max." }],29    stream: true,30    stream_options: { include_usage: true },31    max_completion_tokens: 200,32  });33  const evs = s.events;34  const deltaKeys = new Set<string>();35  let content = "";36  let reasoning = "";37  for (const e of evs) {38    if (e.data === "[DONE]" || !e.data?.choices) continue;39    const d = e.data.choices[0]?.delta ?? {};40    Object.keys(d).forEach((k) => deltaKeys.add(k));41    if (d.content) content += d.content;42    if (d.reasoning_content) reasoning += d.reasoning_content;43  }44  const withUsage = evs.filter((e) => e.data?.usage);45  r.stream = {46    status: s.status,47    headers: s.headers,48    error: (s as any).error,49    nChunks: evs.length,50    firstChunk: evs[0]?.data,51    secondChunk: evs[1]?.data,52    lastChunks: evs.slice(-3).map((e) => e.data),53    deltaKeys: [...deltaKeys],54    content,55    reasoningLen: reasoning.length,56    usageChunkCount: withUsage.length,57    finishReasons: [...new Set(evs.map((e) => e.data?.choices?.[0]?.finish_reason).filter(Boolean))],58    eventNames: [...new Set(evs.map((e) => e.event).filter(Boolean))],59  };60  console.log(model, "stream", s.status, "chunks", evs.length, "deltaKeys", [...deltaKeys], "usage:", short(withUsage.at(-1)?.data?.usage, 400));61  results[model] = r;62}63save("01-chat-stream.json", results);64