/** * Translator: OpenAI Responses API → OpenAI Chat Completions * * Responses API uses: { input: [...], instructions: "..." } * Chat API uses: { messages: [...] } */ import { register } from "../index.js"; import { FORMATS } from "../formats.js"; /** * Convert OpenAI Responses API request to OpenAI Chat Completions format */ function translateRequest(model, body, stream, credentials) { 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 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; } // Flush any pending tool results first if (pendingToolResults.length > 0) { for (const tr of pendingToolResults) { result.messages.push(tr); } pendingToolResults = []; } // Add tool result immediately (not pending) result.messages.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); } } // Tools are already in OpenAI format, just keep them // Responses API tools: { type: "function", name, description, parameters } // OpenAI tools: { type: "function", function: { name, description, parameters } } if (body.tools && Array.isArray(body.tools)) { result.tools = body.tools.map(tool => { // Already has function wrapper if (tool.function) return tool; // Responses API format: flatten to OpenAI format return { type: "function", function: { name: tool.name, description: tool.description, parameters: tool.parameters, strict: tool.strict } }; }); } // 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; } // Register translator register(FORMATS.OPENAI_RESPONSES, FORMATS.OPENAI, translateRequest, null);