caiosilva1221 commited on
Commit
0c97c9d
·
verified ·
1 Parent(s): 1477dcf

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +64 -129
server.js CHANGED
@@ -4,166 +4,101 @@ import { fileURLToPath } from "url";
4
  import dotenv from "dotenv";
5
  import bodyParser from "body-parser";
6
 
7
- import { PROVIDERS } from "./utils/providers.js";
8
-
9
- // Load environment variables from .env file
10
  dotenv.config();
11
 
12
  const app = express();
13
-
14
  const __filename = fileURLToPath(import.meta.url);
15
  const __dirname = path.dirname(__filename);
16
 
17
- const PORT = process.env.APP_PORT || 3000;
 
 
 
18
 
19
  app.use(bodyParser.json());
20
  app.use(express.static(path.join(__dirname, "dist")));
21
 
22
  app.post("/api/ask-ai", async (req, res) => {
23
- const { prompt, html, previousPrompt, provider } = req.body;
 
24
  if (!prompt) {
25
- return res.status(400).send({
 
 
 
 
26
  ok: false,
27
- message: "Missing required fields",
28
  });
29
  }
30
 
31
- // Set up response headers for streaming
32
  res.setHeader("Content-Type", "text/plain");
33
  res.setHeader("Cache-Control", "no-cache");
34
  res.setHeader("Connection", "keep-alive");
35
 
36
- let 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 by using only HTML, CSS and JAVASCRIPT. Use as much as you can TailwindCSS for the CSS, if you can't do something with TailwindCSS, then use custom CSS (make sure to import <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script> in the head). Also, try to ellaborate as much as you can, to create something unique. ALWAYS GIVE THE RESPONSE INTO A SINGLE HTML FILE`;
37
-
38
- let TOKENS_USED = prompt?.length;
39
- if (previousPrompt) TOKENS_USED += previousPrompt.length;
40
- if (html) TOKENS_USED += html.length;
41
-
42
- const DEFAULT_PROVIDER = PROVIDERS.openrouter;
43
- const selectedProvider =
44
- provider === "auto"
45
- ? DEFAULT_PROVIDER
46
- : PROVIDERS[provider] ?? DEFAULT_PROVIDER;
47
-
48
- if (provider !== "auto" && TOKENS_USED >= selectedProvider.max_tokens) {
49
- return res.status(400).send({
50
- ok: false,
51
- openSelectProvider: true,
52
- message: `Context is too long. ${selectedProvider.name} allow ${selectedProvider.max_tokens} max tokens.`,
 
 
53
  });
54
- }
55
 
56
- if (["local", "openrouter"].includes(selectedProvider.id)) {
57
- try {
58
- const { ApiKey, ApiUrl, Model } = req.body;
59
- if (!ApiUrl || !Model) {
60
- return res.status(400).send({
61
- ok: false,
62
- message: "Missing required fields for provider, set API KEY, BASE URL, and MODEL.",
63
- });
64
- }
65
- const response = await fetch(`${ApiUrl}/chat/completions`, {
66
- method: "POST",
67
- headers: {
68
- "Content-Type": "application/json",
69
- Authorization: `Bearer ${ApiKey}`,
70
- },
71
- body: JSON.stringify({
72
- model: Model,
73
- messages: [
74
- {
75
- role: "system",
76
- content: systemPrompt,
77
- },
78
- ...(previousPrompt
79
- ? [
80
- {
81
- role: "user",
82
- content: previousPrompt,
83
- },
84
- ]
85
- : []),
86
- ...(html
87
- ? [
88
- {
89
- role: "assistant",
90
- content: `The current code is: ${html}.`,
91
- },
92
- ]
93
- : []),
94
- {
95
- role: "user",
96
- content: prompt,
97
- },
98
- ],
99
- stream: true
100
- })
101
  });
102
- if (!response.ok) {
103
- const errorBody = await response.text();
104
- throw new Error(`API Error: ${response.status} - ${errorBody}`);
105
- }
106
-
107
- const reader = response.body.getReader();
108
- const decoder = new TextDecoder();
109
-
110
- while (true) {
111
- const { done, value } = await reader.read();
112
- if (done) break;
113
 
114
- const chunk = decoder.decode(value);
115
- const lines = chunk.split('\n').filter(line => line.trim());
116
 
117
- for (const line of lines) {
118
- if (!line || !line.startsWith('data: ') || line.includes('[DONE]')) continue;
 
119
 
120
- try {
121
- if (line.includes('exceeded')) {
122
- return res.status(402).send({
123
- ok: false,
124
- message: line,
125
- });
126
- }
127
 
128
- const json = line.slice(6).trim();
 
129
 
130
- if (!json.startsWith('{')) {
131
- continue;
132
- }
133
 
134
- const message = JSON.parse(json);
135
- const content = message?.choices?.[0]?.delta?.content;
136
 
137
- if (content) {
138
- res.write(content);
139
- }
140
- } catch (e) {
141
- console.error('Error on line stream:', e.message);
142
- // continue ao invés de throw, pra não matar tudo por causa de uma linha podre
143
- continue;
144
- }
145
  }
146
-
147
- }
148
- res.end();
149
- } catch (error) {
150
- if (error.message.includes("exceeded")) {
151
- return res.status(402).send({
152
- ok: false,
153
- message: error.message,
154
- });
155
- }
156
- if (!res.headersSent) {
157
- res.status(500).send({
158
- ok: false,
159
- message:
160
- error.message || "An error occurred while processing your request.",
161
- });
162
- } else {
163
- // Otherwise end the stream
164
- res.end();
165
  }
166
  }
 
 
 
 
 
 
 
 
167
  }
168
  });
