hadadrjt commited on
Commit
7e6a554
·
1 Parent(s): 1dfeea6

ai: Production.

Browse files
Files changed (2) hide show
  1. index.js +91 -127
  2. package.json +1 -1
index.js CHANGED
@@ -13,196 +13,160 @@ import path from "path";
13
  const app = express();
14
  const server = http.createServer(app);
15
  const wss = new WebSocketServer({ server });
 
16
  const OPENAI_API_BASE_URL = process.env.OPENAI_API_BASE_URL || "";
17
  const OPENAI_API_KEY = process.env.OPENAI_API_KEY || "";
18
  const UMINT = process.env.UMINT || ``;
19
 
 
20
  app.use(cookieParser());
21
 
22
- // Root endpoint.
23
  app.get("/", (_req, res) => res.send(UMINT));
24
 
25
- // Search Engine Optimization (SEO).
26
- // Robots Exclusion Protocol.
27
  app.get("/robots.txt", (_req, res) => {
28
  res.sendFile(path.resolve("src/crawlers/robots.txt"));
29
- }); // https://umint-ai.hf.space/robots.txt
30
- // Sitemaps.
31
  app.get("/sitemap.xml", (_req, res) => {
32
  res.sendFile(path.resolve("src/crawlers/sitemap.xml"));
33
- }); // https://umint-ai.hf.space/sitemap.xml
34
- // Google Search Console Tools.
35
  app.get("/google15aba15fe250d693.html", (_req, res) => {
36
  res.sendFile(path.resolve("src/webmasters/google.html"));
37
- }); // https://umint-ai.hf.space/google15aba15fe250d693.html
38
- // Bing Webmaster Tools.
39
  app.get("/BingSiteAuth.xml", (_req, res) => {
40
  res.sendFile(path.resolve("src/webmasters/bing.xml"));
41
- }); // https://umint-ai.hf.space/BingSiteAuth.xml
42
- // End of SEO.
43
 
44
  // Favicon.
45
  app.get("/assets/images/favicon.ico", (_req, res) => {
46
  res.sendFile(path.resolve("assets/images/favicon.ico"));
47
  });
