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%
3.3 KB · 76 lines typescript
Raw Blame History
1import { chat, rawSSE, save, MODELS, short } from "./lib.ts";23const out: Record<string, unknown> = {};4for (const model of MODELS) {5  // (a) tiny non-streaming6  const r = await chat({7    model,8    messages: [{ role: "user", content: "What is 2+2? Answer in one short sentence." }],9    max_completion_tokens: 200,10  });11  const b: any = r.body;12  const usage = b?.usage;13  const tps = usage && b?.time_info ? Math.round(usage.completion_tokens / b.time_info.completion_time) : null;14  out[`${model}:nonstream`] = { ...r, tokensPerSecond: tps };15  console.log(model, "nonstream", r.status, r.ms + "ms", "tps=", tps, "\n  message keys:", b?.choices?.[0]?.message && Object.keys(b.choices[0].message), "\n  content:", short(b?.choices?.[0]?.message?.content, 200), "\n  reasoning:", short(b?.choices?.[0]?.message?.reasoning, 120), "\n  usage:", JSON.stringify(usage), "\n  time_info:", JSON.stringify(b?.time_info), "\n  top keys:", b && Object.keys(b));1617  // (b) streaming with include_usage18  const s = await rawSSE("/chat/completions", {19    model,20    messages: [{ role: "user", content: "Say hello in French, 5 words max." }],21    max_completion_tokens: 200,22    stream: true,23    stream_options: { include_usage: true },24  });25  const deltaKeys = new Set<string>();26  const finishes: string[] = [];27  let content = "";28  let reasoning = "";29  const withUsage: number[] = [];30  const withTimeInfo: number[] = [];31  const otherKeys = new Set<string>();32  s.events.forEach((e, i) => {33    if (e.data === "[DONE]") return;34    const d = e.data;35    Object.keys(d).forEach((k) => otherKeys.add(k));36    if (d.usage) withUsage.push(i);37    if (d.time_info) withTimeInfo.push(i);38    const c = d.choices?.[0];39    if (c?.delta) Object.keys(c.delta).forEach((k) => deltaKeys.add(k));40    if (c?.delta?.content) content += c.delta.content;41    if (c?.delta?.reasoning) reasoning += c.delta.reasoning;42    if (c?.delta?.reasoning_content) reasoning += "[RC]" + c.delta.reasoning_content;43    if (c?.finish_reason) finishes.push(`${i}:${c.finish_reason}`);44  });45  out[`${model}:stream`] = {46    status: s.status,47    headers: s.headers,48    ttfbMs: s.ttfbMs,49    totalMs: s.totalMs,50    nEvents: s.events.length,51    deltaKeys: [...deltaKeys],52    topLevelKeys: [...otherKeys],53    finishes,54    withUsage,55    withTimeInfo,56    content,57    reasoning: short(reasoning, 400),58    hasThinkTag: /<think>/.test(content),59    first3: s.events.slice(0, 3),60    last3: s.events.slice(-3),61    error: s.error,62  };63  console.log(model, "stream", s.status, "events", s.events.length, "ttfb", s.ttfbMs, "deltaKeys", [...deltaKeys], "finishes", finishes, "usageAt", withUsage, "timeInfoAt", withTimeInfo, "\n  content:", short(content, 150), "\n  reasoning:", short(reasoning, 150), "\n  last3:", short(s.events.slice(-3), 900));64  // (b2) streaming WITHOUT stream_options: is usage still present?65  const s2 = await rawSSE("/chat/completions", {66    model,67    messages: [{ role: "user", content: "Say hi." }],68    max_completion_tokens: 30,69    stream: true,70  });71  const usageIdx = s2.events.map((e, i) => (e.data !== "[DONE]" && e.data?.usage ? i : -1)).filter((i) => i >= 0);72  out[`${model}:stream-no-options`] = { status: s2.status, nEvents: s2.events.length, usageIdx, last2: s2.events.slice(-2) };73  console.log(model, "stream w/o stream_options: usage at", usageIdx, "of", s2.events.length);74}75save("01-chat-stream.json", out);76