const ZAI_API_URL = process.env.ZAI_API_URL || "https://open.bigmodel.cn/api/paas/v4/chat/completions"; const ZAI_MODEL = process.env.ZAI_MODEL || "glm-5.2"; const CEREBRAS_API_URL = "https://api.cerebras.ai/v1/chat/completions"; const CEREBRAS_MODEL = "gpt-oss-120b"; async function callWithTimeout( url: string, body: any, apiKey: string, timeoutMs: number = 120000 ): Promise { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), timeoutMs); let response: Response; try { response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${apiKey}`, }, body: JSON.stringify(body), signal: controller.signal, }); } catch (err: any) { if (err.name === "AbortError") { throw new Error(`API call to ${url} timed out after ${timeoutMs}ms`); } throw err; } finally { clearTimeout(timeoutId); } if (!response.ok) { const errText = await response.text(); throw new Error(`API error ${response.status} from ${url}: ${errText}`); } const data = await response.json(); const content = data?.choices?.[0]?.message?.content; if (!content) { throw new Error(`No content returned from ${url}`); } return content; } async function callGLM(prompt: string): Promise { const apiKey = process.env.ZAI_API_KEY; if (!apiKey) throw new Error("ZAI_API_KEY environment variable is not set"); return callWithTimeout( ZAI_API_URL, { model: ZAI_MODEL, messages: [{ role: "user", content: prompt }], max_tokens: 32000, temperature: 0.4, }, apiKey ); } async function callCerebras(prompt: string): Promise { const apiKey = process.env.CEREBRAS_API_KEY; if (!apiKey) throw new Error("CEREBRAS_API_KEY environment variable is not set"); return callWithTimeout( CEREBRAS_API_URL, { model: CEREBRAS_MODEL, messages: [{ role: "user", content: prompt }], max_tokens: 16000, temperature: 0.4, }, apiKey ); } export async function generateWebsite(prompt: string): Promise { if (process.env.ZAI_API_KEY) { try { console.log("[llm] calling GLM-5.2 (primary)..."); return await callGLM(prompt); } catch (err: any) { console.log("[llm] GLM-5.2 failed, falling back to Cerebras/gpt-oss-120b:", err.message); } } console.log("[llm] calling Cerebras/gpt-oss-120b (fallback)..."); return await callCerebras(prompt); }