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.7 KB · 100 lines typescript
Raw Blame History
1// Shared helpers for DeepSeek probes. Key from process.env.DEEPSEEK_API_KEY (never logged).2import { mkdirSync, writeFileSync } from "node:fs";3import * as zlib from "node:zlib";4import OpenAI from "openai";56export const BASE = "https://api.deepseek.com";7export const KEY = process.env.DEEPSEEK_API_KEY ?? "";8if (!KEY) {9  console.error("DEEPSEEK_API_KEY missing (run: set -a; . ./.env; set +a)");10  process.exit(1);11}12export const OUT = new URL("./out/", import.meta.url).pathname;13mkdirSync(OUT, { recursive: true });1415export const client = new OpenAI({ apiKey: KEY, baseURL: BASE, timeout: 300_000, maxRetries: 0 });16export const MODELS = ["deepseek-v4-flash", "deepseek-v4-pro", "deepseek-v4-flash-vision-exp"];1718export function save(name: string, data: unknown) {19  writeFileSync(`${OUT}${name}`, JSON.stringify(data, null, 2));20  console.log(`saved out/${name}`);21}2223export function pickHeaders(h: Headers) {24  const out: Record<string, string> = {};25  h.forEach((v, k) => {26    if (/ratelimit|request-id|x-request|retry-after|content-type|server|date|cf-ray|x-ds|x-deepseek|via|alt-svc/i.test(k)) out[k] = v;27  });28  return out;29}3031/** Raw request; returns status, selected headers, parsed body. */32export async function raw(path: string, init: RequestInit & { key?: string; base?: string } = {}) {33  const { key, base, ...rest } = init;34  const res = await fetch(`${base ?? BASE}${path}`, {35    ...rest,36    headers: { "Content-Type": "application/json", Authorization: `Bearer ${key ?? KEY}`, ...(rest.headers ?? {}) },37  });38  const text = await res.text();39  let body: unknown = text;40  try { body = JSON.parse(text); } catch {}41  return { status: res.status, headers: pickHeaders(res.headers), body };42}4344/** Raw SSE POST; returns parsed data events + raw comment lines (keep-alive). */45export async function rawSSE(path: string, payload: unknown, key?: string) {46  const res = await fetch(`${BASE}${path}`, {47    method: "POST",48    headers: { "Content-Type": "application/json", Authorization: `Bearer ${key ?? KEY}` },49    body: JSON.stringify(payload),50  });51  const headers = pickHeaders(res.headers);52  if (!res.ok || !res.body) {53    const text = await res.text();54    let body: unknown = text;55    try { body = JSON.parse(text); } catch {}56    return { status: res.status, headers, error: body, events: [] as any[], comments: [] as string[] };57  }58  const reader = res.body.getReader();59  const dec = new TextDecoder();60  let buf = "";61  const events: any[] = [];62  const comments: string[] = [];63  for (;;) {64    const { value, done } = await reader.read();65    if (done) break;66    buf += dec.decode(value, { stream: true });67    let idx;68    while ((idx = buf.indexOf("\n\n")) >= 0) {69      const block = buf.slice(0, idx);70      buf = buf.slice(idx + 2);71      for (const line of block.split("\n")) {72        if (line.startsWith(":")) comments.push(line);73        else if (line.startsWith("data:")) {74          const d = line.slice(5).trim();75          if (d === "[DONE]") events.push("[DONE]");76          else { try { events.push(JSON.parse(d)); } catch { events.push({ unparsed: d }); } }77        } else if (line.trim()) comments.push("??" + line);78      }79    }80  }81  return { status: res.status, headers, events, comments };82}8384export function errInfo(e: any) {85  return { status: e?.status, message: e?.message, error: e?.error ?? e?.response?.data ?? null };86}8788/** 32x32 RGB PNG (red/blue checker) as data URL, generated with zlib. */89export function pngDataUrl(w = 32, h = 32) {90  const crcTable = (() => { const t = new Uint32Array(256); for (let n = 0; n < 256; n++) { let c = n; for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; t[n] = c >>> 0; } return t; })();91  const crc = (buf: Buffer) => { let c = 0xffffffff; for (const b of buf) c = crcTable[(c ^ b) & 0xff] ^ (c >>> 8); return (c ^ 0xffffffff) >>> 0; };92  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]); };93  const ihdr = Buffer.alloc(13); ihdr.writeUInt32BE(w, 0); ihdr.writeUInt32BE(h, 4); ihdr[8] = 8; ihdr[9] = 2; ihdr[10] = 0; ihdr[11] = 0; ihdr[12] = 0;94  const rows: Buffer[] = [];95  for (let y = 0; y < h; y++) { const row = Buffer.alloc(1 + w * 3); row[0] = 0; for (let x = 0; x < w; x++) { const red = ((x >> 3) + (y >> 3)) % 2 === 0; row[1 + x * 3] = red ? 220 : 30; row[2 + x * 3] = 30; row[3 + x * 3] = red ? 30 : 220; } rows.push(row); }96  const idat = zlib.deflateSync(Buffer.concat(rows));97  const png = Buffer.concat([Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]), chunk("IHDR", ihdr), chunk("IDAT", idat), chunk("IEND", Buffer.alloc(0))]);98  return `data:image/png;base64,${png.toString("base64")}`;99}100