everydaycats commited on
Commit
0ef87a8
·
verified ·
1 Parent(s): 4b0f1ef

Delete server.js

Browse files
Files changed (1) hide show
  1. server.js +0 -275
server.js DELETED
@@ -1,275 +0,0 @@
1
- // server.js
2
- import express from 'express';
3
- import bodyParser from 'body-parser';
4
- import cors from 'cors';
5
- import { StateManager } from './stateManager.js';
6
- import { AIEngine } from './aiEngine.js';
7
- import fs from 'fs';
8
-
9
- const app = express();
10
- const PORT = process.env.PORT || 7860;
11
-
12
- // Load prompts for dynamic usage
13
- const sysPrompts = JSON.parse(fs.readFileSync('./prompts.json', 'utf8'));
14
-
15
- app.use(cors());
16
- app.use(bodyParser.json({ limit: '50mb' })); // Increased limit for images
17
-
18
- // Middleware: Validate User/Project IDs
19
- const validateRequest = (req, res, next) => {
20
- const { userId, projectId } = req.body;
21
- if (!userId || !projectId) {
22
- return res.status(400).json({ error: "Missing userId or projectId" });
23
- }
24
- next();
25
- };
26
-
27
- /**
28
- * 1. NEW PROJECT
29
- * Flow: PM (GDD) -> PM (Tasks) -> Worker (Task 1)
30
- */
31
- app.post('/new/project', validateRequest, async (req, res) => {
32
- const { userId, projectId, description } = req.body;
33
-
34
- try {
35
- // 1. Generate GDD with PM (High Thinking)
36
- const pmHistory = [];
37
- const gddPrompt = `Create a comprehensive GDD for: ${description}`;
38
- const gddResponse = await AIEngine.callPM(pmHistory, gddPrompt);
39
-
40
- pmHistory.push({ role: 'user', parts: [{ text: gddPrompt }] });
41
- pmHistory.push({ role: 'model', parts: [{ text: gddResponse }] });
42
-
43
- // 2. Generate Initial Tasks
44
- const taskPrompt = "Based on the GDD, generate a prioritized list of initial technical tasks. Output them as a JSON list.";
45
- const taskResponse = await AIEngine.callPM(pmHistory, taskPrompt);
46
-
47
- pmHistory.push({ role: 'user', parts: [{ text: taskPrompt }] });
48
- pmHistory.push({ role: 'model', parts: [{ text: taskResponse }] });
49
-
50
- // 3. Initialize Worker with GDD Context and Execute First Task
51
- const workerHistory = [];
52
- const initialWorkerPrompt = `Here is the GDD: ${gddResponse}. \n\n Here are the tasks: ${taskResponse}. \n\n EXECUTE THE FIRST TASK NOW.`;
53
- const workerResponse = await AIEngine.callWorker(workerHistory, initialWorkerPrompt);
54
-
55
- workerHistory.push({ role: 'user', parts: [{ text: initialWorkerPrompt }] });
56
- workerHistory.push({ role: 'model', parts: [{ text: workerResponse }] });
57
-
58
- // Save State
59
- await StateManager.updateProject(projectId, {
60
- userId,
61
- pmHistory,
62
- workerHistory,
63
- gdd: gddResponse,
64
- failureCount: 0
65
- });
66
-
67
- // Queue the result for the plugin
68
- StateManager.queueCommand(projectId, workerResponse);
69
-
70
- res.json({ success: true, message: "Project initialized", gddPreview: gddResponse.substring(0, 200) });
71
-
72
- } catch (err) {
73
- console.error(err);
74
- res.status(500).json({ error: "AI Processing Failed" });
75
- }
76
- });
77
-
78
- /**
79
- * 2. FEEDBACK (The Main Loop Endpoint)
80
- * Accepts text + optional image. Hits Worker. Checks for escalation.
81
- */
82
-
83
- app.post('/project/feedback', async (req, res) => {
84
- const { projectId, prompt, hierarchyContext, scriptContext, logContext, taskComplete } = req.body;
85
-
86
- const project = await StateManager.getProject(projectId);
87
- if (!project) return res.status(404).json({ error: "Project not found." });
88
-
89
- // 1. MISSION COMPLETE: CALL PM & NUKE WORKER
90
- if (taskComplete) {
91
- console.log(`[${projectId}] ✅ TASK COMPLETE. Calling PM & Nuking Worker.`);
92
-
93
- // A. Notify PM (Add to PM History)
94
- const summary = `Worker has successfully completed the previous task. Logs: ${logContext?.logs || "Clean"}. Ready for next assignment.`;
95
- project.pmHistory.push({ role: 'user', parts: [{ text: summary }] });
96
-
97
- // B. Nuke Worker (Reset History)
98
- project.workerHistory = [];
99
-
100
- // C. Update State
101
- await StateManager.updateProject(projectId, {
102
- pmHistory: project.pmHistory,
103
- workerHistory: [], // THE NUKE
104
- status: "IDLE" // Waiting for user or PM to start next task
105
- });
106
-
107
- return res.json({ success: true, message: "Worker Nuked. PM Notified. Loop Stopped." });
108
- }
109
-
110
- // 2. ERROR DETECTION (Safety Net)
111
- let isFailure = false;
112
- if (logContext && logContext.logs) {
113
- const errorKeywords = ["Infinite yield", "Stack Begin", "Error:", "Exception", "failed"];
114
- if (errorKeywords.some(keyword => logContext.logs.includes(keyword))) {
115
- isFailure = true;
116
- console.log(`[${projectId}] ⚠️ Detected Error in Logs.`);
117
- }
118
- }
119
-
120
- // 3. BUILD AI PROMPT
121
- const fullInput = `USER: ${prompt || "Automatic Feedback"}` + formatContext({ hierarchyContext, scriptContext, logContext });
122
-
123
- let finalPrompt = fullInput;
124
- if (isFailure && (!prompt || prompt.length < 5)) {
125
- finalPrompt += "\n[SYSTEM ALERT]: Runtime Error detected. Fix the code immediately. Do not use WaitForChild. Do not yield.";
126
- }
127
-
128
- console.log(`[${projectId}] Processing Feedback...`);
129
-
130
- // 4. CALL AI
131
- try {
132
- const response = await AIEngine.callWorker(project.workerHistory, finalPrompt);
133
-
134
- // Escalation Logic
135
- if (response.includes("STATUS: ESCALATE_TO_PM") || (project.failureCount > 2)) {
136
- console.log(`[${projectId}] Escalating to PM...`);
137
- const guidance = await AIEngine.callPM(project.pmHistory, `Worker Stuck. Input: ${fullInput}`);
138
- const fixed = await AIEngine.callWorker(project.workerHistory, `PM GUIDANCE: ${guidance}`);
139
-
140
- await StateManager.updateProject(projectId, { failureCount: 0 });
141
- project.workerHistory.push({ role: 'user', parts: [{ text: fullInput }] });
142
- project.workerHistory.push({ role: 'model', parts: [{ text: fixed }] });
143
- await StateManager.queueCommand(projectId, fixed);
144
- return res.json({ success: true, message: "Escalated & Fixed." });
145
- }
146
-
147
- project.workerHistory.push({ role: 'user', parts: [{ text: fullInput }] });
148
- project.workerHistory.push({ role: 'model', parts: [{ text: response }] });
149
- await StateManager.updateProject(projectId, { workerHistory: project.workerHistory });
150
- await StateManager.queueCommand(projectId, response);
151
-
152
- res.json({ success: true, message: "Input Processed." });
153
-
154
- } catch (err) {
155
- console.error("AI Error:", err);
156
- res.status(500).json({ error: "AI Failed" });
157
- }
158
- });
159
-
160
-
161
- /**
162
- * 3. INTERNAL PING WORKER
163
- * PM sends guidance to Worker.
164
- */
165
- app.post('/internal/ping/worker', validateRequest, async (req, res) => {
166
- const { projectId, guidancePrompt } = req.body;
167
- const project = await StateManager.getProject(projectId);
168
- if (!project) return res.status(404).json({ error: "Project not found" });
169
-
170
- // Inject PM Context (GDD/History) into the message if requested
171
- const fullContextPrompt = `PM CONTEXT: ${JSON.stringify(project.pmHistory)}. \n GUIDANCE: ${guidancePrompt}`;
172
-
173
- const response = await AIEngine.callWorker(project.workerHistory, fullContextPrompt);
174
- StateManager.queueCommand(projectId, response);
175
-
176
- res.json({ success: true, message: "Guidance sent to Worker" });
177
- });
178
-
179
- /**
180
- * 4. INTERNAL PING PM
181
- * Worker signals distress -> PM responds.
182
- */
183
- app.post('/internal/ping/pm', validateRequest, async (req, res) => {
184
- const { projectId, distressMessage } = req.body;
185
- const project = await StateManager.getProject(projectId);
186
-
187
- // PM analyzes distress
188
- const pmResponse = await AIEngine.callPM(project.pmHistory, `Worker Distress: ${distressMessage}. Provide solution.`);
189
-
190
- // Logic: Decide to reset worker OR guide worker
191
- if (pmResponse.includes("RESET_RECOMMENDED")) {
192
- // Call reset endpoint logic (internal function call)
193
- project.workerHistory = [{ role: 'user', parts: [{ text: sysPrompts.worker_reset_prompt.replace('{{INSTRUCTION}}', pmResponse) }] }];
194
- await StateManager.updateProject(projectId, { workerHistory: project.workerHistory });
195
- res.json({ action: "RESET", guidance: pmResponse });
196
- } else {
197
- // Just guide
198
- const workerResp = await AIEngine.callWorker(project.workerHistory, `PM FIX: ${pmResponse}`);
199
- StateManager.queueCommand(projectId, workerResp);
200
- res.json({ action: "GUIDANCE", guidance: pmResponse });
201
- }
202
- });
203
-
204
- /**
205
- * 5. PROJECT RESET
206
- * Resets the worker thread completely.
207
- */
208
- app.post('/project/reset', validateRequest, async (req, res) => {
209
- const { projectId } = req.body;
210
- const project = await StateManager.getProject(projectId);
211
-
212
- // Clear history, keep GDD context
213
- const resetPrompt = `System reset. Current GDD: ${project.gdd}. Await instructions.`;
214
-
215
- await StateManager.updateProject(projectId, {
216
- workerHistory: [{ role: 'user', parts: [{ text: resetPrompt }] }],
217
- failureCount: 0
218
- });
219
-
220
- res.json({ success: true, message: "Worker thread reset" });
221
- });
222
-
223
- /**
224
- * 6. PROJECT PING (The Roblox Plugin Endpoint)
225
- * Plugin calls this to fetch executable code.
226
- */
227
- /*
228
- app.post('/project/ping', validateRequest, async (req, res) => {
229
- const { projectId } = req.body;
230
- const project = await StateManager.getProject(projectId);
231
-
232
- if (!project || !project.commandQueue || project.commandQueue.length === 0) {
233
- return res.json({ status: "IDLE" });
234
- }
235
-
236
- // Pop the oldest command
237
- const command = project.commandQueue.shift();
238
- await StateManager.updateProject(projectId, { commandQueue: project.commandQueue });
239
-
240
- // Return the whole response, but specifically parsed code for execution
241
- res.json({
242
- status: "EXECUTE",
243
- fullResponse: command.raw,
244
- codeSnippet: command.code // The markdown snippet extracted in StateManager
245
- });
246
- });
247
- */
248
-
249
- /**
250
- * 7. INACTIVITY CLEANUP
251
- */
252
- app.delete('/internal/cleanup', async (req, res) => {
253
- const count = StateManager.cleanupInactivity();
254
- res.json({ success: true, removed: count });
255
- });
256
-
257
- app.post('/project/ping', async (req, res) => {
258
- const { projectId } = req.body;
259
- const command = await StateManager.popCommand(projectId);
260
-
261
- if (command) {
262
- // Sends: { action: "EXECUTE", target: "...", code: "..." }
263
- res.json({
264
- action: command.type,
265
- target: command.payload,
266
- code: command.type === 'EXECUTE' ? command.payload : null
267
- });
268
- } else {
269
- res.json({ action: "IDLE" });
270
- }
271
- });
272
-
273
- app.listen(PORT, () => {
274
- console.log(`AI Builder Backend running on port ${PORT}`);
275
- });