Update stateManager.js
Browse files- stateManager.js +44 -6
stateManager.js
CHANGED
|
@@ -22,6 +22,7 @@ export const StateManager = {
|
|
| 22 |
// 1. Check Cache
|
| 23 |
if (activeProjects.has(projectId)) {
|
| 24 |
const cached = activeProjects.get(projectId);
|
|
|
|
| 25 |
if (cached.workerHistory && cached.pmHistory) {
|
| 26 |
return cached;
|
| 27 |
}
|
|
@@ -39,12 +40,14 @@ export const StateManager = {
|
|
| 39 |
const memoryObject = {
|
| 40 |
...proj.info,
|
| 41 |
id: proj.id,
|
| 42 |
-
userId: proj.user_id,
|
| 43 |
-
//
|
|
|
|
|
|
|
|
|
|
| 44 |
workerHistory: (chunks || []).filter(c => c.type === 'worker').reverse().flatMap(c => c.payload || []),
|
| 45 |
pmHistory: (chunks || []).filter(c => c.type === 'pm').reverse().flatMap(c => c.payload || []),
|
| 46 |
|
| 47 |
-
// TRANSIENT STATE (Not loaded from DB anymore, start fresh)
|
| 48 |
commandQueue: [],
|
| 49 |
failureCount: proj.info?.failureCount || 0,
|
| 50 |
lastActive: Date.now()
|
|
@@ -54,6 +57,7 @@ export const StateManager = {
|
|
| 54 |
return memoryObject;
|
| 55 |
},
|
| 56 |
|
|
|
|
| 57 |
// --- HISTORY (PERSISTENT) ---
|
| 58 |
addHistory: async (projectId, type, role, text) => {
|
| 59 |
const newMessage = { role, parts: [{ text }] };
|
|
@@ -91,20 +95,54 @@ export const StateManager = {
|
|
| 91 |
});
|
| 92 |
}
|
| 93 |
},
|
|
|
|
| 94 |
|
| 95 |
// --- COMMANDS (MEMORY ONLY) ---
|
| 96 |
-
queueCommand: async (projectId,
|
| 97 |
let project = activeProjects.get(projectId);
|
| 98 |
|
| 99 |
-
// If not in RAM, try to load it first (rare, but good for safety)
|
| 100 |
if (!project) {
|
| 101 |
project = await StateManager.getProject(projectId);
|
| 102 |
}
|
| 103 |
|
| 104 |
-
if (project)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
if (!project.commandQueue) project.commandQueue = [];
|
| 106 |
project.commandQueue.push(command);
|
| 107 |
console.log(`[Memory] Queued command for ${projectId}: ${command.type}`);
|
|
|
|
|
|
|
|
|
|
| 108 |
}
|
| 109 |
},
|
| 110 |
|
|
|
|
| 22 |
// 1. Check Cache
|
| 23 |
if (activeProjects.has(projectId)) {
|
| 24 |
const cached = activeProjects.get(projectId);
|
| 25 |
+
// Ensure we have history arrays to prevent crashes
|
| 26 |
if (cached.workerHistory && cached.pmHistory) {
|
| 27 |
return cached;
|
| 28 |
}
|
|
|
|
| 40 |
const memoryObject = {
|
| 41 |
...proj.info,
|
| 42 |
id: proj.id,
|
| 43 |
+
userId: proj.user_id,
|
| 44 |
+
// --- RESTORED FIELDS ---
|
| 45 |
+
thumbnail: proj.info?.thumbnail || null, // Ensure thumbnail is carried over
|
| 46 |
+
gdd: proj.info?.gdd || null, // Ensure GDD is carried over
|
| 47 |
+
// -----------------------
|
| 48 |
workerHistory: (chunks || []).filter(c => c.type === 'worker').reverse().flatMap(c => c.payload || []),
|
| 49 |
pmHistory: (chunks || []).filter(c => c.type === 'pm').reverse().flatMap(c => c.payload || []),
|
| 50 |
|
|
|
|
| 51 |
commandQueue: [],
|
| 52 |
failureCount: proj.info?.failureCount || 0,
|
| 53 |
lastActive: Date.now()
|
|
|
|
| 57 |
return memoryObject;
|
| 58 |
},
|
| 59 |
|
| 60 |
+
|
| 61 |
// --- HISTORY (PERSISTENT) ---
|
| 62 |
addHistory: async (projectId, type, role, text) => {
|
| 63 |
const newMessage = { role, parts: [{ text }] };
|
|
|
|
| 95 |
});
|
| 96 |
}
|
| 97 |
},
|
| 98 |
+
|
| 99 |
|
| 100 |
// --- COMMANDS (MEMORY ONLY) ---
|
| 101 |
+
queueCommand: async (projectId, input) => {
|
| 102 |
let project = activeProjects.get(projectId);
|
| 103 |
|
|
|
|
| 104 |
if (!project) {
|
| 105 |
project = await StateManager.getProject(projectId);
|
| 106 |
}
|
| 107 |
|
| 108 |
+
if (!project) return;
|
| 109 |
+
|
| 110 |
+
// --- RESTORED PARSING LOGIC START ---
|
| 111 |
+
let command = null;
|
| 112 |
+
|
| 113 |
+
if (typeof input === 'object' && input.type && input.payload) {
|
| 114 |
+
// It's already a formatted command object
|
| 115 |
+
command = input;
|
| 116 |
+
}
|
| 117 |
+
else if (typeof input === 'string') {
|
| 118 |
+
const rawResponse = input;
|
| 119 |
+
|
| 120 |
+
// Filters to prevent loops
|
| 121 |
+
if (rawResponse.includes("[ASK_PM:")) return;
|
| 122 |
+
if (rawResponse.includes("[ROUTE_TO_PM:")) return;
|
| 123 |
+
// Ignore generic image generation triggers if no code is present
|
| 124 |
+
if (rawResponse.includes("[GENERATE_IMAGE:") && !rawResponse.includes("```")) return;
|
| 125 |
+
|
| 126 |
+
// REGEX: Extract Lua code, Read Script, Read Hierarchy, Logs
|
| 127 |
+
const codeMatch = rawResponse.match(/```(?:lua|luau)?([\s\S]*?)```/i);
|
| 128 |
+
const readScriptMatch = rawResponse.match(/\[READ_SCRIPT:\s*(.*?)\]/);
|
| 129 |
+
const readHierarchyMatch = rawResponse.match(/\[READ_HIERARCHY:\s*(.*?)\]/);
|
| 130 |
+
const readLogsMatch = rawResponse.includes("[READ_LOGS]");
|
| 131 |
+
|
| 132 |
+
if (codeMatch) command = { type: "EXECUTE", payload: codeMatch[1].trim() };
|
| 133 |
+
else if (readScriptMatch) command = { type: "READ_SCRIPT", payload: readScriptMatch[1].trim() };
|
| 134 |
+
else if (readHierarchyMatch) command = { type: "READ_HIERARCHY", payload: readHierarchyMatch[1].trim() };
|
| 135 |
+
else if (readLogsMatch) command = { type: "READ_LOGS", payload: null };
|
| 136 |
+
}
|
| 137 |
+
// --- RESTORED PARSING LOGIC END ---
|
| 138 |
+
|
| 139 |
+
if (command) {
|
| 140 |
if (!project.commandQueue) project.commandQueue = [];
|
| 141 |
project.commandQueue.push(command);
|
| 142 |
console.log(`[Memory] Queued command for ${projectId}: ${command.type}`);
|
| 143 |
+
|
| 144 |
+
// Optional: If you want to persist the queue to Supabase like you did in Firebase,
|
| 145 |
+
// you would call updateProject here. But keeping it memory-only is faster.
|
| 146 |
}
|
| 147 |
},
|
| 148 |
|