TypeScript 97.4%
SQL 1%
JavaScript 0.9%
CSS 0.6%
1import { chat, rawSSE, save, MODELS, short } from "./lib.ts";23const tools = [4 {5 type: "function",6 function: {7 name: "get_weather",8 description: "Get the current weather for a city",9 parameters: { type: "object", properties: { city: { type: "string", description: "City name" } }, required: ["city"], additionalProperties: false },10 },11 },12];1314const out: Record<string, unknown> = {};15for (const model of MODELS) {16 const messages: any[] = [{ role: "user", content: "What's the weather in Montreal right now? Use the tool." }];17 const s = await rawSSE("/chat/completions", { model, messages, tools, tool_choice: "auto", max_completion_tokens: 200, stream: true, stream_options: { include_usage: true } });18 const tcEvents = s.events.filter((e) => e.data !== "[DONE]" && e.data?.choices?.[0]?.delta?.tool_calls);19 const finishes = s.events.filter((e) => e.data !== "[DONE]" && e.data?.choices?.[0]?.finish_reason).map((e) => e.data.choices[0].finish_reason);20 // accumulate21 const acc: Record<number, { id?: string; name?: string; args: string; type?: string }> = {};22 for (const e of tcEvents) {23 for (const tc of e.data.choices[0].delta.tool_calls) {24 const i = tc.index ?? 0;25 acc[i] ??= { args: "" };26 if (tc.id) acc[i].id = tc.id;27 if (tc.type) acc[i].type = tc.type;28 if (tc.function?.name) acc[i].name = tc.function.name;29 if (tc.function?.arguments) acc[i].args += tc.function.arguments;30 }31 }32 console.log(model, "stream tools:", s.status, "events", s.events.length, "toolCallChunks", tcEvents.length, "finishes", finishes, "\n accumulated:", JSON.stringify(acc), "\n tc deltas:", short(tcEvents.map((e) => e.data.choices[0].delta), 800), s.error ? "\n ERROR " + short(s.error) : "");33 out[`${model}:stream`] = { status: s.status, nEvents: s.events.length, toolCallChunkCount: tcEvents.length, finishes, accumulated: acc, toolCallDeltas: tcEvents.map((e) => e.data.choices[0].delta), usageEvent: s.events.find((e) => e.data !== "[DONE]" && e.data?.usage)?.data, error: s.error };3435 // round trip (non-stream round 2)36 const first = Object.values(acc)[0];37 if (first?.id) {38 messages.push({ role: "assistant", content: null, tool_calls: [{ id: first.id, type: "function", function: { name: first.name, arguments: first.args } }] });39 messages.push({ role: "tool", tool_call_id: first.id, content: JSON.stringify({ city: "Montreal", temp_c: 21, sky: "sunny" }) });40 const r2 = await chat({ model, messages, tools, max_completion_tokens: 150 });41 const b: any = r2.body;42 out[`${model}:round2`] = { status: r2.status, body: b };43 console.log(model, "round2:", r2.status, short(b?.choices?.[0]?.message?.content ?? b, 200), "finish", b?.choices?.[0]?.finish_reason);44 } else {45 // non-stream tool call for comparison46 const r1 = await chat({ model, messages, tools, tool_choice: "required", max_completion_tokens: 200 });47 out[`${model}:nonstream-required`] = r1;48 console.log(model, "nonstream required:", r1.status, short((r1.body as any)?.choices?.[0]?.message ?? r1.body, 400));49 }50}51save("03-tools-stream.json", out);52