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.6 KB · 111 lines typescript
Raw Blame History
1// Shared helpers for xAI probes. Key comes from process.env.XAI_API_KEY (never logged).2import { mkdirSync, writeFileSync } from "node:fs";3import OpenAI from "openai";45export const BASE = "https://api.x.ai/v1";6export const KEY = process.env.XAI_API_KEY ?? "";7if (!KEY) {8  console.error("XAI_API_KEY missing (run: set -a; . ./.env; set +a)");9  process.exit(1);10}1112export const OUT = new URL("./out/", import.meta.url).pathname;13mkdirSync(OUT, { recursive: true });1415export const client = new OpenAI({ apiKey: KEY, baseURL: BASE, timeout: 120_000, maxRetries: 0 });1617export const CHAT_MODELS = [18  "grok-4.6",19  "grok-4.5",20  "grok-4.3",21  "grok-4.20-0309-reasoning",22  "grok-4.20-0309-non-reasoning",23  "grok-build-0.1",24];2526export function save(name: string, data: unknown) {27  writeFileSync(`${OUT}${name}`, JSON.stringify(data, null, 2));28  console.log(`saved out/${name}`);29}3031/** Raw request; returns status, selected headers, and parsed body (never echoes the key). */32export async function raw(path: string, init: RequestInit & { key?: string } = {}) {33  const { key, ...rest } = init;34  const res = await fetch(`${BASE}${path}`, {35    ...rest,36    headers: {37      "Content-Type": "application/json",38      Authorization: `Bearer ${key ?? KEY}`,39      ...(rest.headers ?? {}),40    },41  });42  const text = await res.text();43  let body: unknown = text;44  try {45    body = JSON.parse(text);46  } catch {}47  const headers: Record<string, string> = {};48  res.headers.forEach((v, k) => {49    if (/ratelimit|request-id|x-request|retry-after|content-type|server|date|cf-ray|x-grok/i.test(k)) headers[k] = v;50  });51  return { status: res.status, headers, body };52}5354/** Raw SSE POST; returns list of parsed events (data lines) and raw event names if present. */55export async function rawSSE(path: string, payload: unknown, key?: string) {56  const res = await fetch(`${BASE}${path}`, {57    method: "POST",58    headers: { "Content-Type": "application/json", Authorization: `Bearer ${key ?? KEY}` },59    body: JSON.stringify(payload),60  });61  const headers: Record<string, string> = {};62  res.headers.forEach((v, k) => {63    if (/ratelimit|request-id|x-request|content-type|x-grok/i.test(k)) headers[k] = v;64  });65  if (!res.ok || !res.body) {66    const text = await res.text();67    let body: unknown = text;68    try {69      body = JSON.parse(text);70    } catch {}71    return { status: res.status, headers, error: body, events: [] as any[] };72  }73  const reader = res.body.getReader();74  const dec = new TextDecoder();75  let buf = "";76  const events: { event?: string; data: any; raw?: string }[] = [];77  for (;;) {78    const { value, done } = await reader.read();79    if (done) break;80    buf += dec.decode(value, { stream: true });81    let idx;82    while ((idx = buf.indexOf("\n\n")) >= 0) {83      const block = buf.slice(0, idx);84      buf = buf.slice(idx + 2);85      let ev: string | undefined;86      const datas: string[] = [];87      for (const line of block.split("\n")) {88        if (line.startsWith("event:")) ev = line.slice(6).trim();89        else if (line.startsWith("data:")) datas.push(line.slice(5).trim());90      }91      if (!datas.length) continue;92      const d = datas.join("\n");93      if (d === "[DONE]") {94        events.push({ event: ev, data: "[DONE]" });95        continue;96      }97      try {98        events.push({ event: ev, data: JSON.parse(d) });99      } catch {100        events.push({ event: ev, data: null, raw: d });101      }102    }103  }104  return { status: res.status, headers, events };105}106107export function short(s: unknown, n = 300) {108  const t = typeof s === "string" ? s : JSON.stringify(s) ?? String(s);109  return t.length > n ? t.slice(0, n) + "…" : t;110}111