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%
4.8 KB · 91 lines typescript
Raw Blame History
1// Shared helpers for the PolyLLM OpenAI probes. The API key is read from the OPENAI_API_KEY2// environment variable by the SDK; nothing secret is stored in these files or in results/.3import OpenAI from "openai";4import fs from "node:fs";5import zlib from "node:zlib";67export const client = new OpenAI({ maxRetries: 1, timeout: 180_000 });89// Six focus models required by the audit (+ broad sweep list in 02-basic.ts).10export const PROBE_MODELS = ["gpt-5.5", "gpt-5.4-mini", "gpt-5.6-sol", "gpt-6-astra", "gpt-4.1-mini", "o4-mini"];11export const REASONING_MODELS = new Set(["gpt-5.5", "gpt-5.4-mini", "gpt-5.6-sol", "gpt-6-astra", "o4-mini"]);1213export function errInfo(e: any) {14  return {15    status: e?.status ?? null,16    code: e?.code ?? e?.error?.code ?? null,17    type: e?.type ?? e?.error?.type ?? null,18    param: e?.param ?? e?.error?.param ?? null,19    message: e?.error?.message ?? e?.message ?? String(e),20    request_id: e?.requestID ?? null,21    sdk_class: e?.constructor?.name ?? null,22  };23}2425export async function attempt<T>(label: string, fn: () => Promise<T>) {26  const t0 = Date.now();27  try {28    const result = await fn();29    const r = { label, ok: true as const, ms: Date.now() - t0, result };30    console.log(`OK   ${label} (${r.ms} ms)`);31    return r;32  } catch (e: any) {33    const r = { label, ok: false as const, ms: Date.now() - t0, error: errInfo(e) };34    console.log(`FAIL ${label} -> ${r.error.status} ${r.error.code ?? ""} ${r.error.message}`);35    return r;36  }37}3839export function save(name: string, data: unknown) {40  fs.mkdirSync("results", { recursive: true });41  fs.writeFileSync(`results/${name}.json`, JSON.stringify(data, null, 1));42  console.log(`saved results/${name}.json`);43}4445export function pickHeaders(h: Headers) {46  const out: Record<string, string> = {};47  h.forEach((v, k) => { if (/^(x-ratelimit|x-request-id|openai-|retry-after|x-openai|cf-ray|content-type)/i.test(k)) out[k] = v; });48  return out;49}5051export function summarizeResponse(r: any) {52  return {53    id: r.id, model: r.model, status: r.status, incomplete_details: r.incomplete_details ?? null,54    service_tier: r.service_tier ?? null, store: r.store ?? null,55    output_item_types: (r.output ?? []).map((o: any) => o.type + (o.type === "message" ? `[${(o.content ?? []).map((c: any) => c.type).join(",")}]` : "")),56    output_text: (r.output_text ?? "").slice(0, 160),57    usage: r.usage ?? null,58    reasoning: r.reasoning ?? null, text: r.text ?? null, temperature: r.temperature ?? null, top_p: r.top_p ?? null,59    truncation: r.truncation ?? null, max_output_tokens: r.max_output_tokens ?? null,60  };61}6263// 2x2 RGBA PNG (red, green / blue, white) built with zlib, no deps.64export function tinyPngBase64(): string {65  const w = 2, h = 2;66  const px = [[255, 0, 0, 255], [0, 255, 0, 255], [0, 0, 255, 255], [255, 255, 255, 255]];67  const raw = Buffer.alloc((1 + w * 4) * h);68  for (let y = 0; y < h; y++) { raw[y * (1 + w * 4)] = 0; for (let x = 0; x < w; x++) Buffer.from(px[y * w + x]).copy(raw, y * (1 + w * 4) + 1 + x * 4); }69  const crcTable = new Int32Array(256).map((_, n) => { let c = n; for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; return c; });70  const crc = (b: Buffer) => { let c = -1; for (const x of b) c = crcTable[(c ^ x) & 0xff] ^ (c >>> 8); return (c ^ -1) >>> 0; };71  const chunk = (type: string, data: Buffer) => { const len = Buffer.alloc(4); len.writeUInt32BE(data.length); const td = Buffer.concat([Buffer.from(type), data]); const c = Buffer.alloc(4); c.writeUInt32BE(crc(td)); return Buffer.concat([len, td, c]); };72  const ihdr = Buffer.alloc(13); ihdr.writeUInt32BE(w, 0); ihdr.writeUInt32BE(h, 4); ihdr[8] = 8; ihdr[9] = 6; ihdr[10] = 0; ihdr[11] = 0; ihdr[12] = 0;73  return Buffer.concat([Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]), chunk("IHDR", ihdr), chunk("IDAT", zlib.deflateSync(raw)), chunk("IEND", Buffer.alloc(0))]).toString("base64");74}7576// Minimal one-page PDF with the text "PolyLLM probe PDF".77export function tinyPdfBase64(): string {78  const objs = [79    "<< /Type /Catalog /Pages 2 0 R >>",80    "<< /Type /Pages /Kids [3 0 R] /Count 1 >>",81    "<< /Type /Page /Parent 2 0 R /MediaBox [0 0 200 100] /Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >>",82    "<< /Length 60 >>\nstream\nBT /F1 14 Tf 10 50 Td (PolyLLM probe PDF secret=42) Tj ET\nendstream",83    "<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>",84  ];85  let pdf = "%PDF-1.4\n"; const offs: number[] = [];86  objs.forEach((o, i) => { offs.push(pdf.length); pdf += `${i + 1} 0 obj\n${o}\nendobj\n`; });87  const xref = pdf.length;88  pdf += `xref\n0 ${objs.length + 1}\n0000000000 65535 f \n` + offs.map(o => String(o).padStart(10, "0") + " 00000 n \n").join("") + `trailer\n<< /Size ${objs.length + 1} /Root 1 0 R >>\nstartxref\n${xref}\n%%EOF\n`;89  return Buffer.from(pdf, "latin1").toString("base64");90}91