48
 
 
49
  wss.on("connection", (ws) => {
50
- // Abort controller for the currently active streaming request.
51
  let currentAbortController = null;
52
 
53
- // Handle incoming messages from the WebSocket client.
54
- ws.on("message", async (msg) => {
55
- try {
56
- const data = JSON.parse(msg.toString());
57
 
58
- // Handle explicit stop request from client.
59
- if (data.type === "stop") {
60
- if (currentAbortController) {
61
- // Abort the active fetch request to stop streaming.
62
- currentAbortController.abort();
63
- currentAbortController = null;
64
- }
65
- // Notify client that streaming ended.
66
- ws.send(JSON.stringify({ type: "end" }));
67
- return;
68
- }
69
 
70
- // Extract user message and optional history for context.
71
- const message = data.message;
72
- const history = data.history || [];
73
- // Build messages array with history and the new user message.
74
- const setup_messages = [...history, { role: "user", content: message }];
75
-
76
- // Create a new AbortController to allow client to cancel the stream.
77
  currentAbortController = new AbortController();
78
  const signal = currentAbortController.signal;
79
 
80
- // Send request to the Endpoint.
81
- const request = await fetch(OPENAI_API_BASE_URL, {
82
- method: "POST",
83
- headers: {
84
- "Content-Type": "application/json",
85
- "Authorization": `Bearer ${OPENAI_API_KEY}`,
86
- },
87
- body: JSON.stringify({
88
- model: "gpt-4.1-nano",
89
- messages: setup_messages,
90
- stream: true,
91
- private: true,
92
- isPrivate: true
93
- }),
94
- signal
95
- });
96
-
97
- // Handle non 2xx responses by returning an error to the client.
98
- if (!request.ok) {
99
- const errorData = await request.text();
100
- ws.send(JSON.stringify({ type: "error", error: `HTTP ${request.status}: ${request.statusText} - ${errorData}` }));
101
- if (currentAbortController) {
102
- currentAbortController.abort();
103
- currentAbortController = null;
 
104
  }
105
- return;
106
- }
107
 
108
- // Get the response body stream to read incremental chunks.
109
- const reader = request.body;
110
- if (!reader) {
111
- ws.send(JSON.stringify({ type: "error", error: "Response body is empty" }));
112
- if (currentAbortController) {
113
- currentAbortController.abort();
114
- currentAbortController = null;
115
  }
116
- return;
117
- }
118
 
119
- // Buffer partial data between streamed chunks.
120
- let buffer = "";
121
- try {
122
- // Iterate over stream chunks as they arrive.
123
- for await (const chunk of reader) {
124
- // If client requested abort, stop processing and inform the client.
 
125
  if (signal.aborted) {
126
- ws.send(JSON.stringify({ type: "end" }));
127
- if (currentAbortController) {
128
- currentAbortController.abort();
129
- currentAbortController = null;
130
- }
131
  return;
132
  }
133
-
134
- // Append raw chunk text to the buffer.
135
  buffer += chunk.toString();
136
-
137
- // Process full lines separated by newline characters.
138
  let idx;
139
  while ((idx = buffer.indexOf("\n")) !== -1) {
140
  const line = buffer.slice(0, idx).trim();
141
  buffer = buffer.slice(idx + 1);
142
-
143
  if (line.startsWith("data: ")) {
144
  const dataStr = line.substring(6).trim();
145
- // Skip empty events and the stream terminator.
146
  if (!dataStr || dataStr === "[DONE]") continue;
147
  try {
148
- // Parse JSON payload and extract incremental content.
149
  const parsed = JSON.parse(dataStr);
150
  const part = parsed?.choices?.[0]?.delta?.content;
151
- if (part) {
152
- // Send incremental chunk to the client.
153
- ws.send(JSON.stringify({ type: "chunk", chunk: part }));
154
- }
155
- } catch (parseError) {
156
- // Log parsing errors for debugging.
157
- console.error("Error parsing JSON:", parseError, "Data string:", dataStr);
158
  }
159
  }
160
  }
161
  }
162
- } catch (logs) {
163
- // If the fetch was aborted by the client, signal end.
 
 
164
  if (signal.aborted) {
165
- ws.send(JSON.stringify({ type: "end" }));
166
- } else {
167
- // For unexpected stream errors, log and notify client.
168
- console.error("Error:", logs);
169
- ws.send(JSON.stringify({ type: "error", error: "Error: " + (logs && logs.message ? logs.message : String(logs)) }));
170
  }
171
- if (currentAbortController) {
172
- currentAbortController.abort();
173
- currentAbortController = null;
174
  }
175
- return;
176
  }
 
 
177
 
178
- // Normal end of stream, notify client.
179
- ws.send(JSON.stringify({ type: "end" }));
180
- if (currentAbortController) {
181
- currentAbortController.abort();
182
- currentAbortController = null;
183
- }
184
- } catch (e) {
185
- // Catch JSON parse errors and other unexpected exceptions.
186
- console.error("General error:", e);
187
- ws.send(JSON.stringify({ type: "error", error: e.message || "An unknown error occurred" }));
188
- if (currentAbortController) {
189
- currentAbortController.abort();
190
- currentAbortController = null;
191
  }
 
 
 
 
 
 
 
 
 
192
  }
193
  });
194
 
195
- // Ensure any active fetch is aborted when the WebSocket closes.
196
  ws.on("close", () => {
197
- if (currentAbortController) {
198
- currentAbortController.abort();
199
- currentAbortController = null;
200
- }
201
  });
202
  });
203
 
204
  const PORT = process.env.PORT || 7860;
205
- // Start the HTTP and WebSocket server.
206
- server.listen(PORT, () => {
207
- console.log(`Server running on port ${PORT}`);
208
- });
 
13
  const app = express();
14
  const server = http.createServer(app);
15
  const wss = new WebSocketServer({ server });
16
+
17
  const OPENAI_API_BASE_URL = process.env.OPENAI_API_BASE_URL || "";
18
  const OPENAI_API_KEY = process.env.OPENAI_API_KEY || "";
19
  const UMINT = process.env.UMINT || ``;
20
 
21
+ // Use cookies.
22
  app.use(cookieParser());
23
 
24
+ // Root.
25
  app.get("/", (_req, res) => res.send(UMINT));
26
 
27
+ // SEO.
 
28
  app.get("/robots.txt", (_req, res) => {
29
  res.sendFile(path.resolve("src/crawlers/robots.txt"));
30
+ });
 
31
  app.get("/sitemap.xml", (_req, res) => {
32
  res.sendFile(path.resolve("src/crawlers/sitemap.xml"));
33
+ });
 
34
  app.get("/google15aba15fe250d693.html", (_req, res) => {
35
  res.sendFile(path.resolve("src/webmasters/google.html"));
36
+ });
 
37
  app.get("/BingSiteAuth.xml", (_req, res) => {
38
  res.sendFile(path.resolve("src/webmasters/bing.xml"));
39
+ });
 
40
 
41
  // Favicon.
42
  app.get("/assets/images/favicon.ico", (_req, res) => {
43
  res.sendFile(path.resolve("assets/images/favicon.ico"));
44
  });
