import { rawPost, save, short } from "./lib.ts"; const model = process.argv[2] ?? "kimi-k3"; const tools = [{ type: "builtin_function", function: { name: "$web_search" } }]; const messages: any[] = [{ role: "user", content: "What was the closing value of the S&P 500 yesterday? Search the web and cite the source URL." }]; const extra = model === "kimi-k3" ? { reasoning_effort: "low" } : {}; // canonical: non-streamed step 1, append message verbatim const r1 = await rawPost("/chat/completions", { model, messages, tools, max_tokens: 6000, ...extra }); const m = (r1.body as any)?.choices?.[0]?.message; console.log(`[${model}] step1 non-stream ${r1.status} finish=${(r1.body as any)?.choices?.[0]?.finish_reason} keys=${Object.keys(m ?? {})} usage=${JSON.stringify((r1.body as any)?.usage)}`); console.log(" message:", short(m, 900)); const out: any = { step1: r1 }; if (m?.tool_calls?.length) { const toolMsgs = m.tool_calls.map((tc: any) => ({ role: "tool", tool_call_id: tc.id, name: tc.function.name, content: tc.function.arguments })); const variants: Array<[string, any]> = [ ["verbatim message", m], ["no reasoning_content", { role: "assistant", content: m.content, tool_calls: m.tool_calls }], ["reasoning_content empty string", { role: "assistant", content: m.content, reasoning_content: "", tool_calls: m.tool_calls }], ["tool_calls type=function instead of builtin_function", { ...m, tool_calls: m.tool_calls.map((tc: any) => ({ ...tc, type: "function" })) }], ]; for (const [label, asst] of variants) { const r2 = await rawPost("/chat/completions", { model, messages: [...messages, asst, ...toolMsgs], tools, max_tokens: 6000, ...extra }); const mm = (r2.body as any)?.choices?.[0]?.message; console.log(` step2 [${label}] ${r2.status} finish=${(r2.body as any)?.choices?.[0]?.finish_reason} usage=${JSON.stringify((r2.body as any)?.usage)}`); console.log(" ->", short(mm?.content ?? mm?.tool_calls ?? r2.body, 700)); if (mm) console.log(" message keys:", Object.keys(mm), "choice keys:", Object.keys((r2.body as any).choices[0])); out[`step2:${label}`] = r2; if (r2.status === 200 && !out.firstOk) out.firstOk = label; } // tool message without name field const noName = await rawPost("/chat/completions", { model, messages: [...messages, m, ...m.tool_calls.map((tc: any) => ({ role: "tool", tool_call_id: tc.id, content: tc.function.arguments }))], tools, max_tokens: 6000, ...extra }); console.log(` step2 [tool msg without name] ${noName.status}`, short((noName.body as any)?.choices?.[0]?.message?.content ?? noName.body, 200)); out["step2:noName"] = noName; } save(`06b-websearch-variants-${model}`, out);