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.7 KB · 88 lines typescript
Raw Blame History
1// Probe 01: (a) tiny non-streaming completion with usage accounting; (b) streaming via raw SSE (comments, delta shapes, final usage).2import { raw, rawSSE, save, short } from "./lib.ts";3import { MODELS, byId } from "./models.ts";45const results: any = {};6for (const model of MODELS) {7  const reasoningCapable = !!byId.get(model)?.reasoning;8  const body: any = {9    model,10    messages: [{ role: "user", content: "What is 2+2? Answer in one short sentence." }],11    max_tokens: 200,12    usage: { include: true },13  };14  if (reasoningCapable) body.reasoning = { effort: "low" };15  const t0 = Date.now();16  const r = await raw("/chat/completions", { method: "POST", body: JSON.stringify(body) });17  const b: any = r.body;18  results[model] = { status: r.status, ms: Date.now() - t0, headers: r.headers, body: b };19  console.log(20    `\n[${model}] ${r.status} ${Date.now() - t0}ms provider=${b?.provider} model=${b?.model} finish=${b?.choices?.[0]?.finish_reason}/${b?.choices?.[0]?.native_finish_reason}`,21  );22  console.log("  top-level keys:", Object.keys(b ?? {}).join(","));23  console.log("  message keys:", Object.keys(b?.choices?.[0]?.message ?? {}).join(","));24  console.log("  content:", short(b?.choices?.[0]?.message?.content, 120));25  console.log("  reasoning:", short(b?.choices?.[0]?.message?.reasoning, 120), "details:", short(b?.choices?.[0]?.message?.reasoning_details, 300));26  console.log("  usage:", JSON.stringify(b?.usage));27  if (b?.error) console.log("  ERROR:", JSON.stringify(b.error));28}29save("01-chat.json", results);3031// (b) streaming32const streams: any = {};33for (const model of MODELS) {34  const reasoningCapable = !!byId.get(model)?.reasoning;35  const body: any = {36    model,37    messages: [{ role: "user", content: "Say hello in French, 5 words max." }],38    max_tokens: 150,39    stream: true,40    usage: { include: true },41  };42  if (reasoningCapable) body.reasoning = { effort: "low" };43  const t0 = Date.now();44  const s = await rawSSE("/chat/completions", body);45  const ev = s.events;46  const deltaKeys = new Set<string>();47  let text = "";48  let reasoning = "";49  let details: any[] = [];50  for (const e of ev) {51    if (e.data === "[DONE]") continue;52    const d = e.data?.choices?.[0]?.delta ?? {};53    for (const k of Object.keys(d)) deltaKeys.add(k);54    if (d.content) text += d.content;55    if (d.reasoning) reasoning += d.reasoning;56    if (d.reasoning_details) details.push(...d.reasoning_details);57  }58  const withUsage = ev.filter((e) => e.data?.usage);59  const finishChunks = ev.filter((e) => e.data?.choices?.[0]?.finish_reason);60  streams[model] = {61    status: s.status,62    ms: Date.now() - t0,63    headers: s.headers,64    comments: s.comments,65    count: ev.length,66    first: ev[0]?.data,67    second: ev[1]?.data,68    finishChunks: finishChunks.map((e) => e.data),69    usageChunk: withUsage.map((e) => e.data),70    last: ev[ev.length - 1]?.data,71    deltaKeys: [...deltaKeys],72    text,73    reasoning: reasoning.slice(0, 400),74    reasoningDetailsTypes: [...new Set(details.map((x) => x.type))],75    reasoningDetailsSample: details.slice(0, 2),76    error: (s as any).error,77  };78  console.log(79    `\n[stream ${model}] ${s.status} ${Date.now() - t0}ms events=${ev.length} comments=${JSON.stringify(s.comments)} deltaKeys=${[...deltaKeys]} usageChunks=${withUsage.length} finishChunks=${finishChunks.length}`,80  );81  console.log("  text:", short(text, 100), "| reasoning:", short(reasoning, 100), "| details types:", streams[model].reasoningDetailsTypes);82  console.log("  first:", short(ev[0]?.data, 400));83  console.log("  usage chunk:", short(withUsage[0]?.data, 700));84  console.log("  last:", short(ev[ev.length - 1]?.data, 200));85  if ((s as any).error) console.log("  ERROR", short((s as any).error));86}87save("01-stream.json", streams);88