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.3 KB · 72 lines typescript
Raw Blame History
1// Probe 03: streamed function-call round trip on each model (OpenAI SDK).2import { client, save, short } from "./lib.ts";3import { MODELS, byId } from "./models.ts";45const tools: any = [6  {7    type: "function",8    function: {9      name: "get_weather",10      description: "Get the current weather for a city",11      parameters: { type: "object", properties: { city: { type: "string" } }, required: ["city"] },12    },13  },14];1516const results: any = {};17for (const model of MODELS) {18  const out: any = { chunks: [] as any[] };19  results[model] = out;20  try {21    const messages: any[] = [{ role: "user", content: "What's the weather in Montreal? Use the tool." }];22    const stream = await client.chat.completions.create({23      model,24      messages,25      tools,26      tool_choice: "auto",27      stream: true,28      max_tokens: 200,29      ...(byId.get(model)?.reasoning ? { reasoning: { effort: "low" } } : {}),30    } as any);31    const acc: Record<number, any> = {};32    let deltaWithTools = 0;33    let finish: string | undefined;34    let usage: any;35    let reasoningDetails: any[] = [];36    for await (const chunk of stream) {37      const c: any = chunk.choices?.[0];38      if (c?.delta?.tool_calls) {39        deltaWithTools++;40        if (out.chunks.length < 4) out.chunks.push(chunk);41        for (const tc of c.delta.tool_calls) {42          const i = tc.index ?? 0;43          acc[i] ??= { id: tc.id, type: "function", function: { name: "", arguments: "" } };44          if (tc.id) acc[i].id = tc.id;45          if (tc.function?.name) acc[i].function.name += tc.function.name;46          if (tc.function?.arguments) acc[i].function.arguments += tc.function.arguments;47        }48      }49      if (c?.delta?.reasoning_details) reasoningDetails.push(...c.delta.reasoning_details);50      if (c?.finish_reason) finish = c.finish_reason;51      if ((chunk as any).usage) usage = (chunk as any).usage;52    }53    const toolCalls = Object.values(acc);54    out.round1 = { finish, deltaWithTools, toolCalls, usage, reasoningDetailsTypes: [...new Set(reasoningDetails.map((d) => d.type))] };55    console.log(`\n[${model}] round1 finish=${finish} toolDeltaChunks=${deltaWithTools} calls=${JSON.stringify(toolCalls)} rt=${usage?.completion_tokens_details?.reasoning_tokens} cost=${usage?.cost}`);56    if (!toolCalls.length) continue;57    const assistantMsg: any = { role: "assistant", content: null, tool_calls: toolCalls };58    if (reasoningDetails.length) assistantMsg.reasoning_details = reasoningDetails; // docs: pass back unmodified59    messages.push(assistantMsg);60    for (const tc of toolCalls) {61      messages.push({ role: "tool", tool_call_id: tc.id, content: JSON.stringify({ city: "Montreal", temp_c: 21, sky: "sunny" }) });62    }63    const r2: any = await client.chat.completions.create({ model, messages, tools, max_tokens: 100, ...(byId.get(model)?.reasoning ? { reasoning: { effort: "low" } } : {}) } as any);64    out.round2 = { finish: r2.choices[0].finish_reason, content: r2.choices[0].message.content, usage: r2.usage, provider: r2.provider };65    console.log(`  round2 finish=${r2.choices[0].finish_reason} provider=${r2.provider} content=${short(r2.choices[0].message.content, 120)}`);66  } catch (e: any) {67    out.error = { status: e.status, message: e.message, body: e.error };68    console.log(`  ERROR ${e.status} ${short(e.error ?? e.message, 300)}`);69  }70}71save("03-tools.json", results);72