/** * Convert OpenAI Responses API format to standard chat completions format * Responses API uses: { input: [...], instructions: "..." } * Chat API uses: { messages: [...] } */ export function convertResponsesApiFormat(body) { if (!body.input) return body; const result = { ...body }; result.messages = []; // Convert instructions to system message if (body.instructions) { result.messages.push({ role: "system", content: body.instructions }); } // Group items by conversation turn let currentAssistantMsg = null; let pendingToolCalls = []; let pendingToolResults = []; for (const item of body.input) { if (item.type === "message") { // Flush any pending assistant message with tool calls if (currentAssistantMsg) { result.messages.push(currentAssistantMsg); currentAssistantMsg = null; } // Flush pending tool results if (pendingToolResults.length > 0) { for (const tr of pendingToolResults) { result.messages.push(tr); } pendingToolResults = []; } // Convert content: input_text → text, output_text → text const content = Array.isArray(item.content) ? item.content.map(c => { if (c.type === "input_text") return { type: "text", text: c.text }; if (c.type === "output_text") return { type: "text", text: c.text }; return c; }) : item.content; result.messages.push({ role: item.role, content }); } else if (item.type === "function_call") { // Start or append to assistant message with tool_calls if (!currentAssistantMsg) { currentAssistantMsg = { role: "assistant", content: null, tool_calls: [] }; } currentAssistantMsg.tool_calls.push({ id: item.call_id, type: "function", function: { name: item.name, arguments: item.arguments } }); } else if (item.type === "function_call_output") { // Flush assistant message first if exists if (currentAssistantMsg) { result.messages.push(currentAssistantMsg); currentAssistantMsg = null; } // Add tool result pendingToolResults.push({ role: "tool", tool_call_id: item.call_id, content: typeof item.output === "string" ? item.output : JSON.stringify(item.output) }); } else if (item.type === "reasoning") { // Skip reasoning items - they are for display only continue; } } // Flush remaining if (currentAssistantMsg) { result.messages.push(currentAssistantMsg); } if (pendingToolResults.length > 0) { for (const tr of pendingToolResults) { result.messages.push(tr); } } // Cleanup Responses API specific fields delete result.input; delete result.instructions; delete result.include; delete result.prompt_cache_key; delete result.store; delete result.reasoning; return result; }