| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| import { register } from "../index.js"; |
| import { FORMATS } from "../formats.js"; |
| import { randomUUID } from "crypto"; |
|
|
| function flattenText(content) { |
| if (content == null) return ""; |
| if (typeof content === "string") return content; |
| if (Array.isArray(content)) { |
| const parts = []; |
| for (const p of content) { |
| if (typeof p === "string") parts.push(p); |
| else if (p && typeof p === "object" && typeof p.text === "string") parts.push(p.text); |
| } |
| return parts.join("\n"); |
| } |
| return String(content); |
| } |
|
|
| function toContentBlocks(content) { |
| if (content == null) return [{ type: "text", text: "" }]; |
| if (typeof content === "string") return [{ type: "text", text: content }]; |
| if (Array.isArray(content)) { |
| const blocks = []; |
| for (const part of content) { |
| if (typeof part === "string") { |
| blocks.push({ type: "text", text: part }); |
| } else if (part && typeof part === "object") { |
| if (part.type === "text" && typeof part.text === "string") { |
| blocks.push({ type: "text", text: part.text }); |
| } else if (part.type === "image_url" || part.type === "image") { |
| blocks.push({ type: "text", text: "[image omitted]" }); |
| } else if (typeof part.text === "string") { |
| blocks.push({ type: "text", text: part.text }); |
| } |
| } |
| } |
| return blocks.length ? blocks : [{ type: "text", text: "" }]; |
| } |
| return [{ type: "text", text: String(content) }]; |
| } |
|
|
| function safeParseJson(s) { |
| if (s == null) return {}; |
| if (typeof s !== "string") return s; |
| try { return JSON.parse(s); } catch { return {}; } |
| } |
|
|
| function convertMessages(messages = []) { |
| const out = []; |
| const systemTexts = []; |
|
|
| for (const m of messages) { |
| if (!m) continue; |
| const role = m.role; |
|
|
| if (role === "system") { |
| const t = flattenText(m.content); |
| if (t) systemTexts.push(t); |
| continue; |
| } |
|
|
| if (role === "tool") { |
| const value = typeof m.content === "string" ? m.content : flattenText(m.content); |
| out.push({ |
| role: "tool", |
| content: [{ |
| type: "tool-result", |
| toolCallId: m.tool_call_id || "", |
| toolName: m.name || "", |
| output: { type: "text", value }, |
| }], |
| }); |
| continue; |
| } |
|
|
| if (role === "assistant") { |
| const blocks = []; |
| const text = flattenText(m.content); |
| if (text) blocks.push({ type: "text", text }); |
| if (Array.isArray(m.tool_calls)) { |
| for (const tc of m.tool_calls) { |
| const fn = tc.function || {}; |
| blocks.push({ |
| type: "tool-call", |
| toolCallId: tc.id || "", |
| toolName: fn.name || "", |
| input: safeParseJson(fn.arguments), |
| }); |
| } |
| } |
| out.push({ role: "assistant", content: blocks.length ? blocks : [{ type: "text", text: "" }] }); |
| continue; |
| } |
|
|
| out.push({ role: "user", content: toContentBlocks(m.content) }); |
| } |
|
|
| return { messages: out, system: systemTexts.join("\n\n") }; |
| } |
|
|
| function convertTools(tools) { |
| if (!Array.isArray(tools) || tools.length === 0) return undefined; |
| const result = []; |
| for (const t of tools) { |
| if (!t) continue; |
| if (t.type === "function" && t.function) { |
| result.push({ |
| name: t.function.name, |
| description: t.function.description, |
| input_schema: t.function.parameters || { type: "object" }, |
| }); |
| } else if (t.name && (t.input_schema || t.parameters)) { |
| result.push({ |
| name: t.name, |
| description: t.description, |
| input_schema: t.input_schema || t.parameters, |
| }); |
| } |
| } |
| return result.length ? result : undefined; |
| } |
|
|
| export function openaiToCommandCode(model, body, stream ) { |
| const { messages, system } = convertMessages(body.messages); |
| const params = { |
| model, |
| messages, |
| stream: stream !== false, |
| max_tokens: body.max_tokens ?? body.max_output_tokens ?? 64000, |
| temperature: body.temperature ?? 0.3, |
| }; |
|
|
| if (system) params.system = system; |
|
|
| const tools = convertTools(body.tools); |
| if (tools) params.tools = tools; |
| if (body.top_p != null) params.top_p = body.top_p; |
|
|
| const today = new Date().toISOString().slice(0, 10); |
|
|
| return { |
| threadId: randomUUID(), |
| memory: "", |
| config: { |
| workingDir: process.cwd(), |
| date: today, |
| environment: process.platform, |
| structure: [], |
| isGitRepo: false, |
| currentBranch: "", |
| mainBranch: "", |
| gitStatus: "", |
| recentCommits: [], |
| }, |
| params, |
| }; |
| } |
|
|
| register(FORMATS.OPENAI, FORMATS.COMMANDCODE, openaiToCommandCode, null); |
|
|