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.7 KB · 49 lines typescript
Raw Blame History
1import { MODELS, rawPost, rawSSE, save, short } from "./lib.ts";23const results: Record<string, unknown> = {};4for (const model of MODELS) {5  const t0 = Date.now();6  // (a) tiny non-streaming7  const a = await rawPost("/chat/completions", {8    model, messages: [{ role: "user", content: "What is 2+2? Answer in one short sentence." }], max_tokens: 200,9  });10  const ms = Date.now() - t0;11  const msg = (a.body as any)?.choices?.[0]?.message;12  console.log(`\n[${model}] non-stream ${a.status} ${ms}ms finish=${(a.body as any)?.choices?.[0]?.finish_reason}`);13  console.log("  headers:", JSON.stringify(a.headers));14  console.log("  content:", short(msg?.content, 200));15  console.log("  reasoning_content:", short(msg?.reasoning_content, 200));16  console.log("  usage:", JSON.stringify((a.body as any)?.usage));17  console.log("  top-level keys:", Object.keys((a.body as any) ?? {}), "message keys:", Object.keys(msg ?? {}));18  if (a.status !== 200) console.log("  body:", short(a.body, 600));1920  // (b) streaming WITHOUT stream_options21  const s1 = await rawSSE("/chat/completions", {22    model, messages: [{ role: "user", content: "Say hello in French, 5 words max." }], max_tokens: 200,23  });24  // (b') streaming WITH include_usage25  const s2 = await rawSSE("/chat/completions", {26    model, messages: [{ role: "user", content: "Say hello in French, 5 words max." }], max_tokens: 200,27    stream_options: { include_usage: true },28  });29  const summarize = (s: typeof s1) => {30    const deltaKeys = new Set<string>();31    let usageChunks = 0; let finish: string | null = null; let emptyChoicesChunks = 0;32    const eventLines = s.rawLines.filter((l) => l.startsWith("event:"));33    for (const c of s.chunks) {34      if (c === "[DONE]") continue;35      if (c.usage) usageChunks++;36      if (Array.isArray(c.choices) && c.choices.length === 0) emptyChoicesChunks++;37      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; }38    }39    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 };40  };41  const sum1 = summarize(s1), sum2 = summarize(s2);42  console.log("  stream (no include_usage):", JSON.stringify(sum1));43  console.log("  stream (include_usage):  ", JSON.stringify(sum2));44  console.log("  first 3 chunks:", short(s2.chunks.slice(0, 3), 900));45  console.log("  last 3 chunks:", short(s2.chunks.slice(-3), 900));46  results[model] = { nonStream: a, stream: { noUsage: { summary: sum1, chunks: s1.chunks }, withUsage: { summary: sum2, chunks: s2.chunks } } };47}48save("01-chat-stream", results);49