169
 
@@ -172,5 +107,5 @@ app.get("*", (_req, res) => {
172
  });
173
 
174
  app.listen(PORT, () => {
175
- console.log(`Server is running on port ${PORT}`);
176
- });
 
4
  import dotenv from "dotenv";
5
  import bodyParser from "body-parser";
6
 
 
 
 
7
  dotenv.config();
8
 
9
  const app = express();
 
10
  const __filename = fileURLToPath(import.meta.url);
11
  const __dirname = path.dirname(__filename);
12
 
13
+ const PORT = process.env.APP_PORT || 7860;
14
+ const ApiKey = process.env.OPENROUTER_API_KEY;
15
+ const Model = process.env.OPENROUTER_MODEL;
16
+ const ApiUrl = "https://openrouter.ai/api/v1";
17
 
18
  app.use(bodyParser.json());
19
  app.use(express.static(path.join(__dirname, "dist")));
20
 
21
  app.post("/api/ask-ai", async (req, res) => {
22
+ const { prompt, html, previousPrompt } = req.body;
23
+
24
  if (!prompt) {
25
+ return res.status(400).send({ ok: false, message: "Missing prompt" });
26
+ }
27
+
28
+ if (!ApiKey || !Model) {
29
+ return res.status(500).send({
30
  ok: false,
31
+ message: "Missing API Key or Model in .env file",
32
  });
33
  }
34
 
 
35
  res.setHeader("Content-Type", "text/plain");
36
  res.setHeader("Cache-Control", "no-cache");
37
  res.setHeader("Connection", "keep-alive");
38
 
39
+ 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`;
40
+
41
+ try {
42
+ const response = await fetch(`${ApiUrl}/chat/completions`, {
43
+ method: "POST",
44
+ headers: {
45
+ Authorization: `Bearer ${ApiKey}`,
46
+ "Content-Type": "application/json",
47
+ },
48
+ body: JSON.stringify({
49
+ model: Model,
50
+ stream: true,
51
+ messages: [
52
+ { role: "system", content: systemPrompt },
53
+ ...(previousPrompt ? [{ role: "user", content: previousPrompt }] : []),
54
+ ...(html ? [{ role: "assistant", content: `The current code is: ${html}` }] : []),
55
+ { role: "user", content: prompt },
56
+ ],
57
+ }),
58
  });
 
59
 
60
+ if (!response.ok || !response.body) {
61
+ return res.status(500).send({
62
+ ok: false,
63
+ message: "Failed to fetch OpenRouter response",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  });
65
+ }
 
 
 
 
 
 
 
 
 
 
66
 
67
+ const reader = response.body.getReader();
68
+ const decoder = new TextDecoder();
69
 
70
+ while (true) {
71
+ const { done, value } = await reader.read();
72
+ if (done) break;
73
 
74
+ const chunk = decoder.decode(value);
75
+ const lines = chunk.split('\n').filter(line => line.trim());
 
 
 
 
 
76
 
77
+ for (const line of lines) {
78
+ if (!line || !line.startsWith('data: ') || line.includes('[DONE]')) continue;
79
 
80
+ try {
81
+ const json = line.slice(6).trim();
82
+ if (!json.startsWith('{')) continue;
83
 
84
+ const message = JSON.parse(json);
85
+ const content = message?.choices?.[0]?.delta?.content;
86
 
87
+ if (content) res.write(content);
88
+ } catch (err) {
89
+ console.error("Streaming error:", err.message);
90
+ continue;
 
 
 
 
91
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  }
93
  }
94
+
95
+ res.end();
96
+ } catch (error) {
97
+ console.error("Request error:", error.message);
98
+ res.status(500).send({
99
+ ok: false,
100
+ message: error.message || "Unexpected error",
101
+ });
102
  }
103
  });
104
 
 
107
  });
108
 
109
  app.listen(PORT, () => {
110
+ console.log(`Server running on port ${PORT}`);
111
+ });