File size: 3,395 Bytes
ea6c2a8
 
 
 
 
 
 
 
 
 
 
d5cae2f
0c97c9d
 
 
 
ea6c2a8
 
 
 
 
0c97c9d
 
ea6c2a8
0c97c9d
 
 
 
 
0e737c6
0c97c9d
0e737c6
 
94b66c3
ea6c2a8
 
 
 
ae120cb
0c97c9d
 
ae120cb
0c97c9d
 
ae120cb
0c97c9d
 
 
 
 
 
 
 
ae120cb
0c97c9d
 
 
ea6c2a8
 
0c97c9d
 
 
 
33d4b9e
0c97c9d
ffa81b7
0c97c9d
 
c2c7576
0c97c9d
 
 
33d4b9e
0c97c9d
 
d5cae2f
0c97c9d
 
33d4b9e
0c97c9d
 
 
d5cae2f
0c97c9d
 
d5cae2f
0c97c9d
 
 
 
33d4b9e
d5cae2f
 
0c97c9d
 
 
 
 
 
 
 
d81515f
 
ffa81b7
ea6c2a8
 
 
 
 
ae120cb
 
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import express from "express";
import path from "path";
import { fileURLToPath } from "url";
import dotenv from "dotenv";
import bodyParser from "body-parser";

dotenv.config();

const app = express();
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const PORT = process.env.APP_PORT || 7860;
const ApiKey = process.env.OPENROUTER_API_KEY;
const Model = process.env.OPENROUTER_MODEL;
const ApiUrl = "https://openrouter.ai/api/v1";

app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, "dist")));

app.post("/api/ask-ai", async (req, res) => {
  const { prompt, html, previousPrompt } = req.body;

  if (!prompt) {
    return res.status(400).send({ ok: false, message: "Missing prompt" });
  }

  if (!ApiKey || !Model) {
    return res.status(500).send({
      ok: false,
      message: "Missing API Key or Model in .env file",
    });
  }

  res.setHeader("Content-Type", "text/plain");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");

  const systemPrompt = `ONLY USE HTML, CSS AND JAVASCRIPT. No explanations, ONLY CODE. If you want to use ICON make sure to import the library first. Try to create the best UI possible using TailwindCSS. If not possible, use custom CSS (remember to import <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script> in the head). ALWAYS GIVE THE RESPONSE INTO A SINGLE HTML FILE`;

  try {
    const response = await fetch(`${ApiUrl}/chat/completions`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${ApiKey}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        model: Model,
        stream: true,
        messages: [
          { role: "system", content: systemPrompt },
          ...(previousPrompt ? [{ role: "user", content: previousPrompt }] : []),
          ...(html ? [{ role: "assistant", content: `The current code is: ${html}` }] : []),
          { role: "user", content: prompt },
        ],
      }),
    });

    if (!response.ok || !response.body) {
      return res.status(500).send({
        ok: false,
        message: "Failed to fetch OpenRouter response",
      });
    }

    const reader = response.body.getReader();
    const decoder = new TextDecoder();

    while (true) {
      const { done, value } = await reader.read();
      if (done) break;

      const chunk = decoder.decode(value);
      const lines = chunk.split('\n').filter(line => line.trim());

      for (const line of lines) {
        if (!line || !line.startsWith('data: ') || line.includes('[DONE]')) continue;

        try {
          const json = line.slice(6).trim();
          if (!json.startsWith('{')) continue;

          const message = JSON.parse(json);
          const content = message?.choices?.[0]?.delta?.content;

          if (content) res.write(content);
        } catch (err) {
          console.error("Streaming error:", err.message);
          continue;
        }
      }
    }

    res.end();
  } catch (error) {
    console.error("Request error:", error.message);
    res.status(500).send({
      ok: false,
      message: error.message || "Unexpected error",
    });
  }
});

app.get("*", (_req, res) => {
  res.sendFile(path.join(__dirname, "dist", "index.html"));
});

app.listen(PORT, () => {
  console.log(`✅ Server running on port ${PORT}`);
});