// Function calling (Responses API, openai SDK): forced strict function -> function_call_output round trip -> streamed arguments. // STATUS: LIVE_VERIFIED 2026-09-18 (gpt-5.4-nano). Run: node --env-file=.env --experimental-strip-types examples/openai/tools/function-calling/function_calling.ts import OpenAI from "openai"; import { logRequest } from "../../../shared/tool-loop/log.ts"; const client = new OpenAI(); const MODEL = "gpt-5.4-nano"; const WEATHER: any = { type: "function", name: "get_weather", description: "Current weather for a city.", strict: true, parameters: { type: "object", properties: { city: { type: "string" } }, required: ["city"], additionalProperties: false } }; const r1: any = await client.responses.create({ model: MODEL, input: "Weather in Paris?", tools: [WEATHER], max_output_tokens: 64, tool_choice: { type: "function", name: "get_weather" }, reasoning: { effort: "low" } }); logRequest("openai", "POST", "/v1/responses", 200, 0.0001, "function_calling.ts forced"); const call = r1.output.find((i: any) => i.type === "function_call"); console.log("function_call:", call.name, call.arguments, call.call_id); const r2: any = await client.responses.create({ model: MODEL, previous_response_id: r1.id, tools: [WEATHER], max_output_tokens: 32, reasoning: { effort: "low" }, input: [{ type: "function_call_output", call_id: call.call_id, output: JSON.stringify({ temp_c: 18, sky: "clear" }) }] }); logRequest("openai", "POST", "/v1/responses", 200, 0.0001, "function_calling.ts round trip"); console.log("final:", r2.output_text); const seen = new Set(); const stream = await client.responses.create({ model: MODEL, input: "Weather in Rome?", tools: [WEATHER], tool_choice: "required", max_output_tokens: 64, reasoning: { effort: "low" }, stream: true }); for await (const ev of stream) seen.add(ev.type); logRequest("openai", "POST", "/v1/responses", 200, 0.0001, "function_calling.ts stream"); console.log("stream events:", [...seen].sort());