45
 
46
+ // Handle WebSocket connections.
47
  wss.on("connection", (ws) => {
 
48
  let currentAbortController = null;
49
 
50
+ // Send messages to client.
51
+ const sendToClient = (type, payload) => {
52
+ ws.send(JSON.stringify({ type, ...payload }));
53
+ };
54
 
55
+ // Send logs to client.
56
+ const sendError = (message) => {
57
+ sendToClient("error", { error: message });
58
+ };
 
 
 
 
 
 
 
59
 
60
+ // Make a request.
61
+ const streamRequest = async (messages, retries = 3) => {
62
+ for (let attempt = 1; attempt <= retries; attempt++) {
 
 
 
 
63
  currentAbortController = new AbortController();
64
  const signal = currentAbortController.signal;
65
 
66
+ try {
67
+ const response = await fetch(OPENAI_API_BASE_URL, {
68
+ method: "POST",
69
+ headers: {
70
+ "Content-Type": "application/json",
71
+ "Authorization": `Bearer ${OPENAI_API_KEY}`,
72
+ },
73
+ body: JSON.stringify({
74
+ model: "gpt-4.1-nano",
75
+ messages,
76
+ stream: true,
77
+ private: true,
78
+ isPrivate: true
79
+ }),
80
+ signal
81
+ });
82
+
83
+ if (response.status === 502) {
84
+ if (attempt === retries) {
85
+ sendError(
86
+ "The server is currently busy. Please wait a moment or try again later."
87
+ );
88
+ return;
89
+ }
90
+ continue;
91
  }
 
 
92
 
93
+ if (!response.ok) {
94
+ const errText = await response.text();
95
+ sendError(`HTTP ${response.status}: ${response.statusText} - ${errText}`);
96
+ return;
 
 
 
97
  }
 
 
98
 
99
+ if (!response.body) {
100
+ sendError("Response body is empty.");
101
+ return;
102
+ }
103
+
104
+ let buffer = "";
105
+ for await (const chunk of response.body) {
106
  if (signal.aborted) {
107
+ sendToClient("end", {});
 
 
 
 
108
  return;
109
  }
 
 
110
  buffer += chunk.toString();
 
 
111
  let idx;
112
  while ((idx = buffer.indexOf("\n")) !== -1) {
113
  const line = buffer.slice(0, idx).trim();
114
  buffer = buffer.slice(idx + 1);
 
115
  if (line.startsWith("data: ")) {
116
  const dataStr = line.substring(6).trim();
 
117
  if (!dataStr || dataStr === "[DONE]") continue;
118
  try {
 
119
  const parsed = JSON.parse(dataStr);
120
  const part = parsed?.choices?.[0]?.delta?.content;
121
+ if (part) sendToClient("chunk", { chunk: part });
122
+ } catch (err) {
123
+ sendError(`Parse error: ${err.message}`);
 
 
 
 
124
  }
125
  }
126
  }
127
  }
128
+
129
+ sendToClient("end", {});
130
+ return;
131
+ } catch (err) {
132
  if (signal.aborted) {
133
+ sendToClient("end", {});
134
+ return;
 
 
 
135
  }
136
+ if (attempt === retries) {
137
+ sendError(err.message || "Unknown error.");
 
138
  }
 
139
  }
140
+ }
141
+ };
142
 
143
+ // Handle messages from client.
144
+ ws.on("message", async (msg) => {
145
+ try {
146
+ const data = JSON.parse(msg.toString());
147
+
148
+ if (data.type === "stop") {
149
+ if (currentAbortController) currentAbortController.abort();
150
+ sendToClient("end", {});
151
+ return;
 
 
 
 
152
  }
153
+
154
+ const message = data.message;
155
+ const history = data.history || [];
156
+ const setupMessages = [...history, { role: "user", content: message }];
157
+ await streamRequest(setupMessages);
158
+
159
+ } catch (err) {
160
+ sendError(err.message || "An unknown error occurred.");
161
+ if (currentAbortController) currentAbortController.abort();
162
  }
163
  });
164
 
165
+ // Abort on WebSocket close.
166
  ws.on("close", () => {
167
+ if (currentAbortController) currentAbortController.abort();
 
 
 
168
  });
169
  });
170
 
171
  const PORT = process.env.PORT || 7860;
172
+ server.listen(PORT);
 
 
 
package.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "UltimaX Intelligence",
3
- "version": "0.0.1",
4
  "type": "module",
5
  "main": "index.js",
6
  "scripts": {
 
1
  {
2
  "name": "UltimaX Intelligence",
3
+ "version": "0.0.2",
4
  "type": "module",
5
  "main": "index.js",
6
  "scripts": {