const MUAPI_BASE = "https://api.muapi.ai/api/v1"; const delay = (ms) => new Promise((r) => setTimeout(r, ms)); export async function callMuAPI({ model, prompt, systemPrompt, temperature = 1.0, maxTokens = 2048, reasoning = false, imageUrl = null, apiKey, }) { const modelName = model.replace(/^muapi:/, ""); const isVision = !!imageUrl; const apiUrl = isVision ? `${MUAPI_BASE}/openrouter-vision` : `${MUAPI_BASE}/any-llm-models`; const payload = { prompt, system_prompt: systemPrompt, model: modelName, temperature: parseFloat(temperature), max_tokens: parseInt(maxTokens), reasoning: !!reasoning, }; if (isVision) payload.images_list = [imageUrl]; const response = await fetch(apiUrl, { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, body: JSON.stringify(payload), }); if (!response.ok) { const errText = await response.text(); console.error("[MUAPI_LLM_ERROR]", errText); throw new Error(`MuAPI error: ${response.statusText}`); } const data = await response.json(); const requestId = data.request_id; if (!requestId) throw new Error("Did not receive a request_id from MuAPI."); let completedText = ""; let status = "processing"; while (status === "processing") { await delay(1500); const checkRes = await fetch(`${MUAPI_BASE}/predictions/${requestId}/result`, { method: "GET", headers: { "Content-Type": "application/json", "x-api-key": apiKey }, }); if (checkRes.ok) { const checkData = await checkRes.json(); status = checkData.status || checkData.state || "processing"; if (status === "completed" || status === "succeeded") { completedText = checkData.outputs?.[0] || (typeof checkData.output === "string" ? checkData.output : "") || checkData.output?.text || checkData.output?.choices?.[0]?.message?.content || checkData.response || ""; break; } else if (status === "failed") { throw new Error("Generation failed on MuAPI."); } } } return { text: completedText || "Hello! How can I help you?", usage: null }; }