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.6 KB · 34 lines typescript
Raw Blame History
1// (d) Function-call round trip with streaming: tool-call event names, function_call item shape, sending function_call_output back.2import { client, attempt, save, PROBE_MODELS, summarizeResponse } from "./lib";3const tools: any = [{ type: "function", name: "get_weather", description: "Get current weather for a city", strict: true,4  parameters: { type: "object", properties: { city: { type: "string" }, unit: { type: "string", enum: ["c", "f"] } }, required: ["city", "unit"], additionalProperties: false } }];5const userMsg = { role: "user", content: "What's the weather in Paris right now in celsius? You must call get_weather." };6const out: any[] = [];7for (const model of PROBE_MODELS) {8  out.push(await attempt(`tools-stream:${model}`, async () => {9    const stream = await client.responses.create({ model, input: [userMsg], tools, tool_choice: "auto", max_output_tokens: 200, stream: true } as any);10    const order: string[] = []; const samples: Record<string, any> = {}; let final: any = null; let args = "";11    for await (const ev of stream as any) {12      if (!samples[ev.type]) { order.push(ev.type); const { response, ...rest } = ev; samples[ev.type] = response ? { ...rest, response: "<omitted>" } : rest; }13      if (ev.type === "response.function_call_arguments.delta") args += ev.delta;14      if (ev.type === "response.completed" || ev.type === "response.incomplete") final = ev.response;15    }16    const call = final.output.find((o: any) => o.type === "function_call");17    let second: any = null, secondViaPrev: any = null;18    if (call) {19      const fco = { type: "function_call_output", call_id: call.call_id, output: JSON.stringify({ city: "Paris", temp_c: 18, sky: "cloudy" }) };20      // Stateless pass-back: replay user msg + ALL output items (incl. reasoning items) + tool output.21      const r2: any = await client.responses.create({ model, input: [userMsg, ...final.output, fco], tools, max_output_tokens: 120 } as any);22      second = summarizeResponse(r2);23      if (model === "gpt-5.4-mini") { // stateful variant on one model only24        const r3: any = await client.responses.create({ model, previous_response_id: final.id, input: [fco], tools, max_output_tokens: 120 } as any);25        secondViaPrev = summarizeResponse(r3);26      }27    }28    return { event_order: order, samples, streamed_arguments: args, first: summarizeResponse(final), function_call_item: call ?? null,29      output_items_full: final.output.map((o: any) => ({ ...o, encrypted_content: o.encrypted_content ? `<${o.encrypted_content.length} chars>` : undefined })),30      second_turn: second, second_turn_via_previous_response_id: secondViaPrev };31  }));32}33save("05-tools-stream", out);34