File size: 2,571 Bytes
ec675f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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<string> {
  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<string> {
  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<string> {
  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<string> {
  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);
}