import OpenAI from "openai"; export async function callOpenAI({ model, messages, temperature = 1.0, maxTokens = 2048, reasoning = false, stream = false, apiKey, onToken, }) { const client = new OpenAI({ apiKey }); const modelName = model.replace(/^openai:/, ""); const openaiMessages = messages.map((m) => { if (m.imageUrl) { return { role: m.role, content: [ { type: "text", text: m.content || "" }, { type: "image_url", image_url: { url: m.imageUrl } }, ], }; } return { role: m.role, content: m.content }; }); const params = { model: modelName, messages: openaiMessages, temperature: reasoning ? undefined : Number(temperature), max_tokens: Number(maxTokens), stream, }; if (reasoning || modelName.startsWith("o1") || modelName.startsWith("o3")) { delete params.temperature; delete params.max_tokens; } if (stream) { const completion = await client.chat.completions.create({ ...params, stream: true, stream_options: { include_usage: true }, }); let fullText = ""; let usage = null; for await (const chunk of completion) { const delta = chunk.choices?.[0]?.delta?.content; if (delta) { fullText += delta; onToken?.(delta); } if (chunk.usage) { usage = { promptTokens: chunk.usage.prompt_tokens, completionTokens: chunk.usage.completion_tokens }; } } return { text: fullText, usage }; } const completion = await client.chat.completions.create(params); return { text: completion.choices?.[0]?.message?.content || "", usage: { promptTokens: completion.usage?.prompt_tokens, completionTokens: completion.usage?.completion_tokens, }, }; }