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%
2.4 KB · 66 lines typescript
Raw Blame History
1// Probe 04: structured output (json_schema strict) — with and without provider.require_parameters, streaming once.2import { raw, rawSSE, save, short } from "./lib.ts";3import { MODELS, OPENAI, byId } from "./models.ts";45const response_format = {6  type: "json_schema",7  json_schema: {8    name: "city_info",9    strict: true,10    schema: {11      type: "object",12      properties: {13        city: { type: "string" },14        country: { type: "string" },15        population_millions: { type: "number" },16        landmarks: { type: "array", items: { type: "string" } },17      },18      required: ["city", "country", "population_millions", "landmarks"],19      additionalProperties: false,20    },21  },22};2324const results: any = {};25for (const model of MODELS) {26  const body: any = {27    model,28    messages: [{ role: "user", content: "Give facts about Montreal." }],29    response_format,30    max_tokens: 200,31    provider: { require_parameters: true },32    usage: { include: true },33    ...(byId.get(model)?.reasoning ? { reasoning: { effort: "low" } } : {}),34  };35  const r = await raw("/chat/completions", { method: "POST", body: JSON.stringify(body) });36  const b: any = r.body;37  const content = b?.choices?.[0]?.message?.content;38  let parsed: any = null;39  let valid = false;40  try {41    parsed = JSON.parse(content);42    valid = typeof parsed.city === "string" && Array.isArray(parsed.landmarks) && typeof parsed.population_millions === "number";43  } catch {}44  results[model] = { status: r.status, provider: b?.provider, finish: b?.choices?.[0]?.finish_reason, content, valid, usage: b?.usage, error: b?.error };45  console.log(`[${model}] ${r.status} provider=${b?.provider} valid=${valid} ${short(content, 160)} ${b?.error ? "ERR=" + short(b.error, 300) : ""}`);46}4748// streaming structured output49const s = await rawSSE("/chat/completions", {50  model: OPENAI,51  messages: [{ role: "user", content: "Give facts about Montreal." }],52  response_format,53  max_tokens: 200,54  stream: true,55  reasoning: { effort: "low" },56});57let text = "";58for (const e of s.events) if (e.data !== "[DONE]") text += e.data?.choices?.[0]?.delta?.content ?? "";59let streamValid = false;60try {61  streamValid = typeof JSON.parse(text).city === "string";62} catch {}63results.streamed = { model: OPENAI, status: s.status, events: s.events.length, text, valid: streamValid };64console.log(`[stream ${OPENAI}] events=${s.events.length} valid=${streamValid} ${short(text, 160)}`);65save("04-structured.json", results);66