@superatomai/sdk-node 0.0.53-dsp → 0.0.54-dsp
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +81 -94
- package/dist/index.d.ts +81 -94
- package/dist/index.js +465 -863
- package/dist/index.mjs +465 -863
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -316,8 +316,7 @@ var ComponentPropsSchema = z3.object({
|
|
|
316
316
|
query: z3.string().or(z3.object({})).nullable().optional(),
|
|
317
317
|
title: z3.string().optional(),
|
|
318
318
|
description: z3.string().optional(),
|
|
319
|
-
config: z3.record(z3.unknown()).optional()
|
|
320
|
-
actions: z3.array(z3.any()).optional()
|
|
319
|
+
config: z3.record(z3.unknown()).optional()
|
|
321
320
|
}).passthrough();
|
|
322
321
|
var ComponentSchema = z3.object({
|
|
323
322
|
id: z3.string(),
|
|
@@ -431,19 +430,6 @@ var UILogsMessageSchema = z3.object({
|
|
|
431
430
|
type: z3.literal("UI_LOGS"),
|
|
432
431
|
payload: UILogsPayloadSchema
|
|
433
432
|
});
|
|
434
|
-
var ActionsRequestPayloadSchema = z3.object({
|
|
435
|
-
userId: z3.string().optional(),
|
|
436
|
-
SA_RUNTIME: z3.object({
|
|
437
|
-
threadId: z3.string(),
|
|
438
|
-
uiBlockId: z3.string()
|
|
439
|
-
}).optional()
|
|
440
|
-
});
|
|
441
|
-
var ActionsRequestMessageSchema = z3.object({
|
|
442
|
-
id: z3.string(),
|
|
443
|
-
from: MessageParticipantSchema,
|
|
444
|
-
type: z3.literal("ACTIONS"),
|
|
445
|
-
payload: ActionsRequestPayloadSchema
|
|
446
|
-
});
|
|
447
433
|
var DashboardQueryFiltersSchema = z3.object({
|
|
448
434
|
dashboardId: z3.string().optional(),
|
|
449
435
|
projectId: z3.string().optional(),
|
|
@@ -553,8 +539,6 @@ var UIBlockSchema = z3.object({
|
|
|
553
539
|
generatedComponentMetadata: ComponentSchema.optional(),
|
|
554
540
|
// Actual field used by UIBlock class
|
|
555
541
|
componentData: z3.record(z3.any()).optional(),
|
|
556
|
-
actions: z3.array(z3.any()).optional(),
|
|
557
|
-
isFetchingActions: z3.boolean().optional(),
|
|
558
542
|
createdAt: z3.string().optional(),
|
|
559
543
|
/**
|
|
560
544
|
* Which script recipe produced this answer. Set whenever the turn was answered
|
|
@@ -1078,11 +1062,10 @@ var UIBlock = class {
|
|
|
1078
1062
|
* @param userQuestion - The user's question or input
|
|
1079
1063
|
* @param componentData - The component data object
|
|
1080
1064
|
* @param generatedComponentMetadata - Optional metadata about the generated component
|
|
1081
|
-
* @param actions - Optional array of available actions
|
|
1082
1065
|
* @param id - Optional custom ID, generates UUID if not provided
|
|
1083
1066
|
* @param textResponse - Optional text response from LLM
|
|
1084
1067
|
*/
|
|
1085
|
-
constructor(userQuestion, componentData = {}, generatedComponentMetadata = {},
|
|
1068
|
+
constructor(userQuestion, componentData = {}, generatedComponentMetadata = {}, id, textResponse = null) {
|
|
1086
1069
|
/**
|
|
1087
1070
|
* Which script recipe produced this answer, when a script did. Read on the
|
|
1088
1071
|
* NEXT turn so the user can say "use mode instead" and have the matcher
|
|
@@ -1094,7 +1077,6 @@ var UIBlock = class {
|
|
|
1094
1077
|
this.userQuestion = userQuestion;
|
|
1095
1078
|
this.componentData = componentData;
|
|
1096
1079
|
this.generatedComponentMetadata = generatedComponentMetadata;
|
|
1097
|
-
this.actions = actions;
|
|
1098
1080
|
this.textResponse = textResponse;
|
|
1099
1081
|
this.createdAt = /* @__PURE__ */ new Date();
|
|
1100
1082
|
}
|
|
@@ -1223,76 +1205,6 @@ var UIBlock = class {
|
|
|
1223
1205
|
setTextResponse(textResponse) {
|
|
1224
1206
|
this.textResponse = textResponse;
|
|
1225
1207
|
}
|
|
1226
|
-
/**
|
|
1227
|
-
* Get all actions (only if they are resolved, not if fetching)
|
|
1228
|
-
*/
|
|
1229
|
-
getActions() {
|
|
1230
|
-
return this.actions;
|
|
1231
|
-
}
|
|
1232
|
-
/**
|
|
1233
|
-
* Get or fetch actions
|
|
1234
|
-
* If actions don't exist or are a Promise, calls the generateFn and stores the promise
|
|
1235
|
-
* If actions already exist, returns them
|
|
1236
|
-
* @param generateFn - Async function to generate actions
|
|
1237
|
-
* @returns Promise resolving to Action[]
|
|
1238
|
-
*/
|
|
1239
|
-
async getOrFetchActions(generateFn) {
|
|
1240
|
-
if (this.actions && !(this.actions instanceof Promise) && Array.isArray(this.actions) && this.actions.length > 0) {
|
|
1241
|
-
return this.actions;
|
|
1242
|
-
}
|
|
1243
|
-
const fetchPromise = generateFn();
|
|
1244
|
-
this.actions = fetchPromise;
|
|
1245
|
-
try {
|
|
1246
|
-
const resolvedActions = await fetchPromise;
|
|
1247
|
-
logger.info(`Fetched ${resolvedActions.length} actions for UIBlock: ${this.id}`);
|
|
1248
|
-
this.actions = resolvedActions;
|
|
1249
|
-
return resolvedActions;
|
|
1250
|
-
} catch (error) {
|
|
1251
|
-
this.actions = null;
|
|
1252
|
-
throw error;
|
|
1253
|
-
}
|
|
1254
|
-
}
|
|
1255
|
-
/**
|
|
1256
|
-
* Set or replace all actions
|
|
1257
|
-
*/
|
|
1258
|
-
setActions(actions) {
|
|
1259
|
-
this.actions = actions;
|
|
1260
|
-
}
|
|
1261
|
-
/**
|
|
1262
|
-
* Add a single action (only if actions are resolved)
|
|
1263
|
-
*/
|
|
1264
|
-
addAction(action) {
|
|
1265
|
-
if (this.actions && Array.isArray(this.actions)) {
|
|
1266
|
-
this.actions.push(action);
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
/**
|
|
1270
|
-
* Add multiple actions (only if actions are resolved)
|
|
1271
|
-
*/
|
|
1272
|
-
addActions(actions) {
|
|
1273
|
-
if (this.actions && Array.isArray(this.actions)) {
|
|
1274
|
-
this.actions.push(...actions);
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
/**
|
|
1278
|
-
* Remove an action by ID (only if actions are resolved)
|
|
1279
|
-
*/
|
|
1280
|
-
removeAction(actionId) {
|
|
1281
|
-
if (this.actions && Array.isArray(this.actions)) {
|
|
1282
|
-
const index = this.actions.findIndex((a) => a.id === actionId);
|
|
1283
|
-
if (index > -1) {
|
|
1284
|
-
this.actions.splice(index, 1);
|
|
1285
|
-
return true;
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1288
|
-
return false;
|
|
1289
|
-
}
|
|
1290
|
-
/**
|
|
1291
|
-
* Clear all actions
|
|
1292
|
-
*/
|
|
1293
|
-
clearActions() {
|
|
1294
|
-
this.actions = null;
|
|
1295
|
-
}
|
|
1296
1208
|
/**
|
|
1297
1209
|
* Bind this block to the script recipe that produced its answer.
|
|
1298
1210
|
*/
|
|
@@ -1322,18 +1234,12 @@ var UIBlock = class {
|
|
|
1322
1234
|
* Convert UIBlock to JSON-serializable object
|
|
1323
1235
|
*/
|
|
1324
1236
|
toJSON() {
|
|
1325
|
-
let actionsValue = null;
|
|
1326
|
-
if (this.actions && !(this.actions instanceof Promise) && Array.isArray(this.actions)) {
|
|
1327
|
-
actionsValue = this.actions;
|
|
1328
|
-
}
|
|
1329
1237
|
return {
|
|
1330
1238
|
id: this.id,
|
|
1331
1239
|
userQuestion: this.userQuestion,
|
|
1332
1240
|
generatedComponentMetadata: this.generatedComponentMetadata,
|
|
1333
1241
|
componentData: this.componentData,
|
|
1334
1242
|
textResponse: this.textResponse,
|
|
1335
|
-
actions: actionsValue,
|
|
1336
|
-
isFetchingActions: this.actions instanceof Promise,
|
|
1337
1243
|
createdAt: this.createdAt.toISOString(),
|
|
1338
1244
|
...this.scriptBinding ? { scriptBinding: this.scriptBinding } : {},
|
|
1339
1245
|
...this.programAnswer ? { programAnswer: this.programAnswer } : {}
|
|
@@ -1471,23 +1377,55 @@ var Thread = class {
|
|
|
1471
1377
|
* since-edited) live body. Owned by the caller (needs a ScriptStore, which
|
|
1472
1378
|
* Thread doesn't hold) — omit it and every turn falls back to the
|
|
1473
1379
|
* no-script summary below.
|
|
1474
|
-
|
|
1475
|
-
|
|
1380
|
+
* @param fetchRecentFromDb When provided, this is now the SOURCE OF TRUTH
|
|
1381
|
+
* for history instead of this process's in-memory `uiblocks` map — reads
|
|
1382
|
+
* the persisted `user_conversations` rows (DB `response` jsonb shape, see
|
|
1383
|
+
* transformUIBlockForDB in conversation-saver.ts) via the caller's own
|
|
1384
|
+
* `user-conversations.getRecentForContext` collection. Rows come back
|
|
1385
|
+
* newest-first (already excluding status='aborted' — the query itself
|
|
1386
|
+
* filters that, matching what the in-memory path achieved via
|
|
1387
|
+
* thread.removeUIBlock() on abort). Fixes the standing gap where a backend
|
|
1388
|
+
* restart lost every thread's history (ThreadManager has no DB-backed
|
|
1389
|
+
* rehydration) — DB-backed history survives that, and is correct even if
|
|
1390
|
+
* a different process instance saved the row. Omit it and this falls back
|
|
1391
|
+
* to the in-memory map, for any caller not yet updated.
|
|
1392
|
+
*/
|
|
1393
|
+
async getConversationContext(limit = 5, currentUIBlockId, getScriptBody, fetchRecentFromDb) {
|
|
1476
1394
|
if (limit === 0) {
|
|
1477
1395
|
return "";
|
|
1478
1396
|
}
|
|
1479
|
-
|
|
1480
|
-
if (
|
|
1397
|
+
let turns;
|
|
1398
|
+
if (fetchRecentFromDb) {
|
|
1399
|
+
const rows = await fetchRecentFromDb(limit);
|
|
1400
|
+
turns = rows.slice().reverse().map((row) => {
|
|
1401
|
+
const r = row.response || {};
|
|
1402
|
+
return {
|
|
1403
|
+
question: row.userprompt || r.user_prompt || "",
|
|
1404
|
+
metadata: r.component || {},
|
|
1405
|
+
programAnswer: r.programAnswer || null,
|
|
1406
|
+
textResponse: r.analysis || "",
|
|
1407
|
+
scriptBinding: r.scriptBinding || null
|
|
1408
|
+
};
|
|
1409
|
+
});
|
|
1410
|
+
} else {
|
|
1411
|
+
const allBlocks = Array.from(this.uiblocks.values()).filter((block) => !currentUIBlockId || block.getId() !== currentUIBlockId).sort((a, b) => a.getCreatedAt().getTime() - b.getCreatedAt().getTime());
|
|
1412
|
+
if (allBlocks.length === 0) {
|
|
1413
|
+
return "";
|
|
1414
|
+
}
|
|
1415
|
+
turns = allBlocks.slice(-limit).map((block) => ({
|
|
1416
|
+
question: block.getUserQuestion(),
|
|
1417
|
+
metadata: block.getComponentMetadata(),
|
|
1418
|
+
programAnswer: block.getProgramAnswer(),
|
|
1419
|
+
textResponse: block.getTextResponse(),
|
|
1420
|
+
scriptBinding: block.getScriptBinding()
|
|
1421
|
+
}));
|
|
1422
|
+
}
|
|
1423
|
+
if (turns.length === 0) {
|
|
1481
1424
|
return "";
|
|
1482
1425
|
}
|
|
1483
|
-
const recentBlocks = allBlocks.slice(-limit);
|
|
1484
1426
|
const contextLines = [];
|
|
1485
|
-
for (const
|
|
1486
|
-
const question =
|
|
1487
|
-
const metadata = block.getComponentMetadata();
|
|
1488
|
-
const programAnswer = block.getProgramAnswer();
|
|
1489
|
-
const textResponse = block.getTextResponse();
|
|
1490
|
-
const scriptBinding = block.getScriptBinding();
|
|
1427
|
+
for (const turn of turns) {
|
|
1428
|
+
const { question, metadata, programAnswer, textResponse, scriptBinding } = turn;
|
|
1491
1429
|
const responseParts = [];
|
|
1492
1430
|
let analysisText = "";
|
|
1493
1431
|
const hasProgramAnswer = programAnswer && programAnswer.trim().length > 0;
|
|
@@ -3417,7 +3355,6 @@ var MAX_TOKENS_COMPONENT_MATCHING = 8192;
|
|
|
3417
3355
|
var MAX_TOKENS_CLASSIFICATION = 1500;
|
|
3418
3356
|
var MAX_TOKENS_ADAPTATION = 8192;
|
|
3419
3357
|
var MAX_TOKENS_TEXT_RESPONSE = 4e3;
|
|
3420
|
-
var MAX_TOKENS_NEXT_QUESTIONS = 1200;
|
|
3421
3358
|
var MAX_ROWS_FETCHED = 50;
|
|
3422
3359
|
var MAX_ROWS_TO_LLM = 10;
|
|
3423
3360
|
var LLM_SAMPLE_ROWS = 10;
|
|
@@ -5790,7 +5727,6 @@ You receive TWO key inputs:
|
|
|
5790
5727
|
3. **Additional visualizations**: Based on the analysis text and EXECUTED_TOOLS data, generate additional visualizations that show different aspects of the data (e.g., if the answer is a KPI total, add a breakdown chart and a detail table). Stay within the complexity limit above.
|
|
5791
5728
|
4. **Generate props**: Use \`externalTool\` to reference the executed source tool. Get SQL from \`EXECUTED_TOOLS.parameters\` \u2014 reuse exact SQL when possible, write new SQL only when a different aggregation or grouping is needed.
|
|
5792
5729
|
5. **Dashboard metadata**: Title (5-10 words) and description (1-2 sentences)
|
|
5793
|
-
6. **Actions**: Exactly 3 simple follow-up questions. Each question must be answerable by running a SQL query on the available data \u2014 no consulting, opinion, or "why" questions. Explore different dimensions of the data (different grouping, time range, filter, comparison). Use specific column names or values from the data when relevant. Keep questions short and direct \u2014 one sentence, one clear ask.
|
|
5794
5730
|
|
|
5795
5731
|
### Choosing Complexity
|
|
5796
5732
|
Determine complexity from the analysis text and EXECUTED_TOOLS:
|
|
@@ -6004,8 +5940,7 @@ When using \`externalTool\`, use field names from the tool's \`outputSchema\` in
|
|
|
6004
5940
|
"answerComponent": { ... } | null,
|
|
6005
5941
|
"layoutTitle": "Dashboard title (5-10 words)",
|
|
6006
5942
|
"layoutDescription": "Dashboard purpose (1-2 sentences)",
|
|
6007
|
-
"matchedComponents": [ ... ]
|
|
6008
|
-
"actions": ["Follow-up question 1?", "Follow-up question 2?", "Follow-up question 3?"]
|
|
5943
|
+
"matchedComponents": [ ... ]
|
|
6009
5944
|
}
|
|
6010
5945
|
\`\`\`
|
|
6011
5946
|
|
|
@@ -6120,52 +6055,6 @@ Example when hasAnswerComponent is true:
|
|
|
6120
6055
|
|
|
6121
6056
|
Remember: Use this analysis for DynamicMarkdownBlock content and to understand what to visualize. Use EXECUTED_TOOLS (in system prompt) for SQL queries, toolIds, field names, and data shapes.
|
|
6122
6057
|
---`
|
|
6123
|
-
},
|
|
6124
|
-
"actions": {
|
|
6125
|
-
system: `You are a data analyst suggesting follow-up questions. The questions will be used to query data sources via SQL \u2014 they must be simple, useful, and answerable from the data.
|
|
6126
|
-
|
|
6127
|
-
**Rules:**
|
|
6128
|
-
- Keep questions short and simple \u2014 one clear ask per question
|
|
6129
|
-
- Questions MUST be answerable by querying the available data columns (SQL queries)
|
|
6130
|
-
- Suggest different slices of the same data: by time period, by category, by route, top/bottom N, trends, comparisons
|
|
6131
|
-
- Avoid repeating topics already covered in the conversation
|
|
6132
|
-
- NEVER suggest questions about: root causes, recommendations, process changes, staffing, business decisions, or anything requiring human judgment
|
|
6133
|
-
- NEVER ask "why" questions \u2014 only "what", "which", "how much", "how does X compare to Y"
|
|
6134
|
-
|
|
6135
|
-
---
|
|
6136
|
-
|
|
6137
|
-
## CONTEXT (for this specific request)
|
|
6138
|
-
|
|
6139
|
-
### Previous Conversation
|
|
6140
|
-
{{CONVERSATION_HISTORY}}`,
|
|
6141
|
-
user: `Current Date and Time: {{CURRENT_DATETIME}}
|
|
6142
|
-
|
|
6143
|
-
Given the following context:
|
|
6144
|
-
|
|
6145
|
-
Latest User Question: {{ORIGINAL_USER_PROMPT}}
|
|
6146
|
-
|
|
6147
|
-
Current Component:
|
|
6148
|
-
{{COMPONENT_INFO}}
|
|
6149
|
-
|
|
6150
|
-
{{COMPONENT_DATA}}
|
|
6151
|
-
|
|
6152
|
-
Generate a JSON array of exactly 3 simple follow-up questions. Each question should:
|
|
6153
|
-
1. Be answerable by running a SQL query on the available data \u2014 no consulting or opinion questions
|
|
6154
|
-
2. Explore a different dimension or slice of the data (different grouping, time range, filter, comparison)
|
|
6155
|
-
3. NOT repeat topics already covered in the conversation
|
|
6156
|
-
4. Be short and direct \u2014 one sentence, one clear ask
|
|
6157
|
-
5. Use specific column names or values from the data when relevant
|
|
6158
|
-
|
|
6159
|
-
Format your response as a JSON object with this structure:
|
|
6160
|
-
{
|
|
6161
|
-
"nextQuestions": [
|
|
6162
|
-
"Question 1?",
|
|
6163
|
-
"Question 2?",
|
|
6164
|
-
...
|
|
6165
|
-
]
|
|
6166
|
-
}
|
|
6167
|
-
|
|
6168
|
-
Return ONLY valid JSON.`
|
|
6169
6058
|
},
|
|
6170
6059
|
"category-classification": {
|
|
6171
6060
|
system: `You categorize user questions and identify required data source tools. Respond with ONLY valid JSON.
|
|
@@ -6331,7 +6220,7 @@ Your task is to:
|
|
|
6331
6220
|
## Component Structure Handling
|
|
6332
6221
|
|
|
6333
6222
|
### For Single Components:
|
|
6334
|
-
- Modify props directly (config,
|
|
6223
|
+
- Modify props directly (config, query, filters, etc.)
|
|
6335
6224
|
|
|
6336
6225
|
### For MultiComponentContainer:
|
|
6337
6226
|
The component will have structure:
|
|
@@ -6344,8 +6233,7 @@ The component will have structure:
|
|
|
6344
6233
|
"components": [...], // Array of nested components - ADAPT EACH ONE
|
|
6345
6234
|
"title": "...", // Container title - UPDATE based on new question
|
|
6346
6235
|
"description": "..." // Container description - UPDATE based on new question
|
|
6347
|
-
}
|
|
6348
|
-
"actions": [...] // ADAPT actions if needed
|
|
6236
|
+
}
|
|
6349
6237
|
}
|
|
6350
6238
|
}
|
|
6351
6239
|
\`\`\`
|
|
@@ -6357,7 +6245,6 @@ When adapting MultiComponentContainer:
|
|
|
6357
6245
|
- Adapt its query parameters (WHERE clauses, LIMIT, ORDER BY, filters, date ranges)
|
|
6358
6246
|
- Update its title/description to match the new context
|
|
6359
6247
|
- Update its config settings (colors, sorting, grouping, metrics)
|
|
6360
|
-
- Update \`actions\` if the new question requires different actions
|
|
6361
6248
|
|
|
6362
6249
|
## Important Guidelines:
|
|
6363
6250
|
- Keep the same component type (don't change KPICard to LineChart)
|
|
@@ -6430,8 +6317,7 @@ When adapting queries, follow the database-specific rules below:
|
|
|
6430
6317
|
"type": "component_type",
|
|
6431
6318
|
"description": "updated_description",
|
|
6432
6319
|
"props": {
|
|
6433
|
-
"config": { }
|
|
6434
|
-
"actions": []
|
|
6320
|
+
"config": { }
|
|
6435
6321
|
}
|
|
6436
6322
|
},
|
|
6437
6323
|
"adaptedTextResponse": "The adapted text response with updated values matching the new question...",
|
|
@@ -6488,8 +6374,7 @@ When adapting queries, follow the database-specific rules below:
|
|
|
6488
6374
|
}
|
|
6489
6375
|
}
|
|
6490
6376
|
]
|
|
6491
|
-
}
|
|
6492
|
-
"actions": []
|
|
6377
|
+
}
|
|
6493
6378
|
}
|
|
6494
6379
|
},
|
|
6495
6380
|
"adaptedTextResponse": "The adapted text response with entity names, IDs, and references updated to match the new question. Numeric values replaced with placeholders.",
|
|
@@ -6557,13 +6442,12 @@ When adapting SQL queries, preserve the table and column names from the original
|
|
|
6557
6442
|
|
|
6558
6443
|
1. **Analyze the difference** between the original question and the current question
|
|
6559
6444
|
2. **Identify what data needs to change**:
|
|
6560
|
-
- For single components: adapt the query/config
|
|
6445
|
+
- For single components: adapt the query/config
|
|
6561
6446
|
- For MultiComponentContainer: adapt the container title/description AND each nested component's parameters
|
|
6562
6447
|
|
|
6563
6448
|
3. **Modify the parameters**:
|
|
6564
6449
|
- **Container level** (if MultiComponentContainer):
|
|
6565
6450
|
- Update \`title\` and \`description\` to reflect the new user question
|
|
6566
|
-
- Update \`actions\` if needed
|
|
6567
6451
|
|
|
6568
6452
|
- **For each component** (single or nested in container):
|
|
6569
6453
|
- Identify what it shows (sales, revenue, inventory, etc.)
|
|
@@ -8082,16 +7966,9 @@ Return JSON. Shape each component per the section above (markdown uses \`props.c
|
|
|
8082
7966
|
{ "componentId": "<the answerComponent, repeated as the FIRST entry>", "componentName": "...", "sourceIndex": 0, "props": { "title": "...", "config": { "xAxisKey": "...", "yAxisKey": "..." } } },
|
|
8083
7967
|
{ "componentId": "...", "componentName": "DynamicMarkdownBlock", "props": { "content": "## Recommendation\\n\\n- key point\\n- key point" } },
|
|
8084
7968
|
{ "componentId": "...", "componentName": "DynamicDataTable", "sourceIndex": 0, "props": { "title": "...", "config": { "columns": [ { "key": "<exact data column>", "label": "<Heading>" } ] } } }
|
|
8085
|
-
],
|
|
8086
|
-
"actions": [
|
|
8087
|
-
{ "question": "<follow-up question 1>" },
|
|
8088
|
-
{ "question": "<follow-up question 2>" },
|
|
8089
|
-
{ "question": "<follow-up question 3>" }
|
|
8090
7969
|
]
|
|
8091
7970
|
}
|
|
8092
7971
|
|
|
8093
|
-
Also produce **exactly 3 \`actions\`** \u2014 short, specific follow-up questions a user would naturally ask next, grounded in THIS dashboard's data and analysis (reference the actual entities, metrics, or findings shown \u2014 e.g. a district, a gap, a time window). They must be answerable from the same data domain. Do NOT ask generic questions ("tell me more"); make each one a concrete next step the data supports.
|
|
8094
|
-
|
|
8095
7972
|
---
|
|
8096
7973
|
|
|
8097
7974
|
## CONTEXT (for this specific request)
|
|
@@ -9877,14 +9754,6 @@ function ensurePostgresLimit(query, defaultLimit, maxLimit, hadSemicolon) {
|
|
|
9877
9754
|
}
|
|
9878
9755
|
return trimmedQuery;
|
|
9879
9756
|
}
|
|
9880
|
-
function convertQuestionsToActions(questions) {
|
|
9881
|
-
return questions.map((question, index) => ({
|
|
9882
|
-
id: `action_${index}_${Date.now()}`,
|
|
9883
|
-
name: question,
|
|
9884
|
-
type: "next_question",
|
|
9885
|
-
question
|
|
9886
|
-
}));
|
|
9887
|
-
}
|
|
9888
9757
|
function validateAndFixSqlQuery(query, dbType) {
|
|
9889
9758
|
if (!query || query.trim().length === 0) {
|
|
9890
9759
|
return { query, fixed: false, fixes: [] };
|
|
@@ -13310,7 +13179,7 @@ var DEFAULT_AGENT_CONFIG = {
|
|
|
13310
13179
|
// will use the provider's default model
|
|
13311
13180
|
maxRetries: 2,
|
|
13312
13181
|
// 2 retries = 3 total query attempts (1 initial + 2 retries for SQL errors)
|
|
13313
|
-
maxIterations:
|
|
13182
|
+
maxIterations: 20
|
|
13314
13183
|
// schema search (2-3) + query attempts (2) + write_script/execute_script (2-3) + write_analysis (up to 3) + LLM responses + final
|
|
13315
13184
|
};
|
|
13316
13185
|
|
|
@@ -14121,6 +13990,9 @@ function parseEditPrefix(rawPrompt) {
|
|
|
14121
13990
|
if (!match) return { isExplicitEdit: false, prompt: rawPrompt };
|
|
14122
13991
|
return { isExplicitEdit: true, prompt: rawPrompt.slice(match[0].length) };
|
|
14123
13992
|
}
|
|
13993
|
+
function hasExplicitEditPrefix(prompt) {
|
|
13994
|
+
return EDIT_PREFIX_RE.test(prompt);
|
|
13995
|
+
}
|
|
14124
13996
|
var MAX_FAILURE_RATE = 0.2;
|
|
14125
13997
|
var PROMPT_HISTORY_SEARCH_LIMIT = 20;
|
|
14126
13998
|
var PROMPT_HISTORY_SIMILARITY_THRESHOLD = 0.5;
|
|
@@ -14177,10 +14049,11 @@ var ScriptMatcher = class {
|
|
|
14177
14049
|
traceEntry.sent.userPrompt = userPrompt;
|
|
14178
14050
|
const promptHistoryMatches = await this.searchPromptHistory(userPrompt);
|
|
14179
14051
|
const candidates = [];
|
|
14180
|
-
|
|
14181
|
-
|
|
14182
|
-
|
|
14183
|
-
|
|
14052
|
+
const mostRecentBinding = activeBindings?.[0];
|
|
14053
|
+
if (mostRecentBinding) {
|
|
14054
|
+
const recipe = await this.store.get(mostRecentBinding.recipeId);
|
|
14055
|
+
if (recipe) candidates.push({ recipe, binding: mostRecentBinding });
|
|
14056
|
+
else logger.warn(`[ScriptMatcher] Bound recipe "${mostRecentBinding.recipeId}" no longer in store \u2014 no edit candidate this turn`);
|
|
14184
14057
|
}
|
|
14185
14058
|
const candidateById = new Map(candidates.map((c) => [c.recipe.id, c]));
|
|
14186
14059
|
traceEntry.sent.activeBindingCount = candidates.length;
|
|
@@ -14240,11 +14113,6 @@ var ScriptMatcher = class {
|
|
|
14240
14113
|
} else if (candidates.length === 0) {
|
|
14241
14114
|
logger.info(`[ScriptMatcher] 'edit' coerced to 'none' (no script-backed answer in this thread to edit)`);
|
|
14242
14115
|
tier = "none";
|
|
14243
|
-
} else if (!candidateById.has(response?.scriptId)) {
|
|
14244
|
-
logger.warn(
|
|
14245
|
-
`[ScriptMatcher] 'edit' coerced to 'none' \u2014 matcher targeted "${response?.scriptId}", which is not one of this thread's editable scripts [${candidates.map((c) => c.recipe.id).join(", ")}]. Refusing to edit a script the user hasn't run here.`
|
|
14246
|
-
);
|
|
14247
|
-
tier = "none";
|
|
14248
14116
|
} else if (!response?.editInstruction || !String(response.editInstruction).trim()) {
|
|
14249
14117
|
logger.warn(`[ScriptMatcher] 'edit' coerced to 'none' \u2014 matcher returned no editInstruction`);
|
|
14250
14118
|
tier = "none";
|
|
@@ -14252,35 +14120,45 @@ var ScriptMatcher = class {
|
|
|
14252
14120
|
}
|
|
14253
14121
|
const reasoning = response?.reasoning || "unknown";
|
|
14254
14122
|
traceEntry.received.tier = tier;
|
|
14255
|
-
if (tier === "none"
|
|
14123
|
+
if (tier === "none") {
|
|
14256
14124
|
logger.info(`[ScriptMatcher] No match. Reason: ${reasoning}`);
|
|
14257
14125
|
return null;
|
|
14258
14126
|
}
|
|
14259
|
-
const recipe = candidateById.get(response.scriptId)?.recipe ?? await this.store.get(response.scriptId);
|
|
14260
|
-
if (!recipe) {
|
|
14261
|
-
logger.warn(`[ScriptMatcher] LLM returned unknown script ID: "${response.scriptId}"`);
|
|
14262
|
-
traceEntry.received.error = `LLM returned unknown script ID: "${response.scriptId}"`;
|
|
14263
|
-
return null;
|
|
14264
|
-
}
|
|
14265
14127
|
if (tier === "edit") {
|
|
14128
|
+
const target = candidates[0];
|
|
14129
|
+
if (response?.scriptId && response.scriptId !== target.recipe.id) {
|
|
14130
|
+
logger.info(
|
|
14131
|
+
`[ScriptMatcher] Explicit edit \u2014 matcher suggested "${response.scriptId}", overridden to the most recent script "${target.recipe.id}" ("${target.recipe.name}") per the always-most-recent policy.`
|
|
14132
|
+
);
|
|
14133
|
+
}
|
|
14266
14134
|
const editInstruction = String(response.editInstruction).trim();
|
|
14267
14135
|
const editTarget = String(response.editTarget || "").toLowerCase() === "display" ? "display" : "data";
|
|
14268
|
-
logger.info(`[ScriptMatcher] EDIT [${editTarget}] "${recipe.name}": ${editInstruction} | Reason: ${reasoning}`);
|
|
14136
|
+
logger.info(`[ScriptMatcher] EDIT [${editTarget}] "${target.recipe.name}": ${editInstruction} | Reason: ${reasoning}`);
|
|
14269
14137
|
return {
|
|
14270
|
-
recipe,
|
|
14138
|
+
recipe: target.recipe,
|
|
14271
14139
|
tier: "edit",
|
|
14272
14140
|
editTarget,
|
|
14273
14141
|
similarity: 1,
|
|
14274
14142
|
confidence: "high",
|
|
14275
|
-
// Carry the
|
|
14276
|
-
//
|
|
14277
|
-
extractedParams:
|
|
14143
|
+
// Carry the target's own params so the edited script re-runs on the
|
|
14144
|
+
// same scope the user was looking at, not on bare defaults.
|
|
14145
|
+
extractedParams: target.binding.params || {},
|
|
14278
14146
|
mentions: parseMentions(response.mentions),
|
|
14279
14147
|
entityTypes: parseEntityTypes(response.entityTypes),
|
|
14280
14148
|
editInstruction,
|
|
14281
14149
|
reasoning
|
|
14282
14150
|
};
|
|
14283
14151
|
}
|
|
14152
|
+
if (!response?.scriptId || response.scriptId === "none") {
|
|
14153
|
+
logger.info(`[ScriptMatcher] No match. Reason: ${reasoning}`);
|
|
14154
|
+
return null;
|
|
14155
|
+
}
|
|
14156
|
+
const recipe = candidateById.get(response.scriptId)?.recipe ?? await this.store.get(response.scriptId);
|
|
14157
|
+
if (!recipe) {
|
|
14158
|
+
logger.warn(`[ScriptMatcher] LLM returned unknown script ID: "${response.scriptId}"`);
|
|
14159
|
+
traceEntry.received.error = `LLM returned unknown script ID: "${response.scriptId}"`;
|
|
14160
|
+
return null;
|
|
14161
|
+
}
|
|
14284
14162
|
const declaredParamNames = new Set(recipe.parameters.map((p) => p.name));
|
|
14285
14163
|
const inventedParamKeys = Object.keys(response.params || {}).filter((k) => !declaredParamNames.has(k));
|
|
14286
14164
|
if (inventedParamKeys.length > 0) {
|
|
@@ -14400,41 +14278,41 @@ ${paramList}`;
|
|
|
14400
14278
|
}).join("\n\n");
|
|
14401
14279
|
}
|
|
14402
14280
|
/**
|
|
14403
|
-
* The recent script-backed
|
|
14404
|
-
*
|
|
14405
|
-
*
|
|
14406
|
-
*
|
|
14407
|
-
*
|
|
14281
|
+
* The most recent script-backed answer in this thread — the one an `edit`
|
|
14282
|
+
* targets. Rendered as its own prompt section (never merged into the ranked
|
|
14283
|
+
* catalog) so the `edit` rules have an unambiguous referent.
|
|
14284
|
+
*
|
|
14285
|
+
* `candidates` holds at most one entry (see doMatch) — `edit` always means
|
|
14286
|
+
* "the answer I just got", so there is nothing else to show here.
|
|
14408
14287
|
*
|
|
14409
|
-
*
|
|
14410
|
-
*
|
|
14411
|
-
* one
|
|
14288
|
+
* Carries the QUESTION that produced it plus the columns it returned — that
|
|
14289
|
+
* is what lets the matcher resolve "use the mode for the WSP one" against
|
|
14290
|
+
* this one script's own context.
|
|
14412
14291
|
*/
|
|
14413
14292
|
buildActiveScriptBlock(candidates) {
|
|
14414
|
-
const
|
|
14415
|
-
|
|
14416
|
-
|
|
14417
|
-
|
|
14418
|
-
|
|
14419
|
-
]
|
|
14420
|
-
|
|
14421
|
-
|
|
14422
|
-
|
|
14423
|
-
|
|
14424
|
-
|
|
14425
|
-
|
|
14426
|
-
|
|
14427
|
-
|
|
14428
|
-
|
|
14429
|
-
lines.push(
|
|
14430
|
-
|
|
14431
|
-
|
|
14293
|
+
const target = candidates[0];
|
|
14294
|
+
if (!target) return "";
|
|
14295
|
+
const { recipe, binding } = target;
|
|
14296
|
+
const paramList = this.formatParamList(recipe.parameters);
|
|
14297
|
+
const lines = [
|
|
14298
|
+
`[${recipe.id}] "${recipe.name}"`,
|
|
14299
|
+
`${recipe.intentDescription}`
|
|
14300
|
+
];
|
|
14301
|
+
if (binding.userPrompt) lines.push(`Answered the question: "${binding.userPrompt}"`);
|
|
14302
|
+
if (binding.answerSummary) {
|
|
14303
|
+
const trimmed = binding.answerSummary.length > 1e3 ? binding.answerSummary.slice(0, 1e3) + "...[truncated]" : binding.answerSummary;
|
|
14304
|
+
lines.push(`Last answer: ${trimmed}`);
|
|
14305
|
+
}
|
|
14306
|
+
if (binding.columns?.length) lines.push(`Columns it returned: ${binding.columns.join(", ")}`);
|
|
14307
|
+
if (binding.params && Object.keys(binding.params).length > 0) {
|
|
14308
|
+
lines.push(`Ran with: ${JSON.stringify(binding.params)}`);
|
|
14309
|
+
}
|
|
14310
|
+
lines.push("Parameters:", paramList);
|
|
14432
14311
|
return [
|
|
14433
|
-
"### EDITABLE
|
|
14434
|
-
"An `edit`
|
|
14435
|
-
"name which one, choose #1 (the most recent).",
|
|
14312
|
+
"### EDITABLE SCRIPT \u2014 the answer just given in THIS conversation",
|
|
14313
|
+
"An `edit` always targets this script.",
|
|
14436
14314
|
"",
|
|
14437
|
-
|
|
14315
|
+
lines.join("\n")
|
|
14438
14316
|
].join("\n");
|
|
14439
14317
|
}
|
|
14440
14318
|
};
|
|
@@ -14775,7 +14653,7 @@ async function generateScriptComponents(params) {
|
|
|
14775
14653
|
const queries = scriptResult.executedQueries;
|
|
14776
14654
|
if (!queries || queries.length === 0) {
|
|
14777
14655
|
logger.warn(`[ScriptComponentGen] No query data available \u2014 returning empty`);
|
|
14778
|
-
return { components: [], layoutTitle: "", layoutDescription: "",
|
|
14656
|
+
return { components: [], layoutTitle: "", layoutDescription: "", componentSpecs: [] };
|
|
14779
14657
|
}
|
|
14780
14658
|
logger.info(`[ScriptComponentGen] Starting | ${queries.length} queries | ${availableComponents.length} available components`);
|
|
14781
14659
|
const columnsByIndex = queries.map((q) => {
|
|
@@ -14862,7 +14740,7 @@ ${sampleData}
|
|
|
14862
14740
|
logger.logLLMPrompt("scriptComponentGen:response", "user", JSON.stringify(response, null, 2));
|
|
14863
14741
|
if (!response || !response.components || !Array.isArray(response.components)) {
|
|
14864
14742
|
logger.warn(`[ScriptComponentGen] LLM returned invalid response`);
|
|
14865
|
-
return { components: [], layoutTitle: "", layoutDescription: "",
|
|
14743
|
+
return { components: [], layoutTitle: "", layoutDescription: "", componentSpecs: [] };
|
|
14866
14744
|
}
|
|
14867
14745
|
const layoutTitle = response.layoutTitle || "Dashboard";
|
|
14868
14746
|
const layoutDescription = response.layoutDescription || "";
|
|
@@ -14917,23 +14795,16 @@ ${sampleData}
|
|
|
14917
14795
|
}
|
|
14918
14796
|
}
|
|
14919
14797
|
logger.info(`[ScriptComponentGen] Generated ${matchedComponents.length} components`);
|
|
14920
|
-
const actions = (response.actions || []).map((a, idx) => ({
|
|
14921
|
-
id: `action_${idx}_${Date.now()}`,
|
|
14922
|
-
name: a.name || a.question || "",
|
|
14923
|
-
type: "next_question",
|
|
14924
|
-
question: a.question || a.name || ""
|
|
14925
|
-
}));
|
|
14926
14798
|
return {
|
|
14927
14799
|
components: matchedComponents,
|
|
14928
14800
|
layoutTitle,
|
|
14929
14801
|
layoutDescription,
|
|
14930
|
-
actions,
|
|
14931
14802
|
componentSpecs
|
|
14932
14803
|
};
|
|
14933
14804
|
} catch (error) {
|
|
14934
14805
|
const msg = error instanceof Error ? error.message : String(error);
|
|
14935
14806
|
logger.error(`[ScriptComponentGen] Failed: ${msg}`);
|
|
14936
|
-
return { components: [], layoutTitle: "", layoutDescription: "",
|
|
14807
|
+
return { components: [], layoutTitle: "", layoutDescription: "", componentSpecs: [] };
|
|
14937
14808
|
}
|
|
14938
14809
|
}
|
|
14939
14810
|
async function summarizeToMarkdown(analysis, apiKey, model) {
|
|
@@ -15991,15 +15862,15 @@ var BaseLLM = class {
|
|
|
15991
15862
|
return false;
|
|
15992
15863
|
}
|
|
15993
15864
|
/**
|
|
15994
|
-
* Match components from text response suggestions
|
|
15865
|
+
* Match components from text response suggestions
|
|
15995
15866
|
* Takes a text response with component suggestions (c1:type format) and matches with available components
|
|
15996
|
-
* Also generates title
|
|
15867
|
+
* Also generates title and description based on the analysis
|
|
15997
15868
|
* All components are placed in a default MultiComponentContainer layout
|
|
15998
15869
|
* @param analysisContent - The text response containing component suggestions
|
|
15999
15870
|
* @param components - List of available components
|
|
16000
15871
|
* @param apiKey - Optional API key
|
|
16001
15872
|
* @param componentStreamCallback - Optional callback to stream primary KPI component as soon as it's identified
|
|
16002
|
-
* @returns Object containing matched components
|
|
15873
|
+
* @returns Object containing matched components and layout title/description
|
|
16003
15874
|
*/
|
|
16004
15875
|
async matchComponentsFromAnalysis(analysisContent, components, userPrompt, apiKey, componentStreamCallback, deferredTools, executedTools, collections, userId) {
|
|
16005
15876
|
const methodStartTime = Date.now();
|
|
@@ -16263,8 +16134,6 @@ ${executedToolsText}`);
|
|
|
16263
16134
|
logger.info(`[${this.getProviderName()}] ${idx + 1}. ${comp.componentType} (${comp.componentName}) - ${comp.originalSuggestion || "N/A"}`);
|
|
16264
16135
|
});
|
|
16265
16136
|
logger.file("\n=============================\nFull LLM response:", JSON.stringify(result, null, 2));
|
|
16266
|
-
const rawActions = result.actions || [];
|
|
16267
|
-
const actions = convertQuestionsToActions(rawActions);
|
|
16268
16137
|
const finalComponents = matchedComponents.map((mc) => {
|
|
16269
16138
|
const originalComponent = components.find((c) => c.name === mc.componentName);
|
|
16270
16139
|
if (!originalComponent) {
|
|
@@ -16307,12 +16176,11 @@ ${executedToolsText}`);
|
|
|
16307
16176
|
logger.error(`[${this.getProviderName()}] Skipping query validation - database execute function not available`);
|
|
16308
16177
|
}
|
|
16309
16178
|
const methodDuration = Date.now() - methodStartTime;
|
|
16310
|
-
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | components: ${validatedComponents.length}
|
|
16179
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | components: ${validatedComponents.length}`);
|
|
16311
16180
|
return {
|
|
16312
16181
|
components: validatedComponents,
|
|
16313
16182
|
layoutTitle,
|
|
16314
|
-
layoutDescription
|
|
16315
|
-
actions
|
|
16183
|
+
layoutDescription
|
|
16316
16184
|
};
|
|
16317
16185
|
} catch (error) {
|
|
16318
16186
|
const methodDuration = Date.now() - methodStartTime;
|
|
@@ -16321,8 +16189,7 @@ ${executedToolsText}`);
|
|
|
16321
16189
|
return {
|
|
16322
16190
|
components: [],
|
|
16323
16191
|
layoutTitle: "Dashboard",
|
|
16324
|
-
layoutDescription: "Failed to generate dashboard"
|
|
16325
|
-
actions: []
|
|
16192
|
+
layoutDescription: "Failed to generate dashboard"
|
|
16326
16193
|
};
|
|
16327
16194
|
}
|
|
16328
16195
|
}
|
|
@@ -16361,8 +16228,6 @@ ${executedToolsText}`);
|
|
|
16361
16228
|
});
|
|
16362
16229
|
logger.logLLMPrompt("classifyQuestionCategory", "system", extractPromptText(prompts.system));
|
|
16363
16230
|
logger.logLLMPrompt("classifyQuestionCategory", "user", extractPromptText(prompts.user));
|
|
16364
|
-
logger.logLLMPrompt("generateNextQuestions", "system", extractPromptText(prompts.system));
|
|
16365
|
-
logger.logLLMPrompt("generateNextQuestions", "user", extractPromptText(prompts.user));
|
|
16366
16231
|
const result = await LLM.stream(
|
|
16367
16232
|
{
|
|
16368
16233
|
sys: prompts.system,
|
|
@@ -16715,7 +16580,6 @@ ${executedToolsText}`);
|
|
|
16715
16580
|
data: {
|
|
16716
16581
|
text: textResponse,
|
|
16717
16582
|
// Include the streamed text showing all attempts
|
|
16718
|
-
actions: [],
|
|
16719
16583
|
method: `${this.getProviderName()}-text-response-max-attempts`
|
|
16720
16584
|
}
|
|
16721
16585
|
};
|
|
@@ -16728,21 +16592,8 @@ ${executedToolsText}`);
|
|
|
16728
16592
|
let matchedComponents = [];
|
|
16729
16593
|
let layoutTitle = "Dashboard";
|
|
16730
16594
|
let layoutDescription = "Multi-component dashboard";
|
|
16731
|
-
let actions = [];
|
|
16732
16595
|
if (category === "general") {
|
|
16733
16596
|
logger.info(`[${this.getProviderName()}] General category - wrapping text response in DynamicMarkdownBlock`);
|
|
16734
|
-
const nextQuestions = await this.generateNextQuestions(
|
|
16735
|
-
userPrompt,
|
|
16736
|
-
null,
|
|
16737
|
-
// no component
|
|
16738
|
-
void 0,
|
|
16739
|
-
// no component data
|
|
16740
|
-
apiKey,
|
|
16741
|
-
conversationHistory,
|
|
16742
|
-
textResponse
|
|
16743
|
-
// pass text response as context
|
|
16744
|
-
);
|
|
16745
|
-
actions = convertQuestionsToActions(nextQuestions);
|
|
16746
16597
|
const markdownContent2 = textResponse.replace(/<DashboardComponents>[\s\S]*?<\/DashboardComponents>/g, "").trim();
|
|
16747
16598
|
matchedComponents = [{
|
|
16748
16599
|
id: "dynamic-markdown-block",
|
|
@@ -16793,7 +16644,6 @@ ${executedToolsText}`);
|
|
|
16793
16644
|
matchedComponents = matchResult.components;
|
|
16794
16645
|
layoutTitle = matchResult.layoutTitle;
|
|
16795
16646
|
layoutDescription = matchResult.layoutDescription;
|
|
16796
|
-
actions = matchResult.actions;
|
|
16797
16647
|
}
|
|
16798
16648
|
let container_componet = null;
|
|
16799
16649
|
if (matchedComponents.length > 0) {
|
|
@@ -16807,19 +16657,17 @@ ${executedToolsText}`);
|
|
|
16807
16657
|
title: layoutTitle,
|
|
16808
16658
|
description: layoutDescription,
|
|
16809
16659
|
components: matchedComponents
|
|
16810
|
-
}
|
|
16811
|
-
actions
|
|
16660
|
+
}
|
|
16812
16661
|
}
|
|
16813
16662
|
};
|
|
16814
16663
|
}
|
|
16815
16664
|
const methodDuration = Date.now() - methodStartTime;
|
|
16816
|
-
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | result: success | components: ${matchedComponents.length}
|
|
16665
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | result: success | components: ${matchedComponents.length}`);
|
|
16817
16666
|
return {
|
|
16818
16667
|
success: true,
|
|
16819
16668
|
data: {
|
|
16820
16669
|
text: textResponse,
|
|
16821
16670
|
component: container_componet,
|
|
16822
|
-
actions,
|
|
16823
16671
|
method: `${this.getProviderName()}-text-response`
|
|
16824
16672
|
},
|
|
16825
16673
|
errors: []
|
|
@@ -16841,7 +16689,6 @@ ${executedToolsText}`);
|
|
|
16841
16689
|
errors,
|
|
16842
16690
|
data: {
|
|
16843
16691
|
text: "I apologize, but I encountered an error while processing your question. Please try rephrasing or ask something else.",
|
|
16844
|
-
actions: [],
|
|
16845
16692
|
method: `${this.getProviderName()}-text-response-error`
|
|
16846
16693
|
}
|
|
16847
16694
|
};
|
|
@@ -16883,7 +16730,6 @@ ${executedToolsText}`);
|
|
|
16883
16730
|
data: {
|
|
16884
16731
|
text: cachedTextResponse,
|
|
16885
16732
|
component: null,
|
|
16886
|
-
actions: conversationMatch.uiBlock?.actions || [],
|
|
16887
16733
|
reasoning: `Exact match from previous general conversation`,
|
|
16888
16734
|
method: `${this.getProviderName()}-semantic-match-general`,
|
|
16889
16735
|
semanticSimilarity: conversationMatch.similarity
|
|
@@ -16901,13 +16747,11 @@ ${executedToolsText}`);
|
|
|
16901
16747
|
logger.info(`[${this.getProviderName()}] Streaming cached text response to frontend`);
|
|
16902
16748
|
streamCallback(cachedTextResponse);
|
|
16903
16749
|
}
|
|
16904
|
-
const cachedActions = conversationMatch.uiBlock?.actions || [];
|
|
16905
16750
|
return {
|
|
16906
16751
|
success: true,
|
|
16907
16752
|
data: {
|
|
16908
16753
|
text: cachedTextResponse,
|
|
16909
16754
|
component,
|
|
16910
|
-
actions: cachedActions,
|
|
16911
16755
|
reasoning: `Exact match from previous conversation (${(conversationMatch.similarity * 100).toFixed(2)}% similarity)`,
|
|
16912
16756
|
method: `${this.getProviderName()}-semantic-match-exact`,
|
|
16913
16757
|
semanticSimilarity: conversationMatch.similarity
|
|
@@ -16932,13 +16776,11 @@ ${executedToolsText}`);
|
|
|
16932
16776
|
logger.info(`[${this.getProviderName()}] Streaming ${adaptResult.adaptedTextResponse ? "adapted" : "cached"} text response to frontend`);
|
|
16933
16777
|
streamCallback(textResponseToUse);
|
|
16934
16778
|
}
|
|
16935
|
-
const cachedActions = conversationMatch.uiBlock?.actions || [];
|
|
16936
16779
|
return {
|
|
16937
16780
|
success: true,
|
|
16938
16781
|
data: {
|
|
16939
16782
|
text: textResponseToUse,
|
|
16940
16783
|
component: adaptResult.adaptedComponent,
|
|
16941
|
-
actions: cachedActions,
|
|
16942
16784
|
reasoning: `Adapted from previous conversation: ${originalPrompt}`,
|
|
16943
16785
|
method: `${this.getProviderName()}-semantic-match`,
|
|
16944
16786
|
semanticSimilarity: conversationMatch.similarity,
|
|
@@ -17029,67 +16871,6 @@ ${executedToolsText}`);
|
|
|
17029
16871
|
};
|
|
17030
16872
|
}
|
|
17031
16873
|
}
|
|
17032
|
-
/**
|
|
17033
|
-
* Generate next questions that the user might ask based on the original prompt and generated component
|
|
17034
|
-
* This helps provide intelligent suggestions for follow-up queries
|
|
17035
|
-
* For general/conversational questions without components, pass textResponse instead
|
|
17036
|
-
*/
|
|
17037
|
-
async generateNextQuestions(originalUserPrompt, component, componentData, apiKey, conversationHistory, textResponse, signal) {
|
|
17038
|
-
const methodStartTime = Date.now();
|
|
17039
|
-
const methodName = "generateNextQuestions";
|
|
17040
|
-
const promptPreview = originalUserPrompt.substring(0, 50) + (originalUserPrompt.length > 50 ? "..." : "");
|
|
17041
|
-
logger.info(`[${this.getProviderName()}] [TIMING] START ${methodName} | model: ${this.getModelForTask("simple")} | prompt: "${promptPreview}"`);
|
|
17042
|
-
try {
|
|
17043
|
-
let component_info;
|
|
17044
|
-
if (component) {
|
|
17045
|
-
component_info = `
|
|
17046
|
-
Component Name: ${component.name}
|
|
17047
|
-
Component Type: ${component.type}
|
|
17048
|
-
Component Description: ${component.description || "No description"}
|
|
17049
|
-
Component Props: ${component.props ? JSON.stringify(component.props, null, 2) : "No props"}
|
|
17050
|
-
`;
|
|
17051
|
-
} else if (textResponse) {
|
|
17052
|
-
component_info = `
|
|
17053
|
-
Response Type: Text/Conversational Response
|
|
17054
|
-
Response Content: ${textResponse.substring(0, 1e3)}${textResponse.length > 1e3 ? "..." : ""}
|
|
17055
|
-
`;
|
|
17056
|
-
} else {
|
|
17057
|
-
component_info = "No component or response context available";
|
|
17058
|
-
}
|
|
17059
|
-
const component_data = componentData ? `Component Data: ${JSON.stringify(componentData, null, 2)}` : "";
|
|
17060
|
-
const prompts = await promptLoader.loadPrompts("actions", {
|
|
17061
|
-
ORIGINAL_USER_PROMPT: originalUserPrompt,
|
|
17062
|
-
COMPONENT_INFO: component_info,
|
|
17063
|
-
COMPONENT_DATA: component_data,
|
|
17064
|
-
CONVERSATION_HISTORY: conversationHistory || "No previous conversation",
|
|
17065
|
-
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
17066
|
-
});
|
|
17067
|
-
const result = await LLM.stream(
|
|
17068
|
-
{
|
|
17069
|
-
sys: prompts.system,
|
|
17070
|
-
user: prompts.user
|
|
17071
|
-
},
|
|
17072
|
-
{
|
|
17073
|
-
model: this.getModelForTask("simple"),
|
|
17074
|
-
maxTokens: MAX_TOKENS_NEXT_QUESTIONS,
|
|
17075
|
-
temperature: 0,
|
|
17076
|
-
apiKey: this.getApiKey(apiKey),
|
|
17077
|
-
signal
|
|
17078
|
-
},
|
|
17079
|
-
true
|
|
17080
|
-
// Parse as JSON
|
|
17081
|
-
);
|
|
17082
|
-
const nextQuestions = result.nextQuestions || [];
|
|
17083
|
-
const methodDuration = Date.now() - methodStartTime;
|
|
17084
|
-
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | questions: ${nextQuestions.length}`);
|
|
17085
|
-
return nextQuestions;
|
|
17086
|
-
} catch (error) {
|
|
17087
|
-
const methodDuration = Date.now() - methodStartTime;
|
|
17088
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
17089
|
-
logger.error(`[${this.getProviderName()}] [TIMING] FAILED ${methodName} in ${methodDuration}ms | error: ${errorMsg}`);
|
|
17090
|
-
return [];
|
|
17091
|
-
}
|
|
17092
|
-
}
|
|
17093
16874
|
};
|
|
17094
16875
|
|
|
17095
16876
|
// src/userResponse/anthropic.ts
|
|
@@ -17414,7 +17195,6 @@ var get_agent_user_response = async (prompt, components, anthropicApiKey, groqAp
|
|
|
17414
17195
|
data: {
|
|
17415
17196
|
text: cachedTextResponse,
|
|
17416
17197
|
component: rehydratedComponent,
|
|
17417
|
-
actions: conversationMatch.uiBlock?.actions || [],
|
|
17418
17198
|
reasoning: `Exact match from previous conversation`,
|
|
17419
17199
|
method: `${provider}-agent-exact-match`,
|
|
17420
17200
|
semanticSimilarity: 1,
|
|
@@ -17513,9 +17293,14 @@ var get_agent_user_response = async (prompt, components, anthropicApiKey, groqAp
|
|
|
17513
17293
|
logger.info(`[AgentFlow] Bound recipe ${directReplay.recipeId} no longer in store \u2014 falling back to ScriptMatcher LLM`);
|
|
17514
17294
|
}
|
|
17515
17295
|
}
|
|
17516
|
-
|
|
17296
|
+
const explicitEdit = hasExplicitEditPrefix(prompt);
|
|
17297
|
+
if (!scriptMatch && (process.env.SA_SKIP_SCRIPT_MATCH !== "true" || explicitEdit)) {
|
|
17517
17298
|
const scriptMatcher = new ScriptMatcher(scriptStore, { collections, userId, trace: runTrace });
|
|
17518
17299
|
scriptMatch = await scriptMatcher.match(prompt, apiKey, sourceAgentModel, signal, activeBindings);
|
|
17300
|
+
if (scriptMatch && scriptMatch.tier !== "edit" && process.env.SA_SKIP_SCRIPT_MATCH === "true") {
|
|
17301
|
+
logger.info(`[AgentFlow] Matcher returned '${scriptMatch.tier}' for an "edit :"-prefixed prompt under SA_SKIP_SCRIPT_MATCH=true \u2014 discarding (only an actual edit is let through this opt-out)`);
|
|
17302
|
+
scriptMatch = null;
|
|
17303
|
+
}
|
|
17519
17304
|
} else if (!scriptMatch) {
|
|
17520
17305
|
logger.info("[AgentFlow] ScriptMatcher skipped (SA_SKIP_SCRIPT_MATCH=true) \u2014 proceeding with fresh generation");
|
|
17521
17306
|
}
|
|
@@ -17669,7 +17454,6 @@ ${JSON.stringify(preview, null, 2)}
|
|
|
17669
17454
|
let matchedComponents2 = [];
|
|
17670
17455
|
let layoutTitle2 = "Dashboard";
|
|
17671
17456
|
let layoutDescription2 = "Multi-component dashboard";
|
|
17672
|
-
let actions2 = [];
|
|
17673
17457
|
if (components && components.length > 0 && scriptExecutedTools.length > 0) {
|
|
17674
17458
|
logger.info(`[AgentFlow] Script flow \u2014 generating components (lightweight)`);
|
|
17675
17459
|
if (streamBuffer.hasCallback()) {
|
|
@@ -17778,7 +17562,6 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${scriptMatch
|
|
|
17778
17562
|
matchedComponents2 = compResult.components;
|
|
17779
17563
|
layoutTitle2 = compResult.layoutTitle;
|
|
17780
17564
|
layoutDescription2 = compResult.layoutDescription;
|
|
17781
|
-
actions2 = compResult.actions;
|
|
17782
17565
|
if (compResult.componentSpecs.length > 0) {
|
|
17783
17566
|
try {
|
|
17784
17567
|
scriptMatch.recipe.components = compResult.componentSpecs;
|
|
@@ -17845,15 +17628,10 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${scriptMatch
|
|
|
17845
17628
|
description: layoutDescription2,
|
|
17846
17629
|
components: securedComponents2,
|
|
17847
17630
|
...Object.keys(queryMap2).length > 0 && { _queryMap: queryMap2 }
|
|
17848
|
-
}
|
|
17849
|
-
actions: actions2
|
|
17631
|
+
}
|
|
17850
17632
|
}
|
|
17851
17633
|
};
|
|
17852
17634
|
}
|
|
17853
|
-
actions2 = [];
|
|
17854
|
-
if (containerComponent2) {
|
|
17855
|
-
containerComponent2.props.actions = [];
|
|
17856
|
-
}
|
|
17857
17635
|
const elapsedTime2 = Date.now() - startTime;
|
|
17858
17636
|
logger.info(`[AgentFlow] Script flow complete | ${scriptResult.executedQueries.length} queries | ${matchedComponents2.length} components | ${elapsedTime2}ms`);
|
|
17859
17637
|
return {
|
|
@@ -17862,7 +17640,6 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${scriptMatch
|
|
|
17862
17640
|
text: scriptTextResponse,
|
|
17863
17641
|
...replayProgramAnswer ? { programAnswer: replayProgramAnswer } : {},
|
|
17864
17642
|
component: containerComponent2,
|
|
17865
|
-
actions: actions2,
|
|
17866
17643
|
method: isDisplayEdit ? `${provider}-script-display-edit` : `${provider}-script-response`,
|
|
17867
17644
|
// Bind the answer to the replayed recipe so a follow-up
|
|
17868
17645
|
// ("use mode instead") can edit THIS script.
|
|
@@ -17983,7 +17760,6 @@ BEGIN NOW. Your VERY FIRST action MUST be a \`write_script\` tool call containin
|
|
|
17983
17760
|
data: {
|
|
17984
17761
|
text: "",
|
|
17985
17762
|
component: workflowComponent,
|
|
17986
|
-
actions: [],
|
|
17987
17763
|
method: `${provider}-agent-workflow`,
|
|
17988
17764
|
...runTrace ? { trace: runTrace } : {}
|
|
17989
17765
|
},
|
|
@@ -18039,7 +17815,6 @@ BEGIN NOW. Your VERY FIRST action MUST be a \`write_script\` tool call containin
|
|
|
18039
17815
|
let matchedComponents = [];
|
|
18040
17816
|
let layoutTitle = "Dashboard";
|
|
18041
17817
|
let layoutDescription = "Multi-component dashboard";
|
|
18042
|
-
let actions = [];
|
|
18043
17818
|
let authoredComponentSpecs = [];
|
|
18044
17819
|
if (!hasExecutedTools) {
|
|
18045
17820
|
logger.info(`[AgentFlow] No tools executed \u2014 general question, wrapping in DynamicMarkdownBlock`);
|
|
@@ -18193,7 +17968,6 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${carriedRequ
|
|
|
18193
17968
|
matchedComponents = compResult.components;
|
|
18194
17969
|
layoutTitle = compResult.layoutTitle;
|
|
18195
17970
|
layoutDescription = compResult.layoutDescription;
|
|
18196
|
-
actions = compResult.actions;
|
|
18197
17971
|
authoredComponentSpecs = compResult.componentSpecs;
|
|
18198
17972
|
usedLightweight = true;
|
|
18199
17973
|
logger.info(`[AgentFlow] Lightweight component gen succeeded \u2014 ${matchedComponents.length} components`);
|
|
@@ -18245,13 +18019,10 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${carriedRequ
|
|
|
18245
18019
|
components: securedComponents,
|
|
18246
18020
|
// Persist queryId → SQL mapping so cached responses can re-register queries
|
|
18247
18021
|
...Object.keys(queryMap).length > 0 && { _queryMap: queryMap }
|
|
18248
|
-
}
|
|
18249
|
-
actions
|
|
18022
|
+
}
|
|
18250
18023
|
}
|
|
18251
18024
|
};
|
|
18252
18025
|
}
|
|
18253
|
-
if (containerComponent) {
|
|
18254
|
-
}
|
|
18255
18026
|
if (agentResponse.savedScript && editContext) {
|
|
18256
18027
|
try {
|
|
18257
18028
|
const authored = agentResponse.savedScript;
|
|
@@ -18378,7 +18149,6 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${carriedRequ
|
|
|
18378
18149
|
${programAnswer}` : textResponse,
|
|
18379
18150
|
...programAnswer ? { programAnswer } : {},
|
|
18380
18151
|
component: containerComponent,
|
|
18381
|
-
actions,
|
|
18382
18152
|
method: editContext ? `${provider}-script-edit-response` : `${provider}-agent-response`,
|
|
18383
18153
|
...scriptBinding ? { scriptBinding } : {},
|
|
18384
18154
|
...noDataAnswer ? { noDataAnswer: true } : {},
|
|
@@ -18764,10 +18534,12 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
18764
18534
|
const requestStartTime = Date.now();
|
|
18765
18535
|
logger.info(`Starting user prompt request with ${components.length} components`);
|
|
18766
18536
|
const conversationScriptStore = new ScriptStore({ collections, projectId: process.env.SUPERATOM_PROJECT_ID || "" });
|
|
18537
|
+
const getRecentForContext = collections?.["user-conversations"]?.["getRecentForContext"];
|
|
18767
18538
|
const conversationHistory = await thread.getConversationContext(
|
|
18768
18539
|
CONTEXT_CONFIG.MAX_CONVERSATION_CONTEXT_BLOCKS,
|
|
18769
18540
|
existingUiBlockId,
|
|
18770
|
-
async (recipeId, version) => (await conversationScriptStore.getVersion(recipeId, version))?.scriptBody ?? null
|
|
18541
|
+
async (recipeId, version) => (await conversationScriptStore.getVersion(recipeId, version))?.scriptBody ?? null,
|
|
18542
|
+
getRecentForContext && userId && threadId ? async (limit) => (await getRecentForContext({ userId, threadId, limit }))?.data ?? [] : void 0
|
|
18771
18543
|
);
|
|
18772
18544
|
const MAX_EDIT_CANDIDATES = 5;
|
|
18773
18545
|
let activeScriptBindings = thread.getScriptBindings(MAX_EDIT_CANDIDATES, existingUiBlockId);
|
|
@@ -18792,7 +18564,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
18792
18564
|
`[UserPromptRequest] ${activeScriptBindings.length} editable script(s) in thread: ` + activeScriptBindings.map((b) => b.name || b.recipeId).join(", ")
|
|
18793
18565
|
);
|
|
18794
18566
|
}
|
|
18795
|
-
const uiBlock = new UIBlock(prompt, {}, {},
|
|
18567
|
+
const uiBlock = new UIBlock(prompt, {}, {}, existingUiBlockId, null);
|
|
18796
18568
|
thread.addUIBlock(uiBlock);
|
|
18797
18569
|
logger.info(`Registered UIBlock (early): ${existingUiBlockId} in Thread: ${threadId}`);
|
|
18798
18570
|
const abortController = new AbortController();
|
|
@@ -18980,7 +18752,6 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
18980
18752
|
}
|
|
18981
18753
|
let component = null;
|
|
18982
18754
|
let textResponse = null;
|
|
18983
|
-
let actions = [];
|
|
18984
18755
|
if (userResponse.data) {
|
|
18985
18756
|
if (typeof userResponse.data === "object") {
|
|
18986
18757
|
if ("component" in userResponse.data) {
|
|
@@ -18991,9 +18762,6 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
18991
18762
|
} else if ("textResponse" in userResponse.data) {
|
|
18992
18763
|
textResponse = userResponse.data.textResponse;
|
|
18993
18764
|
}
|
|
18994
|
-
if ("actions" in userResponse.data) {
|
|
18995
|
-
actions = userResponse.data.actions || [];
|
|
18996
|
-
}
|
|
18997
18765
|
}
|
|
18998
18766
|
}
|
|
18999
18767
|
let finalTextResponse = responseMode === "text" && accumulatedStreamResponse ? accumulatedStreamResponse : textResponse;
|
|
@@ -19011,10 +18779,6 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19011
18779
|
}
|
|
19012
18780
|
const programAnswer = userResponse.data?.programAnswer;
|
|
19013
18781
|
if (programAnswer) uiBlock.setProgramAnswer(programAnswer);
|
|
19014
|
-
if (actions.length > 0) {
|
|
19015
|
-
uiBlock.setActions(actions);
|
|
19016
|
-
logger.info(`Stored ${actions.length} actions in UIBlock: ${uiBlockId}`);
|
|
19017
|
-
}
|
|
19018
18782
|
logger.info(`Completed UIBlock: ${uiBlockId} in Thread: ${threadId}`);
|
|
19019
18783
|
let savedConversationId;
|
|
19020
18784
|
let savedResponse;
|
|
@@ -19280,229 +19044,6 @@ function sendResponse(id, res, sendMessage, clientId) {
|
|
|
19280
19044
|
sendMessage(response);
|
|
19281
19045
|
}
|
|
19282
19046
|
|
|
19283
|
-
// src/userResponse/next-questions.ts
|
|
19284
|
-
async function generateNextQuestions(originalUserPrompt, component, componentData, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, conversationHistory) {
|
|
19285
|
-
try {
|
|
19286
|
-
logger.debug("[generateNextQuestions] Starting next questions generation");
|
|
19287
|
-
logger.debug(`[generateNextQuestions] User prompt: "${originalUserPrompt?.substring(0, 50)}..."`);
|
|
19288
|
-
logger.debug(`[generateNextQuestions] Component: ${component?.name || "unknown"} (${component?.type || "unknown"})`);
|
|
19289
|
-
logger.debug(`[generateNextQuestions] Component data available: ${componentData ? "yes" : "no"}`);
|
|
19290
|
-
const providers = llmProviders || ["anthropic", "gemini", "openai", "groq"];
|
|
19291
|
-
logger.info(`[generateNextQuestions] Using LLM providers: [${providers.join(", ")}]`);
|
|
19292
|
-
if (conversationHistory && conversationHistory.length > 0) {
|
|
19293
|
-
const exchangeCount = conversationHistory.split("\n").filter((l) => l.startsWith("Q")).length;
|
|
19294
|
-
logger.debug(`[generateNextQuestions] Using conversation history with ${exchangeCount} previous exchanges`);
|
|
19295
|
-
} else {
|
|
19296
|
-
logger.debug("[generateNextQuestions] No conversation history available");
|
|
19297
|
-
}
|
|
19298
|
-
for (let i = 0; i < providers.length; i++) {
|
|
19299
|
-
const provider = providers[i];
|
|
19300
|
-
const isLastProvider = i === providers.length - 1;
|
|
19301
|
-
try {
|
|
19302
|
-
logger.info(`[generateNextQuestions] Attempting provider: ${provider} (${i + 1}/${providers.length})`);
|
|
19303
|
-
let result = [];
|
|
19304
|
-
if (provider === "groq") {
|
|
19305
|
-
logger.debug("[generateNextQuestions] Using Groq LLM for next questions");
|
|
19306
|
-
result = await groqLLM.generateNextQuestions(
|
|
19307
|
-
originalUserPrompt,
|
|
19308
|
-
component,
|
|
19309
|
-
componentData,
|
|
19310
|
-
groqApiKey,
|
|
19311
|
-
conversationHistory
|
|
19312
|
-
);
|
|
19313
|
-
} else if (provider === "gemini") {
|
|
19314
|
-
logger.debug("[generateNextQuestions] Using Gemini LLM for next questions");
|
|
19315
|
-
result = await geminiLLM.generateNextQuestions(
|
|
19316
|
-
originalUserPrompt,
|
|
19317
|
-
component,
|
|
19318
|
-
componentData,
|
|
19319
|
-
geminiApiKey,
|
|
19320
|
-
conversationHistory
|
|
19321
|
-
);
|
|
19322
|
-
} else if (provider === "openai") {
|
|
19323
|
-
logger.debug("[generateNextQuestions] Using OpenAI LLM for next questions");
|
|
19324
|
-
result = await openaiLLM.generateNextQuestions(
|
|
19325
|
-
originalUserPrompt,
|
|
19326
|
-
component,
|
|
19327
|
-
componentData,
|
|
19328
|
-
openaiApiKey,
|
|
19329
|
-
conversationHistory
|
|
19330
|
-
);
|
|
19331
|
-
} else {
|
|
19332
|
-
logger.debug("[generateNextQuestions] Using Anthropic LLM for next questions");
|
|
19333
|
-
result = await anthropicLLM.generateNextQuestions(
|
|
19334
|
-
originalUserPrompt,
|
|
19335
|
-
component,
|
|
19336
|
-
componentData,
|
|
19337
|
-
anthropicApiKey,
|
|
19338
|
-
conversationHistory
|
|
19339
|
-
);
|
|
19340
|
-
}
|
|
19341
|
-
if (result && result.length > 0) {
|
|
19342
|
-
logger.info(`[generateNextQuestions] Successfully generated ${result.length} questions with ${provider}`);
|
|
19343
|
-
logger.debug(`[generateNextQuestions] Questions: ${JSON.stringify(result)}`);
|
|
19344
|
-
return result;
|
|
19345
|
-
}
|
|
19346
|
-
logger.warn(`[generateNextQuestions] No questions generated from ${provider}${!isLastProvider ? ", trying next provider..." : ""}`);
|
|
19347
|
-
} catch (providerError) {
|
|
19348
|
-
const errorMsg = providerError instanceof Error ? providerError.message : String(providerError);
|
|
19349
|
-
logger.error(`[generateNextQuestions] Provider ${provider} failed: ${errorMsg}`);
|
|
19350
|
-
logger.debug(`[generateNextQuestions] Provider error details:`, providerError);
|
|
19351
|
-
if (!isLastProvider) {
|
|
19352
|
-
logger.info(`[generateNextQuestions] Provider ${provider} failed, trying next provider...`);
|
|
19353
|
-
}
|
|
19354
|
-
continue;
|
|
19355
|
-
}
|
|
19356
|
-
}
|
|
19357
|
-
logger.warn("[generateNextQuestions] All providers failed or returned no questions");
|
|
19358
|
-
return [];
|
|
19359
|
-
} catch (error) {
|
|
19360
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
19361
|
-
const errorStack = error instanceof Error ? error.stack : void 0;
|
|
19362
|
-
logger.error(`[generateNextQuestions] Error generating next questions: ${errorMsg}`);
|
|
19363
|
-
logger.debug("[generateNextQuestions] Error stack trace:", errorStack);
|
|
19364
|
-
return [];
|
|
19365
|
-
}
|
|
19366
|
-
}
|
|
19367
|
-
|
|
19368
|
-
// src/handlers/actions-request.ts
|
|
19369
|
-
async function handleActionsRequest(data, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders) {
|
|
19370
|
-
try {
|
|
19371
|
-
logger.debug("[ACTIONS_REQ] Parsing incoming actions request");
|
|
19372
|
-
const actionsRequest = ActionsRequestMessageSchema.parse(data);
|
|
19373
|
-
const { id, payload } = actionsRequest;
|
|
19374
|
-
const { SA_RUNTIME } = payload;
|
|
19375
|
-
const wsId = actionsRequest.from.id || "unknown";
|
|
19376
|
-
logger.info(`[ACTIONS_REQ ${id}] Processing actions request from client: ${wsId}`);
|
|
19377
|
-
logger.debug(`[ACTIONS_REQ ${id}] Request payload:`, JSON.stringify(payload, null, 2).substring(0, 200));
|
|
19378
|
-
if (!SA_RUNTIME) {
|
|
19379
|
-
logger.error(`[ACTIONS_REQ ${id}] SA_RUNTIME missing from request`);
|
|
19380
|
-
sendResponse2(id, {
|
|
19381
|
-
success: false,
|
|
19382
|
-
error: "SA_RUNTIME with threadId and uiBlockId is required"
|
|
19383
|
-
}, sendMessage, wsId);
|
|
19384
|
-
return;
|
|
19385
|
-
}
|
|
19386
|
-
const uiBlockId = SA_RUNTIME.uiBlockId;
|
|
19387
|
-
const threadId = SA_RUNTIME.threadId;
|
|
19388
|
-
logger.debug(`[ACTIONS_REQ ${id}] SA_RUNTIME validated - threadId: ${threadId}, uiBlockId: ${uiBlockId}`);
|
|
19389
|
-
const threadManager = ThreadManager.getInstance();
|
|
19390
|
-
const thread = threadManager.getThread(threadId);
|
|
19391
|
-
if (!thread) {
|
|
19392
|
-
logger.error(`[ACTIONS_REQ ${id}] Thread '${threadId}' not found`);
|
|
19393
|
-
sendResponse2(id, {
|
|
19394
|
-
success: false,
|
|
19395
|
-
error: `Thread '${threadId}' not found`
|
|
19396
|
-
}, sendMessage, wsId);
|
|
19397
|
-
return;
|
|
19398
|
-
}
|
|
19399
|
-
logger.debug(`[ACTIONS_REQ ${id}] Thread found with ${thread.getUIBlocks().length} UIBlocks`);
|
|
19400
|
-
logger.debug(`[ACTIONS_REQ ${id}] Retrieving UIBlock: ${uiBlockId}`);
|
|
19401
|
-
const uiBlock = thread.getUIBlock(uiBlockId);
|
|
19402
|
-
if (!uiBlock) {
|
|
19403
|
-
logger.error(`[ACTIONS_REQ ${id}] UIBlock '${uiBlockId}' not found in thread '${threadId}'`);
|
|
19404
|
-
sendResponse2(id, {
|
|
19405
|
-
success: false,
|
|
19406
|
-
error: `UIBlock '${uiBlockId}' not found in thread '${threadId}'`
|
|
19407
|
-
}, sendMessage, wsId);
|
|
19408
|
-
return;
|
|
19409
|
-
}
|
|
19410
|
-
logger.info(`[ACTIONS_REQ ${id}] UIBlock retrieved successfully`);
|
|
19411
|
-
logger.debug(`[ACTIONS_REQ ${id}] Extracting data from UIBlock`);
|
|
19412
|
-
const userQuestion = uiBlock.getUserQuestion();
|
|
19413
|
-
const component = uiBlock.getComponentMetadata();
|
|
19414
|
-
const componentData = uiBlock.getComponentData();
|
|
19415
|
-
logger.debug(`[ACTIONS_REQ ${id}] User question: "${userQuestion?.substring(0, 50)}..."`);
|
|
19416
|
-
logger.debug(`[ACTIONS_REQ ${id}] Component: ${component?.name || "unknown"} (${component?.type || "unknown"})`);
|
|
19417
|
-
logger.debug(`[ACTIONS_REQ ${id}] Component data available: ${componentData ? "yes" : "no"}`);
|
|
19418
|
-
logger.debug(`[ACTIONS_REQ ${id}] Extracting conversation history (max ${CONTEXT_CONFIG.MAX_CONVERSATION_CONTEXT_BLOCKS} blocks)`);
|
|
19419
|
-
const conversationHistory = await thread.getConversationContext(CONTEXT_CONFIG.MAX_CONVERSATION_CONTEXT_BLOCKS, uiBlockId);
|
|
19420
|
-
const historyLineCount = conversationHistory.split("\n").filter((l) => l.trim()).length;
|
|
19421
|
-
logger.info(`[ACTIONS_REQ ${id}] Conversation history extracted: ${historyLineCount} lines`);
|
|
19422
|
-
logger.debug(`[ACTIONS_REQ ${id}] Conversation history preview:
|
|
19423
|
-
${conversationHistory.substring(0, 200)}...`);
|
|
19424
|
-
logger.info(`[ACTIONS_REQ ${id}] Generating actions for UIBlock: ${uiBlockId}, component: ${component?.name || "unknown"}`);
|
|
19425
|
-
logger.debug(`[ACTIONS_REQ ${id}] Checking if actions are already cached`);
|
|
19426
|
-
const startTime = Date.now();
|
|
19427
|
-
const actions = await uiBlock.getOrFetchActions(async () => {
|
|
19428
|
-
logger.info(`[ACTIONS_REQ ${id}] Actions not cached, generating new actions...`);
|
|
19429
|
-
logger.info(`[ACTIONS_REQ ${id}] Starting next questions generation with ${llmProviders?.join(", ") || "default"} providers`);
|
|
19430
|
-
const nextQuestions = await generateNextQuestions(
|
|
19431
|
-
userQuestion,
|
|
19432
|
-
component,
|
|
19433
|
-
componentData,
|
|
19434
|
-
anthropicApiKey,
|
|
19435
|
-
groqApiKey,
|
|
19436
|
-
geminiApiKey,
|
|
19437
|
-
openaiApiKey,
|
|
19438
|
-
llmProviders,
|
|
19439
|
-
conversationHistory
|
|
19440
|
-
);
|
|
19441
|
-
logger.info(`[ACTIONS_REQ ${id}] Generated ${nextQuestions.length} questions`);
|
|
19442
|
-
logger.debug(`[ACTIONS_REQ ${id}] Questions: ${JSON.stringify(nextQuestions)}`);
|
|
19443
|
-
logger.debug(`[ACTIONS_REQ ${id}] Converting questions to actions format`);
|
|
19444
|
-
const convertedActions = nextQuestions.map((question, index) => ({
|
|
19445
|
-
id: `action_${index}_${Date.now()}`,
|
|
19446
|
-
name: question,
|
|
19447
|
-
type: "next_question",
|
|
19448
|
-
question
|
|
19449
|
-
}));
|
|
19450
|
-
logger.debug(`[ACTIONS_REQ ${id}] Converted ${convertedActions.length} actions`);
|
|
19451
|
-
return convertedActions;
|
|
19452
|
-
});
|
|
19453
|
-
const processingTime = Date.now() - startTime;
|
|
19454
|
-
logger.info(`[ACTIONS_REQ ${id}] Actions retrieved in ${processingTime}ms - ${actions.length} actions total`);
|
|
19455
|
-
if (actions.length > 0) {
|
|
19456
|
-
logger.info(`[ACTIONS_REQ ${id}] Generated ${actions.length} follow-up questions successfully`);
|
|
19457
|
-
logger.debug(`[ACTIONS_REQ ${id}] Actions: ${actions.map((a) => a.name).join(", ")}`);
|
|
19458
|
-
} else {
|
|
19459
|
-
logger.warn(`[ACTIONS_REQ ${id}] No actions generated`);
|
|
19460
|
-
}
|
|
19461
|
-
logger.debug(`[ACTIONS_REQ ${id}] Sending successful response to client`);
|
|
19462
|
-
sendResponse2(id, {
|
|
19463
|
-
success: true,
|
|
19464
|
-
data: {
|
|
19465
|
-
actions,
|
|
19466
|
-
componentName: component?.name,
|
|
19467
|
-
componentId: component?.id,
|
|
19468
|
-
uiBlockId,
|
|
19469
|
-
threadId
|
|
19470
|
-
}
|
|
19471
|
-
}, sendMessage, wsId);
|
|
19472
|
-
logger.info(`[ACTIONS_REQ ${id}] \u2713 Actions request completed successfully`);
|
|
19473
|
-
} catch (error) {
|
|
19474
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
19475
|
-
const errorStack = error instanceof Error ? error.stack : void 0;
|
|
19476
|
-
logger.error(`[ACTIONS_REQ] Failed to handle actions request: ${errorMessage}`);
|
|
19477
|
-
logger.debug(`[ACTIONS_REQ] Error stack trace:`, errorStack);
|
|
19478
|
-
sendResponse2(null, {
|
|
19479
|
-
success: false,
|
|
19480
|
-
error: errorMessage
|
|
19481
|
-
}, sendMessage);
|
|
19482
|
-
logger.info("[ACTIONS_REQ] \u2717 Actions request completed with errors");
|
|
19483
|
-
}
|
|
19484
|
-
}
|
|
19485
|
-
function sendResponse2(id, res, sendMessage, clientId) {
|
|
19486
|
-
const response = {
|
|
19487
|
-
id: id || "unknown",
|
|
19488
|
-
type: "ACTIONS_RES",
|
|
19489
|
-
from: { type: "data-agent" },
|
|
19490
|
-
to: {
|
|
19491
|
-
type: "runtime",
|
|
19492
|
-
id: clientId
|
|
19493
|
-
},
|
|
19494
|
-
payload: {
|
|
19495
|
-
...res
|
|
19496
|
-
}
|
|
19497
|
-
};
|
|
19498
|
-
logger.debug(`[ACTIONS_RES ${id || "unknown"}] Sending ${res.success ? "successful" : "failed"} response to client`);
|
|
19499
|
-
logger.debug(`[ACTIONS_RES ${id || "unknown"}] Response payload size: ${JSON.stringify(response).length} bytes`);
|
|
19500
|
-
if (res.data?.actions) {
|
|
19501
|
-
logger.debug(`[ACTIONS_RES ${id || "unknown"}] Sending ${res.data.actions.length} actions`);
|
|
19502
|
-
}
|
|
19503
|
-
sendMessage(response);
|
|
19504
|
-
}
|
|
19505
|
-
|
|
19506
19047
|
// src/handlers/components-list-response.ts
|
|
19507
19048
|
async function handleComponentListResponse(data, storeComponents, collections) {
|
|
19508
19049
|
try {
|
|
@@ -19577,7 +19118,7 @@ async function handleUsersRequest(data, collections, sendMessage) {
|
|
|
19577
19118
|
const limit = requestData?.limit;
|
|
19578
19119
|
const sort = requestData?.sort;
|
|
19579
19120
|
if (from.type !== "admin" && operation !== "getOne" && operation !== "getAll" && operation !== "query") {
|
|
19580
|
-
|
|
19121
|
+
sendResponse2(id, {
|
|
19581
19122
|
success: false,
|
|
19582
19123
|
error: "Unauthorized: Only admin can manage users"
|
|
19583
19124
|
}, sendMessage, from.id);
|
|
@@ -19605,14 +19146,14 @@ async function handleUsersRequest(data, collections, sendMessage) {
|
|
|
19605
19146
|
await handleQuery(id, filters, limit, sort, executeCollection, userManager, sendMessage, from.id);
|
|
19606
19147
|
break;
|
|
19607
19148
|
default:
|
|
19608
|
-
|
|
19149
|
+
sendResponse2(id, {
|
|
19609
19150
|
success: false,
|
|
19610
19151
|
error: `Unknown operation: ${operation}`
|
|
19611
19152
|
}, sendMessage, from.id);
|
|
19612
19153
|
}
|
|
19613
19154
|
} catch (error) {
|
|
19614
19155
|
logger.error("Failed to handle users request:", error);
|
|
19615
|
-
|
|
19156
|
+
sendResponse2(null, {
|
|
19616
19157
|
success: false,
|
|
19617
19158
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
19618
19159
|
}, sendMessage);
|
|
@@ -19621,14 +19162,14 @@ async function handleUsersRequest(data, collections, sendMessage) {
|
|
|
19621
19162
|
async function handleCreate(id, userData, executeCollection, userManager, sendMessage, clientId) {
|
|
19622
19163
|
const { username, email, password, fullname, role, userInfo } = userData;
|
|
19623
19164
|
if (!username || username.trim().length === 0) {
|
|
19624
|
-
|
|
19165
|
+
sendResponse2(id, {
|
|
19625
19166
|
success: false,
|
|
19626
19167
|
error: "Username is required and cannot be empty"
|
|
19627
19168
|
}, sendMessage, clientId);
|
|
19628
19169
|
return;
|
|
19629
19170
|
}
|
|
19630
19171
|
if (!password || password.trim().length === 0) {
|
|
19631
|
-
|
|
19172
|
+
sendResponse2(id, {
|
|
19632
19173
|
success: false,
|
|
19633
19174
|
error: "Password is required and cannot be empty"
|
|
19634
19175
|
}, sendMessage, clientId);
|
|
@@ -19637,7 +19178,7 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19637
19178
|
if (email && email.trim().length > 0) {
|
|
19638
19179
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
19639
19180
|
if (!emailRegex.test(email)) {
|
|
19640
|
-
|
|
19181
|
+
sendResponse2(id, {
|
|
19641
19182
|
success: false,
|
|
19642
19183
|
error: "Invalid email format"
|
|
19643
19184
|
}, sendMessage, clientId);
|
|
@@ -19655,7 +19196,7 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19655
19196
|
});
|
|
19656
19197
|
if (result && result.success) {
|
|
19657
19198
|
logger.info(`[DB] User created successfully: ${username}`);
|
|
19658
|
-
|
|
19199
|
+
sendResponse2(id, {
|
|
19659
19200
|
success: true,
|
|
19660
19201
|
data: {
|
|
19661
19202
|
id: result.data?.id,
|
|
@@ -19673,14 +19214,14 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19673
19214
|
}
|
|
19674
19215
|
try {
|
|
19675
19216
|
if (userManager.userExists(username)) {
|
|
19676
|
-
|
|
19217
|
+
sendResponse2(id, {
|
|
19677
19218
|
success: false,
|
|
19678
19219
|
error: `User '${username}' already exists`
|
|
19679
19220
|
}, sendMessage, clientId);
|
|
19680
19221
|
return;
|
|
19681
19222
|
}
|
|
19682
19223
|
if (email && userManager.getUserByEmail(email)) {
|
|
19683
|
-
|
|
19224
|
+
sendResponse2(id, {
|
|
19684
19225
|
success: false,
|
|
19685
19226
|
error: `User with email '${email}' already exists`
|
|
19686
19227
|
}, sendMessage, clientId);
|
|
@@ -19701,7 +19242,7 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19701
19242
|
}
|
|
19702
19243
|
const newUser = userManager.createUser(newUserData);
|
|
19703
19244
|
logger.info(`[FILE] User '${username}' created successfully`);
|
|
19704
|
-
|
|
19245
|
+
sendResponse2(id, {
|
|
19705
19246
|
success: true,
|
|
19706
19247
|
data: {
|
|
19707
19248
|
username: newUser.username,
|
|
@@ -19712,7 +19253,7 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19712
19253
|
}
|
|
19713
19254
|
}, sendMessage, clientId);
|
|
19714
19255
|
} catch (error) {
|
|
19715
|
-
|
|
19256
|
+
sendResponse2(id, {
|
|
19716
19257
|
success: false,
|
|
19717
19258
|
error: error instanceof Error ? error.message : "Failed to create user"
|
|
19718
19259
|
}, sendMessage, clientId);
|
|
@@ -19721,7 +19262,7 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19721
19262
|
async function handleUpdate(id, numericId, userData, executeCollection, userManager, sendMessage, clientId) {
|
|
19722
19263
|
const { username, email, password, fullname, role, userInfo } = userData;
|
|
19723
19264
|
if (!numericId && !username) {
|
|
19724
|
-
|
|
19265
|
+
sendResponse2(id, {
|
|
19725
19266
|
success: false,
|
|
19726
19267
|
error: "User ID or username is required"
|
|
19727
19268
|
}, sendMessage, clientId);
|
|
@@ -19740,7 +19281,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19740
19281
|
});
|
|
19741
19282
|
if (result && result.success) {
|
|
19742
19283
|
logger.info(`[DB] User updated successfully, ID: ${numericId}`);
|
|
19743
|
-
|
|
19284
|
+
sendResponse2(id, {
|
|
19744
19285
|
success: true,
|
|
19745
19286
|
data: {
|
|
19746
19287
|
id: result.data?.id,
|
|
@@ -19758,14 +19299,14 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19758
19299
|
}
|
|
19759
19300
|
}
|
|
19760
19301
|
if (!username || username.trim().length === 0) {
|
|
19761
|
-
|
|
19302
|
+
sendResponse2(id, {
|
|
19762
19303
|
success: false,
|
|
19763
19304
|
error: "Username is required for file-based storage update"
|
|
19764
19305
|
}, sendMessage, clientId);
|
|
19765
19306
|
return;
|
|
19766
19307
|
}
|
|
19767
19308
|
if (!userManager.userExists(username)) {
|
|
19768
|
-
|
|
19309
|
+
sendResponse2(id, {
|
|
19769
19310
|
success: false,
|
|
19770
19311
|
error: `User '${username}' not found`
|
|
19771
19312
|
}, sendMessage, clientId);
|
|
@@ -19776,7 +19317,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19776
19317
|
if (email.trim().length > 0) {
|
|
19777
19318
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
19778
19319
|
if (!emailRegex.test(email)) {
|
|
19779
|
-
|
|
19320
|
+
sendResponse2(id, {
|
|
19780
19321
|
success: false,
|
|
19781
19322
|
error: "Invalid email format"
|
|
19782
19323
|
}, sendMessage, clientId);
|
|
@@ -19784,7 +19325,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19784
19325
|
}
|
|
19785
19326
|
const existingUser = userManager.getUserByEmail(email);
|
|
19786
19327
|
if (existingUser && existingUser.username !== username) {
|
|
19787
|
-
|
|
19328
|
+
sendResponse2(id, {
|
|
19788
19329
|
success: false,
|
|
19789
19330
|
error: `Email '${email}' is already used by another user`
|
|
19790
19331
|
}, sendMessage, clientId);
|
|
@@ -19805,7 +19346,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19805
19346
|
updates.role = role.trim().length > 0 ? role.trim() : void 0;
|
|
19806
19347
|
}
|
|
19807
19348
|
if (Object.keys(updates).length === 0) {
|
|
19808
|
-
|
|
19349
|
+
sendResponse2(id, {
|
|
19809
19350
|
success: false,
|
|
19810
19351
|
error: "No fields to update. Please provide at least one field to update."
|
|
19811
19352
|
}, sendMessage, clientId);
|
|
@@ -19814,7 +19355,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19814
19355
|
try {
|
|
19815
19356
|
const updatedUser = userManager.updateUser(username, updates);
|
|
19816
19357
|
logger.info(`[FILE] User '${username}' updated successfully`);
|
|
19817
|
-
|
|
19358
|
+
sendResponse2(id, {
|
|
19818
19359
|
success: true,
|
|
19819
19360
|
data: {
|
|
19820
19361
|
username: updatedUser.username,
|
|
@@ -19825,7 +19366,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19825
19366
|
}
|
|
19826
19367
|
}, sendMessage, clientId);
|
|
19827
19368
|
} catch (error) {
|
|
19828
|
-
|
|
19369
|
+
sendResponse2(id, {
|
|
19829
19370
|
success: false,
|
|
19830
19371
|
error: error instanceof Error ? error.message : "Failed to update user"
|
|
19831
19372
|
}, sendMessage, clientId);
|
|
@@ -19833,7 +19374,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19833
19374
|
}
|
|
19834
19375
|
async function handleDelete(id, numericId, username, executeCollection, userManager, sendMessage, clientId) {
|
|
19835
19376
|
if (!numericId && !username) {
|
|
19836
|
-
|
|
19377
|
+
sendResponse2(id, {
|
|
19837
19378
|
success: false,
|
|
19838
19379
|
error: "User ID or username is required"
|
|
19839
19380
|
}, sendMessage, clientId);
|
|
@@ -19844,7 +19385,7 @@ async function handleDelete(id, numericId, username, executeCollection, userMana
|
|
|
19844
19385
|
const result = await executeCollection("users", "delete", { id: numericId });
|
|
19845
19386
|
if (result && result.success) {
|
|
19846
19387
|
logger.info(`[DB] User deleted successfully, ID: ${numericId}`);
|
|
19847
|
-
|
|
19388
|
+
sendResponse2(id, {
|
|
19848
19389
|
success: true,
|
|
19849
19390
|
data: {
|
|
19850
19391
|
id: numericId,
|
|
@@ -19859,14 +19400,14 @@ async function handleDelete(id, numericId, username, executeCollection, userMana
|
|
|
19859
19400
|
}
|
|
19860
19401
|
}
|
|
19861
19402
|
if (!username || username.trim().length === 0) {
|
|
19862
|
-
|
|
19403
|
+
sendResponse2(id, {
|
|
19863
19404
|
success: false,
|
|
19864
19405
|
error: "Username is required for file-based storage delete"
|
|
19865
19406
|
}, sendMessage, clientId);
|
|
19866
19407
|
return;
|
|
19867
19408
|
}
|
|
19868
19409
|
if (!userManager.userExists(username)) {
|
|
19869
|
-
|
|
19410
|
+
sendResponse2(id, {
|
|
19870
19411
|
success: false,
|
|
19871
19412
|
error: `User '${username}' not found`
|
|
19872
19413
|
}, sendMessage, clientId);
|
|
@@ -19874,14 +19415,14 @@ async function handleDelete(id, numericId, username, executeCollection, userMana
|
|
|
19874
19415
|
}
|
|
19875
19416
|
const deleted = userManager.deleteUser(username);
|
|
19876
19417
|
if (!deleted) {
|
|
19877
|
-
|
|
19418
|
+
sendResponse2(id, {
|
|
19878
19419
|
success: false,
|
|
19879
19420
|
error: `Failed to delete user '${username}'`
|
|
19880
19421
|
}, sendMessage, clientId);
|
|
19881
19422
|
return;
|
|
19882
19423
|
}
|
|
19883
19424
|
logger.info(`[FILE] User '${username}' deleted successfully`);
|
|
19884
|
-
|
|
19425
|
+
sendResponse2(id, {
|
|
19885
19426
|
success: true,
|
|
19886
19427
|
data: {
|
|
19887
19428
|
username,
|
|
@@ -19904,7 +19445,7 @@ async function handleGetAll(id, executeCollection, userManager, sendMessage, cli
|
|
|
19904
19445
|
updatedAt: user.updatedAt
|
|
19905
19446
|
}));
|
|
19906
19447
|
logger.info(`[DB] Retrieved ${result.count} users`);
|
|
19907
|
-
|
|
19448
|
+
sendResponse2(id, {
|
|
19908
19449
|
success: true,
|
|
19909
19450
|
data: {
|
|
19910
19451
|
users: sanitizedUsers2,
|
|
@@ -19926,7 +19467,7 @@ async function handleGetAll(id, executeCollection, userManager, sendMessage, cli
|
|
|
19926
19467
|
wsIds: user.wsIds || []
|
|
19927
19468
|
}));
|
|
19928
19469
|
logger.info(`[FILE] Retrieved ${sanitizedUsers.length} users`);
|
|
19929
|
-
|
|
19470
|
+
sendResponse2(id, {
|
|
19930
19471
|
success: true,
|
|
19931
19472
|
data: {
|
|
19932
19473
|
users: sanitizedUsers,
|
|
@@ -19937,7 +19478,7 @@ async function handleGetAll(id, executeCollection, userManager, sendMessage, cli
|
|
|
19937
19478
|
}
|
|
19938
19479
|
async function handleGetOne(id, numericId, username, executeCollection, userManager, sendMessage, clientId) {
|
|
19939
19480
|
if (!numericId && !username) {
|
|
19940
|
-
|
|
19481
|
+
sendResponse2(id, {
|
|
19941
19482
|
success: false,
|
|
19942
19483
|
error: "User ID or username is required"
|
|
19943
19484
|
}, sendMessage, clientId);
|
|
@@ -19958,7 +19499,7 @@ async function handleGetOne(id, numericId, username, executeCollection, userMana
|
|
|
19958
19499
|
updatedAt: result.data?.updatedAt
|
|
19959
19500
|
};
|
|
19960
19501
|
logger.info(`[DB] Retrieved user ID: ${numericId}`);
|
|
19961
|
-
|
|
19502
|
+
sendResponse2(id, {
|
|
19962
19503
|
success: true,
|
|
19963
19504
|
data: {
|
|
19964
19505
|
user: sanitizedUser2,
|
|
@@ -19972,14 +19513,14 @@ async function handleGetOne(id, numericId, username, executeCollection, userMana
|
|
|
19972
19513
|
}
|
|
19973
19514
|
}
|
|
19974
19515
|
if (!username || username.trim().length === 0) {
|
|
19975
|
-
|
|
19516
|
+
sendResponse2(id, {
|
|
19976
19517
|
success: false,
|
|
19977
19518
|
error: "Username is required for file-based storage lookup"
|
|
19978
19519
|
}, sendMessage, clientId);
|
|
19979
19520
|
return;
|
|
19980
19521
|
}
|
|
19981
19522
|
if (!userManager.userExists(username)) {
|
|
19982
|
-
|
|
19523
|
+
sendResponse2(id, {
|
|
19983
19524
|
success: false,
|
|
19984
19525
|
error: `User '${username}' not found`
|
|
19985
19526
|
}, sendMessage, clientId);
|
|
@@ -19994,7 +19535,7 @@ async function handleGetOne(id, numericId, username, executeCollection, userMana
|
|
|
19994
19535
|
wsIds: user.wsIds || []
|
|
19995
19536
|
};
|
|
19996
19537
|
logger.info(`[FILE] Retrieved user: ${username}`);
|
|
19997
|
-
|
|
19538
|
+
sendResponse2(id, {
|
|
19998
19539
|
success: true,
|
|
19999
19540
|
data: {
|
|
20000
19541
|
user: sanitizedUser,
|
|
@@ -20021,7 +19562,7 @@ async function handleQuery(id, filters, limit, sort, executeCollection, userMana
|
|
|
20021
19562
|
updatedAt: user.updatedAt
|
|
20022
19563
|
}));
|
|
20023
19564
|
logger.info(`[DB] Query returned ${result.count} users`);
|
|
20024
|
-
|
|
19565
|
+
sendResponse2(id, {
|
|
20025
19566
|
success: true,
|
|
20026
19567
|
data: {
|
|
20027
19568
|
users: sanitizedUsers2,
|
|
@@ -20044,7 +19585,7 @@ async function handleQuery(id, filters, limit, sort, executeCollection, userMana
|
|
|
20044
19585
|
wsIds: user.wsIds || []
|
|
20045
19586
|
}));
|
|
20046
19587
|
logger.info(`[FILE] Retrieved ${sanitizedUsers.length} users (all - no query filter)`);
|
|
20047
|
-
|
|
19588
|
+
sendResponse2(id, {
|
|
20048
19589
|
success: true,
|
|
20049
19590
|
data: {
|
|
20050
19591
|
users: sanitizedUsers,
|
|
@@ -20053,7 +19594,7 @@ async function handleQuery(id, filters, limit, sort, executeCollection, userMana
|
|
|
20053
19594
|
}
|
|
20054
19595
|
}, sendMessage, clientId);
|
|
20055
19596
|
}
|
|
20056
|
-
function
|
|
19597
|
+
function sendResponse2(id, res, sendMessage, clientId) {
|
|
20057
19598
|
const response = {
|
|
20058
19599
|
id: id || "unknown",
|
|
20059
19600
|
type: "USERS_RES",
|
|
@@ -20109,7 +19650,7 @@ async function handleDashboardsRequest(data, collections, sendMessage) {
|
|
|
20109
19650
|
const sort = requestData?.sort;
|
|
20110
19651
|
const readOnlyOperations = ["query", "getAll", "getOne"];
|
|
20111
19652
|
if (!readOnlyOperations.includes(operation) && from.type !== "admin") {
|
|
20112
|
-
|
|
19653
|
+
sendResponse3(id, {
|
|
20113
19654
|
success: false,
|
|
20114
19655
|
error: "Unauthorized: Only admin can manage dashboards"
|
|
20115
19656
|
}, sendMessage, from.id);
|
|
@@ -20137,14 +19678,14 @@ async function handleDashboardsRequest(data, collections, sendMessage) {
|
|
|
20137
19678
|
await handleQuery2(id, filters, limit, sort, executeCollection, dashboardManager2, sendMessage, from.id);
|
|
20138
19679
|
break;
|
|
20139
19680
|
default:
|
|
20140
|
-
|
|
19681
|
+
sendResponse3(id, {
|
|
20141
19682
|
success: false,
|
|
20142
19683
|
error: `Unknown operation: ${operation}`
|
|
20143
19684
|
}, sendMessage, from.id);
|
|
20144
19685
|
}
|
|
20145
19686
|
} catch (error) {
|
|
20146
19687
|
logger.error("Failed to handle dashboards request:", error);
|
|
20147
|
-
|
|
19688
|
+
sendResponse3(null, {
|
|
20148
19689
|
success: false,
|
|
20149
19690
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
20150
19691
|
}, sendMessage);
|
|
@@ -20152,14 +19693,14 @@ async function handleDashboardsRequest(data, collections, sendMessage) {
|
|
|
20152
19693
|
}
|
|
20153
19694
|
async function handleCreate2(id, dashboardId, dashboard, projectId, name, description, published, createdBy, allowedUsers, executeCollection, dashboardManager2, sendMessage, clientId) {
|
|
20154
19695
|
if (!dashboardId || dashboardId.trim().length === 0) {
|
|
20155
|
-
|
|
19696
|
+
sendResponse3(id, {
|
|
20156
19697
|
success: false,
|
|
20157
19698
|
error: "Dashboard ID is required and cannot be empty"
|
|
20158
19699
|
}, sendMessage, clientId);
|
|
20159
19700
|
return;
|
|
20160
19701
|
}
|
|
20161
19702
|
if (!projectId) {
|
|
20162
|
-
|
|
19703
|
+
sendResponse3(id, {
|
|
20163
19704
|
success: false,
|
|
20164
19705
|
error: "Project ID is required"
|
|
20165
19706
|
}, sendMessage, clientId);
|
|
@@ -20178,7 +19719,7 @@ async function handleCreate2(id, dashboardId, dashboard, projectId, name, descri
|
|
|
20178
19719
|
});
|
|
20179
19720
|
if (result && result.success) {
|
|
20180
19721
|
logger.info(`[DB] Dashboard created successfully, ID: ${result.data?.id}`);
|
|
20181
|
-
|
|
19722
|
+
sendResponse3(id, {
|
|
20182
19723
|
success: true,
|
|
20183
19724
|
data: {
|
|
20184
19725
|
id: result.data?.id,
|
|
@@ -20198,7 +19739,7 @@ async function handleCreate2(id, dashboardId, dashboard, projectId, name, descri
|
|
|
20198
19739
|
}
|
|
20199
19740
|
const createdDashboard = dashboardManager2.createDashboard(dashboardId, dashboard);
|
|
20200
19741
|
logger.info(`[FILE] Dashboard '${dashboardId}' created successfully`);
|
|
20201
|
-
|
|
19742
|
+
sendResponse3(id, {
|
|
20202
19743
|
success: true,
|
|
20203
19744
|
data: {
|
|
20204
19745
|
dashboardId,
|
|
@@ -20207,7 +19748,7 @@ async function handleCreate2(id, dashboardId, dashboard, projectId, name, descri
|
|
|
20207
19748
|
}
|
|
20208
19749
|
}, sendMessage, clientId);
|
|
20209
19750
|
} catch (error) {
|
|
20210
|
-
|
|
19751
|
+
sendResponse3(id, {
|
|
20211
19752
|
success: false,
|
|
20212
19753
|
error: error instanceof Error ? error.message : "Failed to create dashboard"
|
|
20213
19754
|
}, sendMessage, clientId);
|
|
@@ -20215,7 +19756,7 @@ async function handleCreate2(id, dashboardId, dashboard, projectId, name, descri
|
|
|
20215
19756
|
}
|
|
20216
19757
|
async function handleUpdate2(id, numericId, dashboardId, dashboard, name, description, published, updatedBy, allowedUsers, executeCollection, dashboardManager2, sendMessage, clientId) {
|
|
20217
19758
|
if (!numericId) {
|
|
20218
|
-
|
|
19759
|
+
sendResponse3(id, {
|
|
20219
19760
|
success: false,
|
|
20220
19761
|
error: "Dashboard ID is required"
|
|
20221
19762
|
}, sendMessage, clientId);
|
|
@@ -20233,7 +19774,7 @@ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, descri
|
|
|
20233
19774
|
});
|
|
20234
19775
|
if (result && result.success) {
|
|
20235
19776
|
logger.info(`[DB] Dashboard updated successfully, ID: ${numericId}`);
|
|
20236
|
-
|
|
19777
|
+
sendResponse3(id, {
|
|
20237
19778
|
success: true,
|
|
20238
19779
|
data: {
|
|
20239
19780
|
id: numericId,
|
|
@@ -20251,14 +19792,14 @@ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, descri
|
|
|
20251
19792
|
try {
|
|
20252
19793
|
const updatedDashboard = dashboardManager2.updateDashboard(fileStorageId, dashboard);
|
|
20253
19794
|
if (!updatedDashboard) {
|
|
20254
|
-
|
|
19795
|
+
sendResponse3(id, {
|
|
20255
19796
|
success: false,
|
|
20256
19797
|
error: `Dashboard '${fileStorageId}' not found`
|
|
20257
19798
|
}, sendMessage, clientId);
|
|
20258
19799
|
return;
|
|
20259
19800
|
}
|
|
20260
19801
|
logger.info(`[FILE] Dashboard '${fileStorageId}' updated successfully`);
|
|
20261
|
-
|
|
19802
|
+
sendResponse3(id, {
|
|
20262
19803
|
success: true,
|
|
20263
19804
|
data: {
|
|
20264
19805
|
id: numericId,
|
|
@@ -20268,7 +19809,7 @@ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, descri
|
|
|
20268
19809
|
}
|
|
20269
19810
|
}, sendMessage, clientId);
|
|
20270
19811
|
} catch (error) {
|
|
20271
|
-
|
|
19812
|
+
sendResponse3(id, {
|
|
20272
19813
|
success: false,
|
|
20273
19814
|
error: error instanceof Error ? error.message : "Failed to update dashboard"
|
|
20274
19815
|
}, sendMessage, clientId);
|
|
@@ -20276,7 +19817,7 @@ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, descri
|
|
|
20276
19817
|
}
|
|
20277
19818
|
async function handleDelete2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, clientId) {
|
|
20278
19819
|
if (!numericId) {
|
|
20279
|
-
|
|
19820
|
+
sendResponse3(id, {
|
|
20280
19821
|
success: false,
|
|
20281
19822
|
error: "Dashboard ID is required"
|
|
20282
19823
|
}, sendMessage, clientId);
|
|
@@ -20286,7 +19827,7 @@ async function handleDelete2(id, numericId, dashboardId, executeCollection, dash
|
|
|
20286
19827
|
const result = await executeCollection("dashboards", "delete", { id: numericId });
|
|
20287
19828
|
if (result && result.success) {
|
|
20288
19829
|
logger.info(`[DB] Dashboard deleted successfully, ID: ${numericId}`);
|
|
20289
|
-
|
|
19830
|
+
sendResponse3(id, {
|
|
20290
19831
|
success: true,
|
|
20291
19832
|
data: {
|
|
20292
19833
|
id: numericId,
|
|
@@ -20301,14 +19842,14 @@ async function handleDelete2(id, numericId, dashboardId, executeCollection, dash
|
|
|
20301
19842
|
const fileStorageId = dashboardId || String(numericId);
|
|
20302
19843
|
const deleted = dashboardManager2.deleteDashboard(fileStorageId);
|
|
20303
19844
|
if (!deleted) {
|
|
20304
|
-
|
|
19845
|
+
sendResponse3(id, {
|
|
20305
19846
|
success: false,
|
|
20306
19847
|
error: `Dashboard '${fileStorageId}' not found`
|
|
20307
19848
|
}, sendMessage, clientId);
|
|
20308
19849
|
return;
|
|
20309
19850
|
}
|
|
20310
19851
|
logger.info(`[FILE] Dashboard '${fileStorageId}' deleted successfully`);
|
|
20311
|
-
|
|
19852
|
+
sendResponse3(id, {
|
|
20312
19853
|
success: true,
|
|
20313
19854
|
data: {
|
|
20314
19855
|
id: numericId,
|
|
@@ -20322,7 +19863,7 @@ async function handleGetAll2(id, executeCollection, dashboardManager2, sendMessa
|
|
|
20322
19863
|
const result = await executeCollection("dashboards", "getAll", {});
|
|
20323
19864
|
if (result && result.success) {
|
|
20324
19865
|
logger.info(`[DB] Retrieved ${result.count} dashboards`);
|
|
20325
|
-
|
|
19866
|
+
sendResponse3(id, {
|
|
20326
19867
|
success: true,
|
|
20327
19868
|
data: {
|
|
20328
19869
|
dashboards: result.data,
|
|
@@ -20337,7 +19878,7 @@ async function handleGetAll2(id, executeCollection, dashboardManager2, sendMessa
|
|
|
20337
19878
|
}
|
|
20338
19879
|
const dashboards = dashboardManager2.getAllDashboards();
|
|
20339
19880
|
logger.info(`[FILE] Retrieved ${dashboards.length} dashboards`);
|
|
20340
|
-
|
|
19881
|
+
sendResponse3(id, {
|
|
20341
19882
|
success: true,
|
|
20342
19883
|
data: {
|
|
20343
19884
|
dashboards,
|
|
@@ -20348,7 +19889,7 @@ async function handleGetAll2(id, executeCollection, dashboardManager2, sendMessa
|
|
|
20348
19889
|
}
|
|
20349
19890
|
async function handleGetOne2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, clientId) {
|
|
20350
19891
|
if (!numericId) {
|
|
20351
|
-
|
|
19892
|
+
sendResponse3(id, {
|
|
20352
19893
|
success: false,
|
|
20353
19894
|
error: "Dashboard ID is required"
|
|
20354
19895
|
}, sendMessage, clientId);
|
|
@@ -20358,7 +19899,7 @@ async function handleGetOne2(id, numericId, dashboardId, executeCollection, dash
|
|
|
20358
19899
|
const result = await executeCollection("dashboards", "getOne", { id: numericId });
|
|
20359
19900
|
if (result && result.success) {
|
|
20360
19901
|
logger.info(`[DB] Retrieved dashboard ID: ${numericId}`);
|
|
20361
|
-
|
|
19902
|
+
sendResponse3(id, {
|
|
20362
19903
|
success: true,
|
|
20363
19904
|
data: {
|
|
20364
19905
|
id: numericId,
|
|
@@ -20375,14 +19916,14 @@ async function handleGetOne2(id, numericId, dashboardId, executeCollection, dash
|
|
|
20375
19916
|
const fileStorageId = dashboardId || String(numericId);
|
|
20376
19917
|
const dashboard = dashboardManager2.getDashboard(fileStorageId);
|
|
20377
19918
|
if (!dashboard) {
|
|
20378
|
-
|
|
19919
|
+
sendResponse3(id, {
|
|
20379
19920
|
success: false,
|
|
20380
19921
|
error: `Dashboard '${fileStorageId}' not found`
|
|
20381
19922
|
}, sendMessage, clientId);
|
|
20382
19923
|
return;
|
|
20383
19924
|
}
|
|
20384
19925
|
logger.info(`[FILE] Retrieved dashboard: ${fileStorageId}`);
|
|
20385
|
-
|
|
19926
|
+
sendResponse3(id, {
|
|
20386
19927
|
success: true,
|
|
20387
19928
|
data: {
|
|
20388
19929
|
id: numericId,
|
|
@@ -20401,7 +19942,7 @@ async function handleQuery2(id, filters, limit, sort, executeCollection, dashboa
|
|
|
20401
19942
|
});
|
|
20402
19943
|
if (result && result.success) {
|
|
20403
19944
|
logger.info(`[DB] Query returned ${result.count} dashboards`);
|
|
20404
|
-
|
|
19945
|
+
sendResponse3(id, {
|
|
20405
19946
|
success: true,
|
|
20406
19947
|
data: {
|
|
20407
19948
|
dashboards: result.data,
|
|
@@ -20416,7 +19957,7 @@ async function handleQuery2(id, filters, limit, sort, executeCollection, dashboa
|
|
|
20416
19957
|
}
|
|
20417
19958
|
const dashboards = dashboardManager2.getAllDashboards();
|
|
20418
19959
|
logger.info(`[FILE] Retrieved ${dashboards.length} dashboards (all - no query filter)`);
|
|
20419
|
-
|
|
19960
|
+
sendResponse3(id, {
|
|
20420
19961
|
success: true,
|
|
20421
19962
|
data: {
|
|
20422
19963
|
dashboards,
|
|
@@ -20425,7 +19966,7 @@ async function handleQuery2(id, filters, limit, sort, executeCollection, dashboa
|
|
|
20425
19966
|
}
|
|
20426
19967
|
}, sendMessage, clientId);
|
|
20427
19968
|
}
|
|
20428
|
-
function
|
|
19969
|
+
function sendResponse3(id, res, sendMessage, clientId) {
|
|
20429
19970
|
const response = {
|
|
20430
19971
|
id: id || "unknown",
|
|
20431
19972
|
type: "DASHBOARDS_RES",
|
|
@@ -20480,7 +20021,7 @@ async function handleReportsRequest(data, collections, sendMessage) {
|
|
|
20480
20021
|
const sort = requestData?.sort;
|
|
20481
20022
|
const readOnlyOperations = ["query", "getAll", "getOne"];
|
|
20482
20023
|
if (!readOnlyOperations.includes(operation) && from.type !== "admin") {
|
|
20483
|
-
|
|
20024
|
+
sendResponse4(id, {
|
|
20484
20025
|
success: false,
|
|
20485
20026
|
error: "Unauthorized: Only admin can manage reports"
|
|
20486
20027
|
}, sendMessage, from.id);
|
|
@@ -20508,14 +20049,14 @@ async function handleReportsRequest(data, collections, sendMessage) {
|
|
|
20508
20049
|
await handleQuery3(id, filters, limit, sort, executeCollection, reportManager2, sendMessage, from.id);
|
|
20509
20050
|
break;
|
|
20510
20051
|
default:
|
|
20511
|
-
|
|
20052
|
+
sendResponse4(id, {
|
|
20512
20053
|
success: false,
|
|
20513
20054
|
error: `Unknown operation: ${operation}`
|
|
20514
20055
|
}, sendMessage, from.id);
|
|
20515
20056
|
}
|
|
20516
20057
|
} catch (error) {
|
|
20517
20058
|
logger.error("Failed to handle reports request:", error);
|
|
20518
|
-
|
|
20059
|
+
sendResponse4(null, {
|
|
20519
20060
|
success: false,
|
|
20520
20061
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
20521
20062
|
}, sendMessage);
|
|
@@ -20523,14 +20064,14 @@ async function handleReportsRequest(data, collections, sendMessage) {
|
|
|
20523
20064
|
}
|
|
20524
20065
|
async function handleCreate3(id, reportId, report, projectId, name, description, published, createdBy, executeCollection, reportManager2, sendMessage, clientId) {
|
|
20525
20066
|
if (!reportId || reportId.trim().length === 0) {
|
|
20526
|
-
|
|
20067
|
+
sendResponse4(id, {
|
|
20527
20068
|
success: false,
|
|
20528
20069
|
error: "Report ID is required and cannot be empty"
|
|
20529
20070
|
}, sendMessage, clientId);
|
|
20530
20071
|
return;
|
|
20531
20072
|
}
|
|
20532
20073
|
if (!projectId) {
|
|
20533
|
-
|
|
20074
|
+
sendResponse4(id, {
|
|
20534
20075
|
success: false,
|
|
20535
20076
|
error: "Project ID is required"
|
|
20536
20077
|
}, sendMessage, clientId);
|
|
@@ -20548,7 +20089,7 @@ async function handleCreate3(id, reportId, report, projectId, name, description,
|
|
|
20548
20089
|
});
|
|
20549
20090
|
if (result && result.success) {
|
|
20550
20091
|
logger.info(`[DB] Report created successfully, ID: ${result.data?.id}`);
|
|
20551
|
-
|
|
20092
|
+
sendResponse4(id, {
|
|
20552
20093
|
success: true,
|
|
20553
20094
|
data: {
|
|
20554
20095
|
id: result.data?.id,
|
|
@@ -20568,7 +20109,7 @@ async function handleCreate3(id, reportId, report, projectId, name, description,
|
|
|
20568
20109
|
}
|
|
20569
20110
|
const createdReport = reportManager2.createReport(reportId, report);
|
|
20570
20111
|
logger.info(`[FILE] Report '${reportId}' created successfully`);
|
|
20571
|
-
|
|
20112
|
+
sendResponse4(id, {
|
|
20572
20113
|
success: true,
|
|
20573
20114
|
data: {
|
|
20574
20115
|
reportId,
|
|
@@ -20577,7 +20118,7 @@ async function handleCreate3(id, reportId, report, projectId, name, description,
|
|
|
20577
20118
|
}
|
|
20578
20119
|
}, sendMessage, clientId);
|
|
20579
20120
|
} catch (error) {
|
|
20580
|
-
|
|
20121
|
+
sendResponse4(id, {
|
|
20581
20122
|
success: false,
|
|
20582
20123
|
error: error instanceof Error ? error.message : "Failed to create report"
|
|
20583
20124
|
}, sendMessage, clientId);
|
|
@@ -20585,7 +20126,7 @@ async function handleCreate3(id, reportId, report, projectId, name, description,
|
|
|
20585
20126
|
}
|
|
20586
20127
|
async function handleUpdate3(id, numericId, reportId, report, name, description, published, updatedBy, executeCollection, reportManager2, sendMessage, clientId) {
|
|
20587
20128
|
if (!numericId) {
|
|
20588
|
-
|
|
20129
|
+
sendResponse4(id, {
|
|
20589
20130
|
success: false,
|
|
20590
20131
|
error: "Report ID is required"
|
|
20591
20132
|
}, sendMessage, clientId);
|
|
@@ -20602,7 +20143,7 @@ async function handleUpdate3(id, numericId, reportId, report, name, description,
|
|
|
20602
20143
|
});
|
|
20603
20144
|
if (result && result.success) {
|
|
20604
20145
|
logger.info(`[DB] Report updated successfully, ID: ${numericId}`);
|
|
20605
|
-
|
|
20146
|
+
sendResponse4(id, {
|
|
20606
20147
|
success: true,
|
|
20607
20148
|
data: {
|
|
20608
20149
|
id: numericId,
|
|
@@ -20620,14 +20161,14 @@ async function handleUpdate3(id, numericId, reportId, report, name, description,
|
|
|
20620
20161
|
try {
|
|
20621
20162
|
const updatedReport = reportManager2.updateReport(fileStorageId, report);
|
|
20622
20163
|
if (!updatedReport) {
|
|
20623
|
-
|
|
20164
|
+
sendResponse4(id, {
|
|
20624
20165
|
success: false,
|
|
20625
20166
|
error: `Report '${fileStorageId}' not found`
|
|
20626
20167
|
}, sendMessage, clientId);
|
|
20627
20168
|
return;
|
|
20628
20169
|
}
|
|
20629
20170
|
logger.info(`[FILE] Report '${fileStorageId}' updated successfully`);
|
|
20630
|
-
|
|
20171
|
+
sendResponse4(id, {
|
|
20631
20172
|
success: true,
|
|
20632
20173
|
data: {
|
|
20633
20174
|
id: numericId,
|
|
@@ -20637,7 +20178,7 @@ async function handleUpdate3(id, numericId, reportId, report, name, description,
|
|
|
20637
20178
|
}
|
|
20638
20179
|
}, sendMessage, clientId);
|
|
20639
20180
|
} catch (error) {
|
|
20640
|
-
|
|
20181
|
+
sendResponse4(id, {
|
|
20641
20182
|
success: false,
|
|
20642
20183
|
error: error instanceof Error ? error.message : "Failed to update report"
|
|
20643
20184
|
}, sendMessage, clientId);
|
|
@@ -20645,7 +20186,7 @@ async function handleUpdate3(id, numericId, reportId, report, name, description,
|
|
|
20645
20186
|
}
|
|
20646
20187
|
async function handleDelete3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, clientId) {
|
|
20647
20188
|
if (!numericId) {
|
|
20648
|
-
|
|
20189
|
+
sendResponse4(id, {
|
|
20649
20190
|
success: false,
|
|
20650
20191
|
error: "Report ID is required"
|
|
20651
20192
|
}, sendMessage, clientId);
|
|
@@ -20655,7 +20196,7 @@ async function handleDelete3(id, numericId, reportId, executeCollection, reportM
|
|
|
20655
20196
|
const result = await executeCollection("reports", "delete", { id: numericId });
|
|
20656
20197
|
if (result && result.success) {
|
|
20657
20198
|
logger.info(`[DB] Report deleted successfully, ID: ${numericId}`);
|
|
20658
|
-
|
|
20199
|
+
sendResponse4(id, {
|
|
20659
20200
|
success: true,
|
|
20660
20201
|
data: {
|
|
20661
20202
|
id: numericId,
|
|
@@ -20670,14 +20211,14 @@ async function handleDelete3(id, numericId, reportId, executeCollection, reportM
|
|
|
20670
20211
|
const fileStorageId = reportId || String(numericId);
|
|
20671
20212
|
const deleted = reportManager2.deleteReport(fileStorageId);
|
|
20672
20213
|
if (!deleted) {
|
|
20673
|
-
|
|
20214
|
+
sendResponse4(id, {
|
|
20674
20215
|
success: false,
|
|
20675
20216
|
error: `Report '${fileStorageId}' not found`
|
|
20676
20217
|
}, sendMessage, clientId);
|
|
20677
20218
|
return;
|
|
20678
20219
|
}
|
|
20679
20220
|
logger.info(`[FILE] Report '${fileStorageId}' deleted successfully`);
|
|
20680
|
-
|
|
20221
|
+
sendResponse4(id, {
|
|
20681
20222
|
success: true,
|
|
20682
20223
|
data: {
|
|
20683
20224
|
id: numericId,
|
|
@@ -20691,7 +20232,7 @@ async function handleGetAll3(id, executeCollection, reportManager2, sendMessage,
|
|
|
20691
20232
|
const result = await executeCollection("reports", "getAll", {});
|
|
20692
20233
|
if (result && result.success) {
|
|
20693
20234
|
logger.info(`[DB] Retrieved ${result.count} reports`);
|
|
20694
|
-
|
|
20235
|
+
sendResponse4(id, {
|
|
20695
20236
|
success: true,
|
|
20696
20237
|
data: {
|
|
20697
20238
|
reports: result.data,
|
|
@@ -20706,7 +20247,7 @@ async function handleGetAll3(id, executeCollection, reportManager2, sendMessage,
|
|
|
20706
20247
|
}
|
|
20707
20248
|
const reports = reportManager2.getAllReports();
|
|
20708
20249
|
logger.info(`[FILE] Retrieved ${reports.length} reports`);
|
|
20709
|
-
|
|
20250
|
+
sendResponse4(id, {
|
|
20710
20251
|
success: true,
|
|
20711
20252
|
data: {
|
|
20712
20253
|
reports,
|
|
@@ -20717,7 +20258,7 @@ async function handleGetAll3(id, executeCollection, reportManager2, sendMessage,
|
|
|
20717
20258
|
}
|
|
20718
20259
|
async function handleGetOne3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, clientId) {
|
|
20719
20260
|
if (!numericId) {
|
|
20720
|
-
|
|
20261
|
+
sendResponse4(id, {
|
|
20721
20262
|
success: false,
|
|
20722
20263
|
error: "Report ID is required"
|
|
20723
20264
|
}, sendMessage, clientId);
|
|
@@ -20727,7 +20268,7 @@ async function handleGetOne3(id, numericId, reportId, executeCollection, reportM
|
|
|
20727
20268
|
const result = await executeCollection("reports", "getOne", { id: numericId });
|
|
20728
20269
|
if (result && result.success) {
|
|
20729
20270
|
logger.info(`[DB] Retrieved report ID: ${numericId}`);
|
|
20730
|
-
|
|
20271
|
+
sendResponse4(id, {
|
|
20731
20272
|
success: true,
|
|
20732
20273
|
data: {
|
|
20733
20274
|
id: numericId,
|
|
@@ -20744,14 +20285,14 @@ async function handleGetOne3(id, numericId, reportId, executeCollection, reportM
|
|
|
20744
20285
|
const fileStorageId = reportId || String(numericId);
|
|
20745
20286
|
const report = reportManager2.getReport(fileStorageId);
|
|
20746
20287
|
if (!report) {
|
|
20747
|
-
|
|
20288
|
+
sendResponse4(id, {
|
|
20748
20289
|
success: false,
|
|
20749
20290
|
error: `Report '${fileStorageId}' not found`
|
|
20750
20291
|
}, sendMessage, clientId);
|
|
20751
20292
|
return;
|
|
20752
20293
|
}
|
|
20753
20294
|
logger.info(`[FILE] Retrieved report: ${fileStorageId}`);
|
|
20754
|
-
|
|
20295
|
+
sendResponse4(id, {
|
|
20755
20296
|
success: true,
|
|
20756
20297
|
data: {
|
|
20757
20298
|
id: numericId,
|
|
@@ -20770,7 +20311,7 @@ async function handleQuery3(id, filters, limit, sort, executeCollection, reportM
|
|
|
20770
20311
|
});
|
|
20771
20312
|
if (result && result.success) {
|
|
20772
20313
|
logger.info(`[DB] Query returned ${result.count} reports`);
|
|
20773
|
-
|
|
20314
|
+
sendResponse4(id, {
|
|
20774
20315
|
success: true,
|
|
20775
20316
|
data: {
|
|
20776
20317
|
reports: result.data,
|
|
@@ -20785,7 +20326,7 @@ async function handleQuery3(id, filters, limit, sort, executeCollection, reportM
|
|
|
20785
20326
|
}
|
|
20786
20327
|
const reports = reportManager2.getAllReports();
|
|
20787
20328
|
logger.info(`[FILE] Retrieved ${reports.length} reports (all - no query filter)`);
|
|
20788
|
-
|
|
20329
|
+
sendResponse4(id, {
|
|
20789
20330
|
success: true,
|
|
20790
20331
|
data: {
|
|
20791
20332
|
reports,
|
|
@@ -20794,7 +20335,7 @@ async function handleQuery3(id, filters, limit, sort, executeCollection, reportM
|
|
|
20794
20335
|
}
|
|
20795
20336
|
}, sendMessage, clientId);
|
|
20796
20337
|
}
|
|
20797
|
-
function
|
|
20338
|
+
function sendResponse4(id, res, sendMessage, clientId) {
|
|
20798
20339
|
const response = {
|
|
20799
20340
|
id: id || "unknown",
|
|
20800
20341
|
type: "REPORTS_RES",
|
|
@@ -20835,7 +20376,7 @@ async function handleUIsRequest(data, collections, sendMessage) {
|
|
|
20835
20376
|
const limit = requestData?.limit;
|
|
20836
20377
|
const sort = requestData?.sort;
|
|
20837
20378
|
if (from.type !== "admin") {
|
|
20838
|
-
|
|
20379
|
+
sendResponse5(id, {
|
|
20839
20380
|
success: false,
|
|
20840
20381
|
error: "Unauthorized: Only admin can manage UIs"
|
|
20841
20382
|
}, sendMessage, from.id);
|
|
@@ -20862,14 +20403,14 @@ async function handleUIsRequest(data, collections, sendMessage) {
|
|
|
20862
20403
|
await handleQuery4(id, filters, limit, sort, executeCollection, sendMessage, from.id);
|
|
20863
20404
|
break;
|
|
20864
20405
|
default:
|
|
20865
|
-
|
|
20406
|
+
sendResponse5(id, {
|
|
20866
20407
|
success: false,
|
|
20867
20408
|
error: `Unknown operation: ${operation}`
|
|
20868
20409
|
}, sendMessage, from.id);
|
|
20869
20410
|
}
|
|
20870
20411
|
} catch (error) {
|
|
20871
20412
|
logger.error("Failed to handle UIs request:", error);
|
|
20872
|
-
|
|
20413
|
+
sendResponse5(null, {
|
|
20873
20414
|
success: false,
|
|
20874
20415
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
20875
20416
|
}, sendMessage);
|
|
@@ -20877,14 +20418,14 @@ async function handleUIsRequest(data, collections, sendMessage) {
|
|
|
20877
20418
|
}
|
|
20878
20419
|
async function handleCreate4(id, uiId, ui, projectId, name, description, createdBy, executeCollection, sendMessage, clientId) {
|
|
20879
20420
|
if (!uiId || uiId.trim().length === 0) {
|
|
20880
|
-
|
|
20421
|
+
sendResponse5(id, {
|
|
20881
20422
|
success: false,
|
|
20882
20423
|
error: "UI ID is required and cannot be empty"
|
|
20883
20424
|
}, sendMessage, clientId);
|
|
20884
20425
|
return;
|
|
20885
20426
|
}
|
|
20886
20427
|
if (!projectId || projectId.trim().length === 0) {
|
|
20887
|
-
|
|
20428
|
+
sendResponse5(id, {
|
|
20888
20429
|
success: false,
|
|
20889
20430
|
error: "Project ID is required and cannot be empty"
|
|
20890
20431
|
}, sendMessage, clientId);
|
|
@@ -20901,7 +20442,7 @@ async function handleCreate4(id, uiId, ui, projectId, name, description, created
|
|
|
20901
20442
|
});
|
|
20902
20443
|
if (result && result.success) {
|
|
20903
20444
|
logger.info(`UI created successfully, ID: ${result.data?.id}`);
|
|
20904
|
-
|
|
20445
|
+
sendResponse5(id, {
|
|
20905
20446
|
success: true,
|
|
20906
20447
|
data: {
|
|
20907
20448
|
id: result.data?.id,
|
|
@@ -20911,13 +20452,13 @@ async function handleCreate4(id, uiId, ui, projectId, name, description, created
|
|
|
20911
20452
|
}
|
|
20912
20453
|
}, sendMessage, clientId);
|
|
20913
20454
|
} else {
|
|
20914
|
-
|
|
20455
|
+
sendResponse5(id, {
|
|
20915
20456
|
success: false,
|
|
20916
20457
|
error: "Failed to create UI"
|
|
20917
20458
|
}, sendMessage, clientId);
|
|
20918
20459
|
}
|
|
20919
20460
|
} catch (error) {
|
|
20920
|
-
|
|
20461
|
+
sendResponse5(id, {
|
|
20921
20462
|
success: false,
|
|
20922
20463
|
error: error instanceof Error ? error.message : "Failed to create UI"
|
|
20923
20464
|
}, sendMessage, clientId);
|
|
@@ -20925,7 +20466,7 @@ async function handleCreate4(id, uiId, ui, projectId, name, description, created
|
|
|
20925
20466
|
}
|
|
20926
20467
|
async function handleUpdate4(id, numericId, ui, name, description, updatedBy, executeCollection, sendMessage, clientId) {
|
|
20927
20468
|
if (!numericId) {
|
|
20928
|
-
|
|
20469
|
+
sendResponse5(id, {
|
|
20929
20470
|
success: false,
|
|
20930
20471
|
error: "UI ID is required"
|
|
20931
20472
|
}, sendMessage, clientId);
|
|
@@ -20941,7 +20482,7 @@ async function handleUpdate4(id, numericId, ui, name, description, updatedBy, ex
|
|
|
20941
20482
|
});
|
|
20942
20483
|
if (result && result.success) {
|
|
20943
20484
|
logger.info(`UI updated successfully, ID: ${numericId}`);
|
|
20944
|
-
|
|
20485
|
+
sendResponse5(id, {
|
|
20945
20486
|
success: true,
|
|
20946
20487
|
data: {
|
|
20947
20488
|
id: numericId,
|
|
@@ -20951,13 +20492,13 @@ async function handleUpdate4(id, numericId, ui, name, description, updatedBy, ex
|
|
|
20951
20492
|
}
|
|
20952
20493
|
}, sendMessage, clientId);
|
|
20953
20494
|
} else {
|
|
20954
|
-
|
|
20495
|
+
sendResponse5(id, {
|
|
20955
20496
|
success: false,
|
|
20956
20497
|
error: "Failed to update UI"
|
|
20957
20498
|
}, sendMessage, clientId);
|
|
20958
20499
|
}
|
|
20959
20500
|
} catch (error) {
|
|
20960
|
-
|
|
20501
|
+
sendResponse5(id, {
|
|
20961
20502
|
success: false,
|
|
20962
20503
|
error: error instanceof Error ? error.message : "Failed to update UI"
|
|
20963
20504
|
}, sendMessage, clientId);
|
|
@@ -20965,7 +20506,7 @@ async function handleUpdate4(id, numericId, ui, name, description, updatedBy, ex
|
|
|
20965
20506
|
}
|
|
20966
20507
|
async function handleDelete4(id, numericId, executeCollection, sendMessage, clientId) {
|
|
20967
20508
|
if (!numericId) {
|
|
20968
|
-
|
|
20509
|
+
sendResponse5(id, {
|
|
20969
20510
|
success: false,
|
|
20970
20511
|
error: "UI ID is required"
|
|
20971
20512
|
}, sendMessage, clientId);
|
|
@@ -20975,7 +20516,7 @@ async function handleDelete4(id, numericId, executeCollection, sendMessage, clie
|
|
|
20975
20516
|
const result = await executeCollection("uis", "delete", { id: numericId });
|
|
20976
20517
|
if (result && result.success) {
|
|
20977
20518
|
logger.info(`UI deleted successfully, ID: ${numericId}`);
|
|
20978
|
-
|
|
20519
|
+
sendResponse5(id, {
|
|
20979
20520
|
success: true,
|
|
20980
20521
|
data: {
|
|
20981
20522
|
id: numericId,
|
|
@@ -20983,13 +20524,13 @@ async function handleDelete4(id, numericId, executeCollection, sendMessage, clie
|
|
|
20983
20524
|
}
|
|
20984
20525
|
}, sendMessage, clientId);
|
|
20985
20526
|
} else {
|
|
20986
|
-
|
|
20527
|
+
sendResponse5(id, {
|
|
20987
20528
|
success: false,
|
|
20988
20529
|
error: "Failed to delete UI"
|
|
20989
20530
|
}, sendMessage, clientId);
|
|
20990
20531
|
}
|
|
20991
20532
|
} catch (error) {
|
|
20992
|
-
|
|
20533
|
+
sendResponse5(id, {
|
|
20993
20534
|
success: false,
|
|
20994
20535
|
error: error instanceof Error ? error.message : "Failed to delete UI"
|
|
20995
20536
|
}, sendMessage, clientId);
|
|
@@ -21000,7 +20541,7 @@ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
|
|
|
21000
20541
|
const result = await executeCollection("uis", "getAll", {});
|
|
21001
20542
|
if (result && result.success) {
|
|
21002
20543
|
logger.info(`Retrieved ${result.count} UIs`);
|
|
21003
|
-
|
|
20544
|
+
sendResponse5(id, {
|
|
21004
20545
|
success: true,
|
|
21005
20546
|
data: {
|
|
21006
20547
|
uis: result.data,
|
|
@@ -21009,13 +20550,13 @@ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
|
|
|
21009
20550
|
}
|
|
21010
20551
|
}, sendMessage, clientId);
|
|
21011
20552
|
} else {
|
|
21012
|
-
|
|
20553
|
+
sendResponse5(id, {
|
|
21013
20554
|
success: false,
|
|
21014
20555
|
error: "Failed to get UIs"
|
|
21015
20556
|
}, sendMessage, clientId);
|
|
21016
20557
|
}
|
|
21017
20558
|
} catch (error) {
|
|
21018
|
-
|
|
20559
|
+
sendResponse5(id, {
|
|
21019
20560
|
success: false,
|
|
21020
20561
|
error: error instanceof Error ? error.message : "Failed to get UIs"
|
|
21021
20562
|
}, sendMessage, clientId);
|
|
@@ -21023,7 +20564,7 @@ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
|
|
|
21023
20564
|
}
|
|
21024
20565
|
async function handleGetOne4(id, numericId, executeCollection, sendMessage, clientId) {
|
|
21025
20566
|
if (!numericId) {
|
|
21026
|
-
|
|
20567
|
+
sendResponse5(id, {
|
|
21027
20568
|
success: false,
|
|
21028
20569
|
error: "UI ID is required"
|
|
21029
20570
|
}, sendMessage, clientId);
|
|
@@ -21033,7 +20574,7 @@ async function handleGetOne4(id, numericId, executeCollection, sendMessage, clie
|
|
|
21033
20574
|
const result = await executeCollection("uis", "getOne", { id: numericId });
|
|
21034
20575
|
if (result && result.success) {
|
|
21035
20576
|
logger.info(`Retrieved UI ID: ${numericId}`);
|
|
21036
|
-
|
|
20577
|
+
sendResponse5(id, {
|
|
21037
20578
|
success: true,
|
|
21038
20579
|
data: {
|
|
21039
20580
|
id: numericId,
|
|
@@ -21043,13 +20584,13 @@ async function handleGetOne4(id, numericId, executeCollection, sendMessage, clie
|
|
|
21043
20584
|
}
|
|
21044
20585
|
}, sendMessage, clientId);
|
|
21045
20586
|
} else {
|
|
21046
|
-
|
|
20587
|
+
sendResponse5(id, {
|
|
21047
20588
|
success: false,
|
|
21048
20589
|
error: `UI not found`
|
|
21049
20590
|
}, sendMessage, clientId);
|
|
21050
20591
|
}
|
|
21051
20592
|
} catch (error) {
|
|
21052
|
-
|
|
20593
|
+
sendResponse5(id, {
|
|
21053
20594
|
success: false,
|
|
21054
20595
|
error: error instanceof Error ? error.message : "Failed to get UI"
|
|
21055
20596
|
}, sendMessage, clientId);
|
|
@@ -21064,7 +20605,7 @@ async function handleQuery4(id, filters, limit, sort, executeCollection, sendMes
|
|
|
21064
20605
|
});
|
|
21065
20606
|
if (result && result.success) {
|
|
21066
20607
|
logger.info(`Query returned ${result.count} UIs`);
|
|
21067
|
-
|
|
20608
|
+
sendResponse5(id, {
|
|
21068
20609
|
success: true,
|
|
21069
20610
|
data: {
|
|
21070
20611
|
uis: result.data,
|
|
@@ -21073,19 +20614,19 @@ async function handleQuery4(id, filters, limit, sort, executeCollection, sendMes
|
|
|
21073
20614
|
}
|
|
21074
20615
|
}, sendMessage, clientId);
|
|
21075
20616
|
} else {
|
|
21076
|
-
|
|
20617
|
+
sendResponse5(id, {
|
|
21077
20618
|
success: false,
|
|
21078
20619
|
error: "Failed to query UIs"
|
|
21079
20620
|
}, sendMessage, clientId);
|
|
21080
20621
|
}
|
|
21081
20622
|
} catch (error) {
|
|
21082
|
-
|
|
20623
|
+
sendResponse5(id, {
|
|
21083
20624
|
success: false,
|
|
21084
20625
|
error: error instanceof Error ? error.message : "Failed to query UIs"
|
|
21085
20626
|
}, sendMessage, clientId);
|
|
21086
20627
|
}
|
|
21087
20628
|
}
|
|
21088
|
-
function
|
|
20629
|
+
function sendResponse5(id, res, sendMessage, clientId) {
|
|
21089
20630
|
const response = {
|
|
21090
20631
|
id: id || "unknown",
|
|
21091
20632
|
type: "UIS_RES",
|
|
@@ -21143,14 +20684,14 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
|
|
|
21143
20684
|
await handleQuery5(id, filters, limit, sort, executeCollection, sendMessage, from.id);
|
|
21144
20685
|
break;
|
|
21145
20686
|
default:
|
|
21146
|
-
|
|
20687
|
+
sendResponse6(id, {
|
|
21147
20688
|
success: false,
|
|
21148
20689
|
error: `Unknown operation: ${operation}`
|
|
21149
20690
|
}, sendMessage, from.id);
|
|
21150
20691
|
}
|
|
21151
20692
|
} catch (error) {
|
|
21152
20693
|
logger.error("Failed to handle bookmarks request:", error);
|
|
21153
|
-
|
|
20694
|
+
sendResponse6(null, {
|
|
21154
20695
|
success: false,
|
|
21155
20696
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
21156
20697
|
}, sendMessage);
|
|
@@ -21158,14 +20699,14 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
|
|
|
21158
20699
|
}
|
|
21159
20700
|
async function handleCreate5(id, userId, threadId, name, description, uiblock, executeCollection, sendMessage, clientId) {
|
|
21160
20701
|
if (!userId) {
|
|
21161
|
-
|
|
20702
|
+
sendResponse6(id, {
|
|
21162
20703
|
success: false,
|
|
21163
20704
|
error: "userId is required"
|
|
21164
20705
|
}, sendMessage, clientId);
|
|
21165
20706
|
return;
|
|
21166
20707
|
}
|
|
21167
20708
|
if (!uiblock) {
|
|
21168
|
-
|
|
20709
|
+
sendResponse6(id, {
|
|
21169
20710
|
success: false,
|
|
21170
20711
|
error: "UIBlock data is required"
|
|
21171
20712
|
}, sendMessage, clientId);
|
|
@@ -21173,14 +20714,14 @@ async function handleCreate5(id, userId, threadId, name, description, uiblock, e
|
|
|
21173
20714
|
}
|
|
21174
20715
|
try {
|
|
21175
20716
|
const result = await executeCollection("bookmarks", "create", { userId, threadId, name, description, uiblock });
|
|
21176
|
-
|
|
20717
|
+
sendResponse6(id, {
|
|
21177
20718
|
success: true,
|
|
21178
20719
|
data: result.data,
|
|
21179
20720
|
message: "Bookmark created successfully"
|
|
21180
20721
|
}, sendMessage, clientId);
|
|
21181
20722
|
logger.info(`Bookmark created: ID ${result.data.id}`);
|
|
21182
20723
|
} catch (error) {
|
|
21183
|
-
|
|
20724
|
+
sendResponse6(id, {
|
|
21184
20725
|
success: false,
|
|
21185
20726
|
error: error instanceof Error ? error.message : "Failed to create bookmark"
|
|
21186
20727
|
}, sendMessage, clientId);
|
|
@@ -21188,7 +20729,7 @@ async function handleCreate5(id, userId, threadId, name, description, uiblock, e
|
|
|
21188
20729
|
}
|
|
21189
20730
|
async function handleUpdate5(id, bookmarkId, threadId, name, description, uiblock, executeCollection, sendMessage, clientId) {
|
|
21190
20731
|
if (!bookmarkId) {
|
|
21191
|
-
|
|
20732
|
+
sendResponse6(id, {
|
|
21192
20733
|
success: false,
|
|
21193
20734
|
error: "Bookmark ID is required"
|
|
21194
20735
|
}, sendMessage, clientId);
|
|
@@ -21196,14 +20737,14 @@ async function handleUpdate5(id, bookmarkId, threadId, name, description, uibloc
|
|
|
21196
20737
|
}
|
|
21197
20738
|
try {
|
|
21198
20739
|
const result = await executeCollection("bookmarks", "update", { id: bookmarkId, threadId, name, description, uiblock });
|
|
21199
|
-
|
|
20740
|
+
sendResponse6(id, {
|
|
21200
20741
|
success: true,
|
|
21201
20742
|
data: result.data,
|
|
21202
20743
|
message: "Bookmark updated successfully"
|
|
21203
20744
|
}, sendMessage, clientId);
|
|
21204
20745
|
logger.info(`Bookmark updated: ID ${bookmarkId}`);
|
|
21205
20746
|
} catch (error) {
|
|
21206
|
-
|
|
20747
|
+
sendResponse6(id, {
|
|
21207
20748
|
success: false,
|
|
21208
20749
|
error: error instanceof Error ? error.message : "Failed to update bookmark"
|
|
21209
20750
|
}, sendMessage, clientId);
|
|
@@ -21211,7 +20752,7 @@ async function handleUpdate5(id, bookmarkId, threadId, name, description, uibloc
|
|
|
21211
20752
|
}
|
|
21212
20753
|
async function handleDelete5(id, bookmarkId, executeCollection, sendMessage, clientId) {
|
|
21213
20754
|
if (!bookmarkId) {
|
|
21214
|
-
|
|
20755
|
+
sendResponse6(id, {
|
|
21215
20756
|
success: false,
|
|
21216
20757
|
error: "Bookmark ID is required"
|
|
21217
20758
|
}, sendMessage, clientId);
|
|
@@ -21219,14 +20760,14 @@ async function handleDelete5(id, bookmarkId, executeCollection, sendMessage, cli
|
|
|
21219
20760
|
}
|
|
21220
20761
|
try {
|
|
21221
20762
|
const result = await executeCollection("bookmarks", "delete", { id: bookmarkId });
|
|
21222
|
-
|
|
20763
|
+
sendResponse6(id, {
|
|
21223
20764
|
success: true,
|
|
21224
20765
|
data: result.data,
|
|
21225
20766
|
message: "Bookmark deleted successfully"
|
|
21226
20767
|
}, sendMessage, clientId);
|
|
21227
20768
|
logger.info(`Bookmark deleted: ID ${bookmarkId}`);
|
|
21228
20769
|
} catch (error) {
|
|
21229
|
-
|
|
20770
|
+
sendResponse6(id, {
|
|
21230
20771
|
success: false,
|
|
21231
20772
|
error: error instanceof Error ? error.message : "Failed to delete bookmark"
|
|
21232
20773
|
}, sendMessage, clientId);
|
|
@@ -21235,7 +20776,7 @@ async function handleDelete5(id, bookmarkId, executeCollection, sendMessage, cli
|
|
|
21235
20776
|
async function handleGetAll5(id, executeCollection, sendMessage, clientId) {
|
|
21236
20777
|
try {
|
|
21237
20778
|
const result = await executeCollection("bookmarks", "getAll", {});
|
|
21238
|
-
|
|
20779
|
+
sendResponse6(id, {
|
|
21239
20780
|
success: true,
|
|
21240
20781
|
data: result.data,
|
|
21241
20782
|
count: result.count,
|
|
@@ -21243,7 +20784,7 @@ async function handleGetAll5(id, executeCollection, sendMessage, clientId) {
|
|
|
21243
20784
|
}, sendMessage, clientId);
|
|
21244
20785
|
logger.info(`Retrieved all bookmarks (count: ${result.count})`);
|
|
21245
20786
|
} catch (error) {
|
|
21246
|
-
|
|
20787
|
+
sendResponse6(id, {
|
|
21247
20788
|
success: false,
|
|
21248
20789
|
error: error instanceof Error ? error.message : "Failed to get bookmarks"
|
|
21249
20790
|
}, sendMessage, clientId);
|
|
@@ -21251,7 +20792,7 @@ async function handleGetAll5(id, executeCollection, sendMessage, clientId) {
|
|
|
21251
20792
|
}
|
|
21252
20793
|
async function handleGetOne5(id, bookmarkId, executeCollection, sendMessage, clientId) {
|
|
21253
20794
|
if (!bookmarkId) {
|
|
21254
|
-
|
|
20795
|
+
sendResponse6(id, {
|
|
21255
20796
|
success: false,
|
|
21256
20797
|
error: "Bookmark ID is required"
|
|
21257
20798
|
}, sendMessage, clientId);
|
|
@@ -21259,14 +20800,14 @@ async function handleGetOne5(id, bookmarkId, executeCollection, sendMessage, cli
|
|
|
21259
20800
|
}
|
|
21260
20801
|
try {
|
|
21261
20802
|
const result = await executeCollection("bookmarks", "getOne", { id: bookmarkId });
|
|
21262
|
-
|
|
20803
|
+
sendResponse6(id, {
|
|
21263
20804
|
success: true,
|
|
21264
20805
|
data: result.data,
|
|
21265
20806
|
message: `Retrieved bookmark ID ${bookmarkId}`
|
|
21266
20807
|
}, sendMessage, clientId);
|
|
21267
20808
|
logger.info(`Retrieved bookmark: ID ${bookmarkId}`);
|
|
21268
20809
|
} catch (error) {
|
|
21269
|
-
|
|
20810
|
+
sendResponse6(id, {
|
|
21270
20811
|
success: false,
|
|
21271
20812
|
error: error instanceof Error ? error.message : "Failed to get bookmark"
|
|
21272
20813
|
}, sendMessage, clientId);
|
|
@@ -21279,7 +20820,7 @@ async function handleQuery5(id, filters, limit, sort, executeCollection, sendMes
|
|
|
21279
20820
|
limit,
|
|
21280
20821
|
sort
|
|
21281
20822
|
});
|
|
21282
|
-
|
|
20823
|
+
sendResponse6(id, {
|
|
21283
20824
|
success: true,
|
|
21284
20825
|
data: result.data,
|
|
21285
20826
|
count: result.count,
|
|
@@ -21287,13 +20828,13 @@ async function handleQuery5(id, filters, limit, sort, executeCollection, sendMes
|
|
|
21287
20828
|
}, sendMessage, clientId);
|
|
21288
20829
|
logger.info(`Query returned ${result.count} bookmarks`);
|
|
21289
20830
|
} catch (error) {
|
|
21290
|
-
|
|
20831
|
+
sendResponse6(id, {
|
|
21291
20832
|
success: false,
|
|
21292
20833
|
error: error instanceof Error ? error.message : "Failed to query bookmarks"
|
|
21293
20834
|
}, sendMessage, clientId);
|
|
21294
20835
|
}
|
|
21295
20836
|
}
|
|
21296
|
-
function
|
|
20837
|
+
function sendResponse6(id, res, sendMessage, clientId) {
|
|
21297
20838
|
const response = {
|
|
21298
20839
|
id: id || "unknown",
|
|
21299
20840
|
type: "BOOKMARKS_RES",
|
|
@@ -21360,14 +20901,14 @@ async function handleArtifactsRequest(data, collections, sendMessage) {
|
|
|
21360
20901
|
await handleQuery6(id, { filters, limit, offset, sort }, executeCollection, sendMessage, from.id);
|
|
21361
20902
|
break;
|
|
21362
20903
|
default:
|
|
21363
|
-
|
|
20904
|
+
sendResponse7(id, {
|
|
21364
20905
|
success: false,
|
|
21365
20906
|
error: `Unknown operation: ${operation}`
|
|
21366
20907
|
}, sendMessage, from.id);
|
|
21367
20908
|
}
|
|
21368
20909
|
} catch (error) {
|
|
21369
20910
|
logger.error("Failed to handle artifacts request:", error);
|
|
21370
|
-
|
|
20911
|
+
sendResponse7(null, {
|
|
21371
20912
|
success: false,
|
|
21372
20913
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
21373
20914
|
}, sendMessage);
|
|
@@ -21375,7 +20916,7 @@ async function handleArtifactsRequest(data, collections, sendMessage) {
|
|
|
21375
20916
|
}
|
|
21376
20917
|
async function handleCreate6(id, name, createdBy, dsl, type, filters, status, executeCollection, sendMessage, clientId) {
|
|
21377
20918
|
if (!name) {
|
|
21378
|
-
|
|
20919
|
+
sendResponse7(id, {
|
|
21379
20920
|
success: false,
|
|
21380
20921
|
error: "name is required"
|
|
21381
20922
|
}, sendMessage, clientId);
|
|
@@ -21390,14 +20931,14 @@ async function handleCreate6(id, name, createdBy, dsl, type, filters, status, ex
|
|
|
21390
20931
|
filters,
|
|
21391
20932
|
status
|
|
21392
20933
|
});
|
|
21393
|
-
|
|
20934
|
+
sendResponse7(id, {
|
|
21394
20935
|
success: true,
|
|
21395
20936
|
data: result.data,
|
|
21396
20937
|
message: "Artifact created successfully"
|
|
21397
20938
|
}, sendMessage, clientId);
|
|
21398
20939
|
logger.info(`Artifact created: ID ${result.data.id}`);
|
|
21399
20940
|
} catch (error) {
|
|
21400
|
-
|
|
20941
|
+
sendResponse7(id, {
|
|
21401
20942
|
success: false,
|
|
21402
20943
|
error: error instanceof Error ? error.message : "Failed to create artifact"
|
|
21403
20944
|
}, sendMessage, clientId);
|
|
@@ -21405,7 +20946,7 @@ async function handleCreate6(id, name, createdBy, dsl, type, filters, status, ex
|
|
|
21405
20946
|
}
|
|
21406
20947
|
async function handleUpdate6(id, artifactId, name, dsl, type, filters, status, deleted, executeCollection, sendMessage, clientId) {
|
|
21407
20948
|
if (!artifactId) {
|
|
21408
|
-
|
|
20949
|
+
sendResponse7(id, {
|
|
21409
20950
|
success: false,
|
|
21410
20951
|
error: "Artifact ID is required"
|
|
21411
20952
|
}, sendMessage, clientId);
|
|
@@ -21413,14 +20954,14 @@ async function handleUpdate6(id, artifactId, name, dsl, type, filters, status, d
|
|
|
21413
20954
|
}
|
|
21414
20955
|
try {
|
|
21415
20956
|
const result = await executeCollection("artifacts", "update", { id: artifactId, name, dsl, type, filters, status, deleted });
|
|
21416
|
-
|
|
20957
|
+
sendResponse7(id, {
|
|
21417
20958
|
success: true,
|
|
21418
20959
|
data: result.data,
|
|
21419
20960
|
message: "Artifact updated successfully"
|
|
21420
20961
|
}, sendMessage, clientId);
|
|
21421
20962
|
logger.info(`Artifact updated: ID ${artifactId}`);
|
|
21422
20963
|
} catch (error) {
|
|
21423
|
-
|
|
20964
|
+
sendResponse7(id, {
|
|
21424
20965
|
success: false,
|
|
21425
20966
|
error: error instanceof Error ? error.message : "Failed to update artifact"
|
|
21426
20967
|
}, sendMessage, clientId);
|
|
@@ -21428,7 +20969,7 @@ async function handleUpdate6(id, artifactId, name, dsl, type, filters, status, d
|
|
|
21428
20969
|
}
|
|
21429
20970
|
async function handleDelete6(id, artifactId, executeCollection, sendMessage, clientId) {
|
|
21430
20971
|
if (!artifactId) {
|
|
21431
|
-
|
|
20972
|
+
sendResponse7(id, {
|
|
21432
20973
|
success: false,
|
|
21433
20974
|
error: "Artifact ID is required"
|
|
21434
20975
|
}, sendMessage, clientId);
|
|
@@ -21436,14 +20977,14 @@ async function handleDelete6(id, artifactId, executeCollection, sendMessage, cli
|
|
|
21436
20977
|
}
|
|
21437
20978
|
try {
|
|
21438
20979
|
const result = await executeCollection("artifacts", "delete", { id: artifactId });
|
|
21439
|
-
|
|
20980
|
+
sendResponse7(id, {
|
|
21440
20981
|
success: true,
|
|
21441
20982
|
data: result.data,
|
|
21442
20983
|
message: "Artifact deleted successfully"
|
|
21443
20984
|
}, sendMessage, clientId);
|
|
21444
20985
|
logger.info(`Artifact deleted: ID ${artifactId}`);
|
|
21445
20986
|
} catch (error) {
|
|
21446
|
-
|
|
20987
|
+
sendResponse7(id, {
|
|
21447
20988
|
success: false,
|
|
21448
20989
|
error: error instanceof Error ? error.message : "Failed to delete artifact"
|
|
21449
20990
|
}, sendMessage, clientId);
|
|
@@ -21452,7 +20993,7 @@ async function handleDelete6(id, artifactId, executeCollection, sendMessage, cli
|
|
|
21452
20993
|
async function handleGetAll6(id, limit, executeCollection, sendMessage, clientId) {
|
|
21453
20994
|
try {
|
|
21454
20995
|
const result = await executeCollection("artifacts", "getAll", { limit });
|
|
21455
|
-
|
|
20996
|
+
sendResponse7(id, {
|
|
21456
20997
|
success: true,
|
|
21457
20998
|
data: result.data,
|
|
21458
20999
|
count: result.count,
|
|
@@ -21460,7 +21001,7 @@ async function handleGetAll6(id, limit, executeCollection, sendMessage, clientId
|
|
|
21460
21001
|
}, sendMessage, clientId);
|
|
21461
21002
|
logger.info(`Retrieved all artifacts (count: ${result.count})`);
|
|
21462
21003
|
} catch (error) {
|
|
21463
|
-
|
|
21004
|
+
sendResponse7(id, {
|
|
21464
21005
|
success: false,
|
|
21465
21006
|
error: error instanceof Error ? error.message : "Failed to get artifacts"
|
|
21466
21007
|
}, sendMessage, clientId);
|
|
@@ -21468,7 +21009,7 @@ async function handleGetAll6(id, limit, executeCollection, sendMessage, clientId
|
|
|
21468
21009
|
}
|
|
21469
21010
|
async function handleGetOne6(id, artifactId, executeCollection, sendMessage, clientId) {
|
|
21470
21011
|
if (!artifactId) {
|
|
21471
|
-
|
|
21012
|
+
sendResponse7(id, {
|
|
21472
21013
|
success: false,
|
|
21473
21014
|
error: "Artifact ID is required"
|
|
21474
21015
|
}, sendMessage, clientId);
|
|
@@ -21476,14 +21017,14 @@ async function handleGetOne6(id, artifactId, executeCollection, sendMessage, cli
|
|
|
21476
21017
|
}
|
|
21477
21018
|
try {
|
|
21478
21019
|
const result = await executeCollection("artifacts", "getOne", { id: artifactId });
|
|
21479
|
-
|
|
21020
|
+
sendResponse7(id, {
|
|
21480
21021
|
success: true,
|
|
21481
21022
|
data: result.data,
|
|
21482
21023
|
message: `Retrieved artifact ID ${artifactId}`
|
|
21483
21024
|
}, sendMessage, clientId);
|
|
21484
21025
|
logger.info(`Retrieved artifact: ID ${artifactId}`);
|
|
21485
21026
|
} catch (error) {
|
|
21486
|
-
|
|
21027
|
+
sendResponse7(id, {
|
|
21487
21028
|
success: false,
|
|
21488
21029
|
error: error instanceof Error ? error.message : "Failed to get artifact"
|
|
21489
21030
|
}, sendMessage, clientId);
|
|
@@ -21500,7 +21041,7 @@ async function handleQuery6(id, queryParams, executeCollection, sendMessage, cli
|
|
|
21500
21041
|
sort: queryParams.sort || "DESC"
|
|
21501
21042
|
});
|
|
21502
21043
|
logger.info("[SDK-NODEJS] handleQuery - executeCollection result count:", result.count);
|
|
21503
|
-
|
|
21044
|
+
sendResponse7(id, {
|
|
21504
21045
|
success: true,
|
|
21505
21046
|
data: result.data,
|
|
21506
21047
|
count: result.count,
|
|
@@ -21508,13 +21049,13 @@ async function handleQuery6(id, queryParams, executeCollection, sendMessage, cli
|
|
|
21508
21049
|
}, sendMessage, clientId);
|
|
21509
21050
|
logger.info(`Query artifacts (count: ${result.count})`);
|
|
21510
21051
|
} catch (error) {
|
|
21511
|
-
|
|
21052
|
+
sendResponse7(id, {
|
|
21512
21053
|
success: false,
|
|
21513
21054
|
error: error instanceof Error ? error.message : "Failed to query artifacts"
|
|
21514
21055
|
}, sendMessage, clientId);
|
|
21515
21056
|
}
|
|
21516
21057
|
}
|
|
21517
|
-
function
|
|
21058
|
+
function sendResponse7(id, res, sendMessage, clientId) {
|
|
21518
21059
|
const response = {
|
|
21519
21060
|
id: id || "unknown",
|
|
21520
21061
|
type: "ARTIFACTS_RES",
|
|
@@ -21588,14 +21129,14 @@ async function handleKbNodesRequest(data, collections, sendMessage) {
|
|
|
21588
21129
|
await handleGetTags(id, executeCollection, sendMessage, from.id);
|
|
21589
21130
|
break;
|
|
21590
21131
|
default:
|
|
21591
|
-
|
|
21132
|
+
sendResponse8(id, {
|
|
21592
21133
|
success: false,
|
|
21593
21134
|
error: `Unknown operation: ${operation}`
|
|
21594
21135
|
}, sendMessage, from.id);
|
|
21595
21136
|
}
|
|
21596
21137
|
} catch (error) {
|
|
21597
21138
|
logger.error("Failed to handle KB nodes request:", error);
|
|
21598
|
-
|
|
21139
|
+
sendResponse8(null, {
|
|
21599
21140
|
success: false,
|
|
21600
21141
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
21601
21142
|
}, sendMessage);
|
|
@@ -21604,21 +21145,21 @@ async function handleKbNodesRequest(data, collections, sendMessage) {
|
|
|
21604
21145
|
async function handleCreate7(id, nodeData, executeCollection, sendMessage, clientId) {
|
|
21605
21146
|
const { title, content, category, tags, type, createdBy } = nodeData;
|
|
21606
21147
|
if (!title || title.trim().length === 0) {
|
|
21607
|
-
|
|
21148
|
+
sendResponse8(id, {
|
|
21608
21149
|
success: false,
|
|
21609
21150
|
error: "Title is required and cannot be empty"
|
|
21610
21151
|
}, sendMessage, clientId);
|
|
21611
21152
|
return;
|
|
21612
21153
|
}
|
|
21613
21154
|
if (!content || content.trim().length === 0) {
|
|
21614
|
-
|
|
21155
|
+
sendResponse8(id, {
|
|
21615
21156
|
success: false,
|
|
21616
21157
|
error: "Content is required and cannot be empty"
|
|
21617
21158
|
}, sendMessage, clientId);
|
|
21618
21159
|
return;
|
|
21619
21160
|
}
|
|
21620
21161
|
if (!createdBy) {
|
|
21621
|
-
|
|
21162
|
+
sendResponse8(id, {
|
|
21622
21163
|
success: false,
|
|
21623
21164
|
error: "createdBy (user ID) is required"
|
|
21624
21165
|
}, sendMessage, clientId);
|
|
@@ -21635,7 +21176,7 @@ async function handleCreate7(id, nodeData, executeCollection, sendMessage, clien
|
|
|
21635
21176
|
});
|
|
21636
21177
|
if (result && result.success) {
|
|
21637
21178
|
logger.info(`[DB] KB node created successfully: ${title}`);
|
|
21638
|
-
|
|
21179
|
+
sendResponse8(id, {
|
|
21639
21180
|
success: true,
|
|
21640
21181
|
data: {
|
|
21641
21182
|
...result.data,
|
|
@@ -21644,13 +21185,13 @@ async function handleCreate7(id, nodeData, executeCollection, sendMessage, clien
|
|
|
21644
21185
|
}, sendMessage, clientId);
|
|
21645
21186
|
return;
|
|
21646
21187
|
}
|
|
21647
|
-
|
|
21188
|
+
sendResponse8(id, {
|
|
21648
21189
|
success: false,
|
|
21649
21190
|
error: "Failed to create knowledge node"
|
|
21650
21191
|
}, sendMessage, clientId);
|
|
21651
21192
|
} catch (error) {
|
|
21652
21193
|
logger.error("[DB] Failed to create KB node:", error);
|
|
21653
|
-
|
|
21194
|
+
sendResponse8(id, {
|
|
21654
21195
|
success: false,
|
|
21655
21196
|
error: error instanceof Error ? error.message : "Failed to create knowledge node"
|
|
21656
21197
|
}, sendMessage, clientId);
|
|
@@ -21659,14 +21200,14 @@ async function handleCreate7(id, nodeData, executeCollection, sendMessage, clien
|
|
|
21659
21200
|
async function handleUpdate7(id, nodeId, nodeData, executeCollection, sendMessage, clientId) {
|
|
21660
21201
|
const { title, content, category, tags, type, updatedBy } = nodeData;
|
|
21661
21202
|
if (!nodeId) {
|
|
21662
|
-
|
|
21203
|
+
sendResponse8(id, {
|
|
21663
21204
|
success: false,
|
|
21664
21205
|
error: "Knowledge node ID is required"
|
|
21665
21206
|
}, sendMessage, clientId);
|
|
21666
21207
|
return;
|
|
21667
21208
|
}
|
|
21668
21209
|
if (!updatedBy) {
|
|
21669
|
-
|
|
21210
|
+
sendResponse8(id, {
|
|
21670
21211
|
success: false,
|
|
21671
21212
|
error: "updatedBy (user ID) is required"
|
|
21672
21213
|
}, sendMessage, clientId);
|
|
@@ -21684,7 +21225,7 @@ async function handleUpdate7(id, nodeId, nodeData, executeCollection, sendMessag
|
|
|
21684
21225
|
});
|
|
21685
21226
|
if (result && result.success) {
|
|
21686
21227
|
logger.info(`[DB] KB node updated successfully, ID: ${nodeId}`);
|
|
21687
|
-
|
|
21228
|
+
sendResponse8(id, {
|
|
21688
21229
|
success: true,
|
|
21689
21230
|
data: {
|
|
21690
21231
|
...result.data,
|
|
@@ -21693,13 +21234,13 @@ async function handleUpdate7(id, nodeId, nodeData, executeCollection, sendMessag
|
|
|
21693
21234
|
}, sendMessage, clientId);
|
|
21694
21235
|
return;
|
|
21695
21236
|
}
|
|
21696
|
-
|
|
21237
|
+
sendResponse8(id, {
|
|
21697
21238
|
success: false,
|
|
21698
21239
|
error: "Failed to update knowledge node"
|
|
21699
21240
|
}, sendMessage, clientId);
|
|
21700
21241
|
} catch (error) {
|
|
21701
21242
|
logger.error("[DB] Failed to update KB node:", error);
|
|
21702
|
-
|
|
21243
|
+
sendResponse8(id, {
|
|
21703
21244
|
success: false,
|
|
21704
21245
|
error: error instanceof Error ? error.message : "Failed to update knowledge node"
|
|
21705
21246
|
}, sendMessage, clientId);
|
|
@@ -21707,7 +21248,7 @@ async function handleUpdate7(id, nodeId, nodeData, executeCollection, sendMessag
|
|
|
21707
21248
|
}
|
|
21708
21249
|
async function handleDelete7(id, nodeId, executeCollection, sendMessage, clientId) {
|
|
21709
21250
|
if (!nodeId) {
|
|
21710
|
-
|
|
21251
|
+
sendResponse8(id, {
|
|
21711
21252
|
success: false,
|
|
21712
21253
|
error: "Knowledge node ID is required"
|
|
21713
21254
|
}, sendMessage, clientId);
|
|
@@ -21717,7 +21258,7 @@ async function handleDelete7(id, nodeId, executeCollection, sendMessage, clientI
|
|
|
21717
21258
|
const result = await executeCollection("kbNodes", "delete", { id: nodeId });
|
|
21718
21259
|
if (result && result.success) {
|
|
21719
21260
|
logger.info(`[DB] KB node deleted successfully, ID: ${nodeId}`);
|
|
21720
|
-
|
|
21261
|
+
sendResponse8(id, {
|
|
21721
21262
|
success: true,
|
|
21722
21263
|
data: {
|
|
21723
21264
|
id: nodeId,
|
|
@@ -21727,13 +21268,13 @@ async function handleDelete7(id, nodeId, executeCollection, sendMessage, clientI
|
|
|
21727
21268
|
}, sendMessage, clientId);
|
|
21728
21269
|
return;
|
|
21729
21270
|
}
|
|
21730
|
-
|
|
21271
|
+
sendResponse8(id, {
|
|
21731
21272
|
success: false,
|
|
21732
21273
|
error: "Failed to delete knowledge node"
|
|
21733
21274
|
}, sendMessage, clientId);
|
|
21734
21275
|
} catch (error) {
|
|
21735
21276
|
logger.error("[DB] Failed to delete KB node:", error);
|
|
21736
|
-
|
|
21277
|
+
sendResponse8(id, {
|
|
21737
21278
|
success: false,
|
|
21738
21279
|
error: error instanceof Error ? error.message : "Failed to delete knowledge node"
|
|
21739
21280
|
}, sendMessage, clientId);
|
|
@@ -21747,7 +21288,7 @@ async function handleGetAll7(id, limit, offset, executeCollection, sendMessage,
|
|
|
21747
21288
|
});
|
|
21748
21289
|
if (result && result.success) {
|
|
21749
21290
|
logger.info(`[DB] Retrieved ${result.count} KB nodes`);
|
|
21750
|
-
|
|
21291
|
+
sendResponse8(id, {
|
|
21751
21292
|
success: true,
|
|
21752
21293
|
data: {
|
|
21753
21294
|
nodes: result.data,
|
|
@@ -21757,13 +21298,13 @@ async function handleGetAll7(id, limit, offset, executeCollection, sendMessage,
|
|
|
21757
21298
|
}, sendMessage, clientId);
|
|
21758
21299
|
return;
|
|
21759
21300
|
}
|
|
21760
|
-
|
|
21301
|
+
sendResponse8(id, {
|
|
21761
21302
|
success: false,
|
|
21762
21303
|
error: "Failed to retrieve knowledge nodes"
|
|
21763
21304
|
}, sendMessage, clientId);
|
|
21764
21305
|
} catch (error) {
|
|
21765
21306
|
logger.error("[DB] Failed to get all KB nodes:", error);
|
|
21766
|
-
|
|
21307
|
+
sendResponse8(id, {
|
|
21767
21308
|
success: false,
|
|
21768
21309
|
error: error instanceof Error ? error.message : "Failed to retrieve knowledge nodes"
|
|
21769
21310
|
}, sendMessage, clientId);
|
|
@@ -21771,7 +21312,7 @@ async function handleGetAll7(id, limit, offset, executeCollection, sendMessage,
|
|
|
21771
21312
|
}
|
|
21772
21313
|
async function handleGetOne7(id, nodeId, executeCollection, sendMessage, clientId) {
|
|
21773
21314
|
if (!nodeId) {
|
|
21774
|
-
|
|
21315
|
+
sendResponse8(id, {
|
|
21775
21316
|
success: false,
|
|
21776
21317
|
error: "Knowledge node ID is required"
|
|
21777
21318
|
}, sendMessage, clientId);
|
|
@@ -21781,7 +21322,7 @@ async function handleGetOne7(id, nodeId, executeCollection, sendMessage, clientI
|
|
|
21781
21322
|
const result = await executeCollection("kbNodes", "getOne", { id: nodeId });
|
|
21782
21323
|
if (result && result.success) {
|
|
21783
21324
|
logger.info(`[DB] Retrieved KB node ID: ${nodeId}`);
|
|
21784
|
-
|
|
21325
|
+
sendResponse8(id, {
|
|
21785
21326
|
success: true,
|
|
21786
21327
|
data: {
|
|
21787
21328
|
node: result.data,
|
|
@@ -21790,13 +21331,13 @@ async function handleGetOne7(id, nodeId, executeCollection, sendMessage, clientI
|
|
|
21790
21331
|
}, sendMessage, clientId);
|
|
21791
21332
|
return;
|
|
21792
21333
|
}
|
|
21793
|
-
|
|
21334
|
+
sendResponse8(id, {
|
|
21794
21335
|
success: false,
|
|
21795
21336
|
error: "Failed to retrieve knowledge node"
|
|
21796
21337
|
}, sendMessage, clientId);
|
|
21797
21338
|
} catch (error) {
|
|
21798
21339
|
logger.error("[DB] Failed to get KB node:", error);
|
|
21799
|
-
|
|
21340
|
+
sendResponse8(id, {
|
|
21800
21341
|
success: false,
|
|
21801
21342
|
error: error instanceof Error ? error.message : "Failed to retrieve knowledge node"
|
|
21802
21343
|
}, sendMessage, clientId);
|
|
@@ -21816,7 +21357,7 @@ async function handleSearch(id, searchParams, executeCollection, sendMessage, cl
|
|
|
21816
21357
|
});
|
|
21817
21358
|
if (result && result.success) {
|
|
21818
21359
|
logger.info(`[DB] Search returned ${result.count} KB nodes`);
|
|
21819
|
-
|
|
21360
|
+
sendResponse8(id, {
|
|
21820
21361
|
success: true,
|
|
21821
21362
|
data: {
|
|
21822
21363
|
nodes: result.data,
|
|
@@ -21826,13 +21367,13 @@ async function handleSearch(id, searchParams, executeCollection, sendMessage, cl
|
|
|
21826
21367
|
}, sendMessage, clientId);
|
|
21827
21368
|
return;
|
|
21828
21369
|
}
|
|
21829
|
-
|
|
21370
|
+
sendResponse8(id, {
|
|
21830
21371
|
success: false,
|
|
21831
21372
|
error: "Failed to search knowledge nodes"
|
|
21832
21373
|
}, sendMessage, clientId);
|
|
21833
21374
|
} catch (error) {
|
|
21834
21375
|
logger.error("[DB] Failed to search KB nodes:", error);
|
|
21835
|
-
|
|
21376
|
+
sendResponse8(id, {
|
|
21836
21377
|
success: false,
|
|
21837
21378
|
error: error instanceof Error ? error.message : "Failed to search knowledge nodes"
|
|
21838
21379
|
}, sendMessage, clientId);
|
|
@@ -21840,7 +21381,7 @@ async function handleSearch(id, searchParams, executeCollection, sendMessage, cl
|
|
|
21840
21381
|
}
|
|
21841
21382
|
async function handleGetByCategory(id, category, limit, offset, executeCollection, sendMessage, clientId) {
|
|
21842
21383
|
if (!category) {
|
|
21843
|
-
|
|
21384
|
+
sendResponse8(id, {
|
|
21844
21385
|
success: false,
|
|
21845
21386
|
error: "Category is required"
|
|
21846
21387
|
}, sendMessage, clientId);
|
|
@@ -21854,7 +21395,7 @@ async function handleGetByCategory(id, category, limit, offset, executeCollectio
|
|
|
21854
21395
|
});
|
|
21855
21396
|
if (result && result.success) {
|
|
21856
21397
|
logger.info(`[DB] Retrieved ${result.count} KB nodes for category: ${category}`);
|
|
21857
|
-
|
|
21398
|
+
sendResponse8(id, {
|
|
21858
21399
|
success: true,
|
|
21859
21400
|
data: {
|
|
21860
21401
|
nodes: result.data,
|
|
@@ -21865,13 +21406,13 @@ async function handleGetByCategory(id, category, limit, offset, executeCollectio
|
|
|
21865
21406
|
}, sendMessage, clientId);
|
|
21866
21407
|
return;
|
|
21867
21408
|
}
|
|
21868
|
-
|
|
21409
|
+
sendResponse8(id, {
|
|
21869
21410
|
success: false,
|
|
21870
21411
|
error: "Failed to retrieve knowledge nodes by category"
|
|
21871
21412
|
}, sendMessage, clientId);
|
|
21872
21413
|
} catch (error) {
|
|
21873
21414
|
logger.error("[DB] Failed to get KB nodes by category:", error);
|
|
21874
|
-
|
|
21415
|
+
sendResponse8(id, {
|
|
21875
21416
|
success: false,
|
|
21876
21417
|
error: error instanceof Error ? error.message : "Failed to retrieve knowledge nodes by category"
|
|
21877
21418
|
}, sendMessage, clientId);
|
|
@@ -21879,7 +21420,7 @@ async function handleGetByCategory(id, category, limit, offset, executeCollectio
|
|
|
21879
21420
|
}
|
|
21880
21421
|
async function handleGetByUser(id, userId, limit, offset, executeCollection, sendMessage, clientId) {
|
|
21881
21422
|
if (!userId) {
|
|
21882
|
-
|
|
21423
|
+
sendResponse8(id, {
|
|
21883
21424
|
success: false,
|
|
21884
21425
|
error: "User ID is required"
|
|
21885
21426
|
}, sendMessage, clientId);
|
|
@@ -21893,7 +21434,7 @@ async function handleGetByUser(id, userId, limit, offset, executeCollection, sen
|
|
|
21893
21434
|
});
|
|
21894
21435
|
if (result && result.success) {
|
|
21895
21436
|
logger.info(`[DB] Retrieved ${result.count} KB nodes for user: ${userId}`);
|
|
21896
|
-
|
|
21437
|
+
sendResponse8(id, {
|
|
21897
21438
|
success: true,
|
|
21898
21439
|
data: {
|
|
21899
21440
|
nodes: result.data,
|
|
@@ -21904,13 +21445,13 @@ async function handleGetByUser(id, userId, limit, offset, executeCollection, sen
|
|
|
21904
21445
|
}, sendMessage, clientId);
|
|
21905
21446
|
return;
|
|
21906
21447
|
}
|
|
21907
|
-
|
|
21448
|
+
sendResponse8(id, {
|
|
21908
21449
|
success: false,
|
|
21909
21450
|
error: "Failed to retrieve knowledge nodes by user"
|
|
21910
21451
|
}, sendMessage, clientId);
|
|
21911
21452
|
} catch (error) {
|
|
21912
21453
|
logger.error("[DB] Failed to get KB nodes by user:", error);
|
|
21913
|
-
|
|
21454
|
+
sendResponse8(id, {
|
|
21914
21455
|
success: false,
|
|
21915
21456
|
error: error instanceof Error ? error.message : "Failed to retrieve knowledge nodes by user"
|
|
21916
21457
|
}, sendMessage, clientId);
|
|
@@ -21921,7 +21462,7 @@ async function handleGetCategories(id, executeCollection, sendMessage, clientId)
|
|
|
21921
21462
|
const result = await executeCollection("kbNodes", "getCategories", {});
|
|
21922
21463
|
if (result && result.success) {
|
|
21923
21464
|
logger.info(`[DB] Retrieved ${result.count} categories`);
|
|
21924
|
-
|
|
21465
|
+
sendResponse8(id, {
|
|
21925
21466
|
success: true,
|
|
21926
21467
|
data: {
|
|
21927
21468
|
categories: result.data,
|
|
@@ -21931,13 +21472,13 @@ async function handleGetCategories(id, executeCollection, sendMessage, clientId)
|
|
|
21931
21472
|
}, sendMessage, clientId);
|
|
21932
21473
|
return;
|
|
21933
21474
|
}
|
|
21934
|
-
|
|
21475
|
+
sendResponse8(id, {
|
|
21935
21476
|
success: false,
|
|
21936
21477
|
error: "Failed to retrieve categories"
|
|
21937
21478
|
}, sendMessage, clientId);
|
|
21938
21479
|
} catch (error) {
|
|
21939
21480
|
logger.error("[DB] Failed to get categories:", error);
|
|
21940
|
-
|
|
21481
|
+
sendResponse8(id, {
|
|
21941
21482
|
success: false,
|
|
21942
21483
|
error: error instanceof Error ? error.message : "Failed to retrieve categories"
|
|
21943
21484
|
}, sendMessage, clientId);
|
|
@@ -21948,7 +21489,7 @@ async function handleGetTags(id, executeCollection, sendMessage, clientId) {
|
|
|
21948
21489
|
const result = await executeCollection("kbNodes", "getTags", {});
|
|
21949
21490
|
if (result && result.success) {
|
|
21950
21491
|
logger.info(`[DB] Retrieved ${result.count} tags`);
|
|
21951
|
-
|
|
21492
|
+
sendResponse8(id, {
|
|
21952
21493
|
success: true,
|
|
21953
21494
|
data: {
|
|
21954
21495
|
tags: result.data,
|
|
@@ -21958,19 +21499,19 @@ async function handleGetTags(id, executeCollection, sendMessage, clientId) {
|
|
|
21958
21499
|
}, sendMessage, clientId);
|
|
21959
21500
|
return;
|
|
21960
21501
|
}
|
|
21961
|
-
|
|
21502
|
+
sendResponse8(id, {
|
|
21962
21503
|
success: false,
|
|
21963
21504
|
error: "Failed to retrieve tags"
|
|
21964
21505
|
}, sendMessage, clientId);
|
|
21965
21506
|
} catch (error) {
|
|
21966
21507
|
logger.error("[DB] Failed to get tags:", error);
|
|
21967
|
-
|
|
21508
|
+
sendResponse8(id, {
|
|
21968
21509
|
success: false,
|
|
21969
21510
|
error: error instanceof Error ? error.message : "Failed to retrieve tags"
|
|
21970
21511
|
}, sendMessage, clientId);
|
|
21971
21512
|
}
|
|
21972
21513
|
}
|
|
21973
|
-
function
|
|
21514
|
+
function sendResponse8(id, res, sendMessage, clientId) {
|
|
21974
21515
|
const response = {
|
|
21975
21516
|
id: id || "unknown",
|
|
21976
21517
|
type: "KB_NODES_RES",
|
|
@@ -22044,14 +21585,14 @@ async function handleMenusRequest(data, collections, sendMessage) {
|
|
|
22044
21585
|
await handleReorder(id, items, executeCollection, sendMessage, from.id);
|
|
22045
21586
|
break;
|
|
22046
21587
|
default:
|
|
22047
|
-
|
|
21588
|
+
sendResponse9(id, {
|
|
22048
21589
|
success: false,
|
|
22049
21590
|
error: `Unknown operation: ${operation}`
|
|
22050
21591
|
}, sendMessage, from.id);
|
|
22051
21592
|
}
|
|
22052
21593
|
} catch (error) {
|
|
22053
21594
|
logger.error("Failed to handle menus request:", error);
|
|
22054
|
-
|
|
21595
|
+
sendResponse9(null, {
|
|
22055
21596
|
success: false,
|
|
22056
21597
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
22057
21598
|
}, sendMessage);
|
|
@@ -22059,14 +21600,14 @@ async function handleMenusRequest(data, collections, sendMessage) {
|
|
|
22059
21600
|
}
|
|
22060
21601
|
async function handleCreate8(id, name, componentName, icon, userMessage, parentId, sortOrder, props, isActive, executeCollection, sendMessage, clientId) {
|
|
22061
21602
|
if (!name) {
|
|
22062
|
-
|
|
21603
|
+
sendResponse9(id, {
|
|
22063
21604
|
success: false,
|
|
22064
21605
|
error: "name is required"
|
|
22065
21606
|
}, sendMessage, clientId);
|
|
22066
21607
|
return;
|
|
22067
21608
|
}
|
|
22068
21609
|
if (!componentName) {
|
|
22069
|
-
|
|
21610
|
+
sendResponse9(id, {
|
|
22070
21611
|
success: false,
|
|
22071
21612
|
error: "componentName is required"
|
|
22072
21613
|
}, sendMessage, clientId);
|
|
@@ -22083,14 +21624,14 @@ async function handleCreate8(id, name, componentName, icon, userMessage, parentI
|
|
|
22083
21624
|
props,
|
|
22084
21625
|
isActive
|
|
22085
21626
|
});
|
|
22086
|
-
|
|
21627
|
+
sendResponse9(id, {
|
|
22087
21628
|
success: true,
|
|
22088
21629
|
data: result.data,
|
|
22089
21630
|
message: "Menu created successfully"
|
|
22090
21631
|
}, sendMessage, clientId);
|
|
22091
21632
|
logger.info(`Menu created: ID ${result.data?.id}`);
|
|
22092
21633
|
} catch (error) {
|
|
22093
|
-
|
|
21634
|
+
sendResponse9(id, {
|
|
22094
21635
|
success: false,
|
|
22095
21636
|
error: error instanceof Error ? error.message : "Failed to create menu"
|
|
22096
21637
|
}, sendMessage, clientId);
|
|
@@ -22098,7 +21639,7 @@ async function handleCreate8(id, name, componentName, icon, userMessage, parentI
|
|
|
22098
21639
|
}
|
|
22099
21640
|
async function handleUpdate8(id, menuId, name, componentName, icon, userMessage, parentId, sortOrder, props, isActive, executeCollection, sendMessage, clientId) {
|
|
22100
21641
|
if (!menuId) {
|
|
22101
|
-
|
|
21642
|
+
sendResponse9(id, {
|
|
22102
21643
|
success: false,
|
|
22103
21644
|
error: "Menu ID is required"
|
|
22104
21645
|
}, sendMessage, clientId);
|
|
@@ -22116,14 +21657,14 @@ async function handleUpdate8(id, menuId, name, componentName, icon, userMessage,
|
|
|
22116
21657
|
props,
|
|
22117
21658
|
isActive
|
|
22118
21659
|
});
|
|
22119
|
-
|
|
21660
|
+
sendResponse9(id, {
|
|
22120
21661
|
success: true,
|
|
22121
21662
|
data: result.data,
|
|
22122
21663
|
message: "Menu updated successfully"
|
|
22123
21664
|
}, sendMessage, clientId);
|
|
22124
21665
|
logger.info(`Menu updated: ID ${menuId}`);
|
|
22125
21666
|
} catch (error) {
|
|
22126
|
-
|
|
21667
|
+
sendResponse9(id, {
|
|
22127
21668
|
success: false,
|
|
22128
21669
|
error: error instanceof Error ? error.message : "Failed to update menu"
|
|
22129
21670
|
}, sendMessage, clientId);
|
|
@@ -22131,7 +21672,7 @@ async function handleUpdate8(id, menuId, name, componentName, icon, userMessage,
|
|
|
22131
21672
|
}
|
|
22132
21673
|
async function handleDelete8(id, menuId, executeCollection, sendMessage, clientId) {
|
|
22133
21674
|
if (!menuId) {
|
|
22134
|
-
|
|
21675
|
+
sendResponse9(id, {
|
|
22135
21676
|
success: false,
|
|
22136
21677
|
error: "Menu ID is required"
|
|
22137
21678
|
}, sendMessage, clientId);
|
|
@@ -22139,14 +21680,14 @@ async function handleDelete8(id, menuId, executeCollection, sendMessage, clientI
|
|
|
22139
21680
|
}
|
|
22140
21681
|
try {
|
|
22141
21682
|
const result = await executeCollection("menus", "delete", { id: menuId });
|
|
22142
|
-
|
|
21683
|
+
sendResponse9(id, {
|
|
22143
21684
|
success: true,
|
|
22144
21685
|
data: result.data,
|
|
22145
21686
|
message: "Menu deleted successfully"
|
|
22146
21687
|
}, sendMessage, clientId);
|
|
22147
21688
|
logger.info(`Menu deleted: ID ${menuId}`);
|
|
22148
21689
|
} catch (error) {
|
|
22149
|
-
|
|
21690
|
+
sendResponse9(id, {
|
|
22150
21691
|
success: false,
|
|
22151
21692
|
error: error instanceof Error ? error.message : "Failed to delete menu"
|
|
22152
21693
|
}, sendMessage, clientId);
|
|
@@ -22155,7 +21696,7 @@ async function handleDelete8(id, menuId, executeCollection, sendMessage, clientI
|
|
|
22155
21696
|
async function handleGetAll8(id, executeCollection, sendMessage, clientId) {
|
|
22156
21697
|
try {
|
|
22157
21698
|
const result = await executeCollection("menus", "getAll", {});
|
|
22158
|
-
|
|
21699
|
+
sendResponse9(id, {
|
|
22159
21700
|
success: true,
|
|
22160
21701
|
data: result.data,
|
|
22161
21702
|
count: result.count,
|
|
@@ -22163,7 +21704,7 @@ async function handleGetAll8(id, executeCollection, sendMessage, clientId) {
|
|
|
22163
21704
|
}, sendMessage, clientId);
|
|
22164
21705
|
logger.info(`Retrieved all menus (count: ${result.count})`);
|
|
22165
21706
|
} catch (error) {
|
|
22166
|
-
|
|
21707
|
+
sendResponse9(id, {
|
|
22167
21708
|
success: false,
|
|
22168
21709
|
error: error instanceof Error ? error.message : "Failed to get menus"
|
|
22169
21710
|
}, sendMessage, clientId);
|
|
@@ -22171,7 +21712,7 @@ async function handleGetAll8(id, executeCollection, sendMessage, clientId) {
|
|
|
22171
21712
|
}
|
|
22172
21713
|
async function handleGetOne8(id, menuId, executeCollection, sendMessage, clientId) {
|
|
22173
21714
|
if (!menuId) {
|
|
22174
|
-
|
|
21715
|
+
sendResponse9(id, {
|
|
22175
21716
|
success: false,
|
|
22176
21717
|
error: "Menu ID is required"
|
|
22177
21718
|
}, sendMessage, clientId);
|
|
@@ -22179,14 +21720,14 @@ async function handleGetOne8(id, menuId, executeCollection, sendMessage, clientI
|
|
|
22179
21720
|
}
|
|
22180
21721
|
try {
|
|
22181
21722
|
const result = await executeCollection("menus", "getOne", { id: menuId });
|
|
22182
|
-
|
|
21723
|
+
sendResponse9(id, {
|
|
22183
21724
|
success: true,
|
|
22184
21725
|
data: result.data,
|
|
22185
21726
|
message: `Retrieved menu ID ${menuId}`
|
|
22186
21727
|
}, sendMessage, clientId);
|
|
22187
21728
|
logger.info(`Retrieved menu: ID ${menuId}`);
|
|
22188
21729
|
} catch (error) {
|
|
22189
|
-
|
|
21730
|
+
sendResponse9(id, {
|
|
22190
21731
|
success: false,
|
|
22191
21732
|
error: error instanceof Error ? error.message : "Failed to get menu"
|
|
22192
21733
|
}, sendMessage, clientId);
|
|
@@ -22195,7 +21736,7 @@ async function handleGetOne8(id, menuId, executeCollection, sendMessage, clientI
|
|
|
22195
21736
|
async function handleGetRootMenus(id, executeCollection, sendMessage, clientId) {
|
|
22196
21737
|
try {
|
|
22197
21738
|
const result = await executeCollection("menus", "getRootMenus", {});
|
|
22198
|
-
|
|
21739
|
+
sendResponse9(id, {
|
|
22199
21740
|
success: true,
|
|
22200
21741
|
data: result.data,
|
|
22201
21742
|
count: result.count,
|
|
@@ -22203,7 +21744,7 @@ async function handleGetRootMenus(id, executeCollection, sendMessage, clientId)
|
|
|
22203
21744
|
}, sendMessage, clientId);
|
|
22204
21745
|
logger.info(`Retrieved root menus (count: ${result.count})`);
|
|
22205
21746
|
} catch (error) {
|
|
22206
|
-
|
|
21747
|
+
sendResponse9(id, {
|
|
22207
21748
|
success: false,
|
|
22208
21749
|
error: error instanceof Error ? error.message : "Failed to get root menus"
|
|
22209
21750
|
}, sendMessage, clientId);
|
|
@@ -22211,7 +21752,7 @@ async function handleGetRootMenus(id, executeCollection, sendMessage, clientId)
|
|
|
22211
21752
|
}
|
|
22212
21753
|
async function handleGetChildMenus(id, parentId, executeCollection, sendMessage, clientId) {
|
|
22213
21754
|
if (parentId === void 0 || parentId === null) {
|
|
22214
|
-
|
|
21755
|
+
sendResponse9(id, {
|
|
22215
21756
|
success: false,
|
|
22216
21757
|
error: "parentId is required"
|
|
22217
21758
|
}, sendMessage, clientId);
|
|
@@ -22219,7 +21760,7 @@ async function handleGetChildMenus(id, parentId, executeCollection, sendMessage,
|
|
|
22219
21760
|
}
|
|
22220
21761
|
try {
|
|
22221
21762
|
const result = await executeCollection("menus", "getChildMenus", { parentId });
|
|
22222
|
-
|
|
21763
|
+
sendResponse9(id, {
|
|
22223
21764
|
success: true,
|
|
22224
21765
|
data: result.data,
|
|
22225
21766
|
count: result.count,
|
|
@@ -22227,7 +21768,7 @@ async function handleGetChildMenus(id, parentId, executeCollection, sendMessage,
|
|
|
22227
21768
|
}, sendMessage, clientId);
|
|
22228
21769
|
logger.info(`Retrieved child menus for parent ${parentId} (count: ${result.count})`);
|
|
22229
21770
|
} catch (error) {
|
|
22230
|
-
|
|
21771
|
+
sendResponse9(id, {
|
|
22231
21772
|
success: false,
|
|
22232
21773
|
error: error instanceof Error ? error.message : "Failed to get child menus"
|
|
22233
21774
|
}, sendMessage, clientId);
|
|
@@ -22236,7 +21777,7 @@ async function handleGetChildMenus(id, parentId, executeCollection, sendMessage,
|
|
|
22236
21777
|
async function handleGetHierarchy(id, executeCollection, sendMessage, clientId) {
|
|
22237
21778
|
try {
|
|
22238
21779
|
const result = await executeCollection("menus", "getHierarchy", {});
|
|
22239
|
-
|
|
21780
|
+
sendResponse9(id, {
|
|
22240
21781
|
success: true,
|
|
22241
21782
|
data: result.data,
|
|
22242
21783
|
count: result.count,
|
|
@@ -22244,7 +21785,7 @@ async function handleGetHierarchy(id, executeCollection, sendMessage, clientId)
|
|
|
22244
21785
|
}, sendMessage, clientId);
|
|
22245
21786
|
logger.info(`Retrieved menus hierarchy (root count: ${result.count})`);
|
|
22246
21787
|
} catch (error) {
|
|
22247
|
-
|
|
21788
|
+
sendResponse9(id, {
|
|
22248
21789
|
success: false,
|
|
22249
21790
|
error: error instanceof Error ? error.message : "Failed to get menus hierarchy"
|
|
22250
21791
|
}, sendMessage, clientId);
|
|
@@ -22257,7 +21798,7 @@ async function handleQuery7(id, filters, limit, sort, executeCollection, sendMes
|
|
|
22257
21798
|
limit,
|
|
22258
21799
|
sort
|
|
22259
21800
|
});
|
|
22260
|
-
|
|
21801
|
+
sendResponse9(id, {
|
|
22261
21802
|
success: true,
|
|
22262
21803
|
data: result.data,
|
|
22263
21804
|
count: result.count,
|
|
@@ -22265,7 +21806,7 @@ async function handleQuery7(id, filters, limit, sort, executeCollection, sendMes
|
|
|
22265
21806
|
}, sendMessage, clientId);
|
|
22266
21807
|
logger.info(`Query returned ${result.count} menus`);
|
|
22267
21808
|
} catch (error) {
|
|
22268
|
-
|
|
21809
|
+
sendResponse9(id, {
|
|
22269
21810
|
success: false,
|
|
22270
21811
|
error: error instanceof Error ? error.message : "Failed to query menus"
|
|
22271
21812
|
}, sendMessage, clientId);
|
|
@@ -22273,7 +21814,7 @@ async function handleQuery7(id, filters, limit, sort, executeCollection, sendMes
|
|
|
22273
21814
|
}
|
|
22274
21815
|
async function handleReorder(id, items, executeCollection, sendMessage, clientId) {
|
|
22275
21816
|
if (!items || !Array.isArray(items) || items.length === 0) {
|
|
22276
|
-
|
|
21817
|
+
sendResponse9(id, {
|
|
22277
21818
|
success: false,
|
|
22278
21819
|
error: "items array is required"
|
|
22279
21820
|
}, sendMessage, clientId);
|
|
@@ -22281,20 +21822,20 @@ async function handleReorder(id, items, executeCollection, sendMessage, clientId
|
|
|
22281
21822
|
}
|
|
22282
21823
|
try {
|
|
22283
21824
|
const result = await executeCollection("menus", "reorder", { items });
|
|
22284
|
-
|
|
21825
|
+
sendResponse9(id, {
|
|
22285
21826
|
success: true,
|
|
22286
21827
|
data: result.data,
|
|
22287
21828
|
message: `Reordered ${items.length} menus successfully`
|
|
22288
21829
|
}, sendMessage, clientId);
|
|
22289
21830
|
logger.info(`Reordered ${items.length} menus`);
|
|
22290
21831
|
} catch (error) {
|
|
22291
|
-
|
|
21832
|
+
sendResponse9(id, {
|
|
22292
21833
|
success: false,
|
|
22293
21834
|
error: error instanceof Error ? error.message : "Failed to reorder menus"
|
|
22294
21835
|
}, sendMessage, clientId);
|
|
22295
21836
|
}
|
|
22296
21837
|
}
|
|
22297
|
-
function
|
|
21838
|
+
function sendResponse9(id, res, sendMessage, clientId) {
|
|
22298
21839
|
const response = {
|
|
22299
21840
|
id: id || "unknown",
|
|
22300
21841
|
type: "MENUS_RES",
|
|
@@ -24063,13 +23604,14 @@ async function runCodingAgent(agentId, options = {}) {
|
|
|
24063
23604
|
const policy = def.session ?? {};
|
|
24064
23605
|
const persistentWorkspace = policy.workspace === "persistent";
|
|
24065
23606
|
const persistentSession = policy.scope === "persistent";
|
|
23607
|
+
const runAsJob = !(options.chat === true && def.mode === "task");
|
|
24066
23608
|
const { key: scopeKey, dirName } = resolveScope(def, { userId: options.userId, threadId: options.threadId });
|
|
24067
23609
|
const scopeDir = path9.join(agentDir, dirName);
|
|
24068
23610
|
const dir = options.workspaceDir || (persistentWorkspace ? scopeDir : path9.join(scopeDir, "runs", runId));
|
|
24069
23611
|
fs8.mkdirSync(dir, { recursive: true });
|
|
24070
23612
|
if (persistentWorkspace && !options.workspaceDir) {
|
|
24071
23613
|
fs8.mkdirSync(path9.join(dir, "memory"), { recursive: true });
|
|
24072
|
-
await clearTransient(dir);
|
|
23614
|
+
if (runAsJob) await clearTransient(dir);
|
|
24073
23615
|
}
|
|
24074
23616
|
const lockKey = persistentWorkspace || persistentSession ? `${def.id}:${scopeKey}` : `dir:${dir}`;
|
|
24075
23617
|
if (inFlight.has(lockKey)) {
|
|
@@ -24124,10 +23666,12 @@ async function runCodingAgent(agentId, options = {}) {
|
|
|
24124
23666
|
};
|
|
24125
23667
|
try {
|
|
24126
23668
|
await installInstructions(def, ws);
|
|
24127
|
-
if (def.prepare) await def.prepare(ws, input, ctx);
|
|
24128
|
-
const outputPath = def.output ? ws.pathTo(def.output.file) : void 0;
|
|
23669
|
+
if (def.prepare && runAsJob) await def.prepare(ws, input, ctx);
|
|
23670
|
+
const outputPath = runAsJob && def.output ? ws.pathTo(def.output.file) : void 0;
|
|
24129
23671
|
if (outputPath) await fsp.rm(outputPath, { force: true });
|
|
24130
|
-
const prompt = options.prompt ??
|
|
23672
|
+
const prompt = options.prompt ?? // buildPrompt may read what prepare() wrote, so it is only asked when
|
|
23673
|
+
// prepare() actually ran.
|
|
23674
|
+
(runAsJob && def.buildPrompt ? await def.buildPrompt(ws, input, ctx) : outputPath ? `Carry out the task described in AGENTS.md. Write your finished result to this exact absolute path: ${outputPath}` : "Carry out the task described in AGENTS.md.");
|
|
24131
23675
|
const tools = { ...cfg.sharedTools ?? {}, ...def.tools ?? {} };
|
|
24132
23676
|
const session = createCodingAgentSession(def.harness || cfg.harness, {
|
|
24133
23677
|
cwd: dir,
|
|
@@ -24178,7 +23722,7 @@ async function runCodingAgent(agentId, options = {}) {
|
|
|
24178
23722
|
return record;
|
|
24179
23723
|
}
|
|
24180
23724
|
const successStatus = result.status === "early" ? "early" : "completed";
|
|
24181
|
-
if (!def.output) {
|
|
23725
|
+
if (!def.output || !runAsJob) {
|
|
24182
23726
|
record.status = successStatus;
|
|
24183
23727
|
return record;
|
|
24184
23728
|
}
|
|
@@ -24207,7 +23751,7 @@ async function runCodingAgent(agentId, options = {}) {
|
|
|
24207
23751
|
} finally {
|
|
24208
23752
|
inFlight.delete(lockKey);
|
|
24209
23753
|
logger.info(
|
|
24210
|
-
`[CodingAgent:${def.id}] run=${runId} status=${record.status} ms=${record.ms} tokens=${record.usage.inputTokens}/${record.usage.outputTokens} tools=${record.usage.toolCalls}` + (record.applied ? ` applied="${record.applied.summary}"` : "") + (record.error ? ` error="${record.error}"` : "")
|
|
23754
|
+
`[CodingAgent:${def.id}] ${runAsJob ? "run" : "chat"}=${runId} status=${record.status} ms=${record.ms} tokens=${record.usage.inputTokens}/${record.usage.outputTokens} tools=${record.usage.toolCalls}` + (record.applied ? ` applied="${record.applied.summary}"` : "") + (record.error ? ` error="${record.error}"` : "")
|
|
24211
23755
|
);
|
|
24212
23756
|
if (!options.workspaceDir && !persistentWorkspace) await pruneRuns(path9.join(scopeDir, "runs"), cfg.keepRuns);
|
|
24213
23757
|
}
|
|
@@ -24321,15 +23865,30 @@ console.log(${JSON.stringify(JSON.stringify(opts.sources, null, 2))});
|
|
|
24321
23865
|
// src/codingAgent/triggers.ts
|
|
24322
23866
|
import * as fs10 from "fs";
|
|
24323
23867
|
import * as path10 from "path";
|
|
23868
|
+
var EVENT_BURST_CAP = 200;
|
|
23869
|
+
var capEvents = (events) => events.length > EVENT_BURST_CAP ? events.slice(-EVENT_BURST_CAP) : events;
|
|
24324
23870
|
function statePath2(agentId) {
|
|
24325
23871
|
return path10.join(getCodingAgentsConfig().runtimeDir, agentId, "_triggers.json");
|
|
24326
23872
|
}
|
|
24327
23873
|
function loadTriggerState(agentId) {
|
|
23874
|
+
let raw;
|
|
24328
23875
|
try {
|
|
24329
|
-
|
|
23876
|
+
raw = JSON.parse(fs10.readFileSync(statePath2(agentId), "utf-8"));
|
|
24330
23877
|
} catch {
|
|
24331
|
-
return { counts: {} };
|
|
23878
|
+
return { counts: {}, pending: {} };
|
|
23879
|
+
}
|
|
23880
|
+
const counts = {};
|
|
23881
|
+
for (const [name, value] of Object.entries(raw?.counts ?? {})) {
|
|
23882
|
+
if (Array.isArray(value)) counts[name] = value;
|
|
23883
|
+
else if (typeof value === "number" && value > 0) counts[name] = Array.from({ length: value }, () => ({ name }));
|
|
23884
|
+
}
|
|
23885
|
+
const pending = {};
|
|
23886
|
+
if (raw?.pending && typeof raw.pending === "object" && !Array.isArray(raw.pending)) {
|
|
23887
|
+
for (const [key, value] of Object.entries(raw.pending)) {
|
|
23888
|
+
if (Array.isArray(value)) pending[key] = value;
|
|
23889
|
+
}
|
|
24332
23890
|
}
|
|
23891
|
+
return { counts, pending, lastRunAt: raw?.lastRunAt };
|
|
24333
23892
|
}
|
|
24334
23893
|
function saveTriggerState(agentId, state) {
|
|
24335
23894
|
try {
|
|
@@ -24343,6 +23902,7 @@ function saveTriggerState(agentId, state) {
|
|
|
24343
23902
|
var asArray = (t) => !t ? [] : Array.isArray(t) ? t : [t];
|
|
24344
23903
|
var intervals = /* @__PURE__ */ new Map();
|
|
24345
23904
|
var debounces = /* @__PURE__ */ new Map();
|
|
23905
|
+
var bursts = /* @__PURE__ */ new Map();
|
|
24346
23906
|
var firing = /* @__PURE__ */ new Set();
|
|
24347
23907
|
var listeners = [];
|
|
24348
23908
|
function onAgentRun(fn) {
|
|
@@ -24352,21 +23912,38 @@ function onAgentRun(fn) {
|
|
|
24352
23912
|
if (i >= 0) listeners.splice(i, 1);
|
|
24353
23913
|
};
|
|
24354
23914
|
}
|
|
24355
|
-
|
|
23915
|
+
function inputFor(trigger, events) {
|
|
23916
|
+
const build = trigger?.buildInput;
|
|
23917
|
+
const lastPayload = () => events.length ? events[events.length - 1].payload : void 0;
|
|
23918
|
+
if (!build) return lastPayload();
|
|
23919
|
+
try {
|
|
23920
|
+
return build(events);
|
|
23921
|
+
} catch (err) {
|
|
23922
|
+
logger.error(`[CodingAgent] buildInput threw, falling back to the last payload: ${err?.message ?? err}`);
|
|
23923
|
+
return lastPayload();
|
|
23924
|
+
}
|
|
23925
|
+
}
|
|
23926
|
+
async function fire(agentId, triggerIndex, reason, events = []) {
|
|
24356
23927
|
if (firing.has(agentId)) {
|
|
24357
|
-
const
|
|
24358
|
-
|
|
24359
|
-
|
|
23928
|
+
const st2 = loadTriggerState(agentId);
|
|
23929
|
+
const key = String(triggerIndex);
|
|
23930
|
+
saveTriggerState(agentId, {
|
|
23931
|
+
...st2,
|
|
23932
|
+
pending: { ...st2.pending, [key]: capEvents([...st2.pending[key] ?? [], ...events]) }
|
|
23933
|
+
});
|
|
23934
|
+
logger.info(`[CodingAgent:${agentId}] ${reason} arrived mid-run \u2014 queued (${events.length} event(s))`);
|
|
24360
23935
|
return;
|
|
24361
23936
|
}
|
|
24362
23937
|
firing.add(agentId);
|
|
24363
23938
|
try {
|
|
23939
|
+
const trigger = asArray(getCodingAgent(agentId)?.trigger)[triggerIndex];
|
|
23940
|
+
const input = inputFor(trigger, events);
|
|
24364
23941
|
logger.info(`[CodingAgent:${agentId}] triggered by ${reason}`);
|
|
24365
|
-
const record = await runCodingAgent(agentId, { input
|
|
24366
|
-
saveTriggerState(agentId, { ...loadTriggerState(agentId), lastRunAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
23942
|
+
const record = await runCodingAgent(agentId, { input });
|
|
23943
|
+
saveTriggerState(agentId, { ...loadTriggerState(agentId), lastRunAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
24367
23944
|
for (const fn of listeners) {
|
|
24368
23945
|
try {
|
|
24369
|
-
fn(record, { agentId, reason,
|
|
23946
|
+
fn(record, { agentId, reason, events, input });
|
|
24370
23947
|
} catch {
|
|
24371
23948
|
}
|
|
24372
23949
|
}
|
|
@@ -24374,9 +23951,13 @@ async function fire(agentId, reason, payload) {
|
|
|
24374
23951
|
logger.error(`[CodingAgent:${agentId}] trigger run failed: ${err?.message ?? err}`);
|
|
24375
23952
|
} finally {
|
|
24376
23953
|
firing.delete(agentId);
|
|
24377
|
-
|
|
24378
|
-
|
|
24379
|
-
|
|
23954
|
+
}
|
|
23955
|
+
const st = loadTriggerState(agentId);
|
|
23956
|
+
const queued = Object.entries(st.pending);
|
|
23957
|
+
if (queued.length) {
|
|
23958
|
+
saveTriggerState(agentId, { ...st, pending: {} });
|
|
23959
|
+
for (const [index, evs] of queued) {
|
|
23960
|
+
await fire(agentId, Number(index), "queued work from during the last run", evs);
|
|
24380
23961
|
}
|
|
24381
23962
|
}
|
|
24382
23963
|
}
|
|
@@ -24384,45 +23965,49 @@ function emitAgentEvent(event, payload) {
|
|
|
24384
23965
|
for (const { id } of listCodingAgents()) {
|
|
24385
23966
|
const def = getCodingAgent(id);
|
|
24386
23967
|
if (!def) continue;
|
|
24387
|
-
|
|
23968
|
+
asArray(def.trigger).forEach((trigger, index) => {
|
|
24388
23969
|
if (trigger.type === "event") {
|
|
24389
23970
|
const names = Array.isArray(trigger.on) ? trigger.on : [trigger.on];
|
|
24390
|
-
if (!names.includes(event))
|
|
23971
|
+
if (!names.includes(event)) return;
|
|
23972
|
+
const arrived = { name: event, payload };
|
|
24391
23973
|
if (!trigger.debounceMs) {
|
|
24392
|
-
void fire(id, `event ${event}`,
|
|
24393
|
-
|
|
23974
|
+
void fire(id, index, `event ${event}`, [arrived]);
|
|
23975
|
+
return;
|
|
24394
23976
|
}
|
|
24395
|
-
const key = `${id}:${
|
|
23977
|
+
const key = `${id}:${index}`;
|
|
23978
|
+
bursts.set(key, capEvents([...bursts.get(key) ?? [], arrived]));
|
|
24396
23979
|
const existing = debounces.get(key);
|
|
24397
23980
|
if (existing) clearTimeout(existing);
|
|
24398
23981
|
debounces.set(key, setTimeout(() => {
|
|
24399
23982
|
debounces.delete(key);
|
|
24400
|
-
|
|
23983
|
+
const batch = bursts.get(key) ?? [];
|
|
23984
|
+
bursts.delete(key);
|
|
23985
|
+
void fire(id, index, `event ${event} (settled, ${batch.length} event(s))`, batch);
|
|
24401
23986
|
}, trigger.debounceMs));
|
|
24402
|
-
|
|
23987
|
+
return;
|
|
24403
23988
|
}
|
|
24404
23989
|
if (trigger.type === "count" && trigger.on === event) {
|
|
24405
23990
|
const state = loadTriggerState(id);
|
|
24406
|
-
const
|
|
24407
|
-
if (
|
|
24408
|
-
saveTriggerState(id, { ...state, counts: { ...state.counts, [event]:
|
|
24409
|
-
|
|
23991
|
+
const banked = capEvents([...state.counts[event] ?? [], { name: event, payload }]);
|
|
23992
|
+
if (banked.length < trigger.every) {
|
|
23993
|
+
saveTriggerState(id, { ...state, counts: { ...state.counts, [event]: banked } });
|
|
23994
|
+
return;
|
|
24410
23995
|
}
|
|
24411
|
-
saveTriggerState(id, { ...state, counts: { ...state.counts, [event]:
|
|
24412
|
-
void fire(id, `${trigger.every}x ${event}`,
|
|
23996
|
+
saveTriggerState(id, { ...state, counts: { ...state.counts, [event]: [] } });
|
|
23997
|
+
void fire(id, index, `${trigger.every}x ${event}`, banked);
|
|
24413
23998
|
}
|
|
24414
|
-
}
|
|
23999
|
+
});
|
|
24415
24000
|
}
|
|
24416
24001
|
}
|
|
24417
24002
|
function startAgentTriggers() {
|
|
24418
24003
|
stopAgentTriggers();
|
|
24419
24004
|
for (const { id } of listCodingAgents()) {
|
|
24420
24005
|
const def = getCodingAgent(id);
|
|
24421
|
-
|
|
24422
|
-
if (trigger.type !== "interval")
|
|
24423
|
-
intervals.set(id
|
|
24006
|
+
asArray(def?.trigger).forEach((trigger, index) => {
|
|
24007
|
+
if (trigger.type !== "interval") return;
|
|
24008
|
+
intervals.set(`${id}:${index}`, setInterval(() => void fire(id, index, `interval ${trigger.everyMs}ms`), trigger.everyMs));
|
|
24424
24009
|
logger.info(`[CodingAgent:${id}] interval trigger every ${trigger.everyMs}ms`);
|
|
24425
|
-
}
|
|
24010
|
+
});
|
|
24426
24011
|
}
|
|
24427
24012
|
}
|
|
24428
24013
|
function stopAgentTriggers() {
|
|
@@ -24430,6 +24015,7 @@ function stopAgentTriggers() {
|
|
|
24430
24015
|
intervals.clear();
|
|
24431
24016
|
for (const t of debounces.values()) clearTimeout(t);
|
|
24432
24017
|
debounces.clear();
|
|
24018
|
+
bursts.clear();
|
|
24433
24019
|
}
|
|
24434
24020
|
function describeTriggers() {
|
|
24435
24021
|
return listCodingAgents().map(({ id }) => {
|
|
@@ -24446,6 +24032,9 @@ function describeTriggers() {
|
|
|
24446
24032
|
// src/codingAgent/collection.ts
|
|
24447
24033
|
import * as fs11 from "fs";
|
|
24448
24034
|
import * as path11 from "path";
|
|
24035
|
+
function isChattable(agent) {
|
|
24036
|
+
return agent.mode !== "task";
|
|
24037
|
+
}
|
|
24449
24038
|
function registerCodingAgentCollection(sdk, config2 = {}) {
|
|
24450
24039
|
const runtimeDir = config2.runtimeDir || process.env.CODING_AGENT_RUNTIME_DIR || path11.join(process.cwd(), ".coding-agent-runtime");
|
|
24451
24040
|
const defaultHarness = config2.harness || process.env.CODING_AGENT_HARNESS || "codex";
|
|
@@ -24469,7 +24058,19 @@ function registerCodingAgentCollection(sdk, config2 = {}) {
|
|
|
24469
24058
|
error: `Unknown agent "${agentId}". Available: ${listCodingAgents().map((a) => a.id).join(", ") || "(none registered)"}`
|
|
24470
24059
|
};
|
|
24471
24060
|
}
|
|
24061
|
+
if (!isChattable(def)) {
|
|
24062
|
+
return {
|
|
24063
|
+
success: false,
|
|
24064
|
+
error: `${def.title} runs as a scheduled task and is not available for chat.`
|
|
24065
|
+
};
|
|
24066
|
+
}
|
|
24472
24067
|
const record = await runCodingAgent(agentId, {
|
|
24068
|
+
// chat:true is what stops a typed message being treated as a job. A
|
|
24069
|
+
// task agent's prepare()/output/apply() set work up and consume it, so
|
|
24070
|
+
// without this every conversational turn failed for not writing a
|
|
24071
|
+
// deliverable nobody asked for — and, for a batching agent, quietly ate
|
|
24072
|
+
// a batch of work on the way.
|
|
24073
|
+
chat: true,
|
|
24473
24074
|
prompt,
|
|
24474
24075
|
projectId,
|
|
24475
24076
|
userId,
|
|
@@ -24489,7 +24090,10 @@ function registerCodingAgentCollection(sdk, config2 = {}) {
|
|
|
24489
24090
|
sessionId: record.sessionId,
|
|
24490
24091
|
...record.output !== void 0 ? { output: record.output } : {},
|
|
24491
24092
|
...record.applied ? { applied: record.applied } : {},
|
|
24492
|
-
|
|
24093
|
+
// A project-scoped agent serialises its runs, so a turn sent while it
|
|
24094
|
+
// is working is a normal outcome, not a fault. Say so in words a
|
|
24095
|
+
// person can act on.
|
|
24096
|
+
...record.status === "skipped" ? { error: `${def.title} is in the middle of a run \u2014 try again in a moment.` } : record.error ? { error: record.error } : {}
|
|
24493
24097
|
};
|
|
24494
24098
|
}
|
|
24495
24099
|
const cwd = path11.join(runtimeDir, "threads", threadId);
|
|
@@ -24536,7 +24140,10 @@ function registerCodingAgentCollection(sdk, config2 = {}) {
|
|
|
24536
24140
|
}
|
|
24537
24141
|
return { success: true };
|
|
24538
24142
|
});
|
|
24539
|
-
sdk.addCollection("coding-agent", "list", async () => ({
|
|
24143
|
+
sdk.addCollection("coding-agent", "list", async () => ({
|
|
24144
|
+
success: true,
|
|
24145
|
+
agents: listCodingAgents().map((a) => ({ ...a, chattable: isChattable(a) }))
|
|
24146
|
+
}));
|
|
24540
24147
|
console.log(`\u2713 coding-agent collection registered (harness: ${defaultHarness})`);
|
|
24541
24148
|
}
|
|
24542
24149
|
|
|
@@ -27670,11 +27277,6 @@ var SuperatomSDK = class {
|
|
|
27670
27277
|
logger.error("Failed to handle user prompt abort request:", error);
|
|
27671
27278
|
}
|
|
27672
27279
|
break;
|
|
27673
|
-
case "ACTIONS":
|
|
27674
|
-
handleActionsRequest(parsed, (msg) => this.send(msg), this.anthropicApiKey, this.groqApiKey, this.geminiApiKey, this.openaiApiKey, this.llmProviders).catch((error) => {
|
|
27675
|
-
logger.error("Failed to handle actions request:", error);
|
|
27676
|
-
});
|
|
27677
|
-
break;
|
|
27678
27280
|
case "USER_PROMPT_SUGGESTIONS_REQ":
|
|
27679
27281
|
handleUserPromptSuggestions(parsed, this.components, (msg) => this.send(msg), this.collections).catch((error) => {
|
|
27680
27282
|
logger.error("Failed to handle user prompt suggestions request:", error);
|