@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.js
CHANGED
|
@@ -390,8 +390,7 @@ var ComponentPropsSchema = import_zod3.z.object({
|
|
|
390
390
|
query: import_zod3.z.string().or(import_zod3.z.object({})).nullable().optional(),
|
|
391
391
|
title: import_zod3.z.string().optional(),
|
|
392
392
|
description: import_zod3.z.string().optional(),
|
|
393
|
-
config: import_zod3.z.record(import_zod3.z.unknown()).optional()
|
|
394
|
-
actions: import_zod3.z.array(import_zod3.z.any()).optional()
|
|
393
|
+
config: import_zod3.z.record(import_zod3.z.unknown()).optional()
|
|
395
394
|
}).passthrough();
|
|
396
395
|
var ComponentSchema = import_zod3.z.object({
|
|
397
396
|
id: import_zod3.z.string(),
|
|
@@ -505,19 +504,6 @@ var UILogsMessageSchema = import_zod3.z.object({
|
|
|
505
504
|
type: import_zod3.z.literal("UI_LOGS"),
|
|
506
505
|
payload: UILogsPayloadSchema
|
|
507
506
|
});
|
|
508
|
-
var ActionsRequestPayloadSchema = import_zod3.z.object({
|
|
509
|
-
userId: import_zod3.z.string().optional(),
|
|
510
|
-
SA_RUNTIME: import_zod3.z.object({
|
|
511
|
-
threadId: import_zod3.z.string(),
|
|
512
|
-
uiBlockId: import_zod3.z.string()
|
|
513
|
-
}).optional()
|
|
514
|
-
});
|
|
515
|
-
var ActionsRequestMessageSchema = import_zod3.z.object({
|
|
516
|
-
id: import_zod3.z.string(),
|
|
517
|
-
from: MessageParticipantSchema,
|
|
518
|
-
type: import_zod3.z.literal("ACTIONS"),
|
|
519
|
-
payload: ActionsRequestPayloadSchema
|
|
520
|
-
});
|
|
521
507
|
var DashboardQueryFiltersSchema = import_zod3.z.object({
|
|
522
508
|
dashboardId: import_zod3.z.string().optional(),
|
|
523
509
|
projectId: import_zod3.z.string().optional(),
|
|
@@ -627,8 +613,6 @@ var UIBlockSchema = import_zod3.z.object({
|
|
|
627
613
|
generatedComponentMetadata: ComponentSchema.optional(),
|
|
628
614
|
// Actual field used by UIBlock class
|
|
629
615
|
componentData: import_zod3.z.record(import_zod3.z.any()).optional(),
|
|
630
|
-
actions: import_zod3.z.array(import_zod3.z.any()).optional(),
|
|
631
|
-
isFetchingActions: import_zod3.z.boolean().optional(),
|
|
632
616
|
createdAt: import_zod3.z.string().optional(),
|
|
633
617
|
/**
|
|
634
618
|
* Which script recipe produced this answer. Set whenever the turn was answered
|
|
@@ -1152,11 +1136,10 @@ var UIBlock = class {
|
|
|
1152
1136
|
* @param userQuestion - The user's question or input
|
|
1153
1137
|
* @param componentData - The component data object
|
|
1154
1138
|
* @param generatedComponentMetadata - Optional metadata about the generated component
|
|
1155
|
-
* @param actions - Optional array of available actions
|
|
1156
1139
|
* @param id - Optional custom ID, generates UUID if not provided
|
|
1157
1140
|
* @param textResponse - Optional text response from LLM
|
|
1158
1141
|
*/
|
|
1159
|
-
constructor(userQuestion, componentData = {}, generatedComponentMetadata = {},
|
|
1142
|
+
constructor(userQuestion, componentData = {}, generatedComponentMetadata = {}, id, textResponse = null) {
|
|
1160
1143
|
/**
|
|
1161
1144
|
* Which script recipe produced this answer, when a script did. Read on the
|
|
1162
1145
|
* NEXT turn so the user can say "use mode instead" and have the matcher
|
|
@@ -1168,7 +1151,6 @@ var UIBlock = class {
|
|
|
1168
1151
|
this.userQuestion = userQuestion;
|
|
1169
1152
|
this.componentData = componentData;
|
|
1170
1153
|
this.generatedComponentMetadata = generatedComponentMetadata;
|
|
1171
|
-
this.actions = actions;
|
|
1172
1154
|
this.textResponse = textResponse;
|
|
1173
1155
|
this.createdAt = /* @__PURE__ */ new Date();
|
|
1174
1156
|
}
|
|
@@ -1297,76 +1279,6 @@ var UIBlock = class {
|
|
|
1297
1279
|
setTextResponse(textResponse) {
|
|
1298
1280
|
this.textResponse = textResponse;
|
|
1299
1281
|
}
|
|
1300
|
-
/**
|
|
1301
|
-
* Get all actions (only if they are resolved, not if fetching)
|
|
1302
|
-
*/
|
|
1303
|
-
getActions() {
|
|
1304
|
-
return this.actions;
|
|
1305
|
-
}
|
|
1306
|
-
/**
|
|
1307
|
-
* Get or fetch actions
|
|
1308
|
-
* If actions don't exist or are a Promise, calls the generateFn and stores the promise
|
|
1309
|
-
* If actions already exist, returns them
|
|
1310
|
-
* @param generateFn - Async function to generate actions
|
|
1311
|
-
* @returns Promise resolving to Action[]
|
|
1312
|
-
*/
|
|
1313
|
-
async getOrFetchActions(generateFn) {
|
|
1314
|
-
if (this.actions && !(this.actions instanceof Promise) && Array.isArray(this.actions) && this.actions.length > 0) {
|
|
1315
|
-
return this.actions;
|
|
1316
|
-
}
|
|
1317
|
-
const fetchPromise = generateFn();
|
|
1318
|
-
this.actions = fetchPromise;
|
|
1319
|
-
try {
|
|
1320
|
-
const resolvedActions = await fetchPromise;
|
|
1321
|
-
logger.info(`Fetched ${resolvedActions.length} actions for UIBlock: ${this.id}`);
|
|
1322
|
-
this.actions = resolvedActions;
|
|
1323
|
-
return resolvedActions;
|
|
1324
|
-
} catch (error) {
|
|
1325
|
-
this.actions = null;
|
|
1326
|
-
throw error;
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
/**
|
|
1330
|
-
* Set or replace all actions
|
|
1331
|
-
*/
|
|
1332
|
-
setActions(actions) {
|
|
1333
|
-
this.actions = actions;
|
|
1334
|
-
}
|
|
1335
|
-
/**
|
|
1336
|
-
* Add a single action (only if actions are resolved)
|
|
1337
|
-
*/
|
|
1338
|
-
addAction(action) {
|
|
1339
|
-
if (this.actions && Array.isArray(this.actions)) {
|
|
1340
|
-
this.actions.push(action);
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
/**
|
|
1344
|
-
* Add multiple actions (only if actions are resolved)
|
|
1345
|
-
*/
|
|
1346
|
-
addActions(actions) {
|
|
1347
|
-
if (this.actions && Array.isArray(this.actions)) {
|
|
1348
|
-
this.actions.push(...actions);
|
|
1349
|
-
}
|
|
1350
|
-
}
|
|
1351
|
-
/**
|
|
1352
|
-
* Remove an action by ID (only if actions are resolved)
|
|
1353
|
-
*/
|
|
1354
|
-
removeAction(actionId) {
|
|
1355
|
-
if (this.actions && Array.isArray(this.actions)) {
|
|
1356
|
-
const index = this.actions.findIndex((a) => a.id === actionId);
|
|
1357
|
-
if (index > -1) {
|
|
1358
|
-
this.actions.splice(index, 1);
|
|
1359
|
-
return true;
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
return false;
|
|
1363
|
-
}
|
|
1364
|
-
/**
|
|
1365
|
-
* Clear all actions
|
|
1366
|
-
*/
|
|
1367
|
-
clearActions() {
|
|
1368
|
-
this.actions = null;
|
|
1369
|
-
}
|
|
1370
1282
|
/**
|
|
1371
1283
|
* Bind this block to the script recipe that produced its answer.
|
|
1372
1284
|
*/
|
|
@@ -1396,18 +1308,12 @@ var UIBlock = class {
|
|
|
1396
1308
|
* Convert UIBlock to JSON-serializable object
|
|
1397
1309
|
*/
|
|
1398
1310
|
toJSON() {
|
|
1399
|
-
let actionsValue = null;
|
|
1400
|
-
if (this.actions && !(this.actions instanceof Promise) && Array.isArray(this.actions)) {
|
|
1401
|
-
actionsValue = this.actions;
|
|
1402
|
-
}
|
|
1403
1311
|
return {
|
|
1404
1312
|
id: this.id,
|
|
1405
1313
|
userQuestion: this.userQuestion,
|
|
1406
1314
|
generatedComponentMetadata: this.generatedComponentMetadata,
|
|
1407
1315
|
componentData: this.componentData,
|
|
1408
1316
|
textResponse: this.textResponse,
|
|
1409
|
-
actions: actionsValue,
|
|
1410
|
-
isFetchingActions: this.actions instanceof Promise,
|
|
1411
1317
|
createdAt: this.createdAt.toISOString(),
|
|
1412
1318
|
...this.scriptBinding ? { scriptBinding: this.scriptBinding } : {},
|
|
1413
1319
|
...this.programAnswer ? { programAnswer: this.programAnswer } : {}
|
|
@@ -1545,23 +1451,55 @@ var Thread = class {
|
|
|
1545
1451
|
* since-edited) live body. Owned by the caller (needs a ScriptStore, which
|
|
1546
1452
|
* Thread doesn't hold) — omit it and every turn falls back to the
|
|
1547
1453
|
* no-script summary below.
|
|
1548
|
-
|
|
1549
|
-
|
|
1454
|
+
* @param fetchRecentFromDb When provided, this is now the SOURCE OF TRUTH
|
|
1455
|
+
* for history instead of this process's in-memory `uiblocks` map — reads
|
|
1456
|
+
* the persisted `user_conversations` rows (DB `response` jsonb shape, see
|
|
1457
|
+
* transformUIBlockForDB in conversation-saver.ts) via the caller's own
|
|
1458
|
+
* `user-conversations.getRecentForContext` collection. Rows come back
|
|
1459
|
+
* newest-first (already excluding status='aborted' — the query itself
|
|
1460
|
+
* filters that, matching what the in-memory path achieved via
|
|
1461
|
+
* thread.removeUIBlock() on abort). Fixes the standing gap where a backend
|
|
1462
|
+
* restart lost every thread's history (ThreadManager has no DB-backed
|
|
1463
|
+
* rehydration) — DB-backed history survives that, and is correct even if
|
|
1464
|
+
* a different process instance saved the row. Omit it and this falls back
|
|
1465
|
+
* to the in-memory map, for any caller not yet updated.
|
|
1466
|
+
*/
|
|
1467
|
+
async getConversationContext(limit = 5, currentUIBlockId, getScriptBody, fetchRecentFromDb) {
|
|
1550
1468
|
if (limit === 0) {
|
|
1551
1469
|
return "";
|
|
1552
1470
|
}
|
|
1553
|
-
|
|
1554
|
-
if (
|
|
1471
|
+
let turns;
|
|
1472
|
+
if (fetchRecentFromDb) {
|
|
1473
|
+
const rows = await fetchRecentFromDb(limit);
|
|
1474
|
+
turns = rows.slice().reverse().map((row) => {
|
|
1475
|
+
const r = row.response || {};
|
|
1476
|
+
return {
|
|
1477
|
+
question: row.userprompt || r.user_prompt || "",
|
|
1478
|
+
metadata: r.component || {},
|
|
1479
|
+
programAnswer: r.programAnswer || null,
|
|
1480
|
+
textResponse: r.analysis || "",
|
|
1481
|
+
scriptBinding: r.scriptBinding || null
|
|
1482
|
+
};
|
|
1483
|
+
});
|
|
1484
|
+
} else {
|
|
1485
|
+
const allBlocks = Array.from(this.uiblocks.values()).filter((block) => !currentUIBlockId || block.getId() !== currentUIBlockId).sort((a, b) => a.getCreatedAt().getTime() - b.getCreatedAt().getTime());
|
|
1486
|
+
if (allBlocks.length === 0) {
|
|
1487
|
+
return "";
|
|
1488
|
+
}
|
|
1489
|
+
turns = allBlocks.slice(-limit).map((block) => ({
|
|
1490
|
+
question: block.getUserQuestion(),
|
|
1491
|
+
metadata: block.getComponentMetadata(),
|
|
1492
|
+
programAnswer: block.getProgramAnswer(),
|
|
1493
|
+
textResponse: block.getTextResponse(),
|
|
1494
|
+
scriptBinding: block.getScriptBinding()
|
|
1495
|
+
}));
|
|
1496
|
+
}
|
|
1497
|
+
if (turns.length === 0) {
|
|
1555
1498
|
return "";
|
|
1556
1499
|
}
|
|
1557
|
-
const recentBlocks = allBlocks.slice(-limit);
|
|
1558
1500
|
const contextLines = [];
|
|
1559
|
-
for (const
|
|
1560
|
-
const question =
|
|
1561
|
-
const metadata = block.getComponentMetadata();
|
|
1562
|
-
const programAnswer = block.getProgramAnswer();
|
|
1563
|
-
const textResponse = block.getTextResponse();
|
|
1564
|
-
const scriptBinding = block.getScriptBinding();
|
|
1501
|
+
for (const turn of turns) {
|
|
1502
|
+
const { question, metadata, programAnswer, textResponse, scriptBinding } = turn;
|
|
1565
1503
|
const responseParts = [];
|
|
1566
1504
|
let analysisText = "";
|
|
1567
1505
|
const hasProgramAnswer = programAnswer && programAnswer.trim().length > 0;
|
|
@@ -3491,7 +3429,6 @@ var MAX_TOKENS_COMPONENT_MATCHING = 8192;
|
|
|
3491
3429
|
var MAX_TOKENS_CLASSIFICATION = 1500;
|
|
3492
3430
|
var MAX_TOKENS_ADAPTATION = 8192;
|
|
3493
3431
|
var MAX_TOKENS_TEXT_RESPONSE = 4e3;
|
|
3494
|
-
var MAX_TOKENS_NEXT_QUESTIONS = 1200;
|
|
3495
3432
|
var MAX_ROWS_FETCHED = 50;
|
|
3496
3433
|
var MAX_ROWS_TO_LLM = 10;
|
|
3497
3434
|
var LLM_SAMPLE_ROWS = 10;
|
|
@@ -5864,7 +5801,6 @@ You receive TWO key inputs:
|
|
|
5864
5801
|
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.
|
|
5865
5802
|
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.
|
|
5866
5803
|
5. **Dashboard metadata**: Title (5-10 words) and description (1-2 sentences)
|
|
5867
|
-
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.
|
|
5868
5804
|
|
|
5869
5805
|
### Choosing Complexity
|
|
5870
5806
|
Determine complexity from the analysis text and EXECUTED_TOOLS:
|
|
@@ -6078,8 +6014,7 @@ When using \`externalTool\`, use field names from the tool's \`outputSchema\` in
|
|
|
6078
6014
|
"answerComponent": { ... } | null,
|
|
6079
6015
|
"layoutTitle": "Dashboard title (5-10 words)",
|
|
6080
6016
|
"layoutDescription": "Dashboard purpose (1-2 sentences)",
|
|
6081
|
-
"matchedComponents": [ ... ]
|
|
6082
|
-
"actions": ["Follow-up question 1?", "Follow-up question 2?", "Follow-up question 3?"]
|
|
6017
|
+
"matchedComponents": [ ... ]
|
|
6083
6018
|
}
|
|
6084
6019
|
\`\`\`
|
|
6085
6020
|
|
|
@@ -6194,52 +6129,6 @@ Example when hasAnswerComponent is true:
|
|
|
6194
6129
|
|
|
6195
6130
|
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.
|
|
6196
6131
|
---`
|
|
6197
|
-
},
|
|
6198
|
-
"actions": {
|
|
6199
|
-
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.
|
|
6200
|
-
|
|
6201
|
-
**Rules:**
|
|
6202
|
-
- Keep questions short and simple \u2014 one clear ask per question
|
|
6203
|
-
- Questions MUST be answerable by querying the available data columns (SQL queries)
|
|
6204
|
-
- Suggest different slices of the same data: by time period, by category, by route, top/bottom N, trends, comparisons
|
|
6205
|
-
- Avoid repeating topics already covered in the conversation
|
|
6206
|
-
- NEVER suggest questions about: root causes, recommendations, process changes, staffing, business decisions, or anything requiring human judgment
|
|
6207
|
-
- NEVER ask "why" questions \u2014 only "what", "which", "how much", "how does X compare to Y"
|
|
6208
|
-
|
|
6209
|
-
---
|
|
6210
|
-
|
|
6211
|
-
## CONTEXT (for this specific request)
|
|
6212
|
-
|
|
6213
|
-
### Previous Conversation
|
|
6214
|
-
{{CONVERSATION_HISTORY}}`,
|
|
6215
|
-
user: `Current Date and Time: {{CURRENT_DATETIME}}
|
|
6216
|
-
|
|
6217
|
-
Given the following context:
|
|
6218
|
-
|
|
6219
|
-
Latest User Question: {{ORIGINAL_USER_PROMPT}}
|
|
6220
|
-
|
|
6221
|
-
Current Component:
|
|
6222
|
-
{{COMPONENT_INFO}}
|
|
6223
|
-
|
|
6224
|
-
{{COMPONENT_DATA}}
|
|
6225
|
-
|
|
6226
|
-
Generate a JSON array of exactly 3 simple follow-up questions. Each question should:
|
|
6227
|
-
1. Be answerable by running a SQL query on the available data \u2014 no consulting or opinion questions
|
|
6228
|
-
2. Explore a different dimension or slice of the data (different grouping, time range, filter, comparison)
|
|
6229
|
-
3. NOT repeat topics already covered in the conversation
|
|
6230
|
-
4. Be short and direct \u2014 one sentence, one clear ask
|
|
6231
|
-
5. Use specific column names or values from the data when relevant
|
|
6232
|
-
|
|
6233
|
-
Format your response as a JSON object with this structure:
|
|
6234
|
-
{
|
|
6235
|
-
"nextQuestions": [
|
|
6236
|
-
"Question 1?",
|
|
6237
|
-
"Question 2?",
|
|
6238
|
-
...
|
|
6239
|
-
]
|
|
6240
|
-
}
|
|
6241
|
-
|
|
6242
|
-
Return ONLY valid JSON.`
|
|
6243
6132
|
},
|
|
6244
6133
|
"category-classification": {
|
|
6245
6134
|
system: `You categorize user questions and identify required data source tools. Respond with ONLY valid JSON.
|
|
@@ -6405,7 +6294,7 @@ Your task is to:
|
|
|
6405
6294
|
## Component Structure Handling
|
|
6406
6295
|
|
|
6407
6296
|
### For Single Components:
|
|
6408
|
-
- Modify props directly (config,
|
|
6297
|
+
- Modify props directly (config, query, filters, etc.)
|
|
6409
6298
|
|
|
6410
6299
|
### For MultiComponentContainer:
|
|
6411
6300
|
The component will have structure:
|
|
@@ -6418,8 +6307,7 @@ The component will have structure:
|
|
|
6418
6307
|
"components": [...], // Array of nested components - ADAPT EACH ONE
|
|
6419
6308
|
"title": "...", // Container title - UPDATE based on new question
|
|
6420
6309
|
"description": "..." // Container description - UPDATE based on new question
|
|
6421
|
-
}
|
|
6422
|
-
"actions": [...] // ADAPT actions if needed
|
|
6310
|
+
}
|
|
6423
6311
|
}
|
|
6424
6312
|
}
|
|
6425
6313
|
\`\`\`
|
|
@@ -6431,7 +6319,6 @@ When adapting MultiComponentContainer:
|
|
|
6431
6319
|
- Adapt its query parameters (WHERE clauses, LIMIT, ORDER BY, filters, date ranges)
|
|
6432
6320
|
- Update its title/description to match the new context
|
|
6433
6321
|
- Update its config settings (colors, sorting, grouping, metrics)
|
|
6434
|
-
- Update \`actions\` if the new question requires different actions
|
|
6435
6322
|
|
|
6436
6323
|
## Important Guidelines:
|
|
6437
6324
|
- Keep the same component type (don't change KPICard to LineChart)
|
|
@@ -6504,8 +6391,7 @@ When adapting queries, follow the database-specific rules below:
|
|
|
6504
6391
|
"type": "component_type",
|
|
6505
6392
|
"description": "updated_description",
|
|
6506
6393
|
"props": {
|
|
6507
|
-
"config": { }
|
|
6508
|
-
"actions": []
|
|
6394
|
+
"config": { }
|
|
6509
6395
|
}
|
|
6510
6396
|
},
|
|
6511
6397
|
"adaptedTextResponse": "The adapted text response with updated values matching the new question...",
|
|
@@ -6562,8 +6448,7 @@ When adapting queries, follow the database-specific rules below:
|
|
|
6562
6448
|
}
|
|
6563
6449
|
}
|
|
6564
6450
|
]
|
|
6565
|
-
}
|
|
6566
|
-
"actions": []
|
|
6451
|
+
}
|
|
6567
6452
|
}
|
|
6568
6453
|
},
|
|
6569
6454
|
"adaptedTextResponse": "The adapted text response with entity names, IDs, and references updated to match the new question. Numeric values replaced with placeholders.",
|
|
@@ -6631,13 +6516,12 @@ When adapting SQL queries, preserve the table and column names from the original
|
|
|
6631
6516
|
|
|
6632
6517
|
1. **Analyze the difference** between the original question and the current question
|
|
6633
6518
|
2. **Identify what data needs to change**:
|
|
6634
|
-
- For single components: adapt the query/config
|
|
6519
|
+
- For single components: adapt the query/config
|
|
6635
6520
|
- For MultiComponentContainer: adapt the container title/description AND each nested component's parameters
|
|
6636
6521
|
|
|
6637
6522
|
3. **Modify the parameters**:
|
|
6638
6523
|
- **Container level** (if MultiComponentContainer):
|
|
6639
6524
|
- Update \`title\` and \`description\` to reflect the new user question
|
|
6640
|
-
- Update \`actions\` if needed
|
|
6641
6525
|
|
|
6642
6526
|
- **For each component** (single or nested in container):
|
|
6643
6527
|
- Identify what it shows (sales, revenue, inventory, etc.)
|
|
@@ -8156,16 +8040,9 @@ Return JSON. Shape each component per the section above (markdown uses \`props.c
|
|
|
8156
8040
|
{ "componentId": "<the answerComponent, repeated as the FIRST entry>", "componentName": "...", "sourceIndex": 0, "props": { "title": "...", "config": { "xAxisKey": "...", "yAxisKey": "..." } } },
|
|
8157
8041
|
{ "componentId": "...", "componentName": "DynamicMarkdownBlock", "props": { "content": "## Recommendation\\n\\n- key point\\n- key point" } },
|
|
8158
8042
|
{ "componentId": "...", "componentName": "DynamicDataTable", "sourceIndex": 0, "props": { "title": "...", "config": { "columns": [ { "key": "<exact data column>", "label": "<Heading>" } ] } } }
|
|
8159
|
-
],
|
|
8160
|
-
"actions": [
|
|
8161
|
-
{ "question": "<follow-up question 1>" },
|
|
8162
|
-
{ "question": "<follow-up question 2>" },
|
|
8163
|
-
{ "question": "<follow-up question 3>" }
|
|
8164
8043
|
]
|
|
8165
8044
|
}
|
|
8166
8045
|
|
|
8167
|
-
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.
|
|
8168
|
-
|
|
8169
8046
|
---
|
|
8170
8047
|
|
|
8171
8048
|
## CONTEXT (for this specific request)
|
|
@@ -9951,14 +9828,6 @@ function ensurePostgresLimit(query, defaultLimit, maxLimit, hadSemicolon) {
|
|
|
9951
9828
|
}
|
|
9952
9829
|
return trimmedQuery;
|
|
9953
9830
|
}
|
|
9954
|
-
function convertQuestionsToActions(questions) {
|
|
9955
|
-
return questions.map((question, index) => ({
|
|
9956
|
-
id: `action_${index}_${Date.now()}`,
|
|
9957
|
-
name: question,
|
|
9958
|
-
type: "next_question",
|
|
9959
|
-
question
|
|
9960
|
-
}));
|
|
9961
|
-
}
|
|
9962
9831
|
function validateAndFixSqlQuery(query, dbType) {
|
|
9963
9832
|
if (!query || query.trim().length === 0) {
|
|
9964
9833
|
return { query, fixed: false, fixes: [] };
|
|
@@ -13384,7 +13253,7 @@ var DEFAULT_AGENT_CONFIG = {
|
|
|
13384
13253
|
// will use the provider's default model
|
|
13385
13254
|
maxRetries: 2,
|
|
13386
13255
|
// 2 retries = 3 total query attempts (1 initial + 2 retries for SQL errors)
|
|
13387
|
-
maxIterations:
|
|
13256
|
+
maxIterations: 20
|
|
13388
13257
|
// schema search (2-3) + query attempts (2) + write_script/execute_script (2-3) + write_analysis (up to 3) + LLM responses + final
|
|
13389
13258
|
};
|
|
13390
13259
|
|
|
@@ -14195,6 +14064,9 @@ function parseEditPrefix(rawPrompt) {
|
|
|
14195
14064
|
if (!match) return { isExplicitEdit: false, prompt: rawPrompt };
|
|
14196
14065
|
return { isExplicitEdit: true, prompt: rawPrompt.slice(match[0].length) };
|
|
14197
14066
|
}
|
|
14067
|
+
function hasExplicitEditPrefix(prompt) {
|
|
14068
|
+
return EDIT_PREFIX_RE.test(prompt);
|
|
14069
|
+
}
|
|
14198
14070
|
var MAX_FAILURE_RATE = 0.2;
|
|
14199
14071
|
var PROMPT_HISTORY_SEARCH_LIMIT = 20;
|
|
14200
14072
|
var PROMPT_HISTORY_SIMILARITY_THRESHOLD = 0.5;
|
|
@@ -14251,10 +14123,11 @@ var ScriptMatcher = class {
|
|
|
14251
14123
|
traceEntry.sent.userPrompt = userPrompt;
|
|
14252
14124
|
const promptHistoryMatches = await this.searchPromptHistory(userPrompt);
|
|
14253
14125
|
const candidates = [];
|
|
14254
|
-
|
|
14255
|
-
|
|
14256
|
-
|
|
14257
|
-
|
|
14126
|
+
const mostRecentBinding = activeBindings?.[0];
|
|
14127
|
+
if (mostRecentBinding) {
|
|
14128
|
+
const recipe = await this.store.get(mostRecentBinding.recipeId);
|
|
14129
|
+
if (recipe) candidates.push({ recipe, binding: mostRecentBinding });
|
|
14130
|
+
else logger.warn(`[ScriptMatcher] Bound recipe "${mostRecentBinding.recipeId}" no longer in store \u2014 no edit candidate this turn`);
|
|
14258
14131
|
}
|
|
14259
14132
|
const candidateById = new Map(candidates.map((c) => [c.recipe.id, c]));
|
|
14260
14133
|
traceEntry.sent.activeBindingCount = candidates.length;
|
|
@@ -14314,11 +14187,6 @@ var ScriptMatcher = class {
|
|
|
14314
14187
|
} else if (candidates.length === 0) {
|
|
14315
14188
|
logger.info(`[ScriptMatcher] 'edit' coerced to 'none' (no script-backed answer in this thread to edit)`);
|
|
14316
14189
|
tier = "none";
|
|
14317
|
-
} else if (!candidateById.has(response?.scriptId)) {
|
|
14318
|
-
logger.warn(
|
|
14319
|
-
`[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.`
|
|
14320
|
-
);
|
|
14321
|
-
tier = "none";
|
|
14322
14190
|
} else if (!response?.editInstruction || !String(response.editInstruction).trim()) {
|
|
14323
14191
|
logger.warn(`[ScriptMatcher] 'edit' coerced to 'none' \u2014 matcher returned no editInstruction`);
|
|
14324
14192
|
tier = "none";
|
|
@@ -14326,35 +14194,45 @@ var ScriptMatcher = class {
|
|
|
14326
14194
|
}
|
|
14327
14195
|
const reasoning = response?.reasoning || "unknown";
|
|
14328
14196
|
traceEntry.received.tier = tier;
|
|
14329
|
-
if (tier === "none"
|
|
14197
|
+
if (tier === "none") {
|
|
14330
14198
|
logger.info(`[ScriptMatcher] No match. Reason: ${reasoning}`);
|
|
14331
14199
|
return null;
|
|
14332
14200
|
}
|
|
14333
|
-
const recipe = candidateById.get(response.scriptId)?.recipe ?? await this.store.get(response.scriptId);
|
|
14334
|
-
if (!recipe) {
|
|
14335
|
-
logger.warn(`[ScriptMatcher] LLM returned unknown script ID: "${response.scriptId}"`);
|
|
14336
|
-
traceEntry.received.error = `LLM returned unknown script ID: "${response.scriptId}"`;
|
|
14337
|
-
return null;
|
|
14338
|
-
}
|
|
14339
14201
|
if (tier === "edit") {
|
|
14202
|
+
const target = candidates[0];
|
|
14203
|
+
if (response?.scriptId && response.scriptId !== target.recipe.id) {
|
|
14204
|
+
logger.info(
|
|
14205
|
+
`[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.`
|
|
14206
|
+
);
|
|
14207
|
+
}
|
|
14340
14208
|
const editInstruction = String(response.editInstruction).trim();
|
|
14341
14209
|
const editTarget = String(response.editTarget || "").toLowerCase() === "display" ? "display" : "data";
|
|
14342
|
-
logger.info(`[ScriptMatcher] EDIT [${editTarget}] "${recipe.name}": ${editInstruction} | Reason: ${reasoning}`);
|
|
14210
|
+
logger.info(`[ScriptMatcher] EDIT [${editTarget}] "${target.recipe.name}": ${editInstruction} | Reason: ${reasoning}`);
|
|
14343
14211
|
return {
|
|
14344
|
-
recipe,
|
|
14212
|
+
recipe: target.recipe,
|
|
14345
14213
|
tier: "edit",
|
|
14346
14214
|
editTarget,
|
|
14347
14215
|
similarity: 1,
|
|
14348
14216
|
confidence: "high",
|
|
14349
|
-
// Carry the
|
|
14350
|
-
//
|
|
14351
|
-
extractedParams:
|
|
14217
|
+
// Carry the target's own params so the edited script re-runs on the
|
|
14218
|
+
// same scope the user was looking at, not on bare defaults.
|
|
14219
|
+
extractedParams: target.binding.params || {},
|
|
14352
14220
|
mentions: parseMentions(response.mentions),
|
|
14353
14221
|
entityTypes: parseEntityTypes(response.entityTypes),
|
|
14354
14222
|
editInstruction,
|
|
14355
14223
|
reasoning
|
|
14356
14224
|
};
|
|
14357
14225
|
}
|
|
14226
|
+
if (!response?.scriptId || response.scriptId === "none") {
|
|
14227
|
+
logger.info(`[ScriptMatcher] No match. Reason: ${reasoning}`);
|
|
14228
|
+
return null;
|
|
14229
|
+
}
|
|
14230
|
+
const recipe = candidateById.get(response.scriptId)?.recipe ?? await this.store.get(response.scriptId);
|
|
14231
|
+
if (!recipe) {
|
|
14232
|
+
logger.warn(`[ScriptMatcher] LLM returned unknown script ID: "${response.scriptId}"`);
|
|
14233
|
+
traceEntry.received.error = `LLM returned unknown script ID: "${response.scriptId}"`;
|
|
14234
|
+
return null;
|
|
14235
|
+
}
|
|
14358
14236
|
const declaredParamNames = new Set(recipe.parameters.map((p) => p.name));
|
|
14359
14237
|
const inventedParamKeys = Object.keys(response.params || {}).filter((k) => !declaredParamNames.has(k));
|
|
14360
14238
|
if (inventedParamKeys.length > 0) {
|
|
@@ -14474,41 +14352,41 @@ ${paramList}`;
|
|
|
14474
14352
|
}).join("\n\n");
|
|
14475
14353
|
}
|
|
14476
14354
|
/**
|
|
14477
|
-
* The recent script-backed
|
|
14478
|
-
*
|
|
14479
|
-
*
|
|
14480
|
-
*
|
|
14481
|
-
*
|
|
14355
|
+
* The most recent script-backed answer in this thread — the one an `edit`
|
|
14356
|
+
* targets. Rendered as its own prompt section (never merged into the ranked
|
|
14357
|
+
* catalog) so the `edit` rules have an unambiguous referent.
|
|
14358
|
+
*
|
|
14359
|
+
* `candidates` holds at most one entry (see doMatch) — `edit` always means
|
|
14360
|
+
* "the answer I just got", so there is nothing else to show here.
|
|
14482
14361
|
*
|
|
14483
|
-
*
|
|
14484
|
-
*
|
|
14485
|
-
* one
|
|
14362
|
+
* Carries the QUESTION that produced it plus the columns it returned — that
|
|
14363
|
+
* is what lets the matcher resolve "use the mode for the WSP one" against
|
|
14364
|
+
* this one script's own context.
|
|
14486
14365
|
*/
|
|
14487
14366
|
buildActiveScriptBlock(candidates) {
|
|
14488
|
-
const
|
|
14489
|
-
|
|
14490
|
-
|
|
14491
|
-
|
|
14492
|
-
|
|
14493
|
-
]
|
|
14494
|
-
|
|
14495
|
-
|
|
14496
|
-
|
|
14497
|
-
|
|
14498
|
-
|
|
14499
|
-
|
|
14500
|
-
|
|
14501
|
-
|
|
14502
|
-
|
|
14503
|
-
lines.push(
|
|
14504
|
-
|
|
14505
|
-
|
|
14367
|
+
const target = candidates[0];
|
|
14368
|
+
if (!target) return "";
|
|
14369
|
+
const { recipe, binding } = target;
|
|
14370
|
+
const paramList = this.formatParamList(recipe.parameters);
|
|
14371
|
+
const lines = [
|
|
14372
|
+
`[${recipe.id}] "${recipe.name}"`,
|
|
14373
|
+
`${recipe.intentDescription}`
|
|
14374
|
+
];
|
|
14375
|
+
if (binding.userPrompt) lines.push(`Answered the question: "${binding.userPrompt}"`);
|
|
14376
|
+
if (binding.answerSummary) {
|
|
14377
|
+
const trimmed = binding.answerSummary.length > 1e3 ? binding.answerSummary.slice(0, 1e3) + "...[truncated]" : binding.answerSummary;
|
|
14378
|
+
lines.push(`Last answer: ${trimmed}`);
|
|
14379
|
+
}
|
|
14380
|
+
if (binding.columns?.length) lines.push(`Columns it returned: ${binding.columns.join(", ")}`);
|
|
14381
|
+
if (binding.params && Object.keys(binding.params).length > 0) {
|
|
14382
|
+
lines.push(`Ran with: ${JSON.stringify(binding.params)}`);
|
|
14383
|
+
}
|
|
14384
|
+
lines.push("Parameters:", paramList);
|
|
14506
14385
|
return [
|
|
14507
|
-
"### EDITABLE
|
|
14508
|
-
"An `edit`
|
|
14509
|
-
"name which one, choose #1 (the most recent).",
|
|
14386
|
+
"### EDITABLE SCRIPT \u2014 the answer just given in THIS conversation",
|
|
14387
|
+
"An `edit` always targets this script.",
|
|
14510
14388
|
"",
|
|
14511
|
-
|
|
14389
|
+
lines.join("\n")
|
|
14512
14390
|
].join("\n");
|
|
14513
14391
|
}
|
|
14514
14392
|
};
|
|
@@ -14849,7 +14727,7 @@ async function generateScriptComponents(params) {
|
|
|
14849
14727
|
const queries = scriptResult.executedQueries;
|
|
14850
14728
|
if (!queries || queries.length === 0) {
|
|
14851
14729
|
logger.warn(`[ScriptComponentGen] No query data available \u2014 returning empty`);
|
|
14852
|
-
return { components: [], layoutTitle: "", layoutDescription: "",
|
|
14730
|
+
return { components: [], layoutTitle: "", layoutDescription: "", componentSpecs: [] };
|
|
14853
14731
|
}
|
|
14854
14732
|
logger.info(`[ScriptComponentGen] Starting | ${queries.length} queries | ${availableComponents.length} available components`);
|
|
14855
14733
|
const columnsByIndex = queries.map((q) => {
|
|
@@ -14936,7 +14814,7 @@ ${sampleData}
|
|
|
14936
14814
|
logger.logLLMPrompt("scriptComponentGen:response", "user", JSON.stringify(response, null, 2));
|
|
14937
14815
|
if (!response || !response.components || !Array.isArray(response.components)) {
|
|
14938
14816
|
logger.warn(`[ScriptComponentGen] LLM returned invalid response`);
|
|
14939
|
-
return { components: [], layoutTitle: "", layoutDescription: "",
|
|
14817
|
+
return { components: [], layoutTitle: "", layoutDescription: "", componentSpecs: [] };
|
|
14940
14818
|
}
|
|
14941
14819
|
const layoutTitle = response.layoutTitle || "Dashboard";
|
|
14942
14820
|
const layoutDescription = response.layoutDescription || "";
|
|
@@ -14991,23 +14869,16 @@ ${sampleData}
|
|
|
14991
14869
|
}
|
|
14992
14870
|
}
|
|
14993
14871
|
logger.info(`[ScriptComponentGen] Generated ${matchedComponents.length} components`);
|
|
14994
|
-
const actions = (response.actions || []).map((a, idx) => ({
|
|
14995
|
-
id: `action_${idx}_${Date.now()}`,
|
|
14996
|
-
name: a.name || a.question || "",
|
|
14997
|
-
type: "next_question",
|
|
14998
|
-
question: a.question || a.name || ""
|
|
14999
|
-
}));
|
|
15000
14872
|
return {
|
|
15001
14873
|
components: matchedComponents,
|
|
15002
14874
|
layoutTitle,
|
|
15003
14875
|
layoutDescription,
|
|
15004
|
-
actions,
|
|
15005
14876
|
componentSpecs
|
|
15006
14877
|
};
|
|
15007
14878
|
} catch (error) {
|
|
15008
14879
|
const msg = error instanceof Error ? error.message : String(error);
|
|
15009
14880
|
logger.error(`[ScriptComponentGen] Failed: ${msg}`);
|
|
15010
|
-
return { components: [], layoutTitle: "", layoutDescription: "",
|
|
14881
|
+
return { components: [], layoutTitle: "", layoutDescription: "", componentSpecs: [] };
|
|
15011
14882
|
}
|
|
15012
14883
|
}
|
|
15013
14884
|
async function summarizeToMarkdown(analysis, apiKey, model) {
|
|
@@ -16065,15 +15936,15 @@ var BaseLLM = class {
|
|
|
16065
15936
|
return false;
|
|
16066
15937
|
}
|
|
16067
15938
|
/**
|
|
16068
|
-
* Match components from text response suggestions
|
|
15939
|
+
* Match components from text response suggestions
|
|
16069
15940
|
* Takes a text response with component suggestions (c1:type format) and matches with available components
|
|
16070
|
-
* Also generates title
|
|
15941
|
+
* Also generates title and description based on the analysis
|
|
16071
15942
|
* All components are placed in a default MultiComponentContainer layout
|
|
16072
15943
|
* @param analysisContent - The text response containing component suggestions
|
|
16073
15944
|
* @param components - List of available components
|
|
16074
15945
|
* @param apiKey - Optional API key
|
|
16075
15946
|
* @param componentStreamCallback - Optional callback to stream primary KPI component as soon as it's identified
|
|
16076
|
-
* @returns Object containing matched components
|
|
15947
|
+
* @returns Object containing matched components and layout title/description
|
|
16077
15948
|
*/
|
|
16078
15949
|
async matchComponentsFromAnalysis(analysisContent, components, userPrompt, apiKey, componentStreamCallback, deferredTools, executedTools, collections, userId) {
|
|
16079
15950
|
const methodStartTime = Date.now();
|
|
@@ -16337,8 +16208,6 @@ ${executedToolsText}`);
|
|
|
16337
16208
|
logger.info(`[${this.getProviderName()}] ${idx + 1}. ${comp.componentType} (${comp.componentName}) - ${comp.originalSuggestion || "N/A"}`);
|
|
16338
16209
|
});
|
|
16339
16210
|
logger.file("\n=============================\nFull LLM response:", JSON.stringify(result, null, 2));
|
|
16340
|
-
const rawActions = result.actions || [];
|
|
16341
|
-
const actions = convertQuestionsToActions(rawActions);
|
|
16342
16211
|
const finalComponents = matchedComponents.map((mc) => {
|
|
16343
16212
|
const originalComponent = components.find((c) => c.name === mc.componentName);
|
|
16344
16213
|
if (!originalComponent) {
|
|
@@ -16381,12 +16250,11 @@ ${executedToolsText}`);
|
|
|
16381
16250
|
logger.error(`[${this.getProviderName()}] Skipping query validation - database execute function not available`);
|
|
16382
16251
|
}
|
|
16383
16252
|
const methodDuration = Date.now() - methodStartTime;
|
|
16384
|
-
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | components: ${validatedComponents.length}
|
|
16253
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | components: ${validatedComponents.length}`);
|
|
16385
16254
|
return {
|
|
16386
16255
|
components: validatedComponents,
|
|
16387
16256
|
layoutTitle,
|
|
16388
|
-
layoutDescription
|
|
16389
|
-
actions
|
|
16257
|
+
layoutDescription
|
|
16390
16258
|
};
|
|
16391
16259
|
} catch (error) {
|
|
16392
16260
|
const methodDuration = Date.now() - methodStartTime;
|
|
@@ -16395,8 +16263,7 @@ ${executedToolsText}`);
|
|
|
16395
16263
|
return {
|
|
16396
16264
|
components: [],
|
|
16397
16265
|
layoutTitle: "Dashboard",
|
|
16398
|
-
layoutDescription: "Failed to generate dashboard"
|
|
16399
|
-
actions: []
|
|
16266
|
+
layoutDescription: "Failed to generate dashboard"
|
|
16400
16267
|
};
|
|
16401
16268
|
}
|
|
16402
16269
|
}
|
|
@@ -16435,8 +16302,6 @@ ${executedToolsText}`);
|
|
|
16435
16302
|
});
|
|
16436
16303
|
logger.logLLMPrompt("classifyQuestionCategory", "system", extractPromptText(prompts.system));
|
|
16437
16304
|
logger.logLLMPrompt("classifyQuestionCategory", "user", extractPromptText(prompts.user));
|
|
16438
|
-
logger.logLLMPrompt("generateNextQuestions", "system", extractPromptText(prompts.system));
|
|
16439
|
-
logger.logLLMPrompt("generateNextQuestions", "user", extractPromptText(prompts.user));
|
|
16440
16305
|
const result = await LLM.stream(
|
|
16441
16306
|
{
|
|
16442
16307
|
sys: prompts.system,
|
|
@@ -16789,7 +16654,6 @@ ${executedToolsText}`);
|
|
|
16789
16654
|
data: {
|
|
16790
16655
|
text: textResponse,
|
|
16791
16656
|
// Include the streamed text showing all attempts
|
|
16792
|
-
actions: [],
|
|
16793
16657
|
method: `${this.getProviderName()}-text-response-max-attempts`
|
|
16794
16658
|
}
|
|
16795
16659
|
};
|
|
@@ -16802,21 +16666,8 @@ ${executedToolsText}`);
|
|
|
16802
16666
|
let matchedComponents = [];
|
|
16803
16667
|
let layoutTitle = "Dashboard";
|
|
16804
16668
|
let layoutDescription = "Multi-component dashboard";
|
|
16805
|
-
let actions = [];
|
|
16806
16669
|
if (category === "general") {
|
|
16807
16670
|
logger.info(`[${this.getProviderName()}] General category - wrapping text response in DynamicMarkdownBlock`);
|
|
16808
|
-
const nextQuestions = await this.generateNextQuestions(
|
|
16809
|
-
userPrompt,
|
|
16810
|
-
null,
|
|
16811
|
-
// no component
|
|
16812
|
-
void 0,
|
|
16813
|
-
// no component data
|
|
16814
|
-
apiKey,
|
|
16815
|
-
conversationHistory,
|
|
16816
|
-
textResponse
|
|
16817
|
-
// pass text response as context
|
|
16818
|
-
);
|
|
16819
|
-
actions = convertQuestionsToActions(nextQuestions);
|
|
16820
16671
|
const markdownContent2 = textResponse.replace(/<DashboardComponents>[\s\S]*?<\/DashboardComponents>/g, "").trim();
|
|
16821
16672
|
matchedComponents = [{
|
|
16822
16673
|
id: "dynamic-markdown-block",
|
|
@@ -16867,7 +16718,6 @@ ${executedToolsText}`);
|
|
|
16867
16718
|
matchedComponents = matchResult.components;
|
|
16868
16719
|
layoutTitle = matchResult.layoutTitle;
|
|
16869
16720
|
layoutDescription = matchResult.layoutDescription;
|
|
16870
|
-
actions = matchResult.actions;
|
|
16871
16721
|
}
|
|
16872
16722
|
let container_componet = null;
|
|
16873
16723
|
if (matchedComponents.length > 0) {
|
|
@@ -16881,19 +16731,17 @@ ${executedToolsText}`);
|
|
|
16881
16731
|
title: layoutTitle,
|
|
16882
16732
|
description: layoutDescription,
|
|
16883
16733
|
components: matchedComponents
|
|
16884
|
-
}
|
|
16885
|
-
actions
|
|
16734
|
+
}
|
|
16886
16735
|
}
|
|
16887
16736
|
};
|
|
16888
16737
|
}
|
|
16889
16738
|
const methodDuration = Date.now() - methodStartTime;
|
|
16890
|
-
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | result: success | components: ${matchedComponents.length}
|
|
16739
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | result: success | components: ${matchedComponents.length}`);
|
|
16891
16740
|
return {
|
|
16892
16741
|
success: true,
|
|
16893
16742
|
data: {
|
|
16894
16743
|
text: textResponse,
|
|
16895
16744
|
component: container_componet,
|
|
16896
|
-
actions,
|
|
16897
16745
|
method: `${this.getProviderName()}-text-response`
|
|
16898
16746
|
},
|
|
16899
16747
|
errors: []
|
|
@@ -16915,7 +16763,6 @@ ${executedToolsText}`);
|
|
|
16915
16763
|
errors,
|
|
16916
16764
|
data: {
|
|
16917
16765
|
text: "I apologize, but I encountered an error while processing your question. Please try rephrasing or ask something else.",
|
|
16918
|
-
actions: [],
|
|
16919
16766
|
method: `${this.getProviderName()}-text-response-error`
|
|
16920
16767
|
}
|
|
16921
16768
|
};
|
|
@@ -16957,7 +16804,6 @@ ${executedToolsText}`);
|
|
|
16957
16804
|
data: {
|
|
16958
16805
|
text: cachedTextResponse,
|
|
16959
16806
|
component: null,
|
|
16960
|
-
actions: conversationMatch.uiBlock?.actions || [],
|
|
16961
16807
|
reasoning: `Exact match from previous general conversation`,
|
|
16962
16808
|
method: `${this.getProviderName()}-semantic-match-general`,
|
|
16963
16809
|
semanticSimilarity: conversationMatch.similarity
|
|
@@ -16975,13 +16821,11 @@ ${executedToolsText}`);
|
|
|
16975
16821
|
logger.info(`[${this.getProviderName()}] Streaming cached text response to frontend`);
|
|
16976
16822
|
streamCallback(cachedTextResponse);
|
|
16977
16823
|
}
|
|
16978
|
-
const cachedActions = conversationMatch.uiBlock?.actions || [];
|
|
16979
16824
|
return {
|
|
16980
16825
|
success: true,
|
|
16981
16826
|
data: {
|
|
16982
16827
|
text: cachedTextResponse,
|
|
16983
16828
|
component,
|
|
16984
|
-
actions: cachedActions,
|
|
16985
16829
|
reasoning: `Exact match from previous conversation (${(conversationMatch.similarity * 100).toFixed(2)}% similarity)`,
|
|
16986
16830
|
method: `${this.getProviderName()}-semantic-match-exact`,
|
|
16987
16831
|
semanticSimilarity: conversationMatch.similarity
|
|
@@ -17006,13 +16850,11 @@ ${executedToolsText}`);
|
|
|
17006
16850
|
logger.info(`[${this.getProviderName()}] Streaming ${adaptResult.adaptedTextResponse ? "adapted" : "cached"} text response to frontend`);
|
|
17007
16851
|
streamCallback(textResponseToUse);
|
|
17008
16852
|
}
|
|
17009
|
-
const cachedActions = conversationMatch.uiBlock?.actions || [];
|
|
17010
16853
|
return {
|
|
17011
16854
|
success: true,
|
|
17012
16855
|
data: {
|
|
17013
16856
|
text: textResponseToUse,
|
|
17014
16857
|
component: adaptResult.adaptedComponent,
|
|
17015
|
-
actions: cachedActions,
|
|
17016
16858
|
reasoning: `Adapted from previous conversation: ${originalPrompt}`,
|
|
17017
16859
|
method: `${this.getProviderName()}-semantic-match`,
|
|
17018
16860
|
semanticSimilarity: conversationMatch.similarity,
|
|
@@ -17103,67 +16945,6 @@ ${executedToolsText}`);
|
|
|
17103
16945
|
};
|
|
17104
16946
|
}
|
|
17105
16947
|
}
|
|
17106
|
-
/**
|
|
17107
|
-
* Generate next questions that the user might ask based on the original prompt and generated component
|
|
17108
|
-
* This helps provide intelligent suggestions for follow-up queries
|
|
17109
|
-
* For general/conversational questions without components, pass textResponse instead
|
|
17110
|
-
*/
|
|
17111
|
-
async generateNextQuestions(originalUserPrompt, component, componentData, apiKey, conversationHistory, textResponse, signal) {
|
|
17112
|
-
const methodStartTime = Date.now();
|
|
17113
|
-
const methodName = "generateNextQuestions";
|
|
17114
|
-
const promptPreview = originalUserPrompt.substring(0, 50) + (originalUserPrompt.length > 50 ? "..." : "");
|
|
17115
|
-
logger.info(`[${this.getProviderName()}] [TIMING] START ${methodName} | model: ${this.getModelForTask("simple")} | prompt: "${promptPreview}"`);
|
|
17116
|
-
try {
|
|
17117
|
-
let component_info;
|
|
17118
|
-
if (component) {
|
|
17119
|
-
component_info = `
|
|
17120
|
-
Component Name: ${component.name}
|
|
17121
|
-
Component Type: ${component.type}
|
|
17122
|
-
Component Description: ${component.description || "No description"}
|
|
17123
|
-
Component Props: ${component.props ? JSON.stringify(component.props, null, 2) : "No props"}
|
|
17124
|
-
`;
|
|
17125
|
-
} else if (textResponse) {
|
|
17126
|
-
component_info = `
|
|
17127
|
-
Response Type: Text/Conversational Response
|
|
17128
|
-
Response Content: ${textResponse.substring(0, 1e3)}${textResponse.length > 1e3 ? "..." : ""}
|
|
17129
|
-
`;
|
|
17130
|
-
} else {
|
|
17131
|
-
component_info = "No component or response context available";
|
|
17132
|
-
}
|
|
17133
|
-
const component_data = componentData ? `Component Data: ${JSON.stringify(componentData, null, 2)}` : "";
|
|
17134
|
-
const prompts = await promptLoader.loadPrompts("actions", {
|
|
17135
|
-
ORIGINAL_USER_PROMPT: originalUserPrompt,
|
|
17136
|
-
COMPONENT_INFO: component_info,
|
|
17137
|
-
COMPONENT_DATA: component_data,
|
|
17138
|
-
CONVERSATION_HISTORY: conversationHistory || "No previous conversation",
|
|
17139
|
-
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
17140
|
-
});
|
|
17141
|
-
const result = await LLM.stream(
|
|
17142
|
-
{
|
|
17143
|
-
sys: prompts.system,
|
|
17144
|
-
user: prompts.user
|
|
17145
|
-
},
|
|
17146
|
-
{
|
|
17147
|
-
model: this.getModelForTask("simple"),
|
|
17148
|
-
maxTokens: MAX_TOKENS_NEXT_QUESTIONS,
|
|
17149
|
-
temperature: 0,
|
|
17150
|
-
apiKey: this.getApiKey(apiKey),
|
|
17151
|
-
signal
|
|
17152
|
-
},
|
|
17153
|
-
true
|
|
17154
|
-
// Parse as JSON
|
|
17155
|
-
);
|
|
17156
|
-
const nextQuestions = result.nextQuestions || [];
|
|
17157
|
-
const methodDuration = Date.now() - methodStartTime;
|
|
17158
|
-
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | questions: ${nextQuestions.length}`);
|
|
17159
|
-
return nextQuestions;
|
|
17160
|
-
} catch (error) {
|
|
17161
|
-
const methodDuration = Date.now() - methodStartTime;
|
|
17162
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
17163
|
-
logger.error(`[${this.getProviderName()}] [TIMING] FAILED ${methodName} in ${methodDuration}ms | error: ${errorMsg}`);
|
|
17164
|
-
return [];
|
|
17165
|
-
}
|
|
17166
|
-
}
|
|
17167
16948
|
};
|
|
17168
16949
|
|
|
17169
16950
|
// src/userResponse/anthropic.ts
|
|
@@ -17488,7 +17269,6 @@ var get_agent_user_response = async (prompt, components, anthropicApiKey, groqAp
|
|
|
17488
17269
|
data: {
|
|
17489
17270
|
text: cachedTextResponse,
|
|
17490
17271
|
component: rehydratedComponent,
|
|
17491
|
-
actions: conversationMatch.uiBlock?.actions || [],
|
|
17492
17272
|
reasoning: `Exact match from previous conversation`,
|
|
17493
17273
|
method: `${provider}-agent-exact-match`,
|
|
17494
17274
|
semanticSimilarity: 1,
|
|
@@ -17587,9 +17367,14 @@ var get_agent_user_response = async (prompt, components, anthropicApiKey, groqAp
|
|
|
17587
17367
|
logger.info(`[AgentFlow] Bound recipe ${directReplay.recipeId} no longer in store \u2014 falling back to ScriptMatcher LLM`);
|
|
17588
17368
|
}
|
|
17589
17369
|
}
|
|
17590
|
-
|
|
17370
|
+
const explicitEdit = hasExplicitEditPrefix(prompt);
|
|
17371
|
+
if (!scriptMatch && (process.env.SA_SKIP_SCRIPT_MATCH !== "true" || explicitEdit)) {
|
|
17591
17372
|
const scriptMatcher = new ScriptMatcher(scriptStore, { collections, userId, trace: runTrace });
|
|
17592
17373
|
scriptMatch = await scriptMatcher.match(prompt, apiKey, sourceAgentModel, signal, activeBindings);
|
|
17374
|
+
if (scriptMatch && scriptMatch.tier !== "edit" && process.env.SA_SKIP_SCRIPT_MATCH === "true") {
|
|
17375
|
+
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)`);
|
|
17376
|
+
scriptMatch = null;
|
|
17377
|
+
}
|
|
17593
17378
|
} else if (!scriptMatch) {
|
|
17594
17379
|
logger.info("[AgentFlow] ScriptMatcher skipped (SA_SKIP_SCRIPT_MATCH=true) \u2014 proceeding with fresh generation");
|
|
17595
17380
|
}
|
|
@@ -17743,7 +17528,6 @@ ${JSON.stringify(preview, null, 2)}
|
|
|
17743
17528
|
let matchedComponents2 = [];
|
|
17744
17529
|
let layoutTitle2 = "Dashboard";
|
|
17745
17530
|
let layoutDescription2 = "Multi-component dashboard";
|
|
17746
|
-
let actions2 = [];
|
|
17747
17531
|
if (components && components.length > 0 && scriptExecutedTools.length > 0) {
|
|
17748
17532
|
logger.info(`[AgentFlow] Script flow \u2014 generating components (lightweight)`);
|
|
17749
17533
|
if (streamBuffer.hasCallback()) {
|
|
@@ -17852,7 +17636,6 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${scriptMatch
|
|
|
17852
17636
|
matchedComponents2 = compResult.components;
|
|
17853
17637
|
layoutTitle2 = compResult.layoutTitle;
|
|
17854
17638
|
layoutDescription2 = compResult.layoutDescription;
|
|
17855
|
-
actions2 = compResult.actions;
|
|
17856
17639
|
if (compResult.componentSpecs.length > 0) {
|
|
17857
17640
|
try {
|
|
17858
17641
|
scriptMatch.recipe.components = compResult.componentSpecs;
|
|
@@ -17919,15 +17702,10 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${scriptMatch
|
|
|
17919
17702
|
description: layoutDescription2,
|
|
17920
17703
|
components: securedComponents2,
|
|
17921
17704
|
...Object.keys(queryMap2).length > 0 && { _queryMap: queryMap2 }
|
|
17922
|
-
}
|
|
17923
|
-
actions: actions2
|
|
17705
|
+
}
|
|
17924
17706
|
}
|
|
17925
17707
|
};
|
|
17926
17708
|
}
|
|
17927
|
-
actions2 = [];
|
|
17928
|
-
if (containerComponent2) {
|
|
17929
|
-
containerComponent2.props.actions = [];
|
|
17930
|
-
}
|
|
17931
17709
|
const elapsedTime2 = Date.now() - startTime;
|
|
17932
17710
|
logger.info(`[AgentFlow] Script flow complete | ${scriptResult.executedQueries.length} queries | ${matchedComponents2.length} components | ${elapsedTime2}ms`);
|
|
17933
17711
|
return {
|
|
@@ -17936,7 +17714,6 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${scriptMatch
|
|
|
17936
17714
|
text: scriptTextResponse,
|
|
17937
17715
|
...replayProgramAnswer ? { programAnswer: replayProgramAnswer } : {},
|
|
17938
17716
|
component: containerComponent2,
|
|
17939
|
-
actions: actions2,
|
|
17940
17717
|
method: isDisplayEdit ? `${provider}-script-display-edit` : `${provider}-script-response`,
|
|
17941
17718
|
// Bind the answer to the replayed recipe so a follow-up
|
|
17942
17719
|
// ("use mode instead") can edit THIS script.
|
|
@@ -18057,7 +17834,6 @@ BEGIN NOW. Your VERY FIRST action MUST be a \`write_script\` tool call containin
|
|
|
18057
17834
|
data: {
|
|
18058
17835
|
text: "",
|
|
18059
17836
|
component: workflowComponent,
|
|
18060
|
-
actions: [],
|
|
18061
17837
|
method: `${provider}-agent-workflow`,
|
|
18062
17838
|
...runTrace ? { trace: runTrace } : {}
|
|
18063
17839
|
},
|
|
@@ -18113,7 +17889,6 @@ BEGIN NOW. Your VERY FIRST action MUST be a \`write_script\` tool call containin
|
|
|
18113
17889
|
let matchedComponents = [];
|
|
18114
17890
|
let layoutTitle = "Dashboard";
|
|
18115
17891
|
let layoutDescription = "Multi-component dashboard";
|
|
18116
|
-
let actions = [];
|
|
18117
17892
|
let authoredComponentSpecs = [];
|
|
18118
17893
|
if (!hasExecutedTools) {
|
|
18119
17894
|
logger.info(`[AgentFlow] No tools executed \u2014 general question, wrapping in DynamicMarkdownBlock`);
|
|
@@ -18267,7 +18042,6 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${carriedRequ
|
|
|
18267
18042
|
matchedComponents = compResult.components;
|
|
18268
18043
|
layoutTitle = compResult.layoutTitle;
|
|
18269
18044
|
layoutDescription = compResult.layoutDescription;
|
|
18270
|
-
actions = compResult.actions;
|
|
18271
18045
|
authoredComponentSpecs = compResult.componentSpecs;
|
|
18272
18046
|
usedLightweight = true;
|
|
18273
18047
|
logger.info(`[AgentFlow] Lightweight component gen succeeded \u2014 ${matchedComponents.length} components`);
|
|
@@ -18319,13 +18093,10 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${carriedRequ
|
|
|
18319
18093
|
components: securedComponents,
|
|
18320
18094
|
// Persist queryId → SQL mapping so cached responses can re-register queries
|
|
18321
18095
|
...Object.keys(queryMap).length > 0 && { _queryMap: queryMap }
|
|
18322
|
-
}
|
|
18323
|
-
actions
|
|
18096
|
+
}
|
|
18324
18097
|
}
|
|
18325
18098
|
};
|
|
18326
18099
|
}
|
|
18327
|
-
if (containerComponent) {
|
|
18328
|
-
}
|
|
18329
18100
|
if (agentResponse.savedScript && editContext) {
|
|
18330
18101
|
try {
|
|
18331
18102
|
const authored = agentResponse.savedScript;
|
|
@@ -18452,7 +18223,6 @@ RENDERING REQUIREMENT (overrides the default choice of component): ${carriedRequ
|
|
|
18452
18223
|
${programAnswer}` : textResponse,
|
|
18453
18224
|
...programAnswer ? { programAnswer } : {},
|
|
18454
18225
|
component: containerComponent,
|
|
18455
|
-
actions,
|
|
18456
18226
|
method: editContext ? `${provider}-script-edit-response` : `${provider}-agent-response`,
|
|
18457
18227
|
...scriptBinding ? { scriptBinding } : {},
|
|
18458
18228
|
...noDataAnswer ? { noDataAnswer: true } : {},
|
|
@@ -18838,10 +18608,12 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
18838
18608
|
const requestStartTime = Date.now();
|
|
18839
18609
|
logger.info(`Starting user prompt request with ${components.length} components`);
|
|
18840
18610
|
const conversationScriptStore = new ScriptStore({ collections, projectId: process.env.SUPERATOM_PROJECT_ID || "" });
|
|
18611
|
+
const getRecentForContext = collections?.["user-conversations"]?.["getRecentForContext"];
|
|
18841
18612
|
const conversationHistory = await thread.getConversationContext(
|
|
18842
18613
|
CONTEXT_CONFIG.MAX_CONVERSATION_CONTEXT_BLOCKS,
|
|
18843
18614
|
existingUiBlockId,
|
|
18844
|
-
async (recipeId, version) => (await conversationScriptStore.getVersion(recipeId, version))?.scriptBody ?? null
|
|
18615
|
+
async (recipeId, version) => (await conversationScriptStore.getVersion(recipeId, version))?.scriptBody ?? null,
|
|
18616
|
+
getRecentForContext && userId && threadId ? async (limit) => (await getRecentForContext({ userId, threadId, limit }))?.data ?? [] : void 0
|
|
18845
18617
|
);
|
|
18846
18618
|
const MAX_EDIT_CANDIDATES = 5;
|
|
18847
18619
|
let activeScriptBindings = thread.getScriptBindings(MAX_EDIT_CANDIDATES, existingUiBlockId);
|
|
@@ -18866,7 +18638,7 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
18866
18638
|
`[UserPromptRequest] ${activeScriptBindings.length} editable script(s) in thread: ` + activeScriptBindings.map((b) => b.name || b.recipeId).join(", ")
|
|
18867
18639
|
);
|
|
18868
18640
|
}
|
|
18869
|
-
const uiBlock = new UIBlock(prompt, {}, {},
|
|
18641
|
+
const uiBlock = new UIBlock(prompt, {}, {}, existingUiBlockId, null);
|
|
18870
18642
|
thread.addUIBlock(uiBlock);
|
|
18871
18643
|
logger.info(`Registered UIBlock (early): ${existingUiBlockId} in Thread: ${threadId}`);
|
|
18872
18644
|
const abortController = new AbortController();
|
|
@@ -19054,7 +18826,6 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19054
18826
|
}
|
|
19055
18827
|
let component = null;
|
|
19056
18828
|
let textResponse = null;
|
|
19057
|
-
let actions = [];
|
|
19058
18829
|
if (userResponse.data) {
|
|
19059
18830
|
if (typeof userResponse.data === "object") {
|
|
19060
18831
|
if ("component" in userResponse.data) {
|
|
@@ -19065,9 +18836,6 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19065
18836
|
} else if ("textResponse" in userResponse.data) {
|
|
19066
18837
|
textResponse = userResponse.data.textResponse;
|
|
19067
18838
|
}
|
|
19068
|
-
if ("actions" in userResponse.data) {
|
|
19069
|
-
actions = userResponse.data.actions || [];
|
|
19070
|
-
}
|
|
19071
18839
|
}
|
|
19072
18840
|
}
|
|
19073
18841
|
let finalTextResponse = responseMode === "text" && accumulatedStreamResponse ? accumulatedStreamResponse : textResponse;
|
|
@@ -19085,10 +18853,6 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
19085
18853
|
}
|
|
19086
18854
|
const programAnswer = userResponse.data?.programAnswer;
|
|
19087
18855
|
if (programAnswer) uiBlock.setProgramAnswer(programAnswer);
|
|
19088
|
-
if (actions.length > 0) {
|
|
19089
|
-
uiBlock.setActions(actions);
|
|
19090
|
-
logger.info(`Stored ${actions.length} actions in UIBlock: ${uiBlockId}`);
|
|
19091
|
-
}
|
|
19092
18856
|
logger.info(`Completed UIBlock: ${uiBlockId} in Thread: ${threadId}`);
|
|
19093
18857
|
let savedConversationId;
|
|
19094
18858
|
let savedResponse;
|
|
@@ -19354,229 +19118,6 @@ function sendResponse(id, res, sendMessage, clientId) {
|
|
|
19354
19118
|
sendMessage(response);
|
|
19355
19119
|
}
|
|
19356
19120
|
|
|
19357
|
-
// src/userResponse/next-questions.ts
|
|
19358
|
-
async function generateNextQuestions(originalUserPrompt, component, componentData, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, conversationHistory) {
|
|
19359
|
-
try {
|
|
19360
|
-
logger.debug("[generateNextQuestions] Starting next questions generation");
|
|
19361
|
-
logger.debug(`[generateNextQuestions] User prompt: "${originalUserPrompt?.substring(0, 50)}..."`);
|
|
19362
|
-
logger.debug(`[generateNextQuestions] Component: ${component?.name || "unknown"} (${component?.type || "unknown"})`);
|
|
19363
|
-
logger.debug(`[generateNextQuestions] Component data available: ${componentData ? "yes" : "no"}`);
|
|
19364
|
-
const providers = llmProviders || ["anthropic", "gemini", "openai", "groq"];
|
|
19365
|
-
logger.info(`[generateNextQuestions] Using LLM providers: [${providers.join(", ")}]`);
|
|
19366
|
-
if (conversationHistory && conversationHistory.length > 0) {
|
|
19367
|
-
const exchangeCount = conversationHistory.split("\n").filter((l) => l.startsWith("Q")).length;
|
|
19368
|
-
logger.debug(`[generateNextQuestions] Using conversation history with ${exchangeCount} previous exchanges`);
|
|
19369
|
-
} else {
|
|
19370
|
-
logger.debug("[generateNextQuestions] No conversation history available");
|
|
19371
|
-
}
|
|
19372
|
-
for (let i = 0; i < providers.length; i++) {
|
|
19373
|
-
const provider = providers[i];
|
|
19374
|
-
const isLastProvider = i === providers.length - 1;
|
|
19375
|
-
try {
|
|
19376
|
-
logger.info(`[generateNextQuestions] Attempting provider: ${provider} (${i + 1}/${providers.length})`);
|
|
19377
|
-
let result = [];
|
|
19378
|
-
if (provider === "groq") {
|
|
19379
|
-
logger.debug("[generateNextQuestions] Using Groq LLM for next questions");
|
|
19380
|
-
result = await groqLLM.generateNextQuestions(
|
|
19381
|
-
originalUserPrompt,
|
|
19382
|
-
component,
|
|
19383
|
-
componentData,
|
|
19384
|
-
groqApiKey,
|
|
19385
|
-
conversationHistory
|
|
19386
|
-
);
|
|
19387
|
-
} else if (provider === "gemini") {
|
|
19388
|
-
logger.debug("[generateNextQuestions] Using Gemini LLM for next questions");
|
|
19389
|
-
result = await geminiLLM.generateNextQuestions(
|
|
19390
|
-
originalUserPrompt,
|
|
19391
|
-
component,
|
|
19392
|
-
componentData,
|
|
19393
|
-
geminiApiKey,
|
|
19394
|
-
conversationHistory
|
|
19395
|
-
);
|
|
19396
|
-
} else if (provider === "openai") {
|
|
19397
|
-
logger.debug("[generateNextQuestions] Using OpenAI LLM for next questions");
|
|
19398
|
-
result = await openaiLLM.generateNextQuestions(
|
|
19399
|
-
originalUserPrompt,
|
|
19400
|
-
component,
|
|
19401
|
-
componentData,
|
|
19402
|
-
openaiApiKey,
|
|
19403
|
-
conversationHistory
|
|
19404
|
-
);
|
|
19405
|
-
} else {
|
|
19406
|
-
logger.debug("[generateNextQuestions] Using Anthropic LLM for next questions");
|
|
19407
|
-
result = await anthropicLLM.generateNextQuestions(
|
|
19408
|
-
originalUserPrompt,
|
|
19409
|
-
component,
|
|
19410
|
-
componentData,
|
|
19411
|
-
anthropicApiKey,
|
|
19412
|
-
conversationHistory
|
|
19413
|
-
);
|
|
19414
|
-
}
|
|
19415
|
-
if (result && result.length > 0) {
|
|
19416
|
-
logger.info(`[generateNextQuestions] Successfully generated ${result.length} questions with ${provider}`);
|
|
19417
|
-
logger.debug(`[generateNextQuestions] Questions: ${JSON.stringify(result)}`);
|
|
19418
|
-
return result;
|
|
19419
|
-
}
|
|
19420
|
-
logger.warn(`[generateNextQuestions] No questions generated from ${provider}${!isLastProvider ? ", trying next provider..." : ""}`);
|
|
19421
|
-
} catch (providerError) {
|
|
19422
|
-
const errorMsg = providerError instanceof Error ? providerError.message : String(providerError);
|
|
19423
|
-
logger.error(`[generateNextQuestions] Provider ${provider} failed: ${errorMsg}`);
|
|
19424
|
-
logger.debug(`[generateNextQuestions] Provider error details:`, providerError);
|
|
19425
|
-
if (!isLastProvider) {
|
|
19426
|
-
logger.info(`[generateNextQuestions] Provider ${provider} failed, trying next provider...`);
|
|
19427
|
-
}
|
|
19428
|
-
continue;
|
|
19429
|
-
}
|
|
19430
|
-
}
|
|
19431
|
-
logger.warn("[generateNextQuestions] All providers failed or returned no questions");
|
|
19432
|
-
return [];
|
|
19433
|
-
} catch (error) {
|
|
19434
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
19435
|
-
const errorStack = error instanceof Error ? error.stack : void 0;
|
|
19436
|
-
logger.error(`[generateNextQuestions] Error generating next questions: ${errorMsg}`);
|
|
19437
|
-
logger.debug("[generateNextQuestions] Error stack trace:", errorStack);
|
|
19438
|
-
return [];
|
|
19439
|
-
}
|
|
19440
|
-
}
|
|
19441
|
-
|
|
19442
|
-
// src/handlers/actions-request.ts
|
|
19443
|
-
async function handleActionsRequest(data, sendMessage, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders) {
|
|
19444
|
-
try {
|
|
19445
|
-
logger.debug("[ACTIONS_REQ] Parsing incoming actions request");
|
|
19446
|
-
const actionsRequest = ActionsRequestMessageSchema.parse(data);
|
|
19447
|
-
const { id, payload } = actionsRequest;
|
|
19448
|
-
const { SA_RUNTIME } = payload;
|
|
19449
|
-
const wsId = actionsRequest.from.id || "unknown";
|
|
19450
|
-
logger.info(`[ACTIONS_REQ ${id}] Processing actions request from client: ${wsId}`);
|
|
19451
|
-
logger.debug(`[ACTIONS_REQ ${id}] Request payload:`, JSON.stringify(payload, null, 2).substring(0, 200));
|
|
19452
|
-
if (!SA_RUNTIME) {
|
|
19453
|
-
logger.error(`[ACTIONS_REQ ${id}] SA_RUNTIME missing from request`);
|
|
19454
|
-
sendResponse2(id, {
|
|
19455
|
-
success: false,
|
|
19456
|
-
error: "SA_RUNTIME with threadId and uiBlockId is required"
|
|
19457
|
-
}, sendMessage, wsId);
|
|
19458
|
-
return;
|
|
19459
|
-
}
|
|
19460
|
-
const uiBlockId = SA_RUNTIME.uiBlockId;
|
|
19461
|
-
const threadId = SA_RUNTIME.threadId;
|
|
19462
|
-
logger.debug(`[ACTIONS_REQ ${id}] SA_RUNTIME validated - threadId: ${threadId}, uiBlockId: ${uiBlockId}`);
|
|
19463
|
-
const threadManager = ThreadManager.getInstance();
|
|
19464
|
-
const thread = threadManager.getThread(threadId);
|
|
19465
|
-
if (!thread) {
|
|
19466
|
-
logger.error(`[ACTIONS_REQ ${id}] Thread '${threadId}' not found`);
|
|
19467
|
-
sendResponse2(id, {
|
|
19468
|
-
success: false,
|
|
19469
|
-
error: `Thread '${threadId}' not found`
|
|
19470
|
-
}, sendMessage, wsId);
|
|
19471
|
-
return;
|
|
19472
|
-
}
|
|
19473
|
-
logger.debug(`[ACTIONS_REQ ${id}] Thread found with ${thread.getUIBlocks().length} UIBlocks`);
|
|
19474
|
-
logger.debug(`[ACTIONS_REQ ${id}] Retrieving UIBlock: ${uiBlockId}`);
|
|
19475
|
-
const uiBlock = thread.getUIBlock(uiBlockId);
|
|
19476
|
-
if (!uiBlock) {
|
|
19477
|
-
logger.error(`[ACTIONS_REQ ${id}] UIBlock '${uiBlockId}' not found in thread '${threadId}'`);
|
|
19478
|
-
sendResponse2(id, {
|
|
19479
|
-
success: false,
|
|
19480
|
-
error: `UIBlock '${uiBlockId}' not found in thread '${threadId}'`
|
|
19481
|
-
}, sendMessage, wsId);
|
|
19482
|
-
return;
|
|
19483
|
-
}
|
|
19484
|
-
logger.info(`[ACTIONS_REQ ${id}] UIBlock retrieved successfully`);
|
|
19485
|
-
logger.debug(`[ACTIONS_REQ ${id}] Extracting data from UIBlock`);
|
|
19486
|
-
const userQuestion = uiBlock.getUserQuestion();
|
|
19487
|
-
const component = uiBlock.getComponentMetadata();
|
|
19488
|
-
const componentData = uiBlock.getComponentData();
|
|
19489
|
-
logger.debug(`[ACTIONS_REQ ${id}] User question: "${userQuestion?.substring(0, 50)}..."`);
|
|
19490
|
-
logger.debug(`[ACTIONS_REQ ${id}] Component: ${component?.name || "unknown"} (${component?.type || "unknown"})`);
|
|
19491
|
-
logger.debug(`[ACTIONS_REQ ${id}] Component data available: ${componentData ? "yes" : "no"}`);
|
|
19492
|
-
logger.debug(`[ACTIONS_REQ ${id}] Extracting conversation history (max ${CONTEXT_CONFIG.MAX_CONVERSATION_CONTEXT_BLOCKS} blocks)`);
|
|
19493
|
-
const conversationHistory = await thread.getConversationContext(CONTEXT_CONFIG.MAX_CONVERSATION_CONTEXT_BLOCKS, uiBlockId);
|
|
19494
|
-
const historyLineCount = conversationHistory.split("\n").filter((l) => l.trim()).length;
|
|
19495
|
-
logger.info(`[ACTIONS_REQ ${id}] Conversation history extracted: ${historyLineCount} lines`);
|
|
19496
|
-
logger.debug(`[ACTIONS_REQ ${id}] Conversation history preview:
|
|
19497
|
-
${conversationHistory.substring(0, 200)}...`);
|
|
19498
|
-
logger.info(`[ACTIONS_REQ ${id}] Generating actions for UIBlock: ${uiBlockId}, component: ${component?.name || "unknown"}`);
|
|
19499
|
-
logger.debug(`[ACTIONS_REQ ${id}] Checking if actions are already cached`);
|
|
19500
|
-
const startTime = Date.now();
|
|
19501
|
-
const actions = await uiBlock.getOrFetchActions(async () => {
|
|
19502
|
-
logger.info(`[ACTIONS_REQ ${id}] Actions not cached, generating new actions...`);
|
|
19503
|
-
logger.info(`[ACTIONS_REQ ${id}] Starting next questions generation with ${llmProviders?.join(", ") || "default"} providers`);
|
|
19504
|
-
const nextQuestions = await generateNextQuestions(
|
|
19505
|
-
userQuestion,
|
|
19506
|
-
component,
|
|
19507
|
-
componentData,
|
|
19508
|
-
anthropicApiKey,
|
|
19509
|
-
groqApiKey,
|
|
19510
|
-
geminiApiKey,
|
|
19511
|
-
openaiApiKey,
|
|
19512
|
-
llmProviders,
|
|
19513
|
-
conversationHistory
|
|
19514
|
-
);
|
|
19515
|
-
logger.info(`[ACTIONS_REQ ${id}] Generated ${nextQuestions.length} questions`);
|
|
19516
|
-
logger.debug(`[ACTIONS_REQ ${id}] Questions: ${JSON.stringify(nextQuestions)}`);
|
|
19517
|
-
logger.debug(`[ACTIONS_REQ ${id}] Converting questions to actions format`);
|
|
19518
|
-
const convertedActions = nextQuestions.map((question, index) => ({
|
|
19519
|
-
id: `action_${index}_${Date.now()}`,
|
|
19520
|
-
name: question,
|
|
19521
|
-
type: "next_question",
|
|
19522
|
-
question
|
|
19523
|
-
}));
|
|
19524
|
-
logger.debug(`[ACTIONS_REQ ${id}] Converted ${convertedActions.length} actions`);
|
|
19525
|
-
return convertedActions;
|
|
19526
|
-
});
|
|
19527
|
-
const processingTime = Date.now() - startTime;
|
|
19528
|
-
logger.info(`[ACTIONS_REQ ${id}] Actions retrieved in ${processingTime}ms - ${actions.length} actions total`);
|
|
19529
|
-
if (actions.length > 0) {
|
|
19530
|
-
logger.info(`[ACTIONS_REQ ${id}] Generated ${actions.length} follow-up questions successfully`);
|
|
19531
|
-
logger.debug(`[ACTIONS_REQ ${id}] Actions: ${actions.map((a) => a.name).join(", ")}`);
|
|
19532
|
-
} else {
|
|
19533
|
-
logger.warn(`[ACTIONS_REQ ${id}] No actions generated`);
|
|
19534
|
-
}
|
|
19535
|
-
logger.debug(`[ACTIONS_REQ ${id}] Sending successful response to client`);
|
|
19536
|
-
sendResponse2(id, {
|
|
19537
|
-
success: true,
|
|
19538
|
-
data: {
|
|
19539
|
-
actions,
|
|
19540
|
-
componentName: component?.name,
|
|
19541
|
-
componentId: component?.id,
|
|
19542
|
-
uiBlockId,
|
|
19543
|
-
threadId
|
|
19544
|
-
}
|
|
19545
|
-
}, sendMessage, wsId);
|
|
19546
|
-
logger.info(`[ACTIONS_REQ ${id}] \u2713 Actions request completed successfully`);
|
|
19547
|
-
} catch (error) {
|
|
19548
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
19549
|
-
const errorStack = error instanceof Error ? error.stack : void 0;
|
|
19550
|
-
logger.error(`[ACTIONS_REQ] Failed to handle actions request: ${errorMessage}`);
|
|
19551
|
-
logger.debug(`[ACTIONS_REQ] Error stack trace:`, errorStack);
|
|
19552
|
-
sendResponse2(null, {
|
|
19553
|
-
success: false,
|
|
19554
|
-
error: errorMessage
|
|
19555
|
-
}, sendMessage);
|
|
19556
|
-
logger.info("[ACTIONS_REQ] \u2717 Actions request completed with errors");
|
|
19557
|
-
}
|
|
19558
|
-
}
|
|
19559
|
-
function sendResponse2(id, res, sendMessage, clientId) {
|
|
19560
|
-
const response = {
|
|
19561
|
-
id: id || "unknown",
|
|
19562
|
-
type: "ACTIONS_RES",
|
|
19563
|
-
from: { type: "data-agent" },
|
|
19564
|
-
to: {
|
|
19565
|
-
type: "runtime",
|
|
19566
|
-
id: clientId
|
|
19567
|
-
},
|
|
19568
|
-
payload: {
|
|
19569
|
-
...res
|
|
19570
|
-
}
|
|
19571
|
-
};
|
|
19572
|
-
logger.debug(`[ACTIONS_RES ${id || "unknown"}] Sending ${res.success ? "successful" : "failed"} response to client`);
|
|
19573
|
-
logger.debug(`[ACTIONS_RES ${id || "unknown"}] Response payload size: ${JSON.stringify(response).length} bytes`);
|
|
19574
|
-
if (res.data?.actions) {
|
|
19575
|
-
logger.debug(`[ACTIONS_RES ${id || "unknown"}] Sending ${res.data.actions.length} actions`);
|
|
19576
|
-
}
|
|
19577
|
-
sendMessage(response);
|
|
19578
|
-
}
|
|
19579
|
-
|
|
19580
19121
|
// src/handlers/components-list-response.ts
|
|
19581
19122
|
async function handleComponentListResponse(data, storeComponents, collections) {
|
|
19582
19123
|
try {
|
|
@@ -19651,7 +19192,7 @@ async function handleUsersRequest(data, collections, sendMessage) {
|
|
|
19651
19192
|
const limit = requestData?.limit;
|
|
19652
19193
|
const sort = requestData?.sort;
|
|
19653
19194
|
if (from.type !== "admin" && operation !== "getOne" && operation !== "getAll" && operation !== "query") {
|
|
19654
|
-
|
|
19195
|
+
sendResponse2(id, {
|
|
19655
19196
|
success: false,
|
|
19656
19197
|
error: "Unauthorized: Only admin can manage users"
|
|
19657
19198
|
}, sendMessage, from.id);
|
|
@@ -19679,14 +19220,14 @@ async function handleUsersRequest(data, collections, sendMessage) {
|
|
|
19679
19220
|
await handleQuery(id, filters, limit, sort, executeCollection, userManager, sendMessage, from.id);
|
|
19680
19221
|
break;
|
|
19681
19222
|
default:
|
|
19682
|
-
|
|
19223
|
+
sendResponse2(id, {
|
|
19683
19224
|
success: false,
|
|
19684
19225
|
error: `Unknown operation: ${operation}`
|
|
19685
19226
|
}, sendMessage, from.id);
|
|
19686
19227
|
}
|
|
19687
19228
|
} catch (error) {
|
|
19688
19229
|
logger.error("Failed to handle users request:", error);
|
|
19689
|
-
|
|
19230
|
+
sendResponse2(null, {
|
|
19690
19231
|
success: false,
|
|
19691
19232
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
19692
19233
|
}, sendMessage);
|
|
@@ -19695,14 +19236,14 @@ async function handleUsersRequest(data, collections, sendMessage) {
|
|
|
19695
19236
|
async function handleCreate(id, userData, executeCollection, userManager, sendMessage, clientId) {
|
|
19696
19237
|
const { username, email, password, fullname, role, userInfo } = userData;
|
|
19697
19238
|
if (!username || username.trim().length === 0) {
|
|
19698
|
-
|
|
19239
|
+
sendResponse2(id, {
|
|
19699
19240
|
success: false,
|
|
19700
19241
|
error: "Username is required and cannot be empty"
|
|
19701
19242
|
}, sendMessage, clientId);
|
|
19702
19243
|
return;
|
|
19703
19244
|
}
|
|
19704
19245
|
if (!password || password.trim().length === 0) {
|
|
19705
|
-
|
|
19246
|
+
sendResponse2(id, {
|
|
19706
19247
|
success: false,
|
|
19707
19248
|
error: "Password is required and cannot be empty"
|
|
19708
19249
|
}, sendMessage, clientId);
|
|
@@ -19711,7 +19252,7 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19711
19252
|
if (email && email.trim().length > 0) {
|
|
19712
19253
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
19713
19254
|
if (!emailRegex.test(email)) {
|
|
19714
|
-
|
|
19255
|
+
sendResponse2(id, {
|
|
19715
19256
|
success: false,
|
|
19716
19257
|
error: "Invalid email format"
|
|
19717
19258
|
}, sendMessage, clientId);
|
|
@@ -19729,7 +19270,7 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19729
19270
|
});
|
|
19730
19271
|
if (result && result.success) {
|
|
19731
19272
|
logger.info(`[DB] User created successfully: ${username}`);
|
|
19732
|
-
|
|
19273
|
+
sendResponse2(id, {
|
|
19733
19274
|
success: true,
|
|
19734
19275
|
data: {
|
|
19735
19276
|
id: result.data?.id,
|
|
@@ -19747,14 +19288,14 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19747
19288
|
}
|
|
19748
19289
|
try {
|
|
19749
19290
|
if (userManager.userExists(username)) {
|
|
19750
|
-
|
|
19291
|
+
sendResponse2(id, {
|
|
19751
19292
|
success: false,
|
|
19752
19293
|
error: `User '${username}' already exists`
|
|
19753
19294
|
}, sendMessage, clientId);
|
|
19754
19295
|
return;
|
|
19755
19296
|
}
|
|
19756
19297
|
if (email && userManager.getUserByEmail(email)) {
|
|
19757
|
-
|
|
19298
|
+
sendResponse2(id, {
|
|
19758
19299
|
success: false,
|
|
19759
19300
|
error: `User with email '${email}' already exists`
|
|
19760
19301
|
}, sendMessage, clientId);
|
|
@@ -19775,7 +19316,7 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19775
19316
|
}
|
|
19776
19317
|
const newUser = userManager.createUser(newUserData);
|
|
19777
19318
|
logger.info(`[FILE] User '${username}' created successfully`);
|
|
19778
|
-
|
|
19319
|
+
sendResponse2(id, {
|
|
19779
19320
|
success: true,
|
|
19780
19321
|
data: {
|
|
19781
19322
|
username: newUser.username,
|
|
@@ -19786,7 +19327,7 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19786
19327
|
}
|
|
19787
19328
|
}, sendMessage, clientId);
|
|
19788
19329
|
} catch (error) {
|
|
19789
|
-
|
|
19330
|
+
sendResponse2(id, {
|
|
19790
19331
|
success: false,
|
|
19791
19332
|
error: error instanceof Error ? error.message : "Failed to create user"
|
|
19792
19333
|
}, sendMessage, clientId);
|
|
@@ -19795,7 +19336,7 @@ async function handleCreate(id, userData, executeCollection, userManager, sendMe
|
|
|
19795
19336
|
async function handleUpdate(id, numericId, userData, executeCollection, userManager, sendMessage, clientId) {
|
|
19796
19337
|
const { username, email, password, fullname, role, userInfo } = userData;
|
|
19797
19338
|
if (!numericId && !username) {
|
|
19798
|
-
|
|
19339
|
+
sendResponse2(id, {
|
|
19799
19340
|
success: false,
|
|
19800
19341
|
error: "User ID or username is required"
|
|
19801
19342
|
}, sendMessage, clientId);
|
|
@@ -19814,7 +19355,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19814
19355
|
});
|
|
19815
19356
|
if (result && result.success) {
|
|
19816
19357
|
logger.info(`[DB] User updated successfully, ID: ${numericId}`);
|
|
19817
|
-
|
|
19358
|
+
sendResponse2(id, {
|
|
19818
19359
|
success: true,
|
|
19819
19360
|
data: {
|
|
19820
19361
|
id: result.data?.id,
|
|
@@ -19832,14 +19373,14 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19832
19373
|
}
|
|
19833
19374
|
}
|
|
19834
19375
|
if (!username || username.trim().length === 0) {
|
|
19835
|
-
|
|
19376
|
+
sendResponse2(id, {
|
|
19836
19377
|
success: false,
|
|
19837
19378
|
error: "Username is required for file-based storage update"
|
|
19838
19379
|
}, sendMessage, clientId);
|
|
19839
19380
|
return;
|
|
19840
19381
|
}
|
|
19841
19382
|
if (!userManager.userExists(username)) {
|
|
19842
|
-
|
|
19383
|
+
sendResponse2(id, {
|
|
19843
19384
|
success: false,
|
|
19844
19385
|
error: `User '${username}' not found`
|
|
19845
19386
|
}, sendMessage, clientId);
|
|
@@ -19850,7 +19391,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19850
19391
|
if (email.trim().length > 0) {
|
|
19851
19392
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
19852
19393
|
if (!emailRegex.test(email)) {
|
|
19853
|
-
|
|
19394
|
+
sendResponse2(id, {
|
|
19854
19395
|
success: false,
|
|
19855
19396
|
error: "Invalid email format"
|
|
19856
19397
|
}, sendMessage, clientId);
|
|
@@ -19858,7 +19399,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19858
19399
|
}
|
|
19859
19400
|
const existingUser = userManager.getUserByEmail(email);
|
|
19860
19401
|
if (existingUser && existingUser.username !== username) {
|
|
19861
|
-
|
|
19402
|
+
sendResponse2(id, {
|
|
19862
19403
|
success: false,
|
|
19863
19404
|
error: `Email '${email}' is already used by another user`
|
|
19864
19405
|
}, sendMessage, clientId);
|
|
@@ -19879,7 +19420,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19879
19420
|
updates.role = role.trim().length > 0 ? role.trim() : void 0;
|
|
19880
19421
|
}
|
|
19881
19422
|
if (Object.keys(updates).length === 0) {
|
|
19882
|
-
|
|
19423
|
+
sendResponse2(id, {
|
|
19883
19424
|
success: false,
|
|
19884
19425
|
error: "No fields to update. Please provide at least one field to update."
|
|
19885
19426
|
}, sendMessage, clientId);
|
|
@@ -19888,7 +19429,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19888
19429
|
try {
|
|
19889
19430
|
const updatedUser = userManager.updateUser(username, updates);
|
|
19890
19431
|
logger.info(`[FILE] User '${username}' updated successfully`);
|
|
19891
|
-
|
|
19432
|
+
sendResponse2(id, {
|
|
19892
19433
|
success: true,
|
|
19893
19434
|
data: {
|
|
19894
19435
|
username: updatedUser.username,
|
|
@@ -19899,7 +19440,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19899
19440
|
}
|
|
19900
19441
|
}, sendMessage, clientId);
|
|
19901
19442
|
} catch (error) {
|
|
19902
|
-
|
|
19443
|
+
sendResponse2(id, {
|
|
19903
19444
|
success: false,
|
|
19904
19445
|
error: error instanceof Error ? error.message : "Failed to update user"
|
|
19905
19446
|
}, sendMessage, clientId);
|
|
@@ -19907,7 +19448,7 @@ async function handleUpdate(id, numericId, userData, executeCollection, userMana
|
|
|
19907
19448
|
}
|
|
19908
19449
|
async function handleDelete(id, numericId, username, executeCollection, userManager, sendMessage, clientId) {
|
|
19909
19450
|
if (!numericId && !username) {
|
|
19910
|
-
|
|
19451
|
+
sendResponse2(id, {
|
|
19911
19452
|
success: false,
|
|
19912
19453
|
error: "User ID or username is required"
|
|
19913
19454
|
}, sendMessage, clientId);
|
|
@@ -19918,7 +19459,7 @@ async function handleDelete(id, numericId, username, executeCollection, userMana
|
|
|
19918
19459
|
const result = await executeCollection("users", "delete", { id: numericId });
|
|
19919
19460
|
if (result && result.success) {
|
|
19920
19461
|
logger.info(`[DB] User deleted successfully, ID: ${numericId}`);
|
|
19921
|
-
|
|
19462
|
+
sendResponse2(id, {
|
|
19922
19463
|
success: true,
|
|
19923
19464
|
data: {
|
|
19924
19465
|
id: numericId,
|
|
@@ -19933,14 +19474,14 @@ async function handleDelete(id, numericId, username, executeCollection, userMana
|
|
|
19933
19474
|
}
|
|
19934
19475
|
}
|
|
19935
19476
|
if (!username || username.trim().length === 0) {
|
|
19936
|
-
|
|
19477
|
+
sendResponse2(id, {
|
|
19937
19478
|
success: false,
|
|
19938
19479
|
error: "Username is required for file-based storage delete"
|
|
19939
19480
|
}, sendMessage, clientId);
|
|
19940
19481
|
return;
|
|
19941
19482
|
}
|
|
19942
19483
|
if (!userManager.userExists(username)) {
|
|
19943
|
-
|
|
19484
|
+
sendResponse2(id, {
|
|
19944
19485
|
success: false,
|
|
19945
19486
|
error: `User '${username}' not found`
|
|
19946
19487
|
}, sendMessage, clientId);
|
|
@@ -19948,14 +19489,14 @@ async function handleDelete(id, numericId, username, executeCollection, userMana
|
|
|
19948
19489
|
}
|
|
19949
19490
|
const deleted = userManager.deleteUser(username);
|
|
19950
19491
|
if (!deleted) {
|
|
19951
|
-
|
|
19492
|
+
sendResponse2(id, {
|
|
19952
19493
|
success: false,
|
|
19953
19494
|
error: `Failed to delete user '${username}'`
|
|
19954
19495
|
}, sendMessage, clientId);
|
|
19955
19496
|
return;
|
|
19956
19497
|
}
|
|
19957
19498
|
logger.info(`[FILE] User '${username}' deleted successfully`);
|
|
19958
|
-
|
|
19499
|
+
sendResponse2(id, {
|
|
19959
19500
|
success: true,
|
|
19960
19501
|
data: {
|
|
19961
19502
|
username,
|
|
@@ -19978,7 +19519,7 @@ async function handleGetAll(id, executeCollection, userManager, sendMessage, cli
|
|
|
19978
19519
|
updatedAt: user.updatedAt
|
|
19979
19520
|
}));
|
|
19980
19521
|
logger.info(`[DB] Retrieved ${result.count} users`);
|
|
19981
|
-
|
|
19522
|
+
sendResponse2(id, {
|
|
19982
19523
|
success: true,
|
|
19983
19524
|
data: {
|
|
19984
19525
|
users: sanitizedUsers2,
|
|
@@ -20000,7 +19541,7 @@ async function handleGetAll(id, executeCollection, userManager, sendMessage, cli
|
|
|
20000
19541
|
wsIds: user.wsIds || []
|
|
20001
19542
|
}));
|
|
20002
19543
|
logger.info(`[FILE] Retrieved ${sanitizedUsers.length} users`);
|
|
20003
|
-
|
|
19544
|
+
sendResponse2(id, {
|
|
20004
19545
|
success: true,
|
|
20005
19546
|
data: {
|
|
20006
19547
|
users: sanitizedUsers,
|
|
@@ -20011,7 +19552,7 @@ async function handleGetAll(id, executeCollection, userManager, sendMessage, cli
|
|
|
20011
19552
|
}
|
|
20012
19553
|
async function handleGetOne(id, numericId, username, executeCollection, userManager, sendMessage, clientId) {
|
|
20013
19554
|
if (!numericId && !username) {
|
|
20014
|
-
|
|
19555
|
+
sendResponse2(id, {
|
|
20015
19556
|
success: false,
|
|
20016
19557
|
error: "User ID or username is required"
|
|
20017
19558
|
}, sendMessage, clientId);
|
|
@@ -20032,7 +19573,7 @@ async function handleGetOne(id, numericId, username, executeCollection, userMana
|
|
|
20032
19573
|
updatedAt: result.data?.updatedAt
|
|
20033
19574
|
};
|
|
20034
19575
|
logger.info(`[DB] Retrieved user ID: ${numericId}`);
|
|
20035
|
-
|
|
19576
|
+
sendResponse2(id, {
|
|
20036
19577
|
success: true,
|
|
20037
19578
|
data: {
|
|
20038
19579
|
user: sanitizedUser2,
|
|
@@ -20046,14 +19587,14 @@ async function handleGetOne(id, numericId, username, executeCollection, userMana
|
|
|
20046
19587
|
}
|
|
20047
19588
|
}
|
|
20048
19589
|
if (!username || username.trim().length === 0) {
|
|
20049
|
-
|
|
19590
|
+
sendResponse2(id, {
|
|
20050
19591
|
success: false,
|
|
20051
19592
|
error: "Username is required for file-based storage lookup"
|
|
20052
19593
|
}, sendMessage, clientId);
|
|
20053
19594
|
return;
|
|
20054
19595
|
}
|
|
20055
19596
|
if (!userManager.userExists(username)) {
|
|
20056
|
-
|
|
19597
|
+
sendResponse2(id, {
|
|
20057
19598
|
success: false,
|
|
20058
19599
|
error: `User '${username}' not found`
|
|
20059
19600
|
}, sendMessage, clientId);
|
|
@@ -20068,7 +19609,7 @@ async function handleGetOne(id, numericId, username, executeCollection, userMana
|
|
|
20068
19609
|
wsIds: user.wsIds || []
|
|
20069
19610
|
};
|
|
20070
19611
|
logger.info(`[FILE] Retrieved user: ${username}`);
|
|
20071
|
-
|
|
19612
|
+
sendResponse2(id, {
|
|
20072
19613
|
success: true,
|
|
20073
19614
|
data: {
|
|
20074
19615
|
user: sanitizedUser,
|
|
@@ -20095,7 +19636,7 @@ async function handleQuery(id, filters, limit, sort, executeCollection, userMana
|
|
|
20095
19636
|
updatedAt: user.updatedAt
|
|
20096
19637
|
}));
|
|
20097
19638
|
logger.info(`[DB] Query returned ${result.count} users`);
|
|
20098
|
-
|
|
19639
|
+
sendResponse2(id, {
|
|
20099
19640
|
success: true,
|
|
20100
19641
|
data: {
|
|
20101
19642
|
users: sanitizedUsers2,
|
|
@@ -20118,7 +19659,7 @@ async function handleQuery(id, filters, limit, sort, executeCollection, userMana
|
|
|
20118
19659
|
wsIds: user.wsIds || []
|
|
20119
19660
|
}));
|
|
20120
19661
|
logger.info(`[FILE] Retrieved ${sanitizedUsers.length} users (all - no query filter)`);
|
|
20121
|
-
|
|
19662
|
+
sendResponse2(id, {
|
|
20122
19663
|
success: true,
|
|
20123
19664
|
data: {
|
|
20124
19665
|
users: sanitizedUsers,
|
|
@@ -20127,7 +19668,7 @@ async function handleQuery(id, filters, limit, sort, executeCollection, userMana
|
|
|
20127
19668
|
}
|
|
20128
19669
|
}, sendMessage, clientId);
|
|
20129
19670
|
}
|
|
20130
|
-
function
|
|
19671
|
+
function sendResponse2(id, res, sendMessage, clientId) {
|
|
20131
19672
|
const response = {
|
|
20132
19673
|
id: id || "unknown",
|
|
20133
19674
|
type: "USERS_RES",
|
|
@@ -20183,7 +19724,7 @@ async function handleDashboardsRequest(data, collections, sendMessage) {
|
|
|
20183
19724
|
const sort = requestData?.sort;
|
|
20184
19725
|
const readOnlyOperations = ["query", "getAll", "getOne"];
|
|
20185
19726
|
if (!readOnlyOperations.includes(operation) && from.type !== "admin") {
|
|
20186
|
-
|
|
19727
|
+
sendResponse3(id, {
|
|
20187
19728
|
success: false,
|
|
20188
19729
|
error: "Unauthorized: Only admin can manage dashboards"
|
|
20189
19730
|
}, sendMessage, from.id);
|
|
@@ -20211,14 +19752,14 @@ async function handleDashboardsRequest(data, collections, sendMessage) {
|
|
|
20211
19752
|
await handleQuery2(id, filters, limit, sort, executeCollection, dashboardManager2, sendMessage, from.id);
|
|
20212
19753
|
break;
|
|
20213
19754
|
default:
|
|
20214
|
-
|
|
19755
|
+
sendResponse3(id, {
|
|
20215
19756
|
success: false,
|
|
20216
19757
|
error: `Unknown operation: ${operation}`
|
|
20217
19758
|
}, sendMessage, from.id);
|
|
20218
19759
|
}
|
|
20219
19760
|
} catch (error) {
|
|
20220
19761
|
logger.error("Failed to handle dashboards request:", error);
|
|
20221
|
-
|
|
19762
|
+
sendResponse3(null, {
|
|
20222
19763
|
success: false,
|
|
20223
19764
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
20224
19765
|
}, sendMessage);
|
|
@@ -20226,14 +19767,14 @@ async function handleDashboardsRequest(data, collections, sendMessage) {
|
|
|
20226
19767
|
}
|
|
20227
19768
|
async function handleCreate2(id, dashboardId, dashboard, projectId, name, description, published, createdBy, allowedUsers, executeCollection, dashboardManager2, sendMessage, clientId) {
|
|
20228
19769
|
if (!dashboardId || dashboardId.trim().length === 0) {
|
|
20229
|
-
|
|
19770
|
+
sendResponse3(id, {
|
|
20230
19771
|
success: false,
|
|
20231
19772
|
error: "Dashboard ID is required and cannot be empty"
|
|
20232
19773
|
}, sendMessage, clientId);
|
|
20233
19774
|
return;
|
|
20234
19775
|
}
|
|
20235
19776
|
if (!projectId) {
|
|
20236
|
-
|
|
19777
|
+
sendResponse3(id, {
|
|
20237
19778
|
success: false,
|
|
20238
19779
|
error: "Project ID is required"
|
|
20239
19780
|
}, sendMessage, clientId);
|
|
@@ -20252,7 +19793,7 @@ async function handleCreate2(id, dashboardId, dashboard, projectId, name, descri
|
|
|
20252
19793
|
});
|
|
20253
19794
|
if (result && result.success) {
|
|
20254
19795
|
logger.info(`[DB] Dashboard created successfully, ID: ${result.data?.id}`);
|
|
20255
|
-
|
|
19796
|
+
sendResponse3(id, {
|
|
20256
19797
|
success: true,
|
|
20257
19798
|
data: {
|
|
20258
19799
|
id: result.data?.id,
|
|
@@ -20272,7 +19813,7 @@ async function handleCreate2(id, dashboardId, dashboard, projectId, name, descri
|
|
|
20272
19813
|
}
|
|
20273
19814
|
const createdDashboard = dashboardManager2.createDashboard(dashboardId, dashboard);
|
|
20274
19815
|
logger.info(`[FILE] Dashboard '${dashboardId}' created successfully`);
|
|
20275
|
-
|
|
19816
|
+
sendResponse3(id, {
|
|
20276
19817
|
success: true,
|
|
20277
19818
|
data: {
|
|
20278
19819
|
dashboardId,
|
|
@@ -20281,7 +19822,7 @@ async function handleCreate2(id, dashboardId, dashboard, projectId, name, descri
|
|
|
20281
19822
|
}
|
|
20282
19823
|
}, sendMessage, clientId);
|
|
20283
19824
|
} catch (error) {
|
|
20284
|
-
|
|
19825
|
+
sendResponse3(id, {
|
|
20285
19826
|
success: false,
|
|
20286
19827
|
error: error instanceof Error ? error.message : "Failed to create dashboard"
|
|
20287
19828
|
}, sendMessage, clientId);
|
|
@@ -20289,7 +19830,7 @@ async function handleCreate2(id, dashboardId, dashboard, projectId, name, descri
|
|
|
20289
19830
|
}
|
|
20290
19831
|
async function handleUpdate2(id, numericId, dashboardId, dashboard, name, description, published, updatedBy, allowedUsers, executeCollection, dashboardManager2, sendMessage, clientId) {
|
|
20291
19832
|
if (!numericId) {
|
|
20292
|
-
|
|
19833
|
+
sendResponse3(id, {
|
|
20293
19834
|
success: false,
|
|
20294
19835
|
error: "Dashboard ID is required"
|
|
20295
19836
|
}, sendMessage, clientId);
|
|
@@ -20307,7 +19848,7 @@ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, descri
|
|
|
20307
19848
|
});
|
|
20308
19849
|
if (result && result.success) {
|
|
20309
19850
|
logger.info(`[DB] Dashboard updated successfully, ID: ${numericId}`);
|
|
20310
|
-
|
|
19851
|
+
sendResponse3(id, {
|
|
20311
19852
|
success: true,
|
|
20312
19853
|
data: {
|
|
20313
19854
|
id: numericId,
|
|
@@ -20325,14 +19866,14 @@ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, descri
|
|
|
20325
19866
|
try {
|
|
20326
19867
|
const updatedDashboard = dashboardManager2.updateDashboard(fileStorageId, dashboard);
|
|
20327
19868
|
if (!updatedDashboard) {
|
|
20328
|
-
|
|
19869
|
+
sendResponse3(id, {
|
|
20329
19870
|
success: false,
|
|
20330
19871
|
error: `Dashboard '${fileStorageId}' not found`
|
|
20331
19872
|
}, sendMessage, clientId);
|
|
20332
19873
|
return;
|
|
20333
19874
|
}
|
|
20334
19875
|
logger.info(`[FILE] Dashboard '${fileStorageId}' updated successfully`);
|
|
20335
|
-
|
|
19876
|
+
sendResponse3(id, {
|
|
20336
19877
|
success: true,
|
|
20337
19878
|
data: {
|
|
20338
19879
|
id: numericId,
|
|
@@ -20342,7 +19883,7 @@ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, descri
|
|
|
20342
19883
|
}
|
|
20343
19884
|
}, sendMessage, clientId);
|
|
20344
19885
|
} catch (error) {
|
|
20345
|
-
|
|
19886
|
+
sendResponse3(id, {
|
|
20346
19887
|
success: false,
|
|
20347
19888
|
error: error instanceof Error ? error.message : "Failed to update dashboard"
|
|
20348
19889
|
}, sendMessage, clientId);
|
|
@@ -20350,7 +19891,7 @@ async function handleUpdate2(id, numericId, dashboardId, dashboard, name, descri
|
|
|
20350
19891
|
}
|
|
20351
19892
|
async function handleDelete2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, clientId) {
|
|
20352
19893
|
if (!numericId) {
|
|
20353
|
-
|
|
19894
|
+
sendResponse3(id, {
|
|
20354
19895
|
success: false,
|
|
20355
19896
|
error: "Dashboard ID is required"
|
|
20356
19897
|
}, sendMessage, clientId);
|
|
@@ -20360,7 +19901,7 @@ async function handleDelete2(id, numericId, dashboardId, executeCollection, dash
|
|
|
20360
19901
|
const result = await executeCollection("dashboards", "delete", { id: numericId });
|
|
20361
19902
|
if (result && result.success) {
|
|
20362
19903
|
logger.info(`[DB] Dashboard deleted successfully, ID: ${numericId}`);
|
|
20363
|
-
|
|
19904
|
+
sendResponse3(id, {
|
|
20364
19905
|
success: true,
|
|
20365
19906
|
data: {
|
|
20366
19907
|
id: numericId,
|
|
@@ -20375,14 +19916,14 @@ async function handleDelete2(id, numericId, dashboardId, executeCollection, dash
|
|
|
20375
19916
|
const fileStorageId = dashboardId || String(numericId);
|
|
20376
19917
|
const deleted = dashboardManager2.deleteDashboard(fileStorageId);
|
|
20377
19918
|
if (!deleted) {
|
|
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] Dashboard '${fileStorageId}' deleted successfully`);
|
|
20385
|
-
|
|
19926
|
+
sendResponse3(id, {
|
|
20386
19927
|
success: true,
|
|
20387
19928
|
data: {
|
|
20388
19929
|
id: numericId,
|
|
@@ -20396,7 +19937,7 @@ async function handleGetAll2(id, executeCollection, dashboardManager2, sendMessa
|
|
|
20396
19937
|
const result = await executeCollection("dashboards", "getAll", {});
|
|
20397
19938
|
if (result && result.success) {
|
|
20398
19939
|
logger.info(`[DB] Retrieved ${result.count} dashboards`);
|
|
20399
|
-
|
|
19940
|
+
sendResponse3(id, {
|
|
20400
19941
|
success: true,
|
|
20401
19942
|
data: {
|
|
20402
19943
|
dashboards: result.data,
|
|
@@ -20411,7 +19952,7 @@ async function handleGetAll2(id, executeCollection, dashboardManager2, sendMessa
|
|
|
20411
19952
|
}
|
|
20412
19953
|
const dashboards = dashboardManager2.getAllDashboards();
|
|
20413
19954
|
logger.info(`[FILE] Retrieved ${dashboards.length} dashboards`);
|
|
20414
|
-
|
|
19955
|
+
sendResponse3(id, {
|
|
20415
19956
|
success: true,
|
|
20416
19957
|
data: {
|
|
20417
19958
|
dashboards,
|
|
@@ -20422,7 +19963,7 @@ async function handleGetAll2(id, executeCollection, dashboardManager2, sendMessa
|
|
|
20422
19963
|
}
|
|
20423
19964
|
async function handleGetOne2(id, numericId, dashboardId, executeCollection, dashboardManager2, sendMessage, clientId) {
|
|
20424
19965
|
if (!numericId) {
|
|
20425
|
-
|
|
19966
|
+
sendResponse3(id, {
|
|
20426
19967
|
success: false,
|
|
20427
19968
|
error: "Dashboard ID is required"
|
|
20428
19969
|
}, sendMessage, clientId);
|
|
@@ -20432,7 +19973,7 @@ async function handleGetOne2(id, numericId, dashboardId, executeCollection, dash
|
|
|
20432
19973
|
const result = await executeCollection("dashboards", "getOne", { id: numericId });
|
|
20433
19974
|
if (result && result.success) {
|
|
20434
19975
|
logger.info(`[DB] Retrieved dashboard ID: ${numericId}`);
|
|
20435
|
-
|
|
19976
|
+
sendResponse3(id, {
|
|
20436
19977
|
success: true,
|
|
20437
19978
|
data: {
|
|
20438
19979
|
id: numericId,
|
|
@@ -20449,14 +19990,14 @@ async function handleGetOne2(id, numericId, dashboardId, executeCollection, dash
|
|
|
20449
19990
|
const fileStorageId = dashboardId || String(numericId);
|
|
20450
19991
|
const dashboard = dashboardManager2.getDashboard(fileStorageId);
|
|
20451
19992
|
if (!dashboard) {
|
|
20452
|
-
|
|
19993
|
+
sendResponse3(id, {
|
|
20453
19994
|
success: false,
|
|
20454
19995
|
error: `Dashboard '${fileStorageId}' not found`
|
|
20455
19996
|
}, sendMessage, clientId);
|
|
20456
19997
|
return;
|
|
20457
19998
|
}
|
|
20458
19999
|
logger.info(`[FILE] Retrieved dashboard: ${fileStorageId}`);
|
|
20459
|
-
|
|
20000
|
+
sendResponse3(id, {
|
|
20460
20001
|
success: true,
|
|
20461
20002
|
data: {
|
|
20462
20003
|
id: numericId,
|
|
@@ -20475,7 +20016,7 @@ async function handleQuery2(id, filters, limit, sort, executeCollection, dashboa
|
|
|
20475
20016
|
});
|
|
20476
20017
|
if (result && result.success) {
|
|
20477
20018
|
logger.info(`[DB] Query returned ${result.count} dashboards`);
|
|
20478
|
-
|
|
20019
|
+
sendResponse3(id, {
|
|
20479
20020
|
success: true,
|
|
20480
20021
|
data: {
|
|
20481
20022
|
dashboards: result.data,
|
|
@@ -20490,7 +20031,7 @@ async function handleQuery2(id, filters, limit, sort, executeCollection, dashboa
|
|
|
20490
20031
|
}
|
|
20491
20032
|
const dashboards = dashboardManager2.getAllDashboards();
|
|
20492
20033
|
logger.info(`[FILE] Retrieved ${dashboards.length} dashboards (all - no query filter)`);
|
|
20493
|
-
|
|
20034
|
+
sendResponse3(id, {
|
|
20494
20035
|
success: true,
|
|
20495
20036
|
data: {
|
|
20496
20037
|
dashboards,
|
|
@@ -20499,7 +20040,7 @@ async function handleQuery2(id, filters, limit, sort, executeCollection, dashboa
|
|
|
20499
20040
|
}
|
|
20500
20041
|
}, sendMessage, clientId);
|
|
20501
20042
|
}
|
|
20502
|
-
function
|
|
20043
|
+
function sendResponse3(id, res, sendMessage, clientId) {
|
|
20503
20044
|
const response = {
|
|
20504
20045
|
id: id || "unknown",
|
|
20505
20046
|
type: "DASHBOARDS_RES",
|
|
@@ -20554,7 +20095,7 @@ async function handleReportsRequest(data, collections, sendMessage) {
|
|
|
20554
20095
|
const sort = requestData?.sort;
|
|
20555
20096
|
const readOnlyOperations = ["query", "getAll", "getOne"];
|
|
20556
20097
|
if (!readOnlyOperations.includes(operation) && from.type !== "admin") {
|
|
20557
|
-
|
|
20098
|
+
sendResponse4(id, {
|
|
20558
20099
|
success: false,
|
|
20559
20100
|
error: "Unauthorized: Only admin can manage reports"
|
|
20560
20101
|
}, sendMessage, from.id);
|
|
@@ -20582,14 +20123,14 @@ async function handleReportsRequest(data, collections, sendMessage) {
|
|
|
20582
20123
|
await handleQuery3(id, filters, limit, sort, executeCollection, reportManager2, sendMessage, from.id);
|
|
20583
20124
|
break;
|
|
20584
20125
|
default:
|
|
20585
|
-
|
|
20126
|
+
sendResponse4(id, {
|
|
20586
20127
|
success: false,
|
|
20587
20128
|
error: `Unknown operation: ${operation}`
|
|
20588
20129
|
}, sendMessage, from.id);
|
|
20589
20130
|
}
|
|
20590
20131
|
} catch (error) {
|
|
20591
20132
|
logger.error("Failed to handle reports request:", error);
|
|
20592
|
-
|
|
20133
|
+
sendResponse4(null, {
|
|
20593
20134
|
success: false,
|
|
20594
20135
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
20595
20136
|
}, sendMessage);
|
|
@@ -20597,14 +20138,14 @@ async function handleReportsRequest(data, collections, sendMessage) {
|
|
|
20597
20138
|
}
|
|
20598
20139
|
async function handleCreate3(id, reportId, report, projectId, name, description, published, createdBy, executeCollection, reportManager2, sendMessage, clientId) {
|
|
20599
20140
|
if (!reportId || reportId.trim().length === 0) {
|
|
20600
|
-
|
|
20141
|
+
sendResponse4(id, {
|
|
20601
20142
|
success: false,
|
|
20602
20143
|
error: "Report ID is required and cannot be empty"
|
|
20603
20144
|
}, sendMessage, clientId);
|
|
20604
20145
|
return;
|
|
20605
20146
|
}
|
|
20606
20147
|
if (!projectId) {
|
|
20607
|
-
|
|
20148
|
+
sendResponse4(id, {
|
|
20608
20149
|
success: false,
|
|
20609
20150
|
error: "Project ID is required"
|
|
20610
20151
|
}, sendMessage, clientId);
|
|
@@ -20622,7 +20163,7 @@ async function handleCreate3(id, reportId, report, projectId, name, description,
|
|
|
20622
20163
|
});
|
|
20623
20164
|
if (result && result.success) {
|
|
20624
20165
|
logger.info(`[DB] Report created successfully, ID: ${result.data?.id}`);
|
|
20625
|
-
|
|
20166
|
+
sendResponse4(id, {
|
|
20626
20167
|
success: true,
|
|
20627
20168
|
data: {
|
|
20628
20169
|
id: result.data?.id,
|
|
@@ -20642,7 +20183,7 @@ async function handleCreate3(id, reportId, report, projectId, name, description,
|
|
|
20642
20183
|
}
|
|
20643
20184
|
const createdReport = reportManager2.createReport(reportId, report);
|
|
20644
20185
|
logger.info(`[FILE] Report '${reportId}' created successfully`);
|
|
20645
|
-
|
|
20186
|
+
sendResponse4(id, {
|
|
20646
20187
|
success: true,
|
|
20647
20188
|
data: {
|
|
20648
20189
|
reportId,
|
|
@@ -20651,7 +20192,7 @@ async function handleCreate3(id, reportId, report, projectId, name, description,
|
|
|
20651
20192
|
}
|
|
20652
20193
|
}, sendMessage, clientId);
|
|
20653
20194
|
} catch (error) {
|
|
20654
|
-
|
|
20195
|
+
sendResponse4(id, {
|
|
20655
20196
|
success: false,
|
|
20656
20197
|
error: error instanceof Error ? error.message : "Failed to create report"
|
|
20657
20198
|
}, sendMessage, clientId);
|
|
@@ -20659,7 +20200,7 @@ async function handleCreate3(id, reportId, report, projectId, name, description,
|
|
|
20659
20200
|
}
|
|
20660
20201
|
async function handleUpdate3(id, numericId, reportId, report, name, description, published, updatedBy, executeCollection, reportManager2, sendMessage, clientId) {
|
|
20661
20202
|
if (!numericId) {
|
|
20662
|
-
|
|
20203
|
+
sendResponse4(id, {
|
|
20663
20204
|
success: false,
|
|
20664
20205
|
error: "Report ID is required"
|
|
20665
20206
|
}, sendMessage, clientId);
|
|
@@ -20676,7 +20217,7 @@ async function handleUpdate3(id, numericId, reportId, report, name, description,
|
|
|
20676
20217
|
});
|
|
20677
20218
|
if (result && result.success) {
|
|
20678
20219
|
logger.info(`[DB] Report updated successfully, ID: ${numericId}`);
|
|
20679
|
-
|
|
20220
|
+
sendResponse4(id, {
|
|
20680
20221
|
success: true,
|
|
20681
20222
|
data: {
|
|
20682
20223
|
id: numericId,
|
|
@@ -20694,14 +20235,14 @@ async function handleUpdate3(id, numericId, reportId, report, name, description,
|
|
|
20694
20235
|
try {
|
|
20695
20236
|
const updatedReport = reportManager2.updateReport(fileStorageId, report);
|
|
20696
20237
|
if (!updatedReport) {
|
|
20697
|
-
|
|
20238
|
+
sendResponse4(id, {
|
|
20698
20239
|
success: false,
|
|
20699
20240
|
error: `Report '${fileStorageId}' not found`
|
|
20700
20241
|
}, sendMessage, clientId);
|
|
20701
20242
|
return;
|
|
20702
20243
|
}
|
|
20703
20244
|
logger.info(`[FILE] Report '${fileStorageId}' updated successfully`);
|
|
20704
|
-
|
|
20245
|
+
sendResponse4(id, {
|
|
20705
20246
|
success: true,
|
|
20706
20247
|
data: {
|
|
20707
20248
|
id: numericId,
|
|
@@ -20711,7 +20252,7 @@ async function handleUpdate3(id, numericId, reportId, report, name, description,
|
|
|
20711
20252
|
}
|
|
20712
20253
|
}, sendMessage, clientId);
|
|
20713
20254
|
} catch (error) {
|
|
20714
|
-
|
|
20255
|
+
sendResponse4(id, {
|
|
20715
20256
|
success: false,
|
|
20716
20257
|
error: error instanceof Error ? error.message : "Failed to update report"
|
|
20717
20258
|
}, sendMessage, clientId);
|
|
@@ -20719,7 +20260,7 @@ async function handleUpdate3(id, numericId, reportId, report, name, description,
|
|
|
20719
20260
|
}
|
|
20720
20261
|
async function handleDelete3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, clientId) {
|
|
20721
20262
|
if (!numericId) {
|
|
20722
|
-
|
|
20263
|
+
sendResponse4(id, {
|
|
20723
20264
|
success: false,
|
|
20724
20265
|
error: "Report ID is required"
|
|
20725
20266
|
}, sendMessage, clientId);
|
|
@@ -20729,7 +20270,7 @@ async function handleDelete3(id, numericId, reportId, executeCollection, reportM
|
|
|
20729
20270
|
const result = await executeCollection("reports", "delete", { id: numericId });
|
|
20730
20271
|
if (result && result.success) {
|
|
20731
20272
|
logger.info(`[DB] Report deleted successfully, ID: ${numericId}`);
|
|
20732
|
-
|
|
20273
|
+
sendResponse4(id, {
|
|
20733
20274
|
success: true,
|
|
20734
20275
|
data: {
|
|
20735
20276
|
id: numericId,
|
|
@@ -20744,14 +20285,14 @@ async function handleDelete3(id, numericId, reportId, executeCollection, reportM
|
|
|
20744
20285
|
const fileStorageId = reportId || String(numericId);
|
|
20745
20286
|
const deleted = reportManager2.deleteReport(fileStorageId);
|
|
20746
20287
|
if (!deleted) {
|
|
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] Report '${fileStorageId}' deleted successfully`);
|
|
20754
|
-
|
|
20295
|
+
sendResponse4(id, {
|
|
20755
20296
|
success: true,
|
|
20756
20297
|
data: {
|
|
20757
20298
|
id: numericId,
|
|
@@ -20765,7 +20306,7 @@ async function handleGetAll3(id, executeCollection, reportManager2, sendMessage,
|
|
|
20765
20306
|
const result = await executeCollection("reports", "getAll", {});
|
|
20766
20307
|
if (result && result.success) {
|
|
20767
20308
|
logger.info(`[DB] Retrieved ${result.count} reports`);
|
|
20768
|
-
|
|
20309
|
+
sendResponse4(id, {
|
|
20769
20310
|
success: true,
|
|
20770
20311
|
data: {
|
|
20771
20312
|
reports: result.data,
|
|
@@ -20780,7 +20321,7 @@ async function handleGetAll3(id, executeCollection, reportManager2, sendMessage,
|
|
|
20780
20321
|
}
|
|
20781
20322
|
const reports = reportManager2.getAllReports();
|
|
20782
20323
|
logger.info(`[FILE] Retrieved ${reports.length} reports`);
|
|
20783
|
-
|
|
20324
|
+
sendResponse4(id, {
|
|
20784
20325
|
success: true,
|
|
20785
20326
|
data: {
|
|
20786
20327
|
reports,
|
|
@@ -20791,7 +20332,7 @@ async function handleGetAll3(id, executeCollection, reportManager2, sendMessage,
|
|
|
20791
20332
|
}
|
|
20792
20333
|
async function handleGetOne3(id, numericId, reportId, executeCollection, reportManager2, sendMessage, clientId) {
|
|
20793
20334
|
if (!numericId) {
|
|
20794
|
-
|
|
20335
|
+
sendResponse4(id, {
|
|
20795
20336
|
success: false,
|
|
20796
20337
|
error: "Report ID is required"
|
|
20797
20338
|
}, sendMessage, clientId);
|
|
@@ -20801,7 +20342,7 @@ async function handleGetOne3(id, numericId, reportId, executeCollection, reportM
|
|
|
20801
20342
|
const result = await executeCollection("reports", "getOne", { id: numericId });
|
|
20802
20343
|
if (result && result.success) {
|
|
20803
20344
|
logger.info(`[DB] Retrieved report ID: ${numericId}`);
|
|
20804
|
-
|
|
20345
|
+
sendResponse4(id, {
|
|
20805
20346
|
success: true,
|
|
20806
20347
|
data: {
|
|
20807
20348
|
id: numericId,
|
|
@@ -20818,14 +20359,14 @@ async function handleGetOne3(id, numericId, reportId, executeCollection, reportM
|
|
|
20818
20359
|
const fileStorageId = reportId || String(numericId);
|
|
20819
20360
|
const report = reportManager2.getReport(fileStorageId);
|
|
20820
20361
|
if (!report) {
|
|
20821
|
-
|
|
20362
|
+
sendResponse4(id, {
|
|
20822
20363
|
success: false,
|
|
20823
20364
|
error: `Report '${fileStorageId}' not found`
|
|
20824
20365
|
}, sendMessage, clientId);
|
|
20825
20366
|
return;
|
|
20826
20367
|
}
|
|
20827
20368
|
logger.info(`[FILE] Retrieved report: ${fileStorageId}`);
|
|
20828
|
-
|
|
20369
|
+
sendResponse4(id, {
|
|
20829
20370
|
success: true,
|
|
20830
20371
|
data: {
|
|
20831
20372
|
id: numericId,
|
|
@@ -20844,7 +20385,7 @@ async function handleQuery3(id, filters, limit, sort, executeCollection, reportM
|
|
|
20844
20385
|
});
|
|
20845
20386
|
if (result && result.success) {
|
|
20846
20387
|
logger.info(`[DB] Query returned ${result.count} reports`);
|
|
20847
|
-
|
|
20388
|
+
sendResponse4(id, {
|
|
20848
20389
|
success: true,
|
|
20849
20390
|
data: {
|
|
20850
20391
|
reports: result.data,
|
|
@@ -20859,7 +20400,7 @@ async function handleQuery3(id, filters, limit, sort, executeCollection, reportM
|
|
|
20859
20400
|
}
|
|
20860
20401
|
const reports = reportManager2.getAllReports();
|
|
20861
20402
|
logger.info(`[FILE] Retrieved ${reports.length} reports (all - no query filter)`);
|
|
20862
|
-
|
|
20403
|
+
sendResponse4(id, {
|
|
20863
20404
|
success: true,
|
|
20864
20405
|
data: {
|
|
20865
20406
|
reports,
|
|
@@ -20868,7 +20409,7 @@ async function handleQuery3(id, filters, limit, sort, executeCollection, reportM
|
|
|
20868
20409
|
}
|
|
20869
20410
|
}, sendMessage, clientId);
|
|
20870
20411
|
}
|
|
20871
|
-
function
|
|
20412
|
+
function sendResponse4(id, res, sendMessage, clientId) {
|
|
20872
20413
|
const response = {
|
|
20873
20414
|
id: id || "unknown",
|
|
20874
20415
|
type: "REPORTS_RES",
|
|
@@ -20909,7 +20450,7 @@ async function handleUIsRequest(data, collections, sendMessage) {
|
|
|
20909
20450
|
const limit = requestData?.limit;
|
|
20910
20451
|
const sort = requestData?.sort;
|
|
20911
20452
|
if (from.type !== "admin") {
|
|
20912
|
-
|
|
20453
|
+
sendResponse5(id, {
|
|
20913
20454
|
success: false,
|
|
20914
20455
|
error: "Unauthorized: Only admin can manage UIs"
|
|
20915
20456
|
}, sendMessage, from.id);
|
|
@@ -20936,14 +20477,14 @@ async function handleUIsRequest(data, collections, sendMessage) {
|
|
|
20936
20477
|
await handleQuery4(id, filters, limit, sort, executeCollection, sendMessage, from.id);
|
|
20937
20478
|
break;
|
|
20938
20479
|
default:
|
|
20939
|
-
|
|
20480
|
+
sendResponse5(id, {
|
|
20940
20481
|
success: false,
|
|
20941
20482
|
error: `Unknown operation: ${operation}`
|
|
20942
20483
|
}, sendMessage, from.id);
|
|
20943
20484
|
}
|
|
20944
20485
|
} catch (error) {
|
|
20945
20486
|
logger.error("Failed to handle UIs request:", error);
|
|
20946
|
-
|
|
20487
|
+
sendResponse5(null, {
|
|
20947
20488
|
success: false,
|
|
20948
20489
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
20949
20490
|
}, sendMessage);
|
|
@@ -20951,14 +20492,14 @@ async function handleUIsRequest(data, collections, sendMessage) {
|
|
|
20951
20492
|
}
|
|
20952
20493
|
async function handleCreate4(id, uiId, ui, projectId, name, description, createdBy, executeCollection, sendMessage, clientId) {
|
|
20953
20494
|
if (!uiId || uiId.trim().length === 0) {
|
|
20954
|
-
|
|
20495
|
+
sendResponse5(id, {
|
|
20955
20496
|
success: false,
|
|
20956
20497
|
error: "UI ID is required and cannot be empty"
|
|
20957
20498
|
}, sendMessage, clientId);
|
|
20958
20499
|
return;
|
|
20959
20500
|
}
|
|
20960
20501
|
if (!projectId || projectId.trim().length === 0) {
|
|
20961
|
-
|
|
20502
|
+
sendResponse5(id, {
|
|
20962
20503
|
success: false,
|
|
20963
20504
|
error: "Project ID is required and cannot be empty"
|
|
20964
20505
|
}, sendMessage, clientId);
|
|
@@ -20975,7 +20516,7 @@ async function handleCreate4(id, uiId, ui, projectId, name, description, created
|
|
|
20975
20516
|
});
|
|
20976
20517
|
if (result && result.success) {
|
|
20977
20518
|
logger.info(`UI created successfully, ID: ${result.data?.id}`);
|
|
20978
|
-
|
|
20519
|
+
sendResponse5(id, {
|
|
20979
20520
|
success: true,
|
|
20980
20521
|
data: {
|
|
20981
20522
|
id: result.data?.id,
|
|
@@ -20985,13 +20526,13 @@ async function handleCreate4(id, uiId, ui, projectId, name, description, created
|
|
|
20985
20526
|
}
|
|
20986
20527
|
}, sendMessage, clientId);
|
|
20987
20528
|
} else {
|
|
20988
|
-
|
|
20529
|
+
sendResponse5(id, {
|
|
20989
20530
|
success: false,
|
|
20990
20531
|
error: "Failed to create UI"
|
|
20991
20532
|
}, sendMessage, clientId);
|
|
20992
20533
|
}
|
|
20993
20534
|
} catch (error) {
|
|
20994
|
-
|
|
20535
|
+
sendResponse5(id, {
|
|
20995
20536
|
success: false,
|
|
20996
20537
|
error: error instanceof Error ? error.message : "Failed to create UI"
|
|
20997
20538
|
}, sendMessage, clientId);
|
|
@@ -20999,7 +20540,7 @@ async function handleCreate4(id, uiId, ui, projectId, name, description, created
|
|
|
20999
20540
|
}
|
|
21000
20541
|
async function handleUpdate4(id, numericId, ui, name, description, updatedBy, executeCollection, sendMessage, clientId) {
|
|
21001
20542
|
if (!numericId) {
|
|
21002
|
-
|
|
20543
|
+
sendResponse5(id, {
|
|
21003
20544
|
success: false,
|
|
21004
20545
|
error: "UI ID is required"
|
|
21005
20546
|
}, sendMessage, clientId);
|
|
@@ -21015,7 +20556,7 @@ async function handleUpdate4(id, numericId, ui, name, description, updatedBy, ex
|
|
|
21015
20556
|
});
|
|
21016
20557
|
if (result && result.success) {
|
|
21017
20558
|
logger.info(`UI updated successfully, ID: ${numericId}`);
|
|
21018
|
-
|
|
20559
|
+
sendResponse5(id, {
|
|
21019
20560
|
success: true,
|
|
21020
20561
|
data: {
|
|
21021
20562
|
id: numericId,
|
|
@@ -21025,13 +20566,13 @@ async function handleUpdate4(id, numericId, ui, name, description, updatedBy, ex
|
|
|
21025
20566
|
}
|
|
21026
20567
|
}, sendMessage, clientId);
|
|
21027
20568
|
} else {
|
|
21028
|
-
|
|
20569
|
+
sendResponse5(id, {
|
|
21029
20570
|
success: false,
|
|
21030
20571
|
error: "Failed to update UI"
|
|
21031
20572
|
}, sendMessage, clientId);
|
|
21032
20573
|
}
|
|
21033
20574
|
} catch (error) {
|
|
21034
|
-
|
|
20575
|
+
sendResponse5(id, {
|
|
21035
20576
|
success: false,
|
|
21036
20577
|
error: error instanceof Error ? error.message : "Failed to update UI"
|
|
21037
20578
|
}, sendMessage, clientId);
|
|
@@ -21039,7 +20580,7 @@ async function handleUpdate4(id, numericId, ui, name, description, updatedBy, ex
|
|
|
21039
20580
|
}
|
|
21040
20581
|
async function handleDelete4(id, numericId, executeCollection, sendMessage, clientId) {
|
|
21041
20582
|
if (!numericId) {
|
|
21042
|
-
|
|
20583
|
+
sendResponse5(id, {
|
|
21043
20584
|
success: false,
|
|
21044
20585
|
error: "UI ID is required"
|
|
21045
20586
|
}, sendMessage, clientId);
|
|
@@ -21049,7 +20590,7 @@ async function handleDelete4(id, numericId, executeCollection, sendMessage, clie
|
|
|
21049
20590
|
const result = await executeCollection("uis", "delete", { id: numericId });
|
|
21050
20591
|
if (result && result.success) {
|
|
21051
20592
|
logger.info(`UI deleted successfully, ID: ${numericId}`);
|
|
21052
|
-
|
|
20593
|
+
sendResponse5(id, {
|
|
21053
20594
|
success: true,
|
|
21054
20595
|
data: {
|
|
21055
20596
|
id: numericId,
|
|
@@ -21057,13 +20598,13 @@ async function handleDelete4(id, numericId, executeCollection, sendMessage, clie
|
|
|
21057
20598
|
}
|
|
21058
20599
|
}, sendMessage, clientId);
|
|
21059
20600
|
} else {
|
|
21060
|
-
|
|
20601
|
+
sendResponse5(id, {
|
|
21061
20602
|
success: false,
|
|
21062
20603
|
error: "Failed to delete UI"
|
|
21063
20604
|
}, sendMessage, clientId);
|
|
21064
20605
|
}
|
|
21065
20606
|
} catch (error) {
|
|
21066
|
-
|
|
20607
|
+
sendResponse5(id, {
|
|
21067
20608
|
success: false,
|
|
21068
20609
|
error: error instanceof Error ? error.message : "Failed to delete UI"
|
|
21069
20610
|
}, sendMessage, clientId);
|
|
@@ -21074,7 +20615,7 @@ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
|
|
|
21074
20615
|
const result = await executeCollection("uis", "getAll", {});
|
|
21075
20616
|
if (result && result.success) {
|
|
21076
20617
|
logger.info(`Retrieved ${result.count} UIs`);
|
|
21077
|
-
|
|
20618
|
+
sendResponse5(id, {
|
|
21078
20619
|
success: true,
|
|
21079
20620
|
data: {
|
|
21080
20621
|
uis: result.data,
|
|
@@ -21083,13 +20624,13 @@ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
|
|
|
21083
20624
|
}
|
|
21084
20625
|
}, sendMessage, clientId);
|
|
21085
20626
|
} else {
|
|
21086
|
-
|
|
20627
|
+
sendResponse5(id, {
|
|
21087
20628
|
success: false,
|
|
21088
20629
|
error: "Failed to get UIs"
|
|
21089
20630
|
}, sendMessage, clientId);
|
|
21090
20631
|
}
|
|
21091
20632
|
} catch (error) {
|
|
21092
|
-
|
|
20633
|
+
sendResponse5(id, {
|
|
21093
20634
|
success: false,
|
|
21094
20635
|
error: error instanceof Error ? error.message : "Failed to get UIs"
|
|
21095
20636
|
}, sendMessage, clientId);
|
|
@@ -21097,7 +20638,7 @@ async function handleGetAll4(id, executeCollection, sendMessage, clientId) {
|
|
|
21097
20638
|
}
|
|
21098
20639
|
async function handleGetOne4(id, numericId, executeCollection, sendMessage, clientId) {
|
|
21099
20640
|
if (!numericId) {
|
|
21100
|
-
|
|
20641
|
+
sendResponse5(id, {
|
|
21101
20642
|
success: false,
|
|
21102
20643
|
error: "UI ID is required"
|
|
21103
20644
|
}, sendMessage, clientId);
|
|
@@ -21107,7 +20648,7 @@ async function handleGetOne4(id, numericId, executeCollection, sendMessage, clie
|
|
|
21107
20648
|
const result = await executeCollection("uis", "getOne", { id: numericId });
|
|
21108
20649
|
if (result && result.success) {
|
|
21109
20650
|
logger.info(`Retrieved UI ID: ${numericId}`);
|
|
21110
|
-
|
|
20651
|
+
sendResponse5(id, {
|
|
21111
20652
|
success: true,
|
|
21112
20653
|
data: {
|
|
21113
20654
|
id: numericId,
|
|
@@ -21117,13 +20658,13 @@ async function handleGetOne4(id, numericId, executeCollection, sendMessage, clie
|
|
|
21117
20658
|
}
|
|
21118
20659
|
}, sendMessage, clientId);
|
|
21119
20660
|
} else {
|
|
21120
|
-
|
|
20661
|
+
sendResponse5(id, {
|
|
21121
20662
|
success: false,
|
|
21122
20663
|
error: `UI not found`
|
|
21123
20664
|
}, sendMessage, clientId);
|
|
21124
20665
|
}
|
|
21125
20666
|
} catch (error) {
|
|
21126
|
-
|
|
20667
|
+
sendResponse5(id, {
|
|
21127
20668
|
success: false,
|
|
21128
20669
|
error: error instanceof Error ? error.message : "Failed to get UI"
|
|
21129
20670
|
}, sendMessage, clientId);
|
|
@@ -21138,7 +20679,7 @@ async function handleQuery4(id, filters, limit, sort, executeCollection, sendMes
|
|
|
21138
20679
|
});
|
|
21139
20680
|
if (result && result.success) {
|
|
21140
20681
|
logger.info(`Query returned ${result.count} UIs`);
|
|
21141
|
-
|
|
20682
|
+
sendResponse5(id, {
|
|
21142
20683
|
success: true,
|
|
21143
20684
|
data: {
|
|
21144
20685
|
uis: result.data,
|
|
@@ -21147,19 +20688,19 @@ async function handleQuery4(id, filters, limit, sort, executeCollection, sendMes
|
|
|
21147
20688
|
}
|
|
21148
20689
|
}, sendMessage, clientId);
|
|
21149
20690
|
} else {
|
|
21150
|
-
|
|
20691
|
+
sendResponse5(id, {
|
|
21151
20692
|
success: false,
|
|
21152
20693
|
error: "Failed to query UIs"
|
|
21153
20694
|
}, sendMessage, clientId);
|
|
21154
20695
|
}
|
|
21155
20696
|
} catch (error) {
|
|
21156
|
-
|
|
20697
|
+
sendResponse5(id, {
|
|
21157
20698
|
success: false,
|
|
21158
20699
|
error: error instanceof Error ? error.message : "Failed to query UIs"
|
|
21159
20700
|
}, sendMessage, clientId);
|
|
21160
20701
|
}
|
|
21161
20702
|
}
|
|
21162
|
-
function
|
|
20703
|
+
function sendResponse5(id, res, sendMessage, clientId) {
|
|
21163
20704
|
const response = {
|
|
21164
20705
|
id: id || "unknown",
|
|
21165
20706
|
type: "UIS_RES",
|
|
@@ -21217,14 +20758,14 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
|
|
|
21217
20758
|
await handleQuery5(id, filters, limit, sort, executeCollection, sendMessage, from.id);
|
|
21218
20759
|
break;
|
|
21219
20760
|
default:
|
|
21220
|
-
|
|
20761
|
+
sendResponse6(id, {
|
|
21221
20762
|
success: false,
|
|
21222
20763
|
error: `Unknown operation: ${operation}`
|
|
21223
20764
|
}, sendMessage, from.id);
|
|
21224
20765
|
}
|
|
21225
20766
|
} catch (error) {
|
|
21226
20767
|
logger.error("Failed to handle bookmarks request:", error);
|
|
21227
|
-
|
|
20768
|
+
sendResponse6(null, {
|
|
21228
20769
|
success: false,
|
|
21229
20770
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
21230
20771
|
}, sendMessage);
|
|
@@ -21232,14 +20773,14 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
|
|
|
21232
20773
|
}
|
|
21233
20774
|
async function handleCreate5(id, userId, threadId, name, description, uiblock, executeCollection, sendMessage, clientId) {
|
|
21234
20775
|
if (!userId) {
|
|
21235
|
-
|
|
20776
|
+
sendResponse6(id, {
|
|
21236
20777
|
success: false,
|
|
21237
20778
|
error: "userId is required"
|
|
21238
20779
|
}, sendMessage, clientId);
|
|
21239
20780
|
return;
|
|
21240
20781
|
}
|
|
21241
20782
|
if (!uiblock) {
|
|
21242
|
-
|
|
20783
|
+
sendResponse6(id, {
|
|
21243
20784
|
success: false,
|
|
21244
20785
|
error: "UIBlock data is required"
|
|
21245
20786
|
}, sendMessage, clientId);
|
|
@@ -21247,14 +20788,14 @@ async function handleCreate5(id, userId, threadId, name, description, uiblock, e
|
|
|
21247
20788
|
}
|
|
21248
20789
|
try {
|
|
21249
20790
|
const result = await executeCollection("bookmarks", "create", { userId, threadId, name, description, uiblock });
|
|
21250
|
-
|
|
20791
|
+
sendResponse6(id, {
|
|
21251
20792
|
success: true,
|
|
21252
20793
|
data: result.data,
|
|
21253
20794
|
message: "Bookmark created successfully"
|
|
21254
20795
|
}, sendMessage, clientId);
|
|
21255
20796
|
logger.info(`Bookmark created: ID ${result.data.id}`);
|
|
21256
20797
|
} catch (error) {
|
|
21257
|
-
|
|
20798
|
+
sendResponse6(id, {
|
|
21258
20799
|
success: false,
|
|
21259
20800
|
error: error instanceof Error ? error.message : "Failed to create bookmark"
|
|
21260
20801
|
}, sendMessage, clientId);
|
|
@@ -21262,7 +20803,7 @@ async function handleCreate5(id, userId, threadId, name, description, uiblock, e
|
|
|
21262
20803
|
}
|
|
21263
20804
|
async function handleUpdate5(id, bookmarkId, threadId, name, description, uiblock, executeCollection, sendMessage, clientId) {
|
|
21264
20805
|
if (!bookmarkId) {
|
|
21265
|
-
|
|
20806
|
+
sendResponse6(id, {
|
|
21266
20807
|
success: false,
|
|
21267
20808
|
error: "Bookmark ID is required"
|
|
21268
20809
|
}, sendMessage, clientId);
|
|
@@ -21270,14 +20811,14 @@ async function handleUpdate5(id, bookmarkId, threadId, name, description, uibloc
|
|
|
21270
20811
|
}
|
|
21271
20812
|
try {
|
|
21272
20813
|
const result = await executeCollection("bookmarks", "update", { id: bookmarkId, threadId, name, description, uiblock });
|
|
21273
|
-
|
|
20814
|
+
sendResponse6(id, {
|
|
21274
20815
|
success: true,
|
|
21275
20816
|
data: result.data,
|
|
21276
20817
|
message: "Bookmark updated successfully"
|
|
21277
20818
|
}, sendMessage, clientId);
|
|
21278
20819
|
logger.info(`Bookmark updated: ID ${bookmarkId}`);
|
|
21279
20820
|
} catch (error) {
|
|
21280
|
-
|
|
20821
|
+
sendResponse6(id, {
|
|
21281
20822
|
success: false,
|
|
21282
20823
|
error: error instanceof Error ? error.message : "Failed to update bookmark"
|
|
21283
20824
|
}, sendMessage, clientId);
|
|
@@ -21285,7 +20826,7 @@ async function handleUpdate5(id, bookmarkId, threadId, name, description, uibloc
|
|
|
21285
20826
|
}
|
|
21286
20827
|
async function handleDelete5(id, bookmarkId, executeCollection, sendMessage, clientId) {
|
|
21287
20828
|
if (!bookmarkId) {
|
|
21288
|
-
|
|
20829
|
+
sendResponse6(id, {
|
|
21289
20830
|
success: false,
|
|
21290
20831
|
error: "Bookmark ID is required"
|
|
21291
20832
|
}, sendMessage, clientId);
|
|
@@ -21293,14 +20834,14 @@ async function handleDelete5(id, bookmarkId, executeCollection, sendMessage, cli
|
|
|
21293
20834
|
}
|
|
21294
20835
|
try {
|
|
21295
20836
|
const result = await executeCollection("bookmarks", "delete", { id: bookmarkId });
|
|
21296
|
-
|
|
20837
|
+
sendResponse6(id, {
|
|
21297
20838
|
success: true,
|
|
21298
20839
|
data: result.data,
|
|
21299
20840
|
message: "Bookmark deleted successfully"
|
|
21300
20841
|
}, sendMessage, clientId);
|
|
21301
20842
|
logger.info(`Bookmark deleted: ID ${bookmarkId}`);
|
|
21302
20843
|
} catch (error) {
|
|
21303
|
-
|
|
20844
|
+
sendResponse6(id, {
|
|
21304
20845
|
success: false,
|
|
21305
20846
|
error: error instanceof Error ? error.message : "Failed to delete bookmark"
|
|
21306
20847
|
}, sendMessage, clientId);
|
|
@@ -21309,7 +20850,7 @@ async function handleDelete5(id, bookmarkId, executeCollection, sendMessage, cli
|
|
|
21309
20850
|
async function handleGetAll5(id, executeCollection, sendMessage, clientId) {
|
|
21310
20851
|
try {
|
|
21311
20852
|
const result = await executeCollection("bookmarks", "getAll", {});
|
|
21312
|
-
|
|
20853
|
+
sendResponse6(id, {
|
|
21313
20854
|
success: true,
|
|
21314
20855
|
data: result.data,
|
|
21315
20856
|
count: result.count,
|
|
@@ -21317,7 +20858,7 @@ async function handleGetAll5(id, executeCollection, sendMessage, clientId) {
|
|
|
21317
20858
|
}, sendMessage, clientId);
|
|
21318
20859
|
logger.info(`Retrieved all bookmarks (count: ${result.count})`);
|
|
21319
20860
|
} catch (error) {
|
|
21320
|
-
|
|
20861
|
+
sendResponse6(id, {
|
|
21321
20862
|
success: false,
|
|
21322
20863
|
error: error instanceof Error ? error.message : "Failed to get bookmarks"
|
|
21323
20864
|
}, sendMessage, clientId);
|
|
@@ -21325,7 +20866,7 @@ async function handleGetAll5(id, executeCollection, sendMessage, clientId) {
|
|
|
21325
20866
|
}
|
|
21326
20867
|
async function handleGetOne5(id, bookmarkId, executeCollection, sendMessage, clientId) {
|
|
21327
20868
|
if (!bookmarkId) {
|
|
21328
|
-
|
|
20869
|
+
sendResponse6(id, {
|
|
21329
20870
|
success: false,
|
|
21330
20871
|
error: "Bookmark ID is required"
|
|
21331
20872
|
}, sendMessage, clientId);
|
|
@@ -21333,14 +20874,14 @@ async function handleGetOne5(id, bookmarkId, executeCollection, sendMessage, cli
|
|
|
21333
20874
|
}
|
|
21334
20875
|
try {
|
|
21335
20876
|
const result = await executeCollection("bookmarks", "getOne", { id: bookmarkId });
|
|
21336
|
-
|
|
20877
|
+
sendResponse6(id, {
|
|
21337
20878
|
success: true,
|
|
21338
20879
|
data: result.data,
|
|
21339
20880
|
message: `Retrieved bookmark ID ${bookmarkId}`
|
|
21340
20881
|
}, sendMessage, clientId);
|
|
21341
20882
|
logger.info(`Retrieved bookmark: ID ${bookmarkId}`);
|
|
21342
20883
|
} catch (error) {
|
|
21343
|
-
|
|
20884
|
+
sendResponse6(id, {
|
|
21344
20885
|
success: false,
|
|
21345
20886
|
error: error instanceof Error ? error.message : "Failed to get bookmark"
|
|
21346
20887
|
}, sendMessage, clientId);
|
|
@@ -21353,7 +20894,7 @@ async function handleQuery5(id, filters, limit, sort, executeCollection, sendMes
|
|
|
21353
20894
|
limit,
|
|
21354
20895
|
sort
|
|
21355
20896
|
});
|
|
21356
|
-
|
|
20897
|
+
sendResponse6(id, {
|
|
21357
20898
|
success: true,
|
|
21358
20899
|
data: result.data,
|
|
21359
20900
|
count: result.count,
|
|
@@ -21361,13 +20902,13 @@ async function handleQuery5(id, filters, limit, sort, executeCollection, sendMes
|
|
|
21361
20902
|
}, sendMessage, clientId);
|
|
21362
20903
|
logger.info(`Query returned ${result.count} bookmarks`);
|
|
21363
20904
|
} catch (error) {
|
|
21364
|
-
|
|
20905
|
+
sendResponse6(id, {
|
|
21365
20906
|
success: false,
|
|
21366
20907
|
error: error instanceof Error ? error.message : "Failed to query bookmarks"
|
|
21367
20908
|
}, sendMessage, clientId);
|
|
21368
20909
|
}
|
|
21369
20910
|
}
|
|
21370
|
-
function
|
|
20911
|
+
function sendResponse6(id, res, sendMessage, clientId) {
|
|
21371
20912
|
const response = {
|
|
21372
20913
|
id: id || "unknown",
|
|
21373
20914
|
type: "BOOKMARKS_RES",
|
|
@@ -21434,14 +20975,14 @@ async function handleArtifactsRequest(data, collections, sendMessage) {
|
|
|
21434
20975
|
await handleQuery6(id, { filters, limit, offset, sort }, executeCollection, sendMessage, from.id);
|
|
21435
20976
|
break;
|
|
21436
20977
|
default:
|
|
21437
|
-
|
|
20978
|
+
sendResponse7(id, {
|
|
21438
20979
|
success: false,
|
|
21439
20980
|
error: `Unknown operation: ${operation}`
|
|
21440
20981
|
}, sendMessage, from.id);
|
|
21441
20982
|
}
|
|
21442
20983
|
} catch (error) {
|
|
21443
20984
|
logger.error("Failed to handle artifacts request:", error);
|
|
21444
|
-
|
|
20985
|
+
sendResponse7(null, {
|
|
21445
20986
|
success: false,
|
|
21446
20987
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
21447
20988
|
}, sendMessage);
|
|
@@ -21449,7 +20990,7 @@ async function handleArtifactsRequest(data, collections, sendMessage) {
|
|
|
21449
20990
|
}
|
|
21450
20991
|
async function handleCreate6(id, name, createdBy, dsl, type, filters, status, executeCollection, sendMessage, clientId) {
|
|
21451
20992
|
if (!name) {
|
|
21452
|
-
|
|
20993
|
+
sendResponse7(id, {
|
|
21453
20994
|
success: false,
|
|
21454
20995
|
error: "name is required"
|
|
21455
20996
|
}, sendMessage, clientId);
|
|
@@ -21464,14 +21005,14 @@ async function handleCreate6(id, name, createdBy, dsl, type, filters, status, ex
|
|
|
21464
21005
|
filters,
|
|
21465
21006
|
status
|
|
21466
21007
|
});
|
|
21467
|
-
|
|
21008
|
+
sendResponse7(id, {
|
|
21468
21009
|
success: true,
|
|
21469
21010
|
data: result.data,
|
|
21470
21011
|
message: "Artifact created successfully"
|
|
21471
21012
|
}, sendMessage, clientId);
|
|
21472
21013
|
logger.info(`Artifact created: ID ${result.data.id}`);
|
|
21473
21014
|
} catch (error) {
|
|
21474
|
-
|
|
21015
|
+
sendResponse7(id, {
|
|
21475
21016
|
success: false,
|
|
21476
21017
|
error: error instanceof Error ? error.message : "Failed to create artifact"
|
|
21477
21018
|
}, sendMessage, clientId);
|
|
@@ -21479,7 +21020,7 @@ async function handleCreate6(id, name, createdBy, dsl, type, filters, status, ex
|
|
|
21479
21020
|
}
|
|
21480
21021
|
async function handleUpdate6(id, artifactId, name, dsl, type, filters, status, deleted, executeCollection, sendMessage, clientId) {
|
|
21481
21022
|
if (!artifactId) {
|
|
21482
|
-
|
|
21023
|
+
sendResponse7(id, {
|
|
21483
21024
|
success: false,
|
|
21484
21025
|
error: "Artifact ID is required"
|
|
21485
21026
|
}, sendMessage, clientId);
|
|
@@ -21487,14 +21028,14 @@ async function handleUpdate6(id, artifactId, name, dsl, type, filters, status, d
|
|
|
21487
21028
|
}
|
|
21488
21029
|
try {
|
|
21489
21030
|
const result = await executeCollection("artifacts", "update", { id: artifactId, name, dsl, type, filters, status, deleted });
|
|
21490
|
-
|
|
21031
|
+
sendResponse7(id, {
|
|
21491
21032
|
success: true,
|
|
21492
21033
|
data: result.data,
|
|
21493
21034
|
message: "Artifact updated successfully"
|
|
21494
21035
|
}, sendMessage, clientId);
|
|
21495
21036
|
logger.info(`Artifact updated: ID ${artifactId}`);
|
|
21496
21037
|
} catch (error) {
|
|
21497
|
-
|
|
21038
|
+
sendResponse7(id, {
|
|
21498
21039
|
success: false,
|
|
21499
21040
|
error: error instanceof Error ? error.message : "Failed to update artifact"
|
|
21500
21041
|
}, sendMessage, clientId);
|
|
@@ -21502,7 +21043,7 @@ async function handleUpdate6(id, artifactId, name, dsl, type, filters, status, d
|
|
|
21502
21043
|
}
|
|
21503
21044
|
async function handleDelete6(id, artifactId, executeCollection, sendMessage, clientId) {
|
|
21504
21045
|
if (!artifactId) {
|
|
21505
|
-
|
|
21046
|
+
sendResponse7(id, {
|
|
21506
21047
|
success: false,
|
|
21507
21048
|
error: "Artifact ID is required"
|
|
21508
21049
|
}, sendMessage, clientId);
|
|
@@ -21510,14 +21051,14 @@ async function handleDelete6(id, artifactId, executeCollection, sendMessage, cli
|
|
|
21510
21051
|
}
|
|
21511
21052
|
try {
|
|
21512
21053
|
const result = await executeCollection("artifacts", "delete", { id: artifactId });
|
|
21513
|
-
|
|
21054
|
+
sendResponse7(id, {
|
|
21514
21055
|
success: true,
|
|
21515
21056
|
data: result.data,
|
|
21516
21057
|
message: "Artifact deleted successfully"
|
|
21517
21058
|
}, sendMessage, clientId);
|
|
21518
21059
|
logger.info(`Artifact deleted: ID ${artifactId}`);
|
|
21519
21060
|
} catch (error) {
|
|
21520
|
-
|
|
21061
|
+
sendResponse7(id, {
|
|
21521
21062
|
success: false,
|
|
21522
21063
|
error: error instanceof Error ? error.message : "Failed to delete artifact"
|
|
21523
21064
|
}, sendMessage, clientId);
|
|
@@ -21526,7 +21067,7 @@ async function handleDelete6(id, artifactId, executeCollection, sendMessage, cli
|
|
|
21526
21067
|
async function handleGetAll6(id, limit, executeCollection, sendMessage, clientId) {
|
|
21527
21068
|
try {
|
|
21528
21069
|
const result = await executeCollection("artifacts", "getAll", { limit });
|
|
21529
|
-
|
|
21070
|
+
sendResponse7(id, {
|
|
21530
21071
|
success: true,
|
|
21531
21072
|
data: result.data,
|
|
21532
21073
|
count: result.count,
|
|
@@ -21534,7 +21075,7 @@ async function handleGetAll6(id, limit, executeCollection, sendMessage, clientId
|
|
|
21534
21075
|
}, sendMessage, clientId);
|
|
21535
21076
|
logger.info(`Retrieved all artifacts (count: ${result.count})`);
|
|
21536
21077
|
} catch (error) {
|
|
21537
|
-
|
|
21078
|
+
sendResponse7(id, {
|
|
21538
21079
|
success: false,
|
|
21539
21080
|
error: error instanceof Error ? error.message : "Failed to get artifacts"
|
|
21540
21081
|
}, sendMessage, clientId);
|
|
@@ -21542,7 +21083,7 @@ async function handleGetAll6(id, limit, executeCollection, sendMessage, clientId
|
|
|
21542
21083
|
}
|
|
21543
21084
|
async function handleGetOne6(id, artifactId, executeCollection, sendMessage, clientId) {
|
|
21544
21085
|
if (!artifactId) {
|
|
21545
|
-
|
|
21086
|
+
sendResponse7(id, {
|
|
21546
21087
|
success: false,
|
|
21547
21088
|
error: "Artifact ID is required"
|
|
21548
21089
|
}, sendMessage, clientId);
|
|
@@ -21550,14 +21091,14 @@ async function handleGetOne6(id, artifactId, executeCollection, sendMessage, cli
|
|
|
21550
21091
|
}
|
|
21551
21092
|
try {
|
|
21552
21093
|
const result = await executeCollection("artifacts", "getOne", { id: artifactId });
|
|
21553
|
-
|
|
21094
|
+
sendResponse7(id, {
|
|
21554
21095
|
success: true,
|
|
21555
21096
|
data: result.data,
|
|
21556
21097
|
message: `Retrieved artifact ID ${artifactId}`
|
|
21557
21098
|
}, sendMessage, clientId);
|
|
21558
21099
|
logger.info(`Retrieved artifact: ID ${artifactId}`);
|
|
21559
21100
|
} catch (error) {
|
|
21560
|
-
|
|
21101
|
+
sendResponse7(id, {
|
|
21561
21102
|
success: false,
|
|
21562
21103
|
error: error instanceof Error ? error.message : "Failed to get artifact"
|
|
21563
21104
|
}, sendMessage, clientId);
|
|
@@ -21574,7 +21115,7 @@ async function handleQuery6(id, queryParams, executeCollection, sendMessage, cli
|
|
|
21574
21115
|
sort: queryParams.sort || "DESC"
|
|
21575
21116
|
});
|
|
21576
21117
|
logger.info("[SDK-NODEJS] handleQuery - executeCollection result count:", result.count);
|
|
21577
|
-
|
|
21118
|
+
sendResponse7(id, {
|
|
21578
21119
|
success: true,
|
|
21579
21120
|
data: result.data,
|
|
21580
21121
|
count: result.count,
|
|
@@ -21582,13 +21123,13 @@ async function handleQuery6(id, queryParams, executeCollection, sendMessage, cli
|
|
|
21582
21123
|
}, sendMessage, clientId);
|
|
21583
21124
|
logger.info(`Query artifacts (count: ${result.count})`);
|
|
21584
21125
|
} catch (error) {
|
|
21585
|
-
|
|
21126
|
+
sendResponse7(id, {
|
|
21586
21127
|
success: false,
|
|
21587
21128
|
error: error instanceof Error ? error.message : "Failed to query artifacts"
|
|
21588
21129
|
}, sendMessage, clientId);
|
|
21589
21130
|
}
|
|
21590
21131
|
}
|
|
21591
|
-
function
|
|
21132
|
+
function sendResponse7(id, res, sendMessage, clientId) {
|
|
21592
21133
|
const response = {
|
|
21593
21134
|
id: id || "unknown",
|
|
21594
21135
|
type: "ARTIFACTS_RES",
|
|
@@ -21662,14 +21203,14 @@ async function handleKbNodesRequest(data, collections, sendMessage) {
|
|
|
21662
21203
|
await handleGetTags(id, executeCollection, sendMessage, from.id);
|
|
21663
21204
|
break;
|
|
21664
21205
|
default:
|
|
21665
|
-
|
|
21206
|
+
sendResponse8(id, {
|
|
21666
21207
|
success: false,
|
|
21667
21208
|
error: `Unknown operation: ${operation}`
|
|
21668
21209
|
}, sendMessage, from.id);
|
|
21669
21210
|
}
|
|
21670
21211
|
} catch (error) {
|
|
21671
21212
|
logger.error("Failed to handle KB nodes request:", error);
|
|
21672
|
-
|
|
21213
|
+
sendResponse8(null, {
|
|
21673
21214
|
success: false,
|
|
21674
21215
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
21675
21216
|
}, sendMessage);
|
|
@@ -21678,21 +21219,21 @@ async function handleKbNodesRequest(data, collections, sendMessage) {
|
|
|
21678
21219
|
async function handleCreate7(id, nodeData, executeCollection, sendMessage, clientId) {
|
|
21679
21220
|
const { title, content, category, tags, type, createdBy } = nodeData;
|
|
21680
21221
|
if (!title || title.trim().length === 0) {
|
|
21681
|
-
|
|
21222
|
+
sendResponse8(id, {
|
|
21682
21223
|
success: false,
|
|
21683
21224
|
error: "Title is required and cannot be empty"
|
|
21684
21225
|
}, sendMessage, clientId);
|
|
21685
21226
|
return;
|
|
21686
21227
|
}
|
|
21687
21228
|
if (!content || content.trim().length === 0) {
|
|
21688
|
-
|
|
21229
|
+
sendResponse8(id, {
|
|
21689
21230
|
success: false,
|
|
21690
21231
|
error: "Content is required and cannot be empty"
|
|
21691
21232
|
}, sendMessage, clientId);
|
|
21692
21233
|
return;
|
|
21693
21234
|
}
|
|
21694
21235
|
if (!createdBy) {
|
|
21695
|
-
|
|
21236
|
+
sendResponse8(id, {
|
|
21696
21237
|
success: false,
|
|
21697
21238
|
error: "createdBy (user ID) is required"
|
|
21698
21239
|
}, sendMessage, clientId);
|
|
@@ -21709,7 +21250,7 @@ async function handleCreate7(id, nodeData, executeCollection, sendMessage, clien
|
|
|
21709
21250
|
});
|
|
21710
21251
|
if (result && result.success) {
|
|
21711
21252
|
logger.info(`[DB] KB node created successfully: ${title}`);
|
|
21712
|
-
|
|
21253
|
+
sendResponse8(id, {
|
|
21713
21254
|
success: true,
|
|
21714
21255
|
data: {
|
|
21715
21256
|
...result.data,
|
|
@@ -21718,13 +21259,13 @@ async function handleCreate7(id, nodeData, executeCollection, sendMessage, clien
|
|
|
21718
21259
|
}, sendMessage, clientId);
|
|
21719
21260
|
return;
|
|
21720
21261
|
}
|
|
21721
|
-
|
|
21262
|
+
sendResponse8(id, {
|
|
21722
21263
|
success: false,
|
|
21723
21264
|
error: "Failed to create knowledge node"
|
|
21724
21265
|
}, sendMessage, clientId);
|
|
21725
21266
|
} catch (error) {
|
|
21726
21267
|
logger.error("[DB] Failed to create KB node:", error);
|
|
21727
|
-
|
|
21268
|
+
sendResponse8(id, {
|
|
21728
21269
|
success: false,
|
|
21729
21270
|
error: error instanceof Error ? error.message : "Failed to create knowledge node"
|
|
21730
21271
|
}, sendMessage, clientId);
|
|
@@ -21733,14 +21274,14 @@ async function handleCreate7(id, nodeData, executeCollection, sendMessage, clien
|
|
|
21733
21274
|
async function handleUpdate7(id, nodeId, nodeData, executeCollection, sendMessage, clientId) {
|
|
21734
21275
|
const { title, content, category, tags, type, updatedBy } = nodeData;
|
|
21735
21276
|
if (!nodeId) {
|
|
21736
|
-
|
|
21277
|
+
sendResponse8(id, {
|
|
21737
21278
|
success: false,
|
|
21738
21279
|
error: "Knowledge node ID is required"
|
|
21739
21280
|
}, sendMessage, clientId);
|
|
21740
21281
|
return;
|
|
21741
21282
|
}
|
|
21742
21283
|
if (!updatedBy) {
|
|
21743
|
-
|
|
21284
|
+
sendResponse8(id, {
|
|
21744
21285
|
success: false,
|
|
21745
21286
|
error: "updatedBy (user ID) is required"
|
|
21746
21287
|
}, sendMessage, clientId);
|
|
@@ -21758,7 +21299,7 @@ async function handleUpdate7(id, nodeId, nodeData, executeCollection, sendMessag
|
|
|
21758
21299
|
});
|
|
21759
21300
|
if (result && result.success) {
|
|
21760
21301
|
logger.info(`[DB] KB node updated successfully, ID: ${nodeId}`);
|
|
21761
|
-
|
|
21302
|
+
sendResponse8(id, {
|
|
21762
21303
|
success: true,
|
|
21763
21304
|
data: {
|
|
21764
21305
|
...result.data,
|
|
@@ -21767,13 +21308,13 @@ async function handleUpdate7(id, nodeId, nodeData, executeCollection, sendMessag
|
|
|
21767
21308
|
}, sendMessage, clientId);
|
|
21768
21309
|
return;
|
|
21769
21310
|
}
|
|
21770
|
-
|
|
21311
|
+
sendResponse8(id, {
|
|
21771
21312
|
success: false,
|
|
21772
21313
|
error: "Failed to update knowledge node"
|
|
21773
21314
|
}, sendMessage, clientId);
|
|
21774
21315
|
} catch (error) {
|
|
21775
21316
|
logger.error("[DB] Failed to update KB node:", error);
|
|
21776
|
-
|
|
21317
|
+
sendResponse8(id, {
|
|
21777
21318
|
success: false,
|
|
21778
21319
|
error: error instanceof Error ? error.message : "Failed to update knowledge node"
|
|
21779
21320
|
}, sendMessage, clientId);
|
|
@@ -21781,7 +21322,7 @@ async function handleUpdate7(id, nodeId, nodeData, executeCollection, sendMessag
|
|
|
21781
21322
|
}
|
|
21782
21323
|
async function handleDelete7(id, nodeId, executeCollection, sendMessage, clientId) {
|
|
21783
21324
|
if (!nodeId) {
|
|
21784
|
-
|
|
21325
|
+
sendResponse8(id, {
|
|
21785
21326
|
success: false,
|
|
21786
21327
|
error: "Knowledge node ID is required"
|
|
21787
21328
|
}, sendMessage, clientId);
|
|
@@ -21791,7 +21332,7 @@ async function handleDelete7(id, nodeId, executeCollection, sendMessage, clientI
|
|
|
21791
21332
|
const result = await executeCollection("kbNodes", "delete", { id: nodeId });
|
|
21792
21333
|
if (result && result.success) {
|
|
21793
21334
|
logger.info(`[DB] KB node deleted successfully, ID: ${nodeId}`);
|
|
21794
|
-
|
|
21335
|
+
sendResponse8(id, {
|
|
21795
21336
|
success: true,
|
|
21796
21337
|
data: {
|
|
21797
21338
|
id: nodeId,
|
|
@@ -21801,13 +21342,13 @@ async function handleDelete7(id, nodeId, executeCollection, sendMessage, clientI
|
|
|
21801
21342
|
}, sendMessage, clientId);
|
|
21802
21343
|
return;
|
|
21803
21344
|
}
|
|
21804
|
-
|
|
21345
|
+
sendResponse8(id, {
|
|
21805
21346
|
success: false,
|
|
21806
21347
|
error: "Failed to delete knowledge node"
|
|
21807
21348
|
}, sendMessage, clientId);
|
|
21808
21349
|
} catch (error) {
|
|
21809
21350
|
logger.error("[DB] Failed to delete KB node:", error);
|
|
21810
|
-
|
|
21351
|
+
sendResponse8(id, {
|
|
21811
21352
|
success: false,
|
|
21812
21353
|
error: error instanceof Error ? error.message : "Failed to delete knowledge node"
|
|
21813
21354
|
}, sendMessage, clientId);
|
|
@@ -21821,7 +21362,7 @@ async function handleGetAll7(id, limit, offset, executeCollection, sendMessage,
|
|
|
21821
21362
|
});
|
|
21822
21363
|
if (result && result.success) {
|
|
21823
21364
|
logger.info(`[DB] Retrieved ${result.count} KB nodes`);
|
|
21824
|
-
|
|
21365
|
+
sendResponse8(id, {
|
|
21825
21366
|
success: true,
|
|
21826
21367
|
data: {
|
|
21827
21368
|
nodes: result.data,
|
|
@@ -21831,13 +21372,13 @@ async function handleGetAll7(id, limit, offset, executeCollection, sendMessage,
|
|
|
21831
21372
|
}, sendMessage, clientId);
|
|
21832
21373
|
return;
|
|
21833
21374
|
}
|
|
21834
|
-
|
|
21375
|
+
sendResponse8(id, {
|
|
21835
21376
|
success: false,
|
|
21836
21377
|
error: "Failed to retrieve knowledge nodes"
|
|
21837
21378
|
}, sendMessage, clientId);
|
|
21838
21379
|
} catch (error) {
|
|
21839
21380
|
logger.error("[DB] Failed to get all KB nodes:", error);
|
|
21840
|
-
|
|
21381
|
+
sendResponse8(id, {
|
|
21841
21382
|
success: false,
|
|
21842
21383
|
error: error instanceof Error ? error.message : "Failed to retrieve knowledge nodes"
|
|
21843
21384
|
}, sendMessage, clientId);
|
|
@@ -21845,7 +21386,7 @@ async function handleGetAll7(id, limit, offset, executeCollection, sendMessage,
|
|
|
21845
21386
|
}
|
|
21846
21387
|
async function handleGetOne7(id, nodeId, executeCollection, sendMessage, clientId) {
|
|
21847
21388
|
if (!nodeId) {
|
|
21848
|
-
|
|
21389
|
+
sendResponse8(id, {
|
|
21849
21390
|
success: false,
|
|
21850
21391
|
error: "Knowledge node ID is required"
|
|
21851
21392
|
}, sendMessage, clientId);
|
|
@@ -21855,7 +21396,7 @@ async function handleGetOne7(id, nodeId, executeCollection, sendMessage, clientI
|
|
|
21855
21396
|
const result = await executeCollection("kbNodes", "getOne", { id: nodeId });
|
|
21856
21397
|
if (result && result.success) {
|
|
21857
21398
|
logger.info(`[DB] Retrieved KB node ID: ${nodeId}`);
|
|
21858
|
-
|
|
21399
|
+
sendResponse8(id, {
|
|
21859
21400
|
success: true,
|
|
21860
21401
|
data: {
|
|
21861
21402
|
node: result.data,
|
|
@@ -21864,13 +21405,13 @@ async function handleGetOne7(id, nodeId, executeCollection, sendMessage, clientI
|
|
|
21864
21405
|
}, sendMessage, clientId);
|
|
21865
21406
|
return;
|
|
21866
21407
|
}
|
|
21867
|
-
|
|
21408
|
+
sendResponse8(id, {
|
|
21868
21409
|
success: false,
|
|
21869
21410
|
error: "Failed to retrieve knowledge node"
|
|
21870
21411
|
}, sendMessage, clientId);
|
|
21871
21412
|
} catch (error) {
|
|
21872
21413
|
logger.error("[DB] Failed to get KB node:", error);
|
|
21873
|
-
|
|
21414
|
+
sendResponse8(id, {
|
|
21874
21415
|
success: false,
|
|
21875
21416
|
error: error instanceof Error ? error.message : "Failed to retrieve knowledge node"
|
|
21876
21417
|
}, sendMessage, clientId);
|
|
@@ -21890,7 +21431,7 @@ async function handleSearch(id, searchParams, executeCollection, sendMessage, cl
|
|
|
21890
21431
|
});
|
|
21891
21432
|
if (result && result.success) {
|
|
21892
21433
|
logger.info(`[DB] Search returned ${result.count} KB nodes`);
|
|
21893
|
-
|
|
21434
|
+
sendResponse8(id, {
|
|
21894
21435
|
success: true,
|
|
21895
21436
|
data: {
|
|
21896
21437
|
nodes: result.data,
|
|
@@ -21900,13 +21441,13 @@ async function handleSearch(id, searchParams, executeCollection, sendMessage, cl
|
|
|
21900
21441
|
}, sendMessage, clientId);
|
|
21901
21442
|
return;
|
|
21902
21443
|
}
|
|
21903
|
-
|
|
21444
|
+
sendResponse8(id, {
|
|
21904
21445
|
success: false,
|
|
21905
21446
|
error: "Failed to search knowledge nodes"
|
|
21906
21447
|
}, sendMessage, clientId);
|
|
21907
21448
|
} catch (error) {
|
|
21908
21449
|
logger.error("[DB] Failed to search KB nodes:", error);
|
|
21909
|
-
|
|
21450
|
+
sendResponse8(id, {
|
|
21910
21451
|
success: false,
|
|
21911
21452
|
error: error instanceof Error ? error.message : "Failed to search knowledge nodes"
|
|
21912
21453
|
}, sendMessage, clientId);
|
|
@@ -21914,7 +21455,7 @@ async function handleSearch(id, searchParams, executeCollection, sendMessage, cl
|
|
|
21914
21455
|
}
|
|
21915
21456
|
async function handleGetByCategory(id, category, limit, offset, executeCollection, sendMessage, clientId) {
|
|
21916
21457
|
if (!category) {
|
|
21917
|
-
|
|
21458
|
+
sendResponse8(id, {
|
|
21918
21459
|
success: false,
|
|
21919
21460
|
error: "Category is required"
|
|
21920
21461
|
}, sendMessage, clientId);
|
|
@@ -21928,7 +21469,7 @@ async function handleGetByCategory(id, category, limit, offset, executeCollectio
|
|
|
21928
21469
|
});
|
|
21929
21470
|
if (result && result.success) {
|
|
21930
21471
|
logger.info(`[DB] Retrieved ${result.count} KB nodes for category: ${category}`);
|
|
21931
|
-
|
|
21472
|
+
sendResponse8(id, {
|
|
21932
21473
|
success: true,
|
|
21933
21474
|
data: {
|
|
21934
21475
|
nodes: result.data,
|
|
@@ -21939,13 +21480,13 @@ async function handleGetByCategory(id, category, limit, offset, executeCollectio
|
|
|
21939
21480
|
}, sendMessage, clientId);
|
|
21940
21481
|
return;
|
|
21941
21482
|
}
|
|
21942
|
-
|
|
21483
|
+
sendResponse8(id, {
|
|
21943
21484
|
success: false,
|
|
21944
21485
|
error: "Failed to retrieve knowledge nodes by category"
|
|
21945
21486
|
}, sendMessage, clientId);
|
|
21946
21487
|
} catch (error) {
|
|
21947
21488
|
logger.error("[DB] Failed to get KB nodes by category:", error);
|
|
21948
|
-
|
|
21489
|
+
sendResponse8(id, {
|
|
21949
21490
|
success: false,
|
|
21950
21491
|
error: error instanceof Error ? error.message : "Failed to retrieve knowledge nodes by category"
|
|
21951
21492
|
}, sendMessage, clientId);
|
|
@@ -21953,7 +21494,7 @@ async function handleGetByCategory(id, category, limit, offset, executeCollectio
|
|
|
21953
21494
|
}
|
|
21954
21495
|
async function handleGetByUser(id, userId, limit, offset, executeCollection, sendMessage, clientId) {
|
|
21955
21496
|
if (!userId) {
|
|
21956
|
-
|
|
21497
|
+
sendResponse8(id, {
|
|
21957
21498
|
success: false,
|
|
21958
21499
|
error: "User ID is required"
|
|
21959
21500
|
}, sendMessage, clientId);
|
|
@@ -21967,7 +21508,7 @@ async function handleGetByUser(id, userId, limit, offset, executeCollection, sen
|
|
|
21967
21508
|
});
|
|
21968
21509
|
if (result && result.success) {
|
|
21969
21510
|
logger.info(`[DB] Retrieved ${result.count} KB nodes for user: ${userId}`);
|
|
21970
|
-
|
|
21511
|
+
sendResponse8(id, {
|
|
21971
21512
|
success: true,
|
|
21972
21513
|
data: {
|
|
21973
21514
|
nodes: result.data,
|
|
@@ -21978,13 +21519,13 @@ async function handleGetByUser(id, userId, limit, offset, executeCollection, sen
|
|
|
21978
21519
|
}, sendMessage, clientId);
|
|
21979
21520
|
return;
|
|
21980
21521
|
}
|
|
21981
|
-
|
|
21522
|
+
sendResponse8(id, {
|
|
21982
21523
|
success: false,
|
|
21983
21524
|
error: "Failed to retrieve knowledge nodes by user"
|
|
21984
21525
|
}, sendMessage, clientId);
|
|
21985
21526
|
} catch (error) {
|
|
21986
21527
|
logger.error("[DB] Failed to get KB nodes by user:", error);
|
|
21987
|
-
|
|
21528
|
+
sendResponse8(id, {
|
|
21988
21529
|
success: false,
|
|
21989
21530
|
error: error instanceof Error ? error.message : "Failed to retrieve knowledge nodes by user"
|
|
21990
21531
|
}, sendMessage, clientId);
|
|
@@ -21995,7 +21536,7 @@ async function handleGetCategories(id, executeCollection, sendMessage, clientId)
|
|
|
21995
21536
|
const result = await executeCollection("kbNodes", "getCategories", {});
|
|
21996
21537
|
if (result && result.success) {
|
|
21997
21538
|
logger.info(`[DB] Retrieved ${result.count} categories`);
|
|
21998
|
-
|
|
21539
|
+
sendResponse8(id, {
|
|
21999
21540
|
success: true,
|
|
22000
21541
|
data: {
|
|
22001
21542
|
categories: result.data,
|
|
@@ -22005,13 +21546,13 @@ async function handleGetCategories(id, executeCollection, sendMessage, clientId)
|
|
|
22005
21546
|
}, sendMessage, clientId);
|
|
22006
21547
|
return;
|
|
22007
21548
|
}
|
|
22008
|
-
|
|
21549
|
+
sendResponse8(id, {
|
|
22009
21550
|
success: false,
|
|
22010
21551
|
error: "Failed to retrieve categories"
|
|
22011
21552
|
}, sendMessage, clientId);
|
|
22012
21553
|
} catch (error) {
|
|
22013
21554
|
logger.error("[DB] Failed to get categories:", error);
|
|
22014
|
-
|
|
21555
|
+
sendResponse8(id, {
|
|
22015
21556
|
success: false,
|
|
22016
21557
|
error: error instanceof Error ? error.message : "Failed to retrieve categories"
|
|
22017
21558
|
}, sendMessage, clientId);
|
|
@@ -22022,7 +21563,7 @@ async function handleGetTags(id, executeCollection, sendMessage, clientId) {
|
|
|
22022
21563
|
const result = await executeCollection("kbNodes", "getTags", {});
|
|
22023
21564
|
if (result && result.success) {
|
|
22024
21565
|
logger.info(`[DB] Retrieved ${result.count} tags`);
|
|
22025
|
-
|
|
21566
|
+
sendResponse8(id, {
|
|
22026
21567
|
success: true,
|
|
22027
21568
|
data: {
|
|
22028
21569
|
tags: result.data,
|
|
@@ -22032,19 +21573,19 @@ async function handleGetTags(id, executeCollection, sendMessage, clientId) {
|
|
|
22032
21573
|
}, sendMessage, clientId);
|
|
22033
21574
|
return;
|
|
22034
21575
|
}
|
|
22035
|
-
|
|
21576
|
+
sendResponse8(id, {
|
|
22036
21577
|
success: false,
|
|
22037
21578
|
error: "Failed to retrieve tags"
|
|
22038
21579
|
}, sendMessage, clientId);
|
|
22039
21580
|
} catch (error) {
|
|
22040
21581
|
logger.error("[DB] Failed to get tags:", error);
|
|
22041
|
-
|
|
21582
|
+
sendResponse8(id, {
|
|
22042
21583
|
success: false,
|
|
22043
21584
|
error: error instanceof Error ? error.message : "Failed to retrieve tags"
|
|
22044
21585
|
}, sendMessage, clientId);
|
|
22045
21586
|
}
|
|
22046
21587
|
}
|
|
22047
|
-
function
|
|
21588
|
+
function sendResponse8(id, res, sendMessage, clientId) {
|
|
22048
21589
|
const response = {
|
|
22049
21590
|
id: id || "unknown",
|
|
22050
21591
|
type: "KB_NODES_RES",
|
|
@@ -22118,14 +21659,14 @@ async function handleMenusRequest(data, collections, sendMessage) {
|
|
|
22118
21659
|
await handleReorder(id, items, executeCollection, sendMessage, from.id);
|
|
22119
21660
|
break;
|
|
22120
21661
|
default:
|
|
22121
|
-
|
|
21662
|
+
sendResponse9(id, {
|
|
22122
21663
|
success: false,
|
|
22123
21664
|
error: `Unknown operation: ${operation}`
|
|
22124
21665
|
}, sendMessage, from.id);
|
|
22125
21666
|
}
|
|
22126
21667
|
} catch (error) {
|
|
22127
21668
|
logger.error("Failed to handle menus request:", error);
|
|
22128
|
-
|
|
21669
|
+
sendResponse9(null, {
|
|
22129
21670
|
success: false,
|
|
22130
21671
|
error: error instanceof Error ? error.message : "Unknown error occurred"
|
|
22131
21672
|
}, sendMessage);
|
|
@@ -22133,14 +21674,14 @@ async function handleMenusRequest(data, collections, sendMessage) {
|
|
|
22133
21674
|
}
|
|
22134
21675
|
async function handleCreate8(id, name, componentName, icon, userMessage, parentId, sortOrder, props, isActive, executeCollection, sendMessage, clientId) {
|
|
22135
21676
|
if (!name) {
|
|
22136
|
-
|
|
21677
|
+
sendResponse9(id, {
|
|
22137
21678
|
success: false,
|
|
22138
21679
|
error: "name is required"
|
|
22139
21680
|
}, sendMessage, clientId);
|
|
22140
21681
|
return;
|
|
22141
21682
|
}
|
|
22142
21683
|
if (!componentName) {
|
|
22143
|
-
|
|
21684
|
+
sendResponse9(id, {
|
|
22144
21685
|
success: false,
|
|
22145
21686
|
error: "componentName is required"
|
|
22146
21687
|
}, sendMessage, clientId);
|
|
@@ -22157,14 +21698,14 @@ async function handleCreate8(id, name, componentName, icon, userMessage, parentI
|
|
|
22157
21698
|
props,
|
|
22158
21699
|
isActive
|
|
22159
21700
|
});
|
|
22160
|
-
|
|
21701
|
+
sendResponse9(id, {
|
|
22161
21702
|
success: true,
|
|
22162
21703
|
data: result.data,
|
|
22163
21704
|
message: "Menu created successfully"
|
|
22164
21705
|
}, sendMessage, clientId);
|
|
22165
21706
|
logger.info(`Menu created: ID ${result.data?.id}`);
|
|
22166
21707
|
} catch (error) {
|
|
22167
|
-
|
|
21708
|
+
sendResponse9(id, {
|
|
22168
21709
|
success: false,
|
|
22169
21710
|
error: error instanceof Error ? error.message : "Failed to create menu"
|
|
22170
21711
|
}, sendMessage, clientId);
|
|
@@ -22172,7 +21713,7 @@ async function handleCreate8(id, name, componentName, icon, userMessage, parentI
|
|
|
22172
21713
|
}
|
|
22173
21714
|
async function handleUpdate8(id, menuId, name, componentName, icon, userMessage, parentId, sortOrder, props, isActive, executeCollection, sendMessage, clientId) {
|
|
22174
21715
|
if (!menuId) {
|
|
22175
|
-
|
|
21716
|
+
sendResponse9(id, {
|
|
22176
21717
|
success: false,
|
|
22177
21718
|
error: "Menu ID is required"
|
|
22178
21719
|
}, sendMessage, clientId);
|
|
@@ -22190,14 +21731,14 @@ async function handleUpdate8(id, menuId, name, componentName, icon, userMessage,
|
|
|
22190
21731
|
props,
|
|
22191
21732
|
isActive
|
|
22192
21733
|
});
|
|
22193
|
-
|
|
21734
|
+
sendResponse9(id, {
|
|
22194
21735
|
success: true,
|
|
22195
21736
|
data: result.data,
|
|
22196
21737
|
message: "Menu updated successfully"
|
|
22197
21738
|
}, sendMessage, clientId);
|
|
22198
21739
|
logger.info(`Menu updated: ID ${menuId}`);
|
|
22199
21740
|
} catch (error) {
|
|
22200
|
-
|
|
21741
|
+
sendResponse9(id, {
|
|
22201
21742
|
success: false,
|
|
22202
21743
|
error: error instanceof Error ? error.message : "Failed to update menu"
|
|
22203
21744
|
}, sendMessage, clientId);
|
|
@@ -22205,7 +21746,7 @@ async function handleUpdate8(id, menuId, name, componentName, icon, userMessage,
|
|
|
22205
21746
|
}
|
|
22206
21747
|
async function handleDelete8(id, menuId, executeCollection, sendMessage, clientId) {
|
|
22207
21748
|
if (!menuId) {
|
|
22208
|
-
|
|
21749
|
+
sendResponse9(id, {
|
|
22209
21750
|
success: false,
|
|
22210
21751
|
error: "Menu ID is required"
|
|
22211
21752
|
}, sendMessage, clientId);
|
|
@@ -22213,14 +21754,14 @@ async function handleDelete8(id, menuId, executeCollection, sendMessage, clientI
|
|
|
22213
21754
|
}
|
|
22214
21755
|
try {
|
|
22215
21756
|
const result = await executeCollection("menus", "delete", { id: menuId });
|
|
22216
|
-
|
|
21757
|
+
sendResponse9(id, {
|
|
22217
21758
|
success: true,
|
|
22218
21759
|
data: result.data,
|
|
22219
21760
|
message: "Menu deleted successfully"
|
|
22220
21761
|
}, sendMessage, clientId);
|
|
22221
21762
|
logger.info(`Menu deleted: ID ${menuId}`);
|
|
22222
21763
|
} catch (error) {
|
|
22223
|
-
|
|
21764
|
+
sendResponse9(id, {
|
|
22224
21765
|
success: false,
|
|
22225
21766
|
error: error instanceof Error ? error.message : "Failed to delete menu"
|
|
22226
21767
|
}, sendMessage, clientId);
|
|
@@ -22229,7 +21770,7 @@ async function handleDelete8(id, menuId, executeCollection, sendMessage, clientI
|
|
|
22229
21770
|
async function handleGetAll8(id, executeCollection, sendMessage, clientId) {
|
|
22230
21771
|
try {
|
|
22231
21772
|
const result = await executeCollection("menus", "getAll", {});
|
|
22232
|
-
|
|
21773
|
+
sendResponse9(id, {
|
|
22233
21774
|
success: true,
|
|
22234
21775
|
data: result.data,
|
|
22235
21776
|
count: result.count,
|
|
@@ -22237,7 +21778,7 @@ async function handleGetAll8(id, executeCollection, sendMessage, clientId) {
|
|
|
22237
21778
|
}, sendMessage, clientId);
|
|
22238
21779
|
logger.info(`Retrieved all menus (count: ${result.count})`);
|
|
22239
21780
|
} catch (error) {
|
|
22240
|
-
|
|
21781
|
+
sendResponse9(id, {
|
|
22241
21782
|
success: false,
|
|
22242
21783
|
error: error instanceof Error ? error.message : "Failed to get menus"
|
|
22243
21784
|
}, sendMessage, clientId);
|
|
@@ -22245,7 +21786,7 @@ async function handleGetAll8(id, executeCollection, sendMessage, clientId) {
|
|
|
22245
21786
|
}
|
|
22246
21787
|
async function handleGetOne8(id, menuId, executeCollection, sendMessage, clientId) {
|
|
22247
21788
|
if (!menuId) {
|
|
22248
|
-
|
|
21789
|
+
sendResponse9(id, {
|
|
22249
21790
|
success: false,
|
|
22250
21791
|
error: "Menu ID is required"
|
|
22251
21792
|
}, sendMessage, clientId);
|
|
@@ -22253,14 +21794,14 @@ async function handleGetOne8(id, menuId, executeCollection, sendMessage, clientI
|
|
|
22253
21794
|
}
|
|
22254
21795
|
try {
|
|
22255
21796
|
const result = await executeCollection("menus", "getOne", { id: menuId });
|
|
22256
|
-
|
|
21797
|
+
sendResponse9(id, {
|
|
22257
21798
|
success: true,
|
|
22258
21799
|
data: result.data,
|
|
22259
21800
|
message: `Retrieved menu ID ${menuId}`
|
|
22260
21801
|
}, sendMessage, clientId);
|
|
22261
21802
|
logger.info(`Retrieved menu: ID ${menuId}`);
|
|
22262
21803
|
} catch (error) {
|
|
22263
|
-
|
|
21804
|
+
sendResponse9(id, {
|
|
22264
21805
|
success: false,
|
|
22265
21806
|
error: error instanceof Error ? error.message : "Failed to get menu"
|
|
22266
21807
|
}, sendMessage, clientId);
|
|
@@ -22269,7 +21810,7 @@ async function handleGetOne8(id, menuId, executeCollection, sendMessage, clientI
|
|
|
22269
21810
|
async function handleGetRootMenus(id, executeCollection, sendMessage, clientId) {
|
|
22270
21811
|
try {
|
|
22271
21812
|
const result = await executeCollection("menus", "getRootMenus", {});
|
|
22272
|
-
|
|
21813
|
+
sendResponse9(id, {
|
|
22273
21814
|
success: true,
|
|
22274
21815
|
data: result.data,
|
|
22275
21816
|
count: result.count,
|
|
@@ -22277,7 +21818,7 @@ async function handleGetRootMenus(id, executeCollection, sendMessage, clientId)
|
|
|
22277
21818
|
}, sendMessage, clientId);
|
|
22278
21819
|
logger.info(`Retrieved root menus (count: ${result.count})`);
|
|
22279
21820
|
} catch (error) {
|
|
22280
|
-
|
|
21821
|
+
sendResponse9(id, {
|
|
22281
21822
|
success: false,
|
|
22282
21823
|
error: error instanceof Error ? error.message : "Failed to get root menus"
|
|
22283
21824
|
}, sendMessage, clientId);
|
|
@@ -22285,7 +21826,7 @@ async function handleGetRootMenus(id, executeCollection, sendMessage, clientId)
|
|
|
22285
21826
|
}
|
|
22286
21827
|
async function handleGetChildMenus(id, parentId, executeCollection, sendMessage, clientId) {
|
|
22287
21828
|
if (parentId === void 0 || parentId === null) {
|
|
22288
|
-
|
|
21829
|
+
sendResponse9(id, {
|
|
22289
21830
|
success: false,
|
|
22290
21831
|
error: "parentId is required"
|
|
22291
21832
|
}, sendMessage, clientId);
|
|
@@ -22293,7 +21834,7 @@ async function handleGetChildMenus(id, parentId, executeCollection, sendMessage,
|
|
|
22293
21834
|
}
|
|
22294
21835
|
try {
|
|
22295
21836
|
const result = await executeCollection("menus", "getChildMenus", { parentId });
|
|
22296
|
-
|
|
21837
|
+
sendResponse9(id, {
|
|
22297
21838
|
success: true,
|
|
22298
21839
|
data: result.data,
|
|
22299
21840
|
count: result.count,
|
|
@@ -22301,7 +21842,7 @@ async function handleGetChildMenus(id, parentId, executeCollection, sendMessage,
|
|
|
22301
21842
|
}, sendMessage, clientId);
|
|
22302
21843
|
logger.info(`Retrieved child menus for parent ${parentId} (count: ${result.count})`);
|
|
22303
21844
|
} catch (error) {
|
|
22304
|
-
|
|
21845
|
+
sendResponse9(id, {
|
|
22305
21846
|
success: false,
|
|
22306
21847
|
error: error instanceof Error ? error.message : "Failed to get child menus"
|
|
22307
21848
|
}, sendMessage, clientId);
|
|
@@ -22310,7 +21851,7 @@ async function handleGetChildMenus(id, parentId, executeCollection, sendMessage,
|
|
|
22310
21851
|
async function handleGetHierarchy(id, executeCollection, sendMessage, clientId) {
|
|
22311
21852
|
try {
|
|
22312
21853
|
const result = await executeCollection("menus", "getHierarchy", {});
|
|
22313
|
-
|
|
21854
|
+
sendResponse9(id, {
|
|
22314
21855
|
success: true,
|
|
22315
21856
|
data: result.data,
|
|
22316
21857
|
count: result.count,
|
|
@@ -22318,7 +21859,7 @@ async function handleGetHierarchy(id, executeCollection, sendMessage, clientId)
|
|
|
22318
21859
|
}, sendMessage, clientId);
|
|
22319
21860
|
logger.info(`Retrieved menus hierarchy (root count: ${result.count})`);
|
|
22320
21861
|
} catch (error) {
|
|
22321
|
-
|
|
21862
|
+
sendResponse9(id, {
|
|
22322
21863
|
success: false,
|
|
22323
21864
|
error: error instanceof Error ? error.message : "Failed to get menus hierarchy"
|
|
22324
21865
|
}, sendMessage, clientId);
|
|
@@ -22331,7 +21872,7 @@ async function handleQuery7(id, filters, limit, sort, executeCollection, sendMes
|
|
|
22331
21872
|
limit,
|
|
22332
21873
|
sort
|
|
22333
21874
|
});
|
|
22334
|
-
|
|
21875
|
+
sendResponse9(id, {
|
|
22335
21876
|
success: true,
|
|
22336
21877
|
data: result.data,
|
|
22337
21878
|
count: result.count,
|
|
@@ -22339,7 +21880,7 @@ async function handleQuery7(id, filters, limit, sort, executeCollection, sendMes
|
|
|
22339
21880
|
}, sendMessage, clientId);
|
|
22340
21881
|
logger.info(`Query returned ${result.count} menus`);
|
|
22341
21882
|
} catch (error) {
|
|
22342
|
-
|
|
21883
|
+
sendResponse9(id, {
|
|
22343
21884
|
success: false,
|
|
22344
21885
|
error: error instanceof Error ? error.message : "Failed to query menus"
|
|
22345
21886
|
}, sendMessage, clientId);
|
|
@@ -22347,7 +21888,7 @@ async function handleQuery7(id, filters, limit, sort, executeCollection, sendMes
|
|
|
22347
21888
|
}
|
|
22348
21889
|
async function handleReorder(id, items, executeCollection, sendMessage, clientId) {
|
|
22349
21890
|
if (!items || !Array.isArray(items) || items.length === 0) {
|
|
22350
|
-
|
|
21891
|
+
sendResponse9(id, {
|
|
22351
21892
|
success: false,
|
|
22352
21893
|
error: "items array is required"
|
|
22353
21894
|
}, sendMessage, clientId);
|
|
@@ -22355,20 +21896,20 @@ async function handleReorder(id, items, executeCollection, sendMessage, clientId
|
|
|
22355
21896
|
}
|
|
22356
21897
|
try {
|
|
22357
21898
|
const result = await executeCollection("menus", "reorder", { items });
|
|
22358
|
-
|
|
21899
|
+
sendResponse9(id, {
|
|
22359
21900
|
success: true,
|
|
22360
21901
|
data: result.data,
|
|
22361
21902
|
message: `Reordered ${items.length} menus successfully`
|
|
22362
21903
|
}, sendMessage, clientId);
|
|
22363
21904
|
logger.info(`Reordered ${items.length} menus`);
|
|
22364
21905
|
} catch (error) {
|
|
22365
|
-
|
|
21906
|
+
sendResponse9(id, {
|
|
22366
21907
|
success: false,
|
|
22367
21908
|
error: error instanceof Error ? error.message : "Failed to reorder menus"
|
|
22368
21909
|
}, sendMessage, clientId);
|
|
22369
21910
|
}
|
|
22370
21911
|
}
|
|
22371
|
-
function
|
|
21912
|
+
function sendResponse9(id, res, sendMessage, clientId) {
|
|
22372
21913
|
const response = {
|
|
22373
21914
|
id: id || "unknown",
|
|
22374
21915
|
type: "MENUS_RES",
|
|
@@ -24137,13 +23678,14 @@ async function runCodingAgent(agentId, options = {}) {
|
|
|
24137
23678
|
const policy = def.session ?? {};
|
|
24138
23679
|
const persistentWorkspace = policy.workspace === "persistent";
|
|
24139
23680
|
const persistentSession = policy.scope === "persistent";
|
|
23681
|
+
const runAsJob = !(options.chat === true && def.mode === "task");
|
|
24140
23682
|
const { key: scopeKey, dirName } = resolveScope(def, { userId: options.userId, threadId: options.threadId });
|
|
24141
23683
|
const scopeDir = path9.join(agentDir, dirName);
|
|
24142
23684
|
const dir = options.workspaceDir || (persistentWorkspace ? scopeDir : path9.join(scopeDir, "runs", runId));
|
|
24143
23685
|
fs8.mkdirSync(dir, { recursive: true });
|
|
24144
23686
|
if (persistentWorkspace && !options.workspaceDir) {
|
|
24145
23687
|
fs8.mkdirSync(path9.join(dir, "memory"), { recursive: true });
|
|
24146
|
-
await clearTransient(dir);
|
|
23688
|
+
if (runAsJob) await clearTransient(dir);
|
|
24147
23689
|
}
|
|
24148
23690
|
const lockKey = persistentWorkspace || persistentSession ? `${def.id}:${scopeKey}` : `dir:${dir}`;
|
|
24149
23691
|
if (inFlight.has(lockKey)) {
|
|
@@ -24198,10 +23740,12 @@ async function runCodingAgent(agentId, options = {}) {
|
|
|
24198
23740
|
};
|
|
24199
23741
|
try {
|
|
24200
23742
|
await installInstructions(def, ws);
|
|
24201
|
-
if (def.prepare) await def.prepare(ws, input, ctx);
|
|
24202
|
-
const outputPath = def.output ? ws.pathTo(def.output.file) : void 0;
|
|
23743
|
+
if (def.prepare && runAsJob) await def.prepare(ws, input, ctx);
|
|
23744
|
+
const outputPath = runAsJob && def.output ? ws.pathTo(def.output.file) : void 0;
|
|
24203
23745
|
if (outputPath) await fsp.rm(outputPath, { force: true });
|
|
24204
|
-
const prompt = options.prompt ??
|
|
23746
|
+
const prompt = options.prompt ?? // buildPrompt may read what prepare() wrote, so it is only asked when
|
|
23747
|
+
// prepare() actually ran.
|
|
23748
|
+
(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.");
|
|
24205
23749
|
const tools = { ...cfg.sharedTools ?? {}, ...def.tools ?? {} };
|
|
24206
23750
|
const session = createCodingAgentSession(def.harness || cfg.harness, {
|
|
24207
23751
|
cwd: dir,
|
|
@@ -24252,7 +23796,7 @@ async function runCodingAgent(agentId, options = {}) {
|
|
|
24252
23796
|
return record;
|
|
24253
23797
|
}
|
|
24254
23798
|
const successStatus = result.status === "early" ? "early" : "completed";
|
|
24255
|
-
if (!def.output) {
|
|
23799
|
+
if (!def.output || !runAsJob) {
|
|
24256
23800
|
record.status = successStatus;
|
|
24257
23801
|
return record;
|
|
24258
23802
|
}
|
|
@@ -24281,7 +23825,7 @@ async function runCodingAgent(agentId, options = {}) {
|
|
|
24281
23825
|
} finally {
|
|
24282
23826
|
inFlight.delete(lockKey);
|
|
24283
23827
|
logger.info(
|
|
24284
|
-
`[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}"` : "")
|
|
23828
|
+
`[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}"` : "")
|
|
24285
23829
|
);
|
|
24286
23830
|
if (!options.workspaceDir && !persistentWorkspace) await pruneRuns(path9.join(scopeDir, "runs"), cfg.keepRuns);
|
|
24287
23831
|
}
|
|
@@ -24395,15 +23939,30 @@ console.log(${JSON.stringify(JSON.stringify(opts.sources, null, 2))});
|
|
|
24395
23939
|
// src/codingAgent/triggers.ts
|
|
24396
23940
|
var fs10 = __toESM(require("fs"));
|
|
24397
23941
|
var path10 = __toESM(require("path"));
|
|
23942
|
+
var EVENT_BURST_CAP = 200;
|
|
23943
|
+
var capEvents = (events) => events.length > EVENT_BURST_CAP ? events.slice(-EVENT_BURST_CAP) : events;
|
|
24398
23944
|
function statePath2(agentId) {
|
|
24399
23945
|
return path10.join(getCodingAgentsConfig().runtimeDir, agentId, "_triggers.json");
|
|
24400
23946
|
}
|
|
24401
23947
|
function loadTriggerState(agentId) {
|
|
23948
|
+
let raw;
|
|
24402
23949
|
try {
|
|
24403
|
-
|
|
23950
|
+
raw = JSON.parse(fs10.readFileSync(statePath2(agentId), "utf-8"));
|
|
24404
23951
|
} catch {
|
|
24405
|
-
return { counts: {} };
|
|
23952
|
+
return { counts: {}, pending: {} };
|
|
23953
|
+
}
|
|
23954
|
+
const counts = {};
|
|
23955
|
+
for (const [name, value] of Object.entries(raw?.counts ?? {})) {
|
|
23956
|
+
if (Array.isArray(value)) counts[name] = value;
|
|
23957
|
+
else if (typeof value === "number" && value > 0) counts[name] = Array.from({ length: value }, () => ({ name }));
|
|
23958
|
+
}
|
|
23959
|
+
const pending = {};
|
|
23960
|
+
if (raw?.pending && typeof raw.pending === "object" && !Array.isArray(raw.pending)) {
|
|
23961
|
+
for (const [key, value] of Object.entries(raw.pending)) {
|
|
23962
|
+
if (Array.isArray(value)) pending[key] = value;
|
|
23963
|
+
}
|
|
24406
23964
|
}
|
|
23965
|
+
return { counts, pending, lastRunAt: raw?.lastRunAt };
|
|
24407
23966
|
}
|
|
24408
23967
|
function saveTriggerState(agentId, state) {
|
|
24409
23968
|
try {
|
|
@@ -24417,6 +23976,7 @@ function saveTriggerState(agentId, state) {
|
|
|
24417
23976
|
var asArray = (t) => !t ? [] : Array.isArray(t) ? t : [t];
|
|
24418
23977
|
var intervals = /* @__PURE__ */ new Map();
|
|
24419
23978
|
var debounces = /* @__PURE__ */ new Map();
|
|
23979
|
+
var bursts = /* @__PURE__ */ new Map();
|
|
24420
23980
|
var firing = /* @__PURE__ */ new Set();
|
|
24421
23981
|
var listeners = [];
|
|
24422
23982
|
function onAgentRun(fn) {
|
|
@@ -24426,21 +23986,38 @@ function onAgentRun(fn) {
|
|
|
24426
23986
|
if (i >= 0) listeners.splice(i, 1);
|
|
24427
23987
|
};
|
|
24428
23988
|
}
|
|
24429
|
-
|
|
23989
|
+
function inputFor(trigger, events) {
|
|
23990
|
+
const build = trigger?.buildInput;
|
|
23991
|
+
const lastPayload = () => events.length ? events[events.length - 1].payload : void 0;
|
|
23992
|
+
if (!build) return lastPayload();
|
|
23993
|
+
try {
|
|
23994
|
+
return build(events);
|
|
23995
|
+
} catch (err) {
|
|
23996
|
+
logger.error(`[CodingAgent] buildInput threw, falling back to the last payload: ${err?.message ?? err}`);
|
|
23997
|
+
return lastPayload();
|
|
23998
|
+
}
|
|
23999
|
+
}
|
|
24000
|
+
async function fire(agentId, triggerIndex, reason, events = []) {
|
|
24430
24001
|
if (firing.has(agentId)) {
|
|
24431
|
-
const
|
|
24432
|
-
|
|
24433
|
-
|
|
24002
|
+
const st2 = loadTriggerState(agentId);
|
|
24003
|
+
const key = String(triggerIndex);
|
|
24004
|
+
saveTriggerState(agentId, {
|
|
24005
|
+
...st2,
|
|
24006
|
+
pending: { ...st2.pending, [key]: capEvents([...st2.pending[key] ?? [], ...events]) }
|
|
24007
|
+
});
|
|
24008
|
+
logger.info(`[CodingAgent:${agentId}] ${reason} arrived mid-run \u2014 queued (${events.length} event(s))`);
|
|
24434
24009
|
return;
|
|
24435
24010
|
}
|
|
24436
24011
|
firing.add(agentId);
|
|
24437
24012
|
try {
|
|
24013
|
+
const trigger = asArray(getCodingAgent(agentId)?.trigger)[triggerIndex];
|
|
24014
|
+
const input = inputFor(trigger, events);
|
|
24438
24015
|
logger.info(`[CodingAgent:${agentId}] triggered by ${reason}`);
|
|
24439
|
-
const record = await runCodingAgent(agentId, { input
|
|
24440
|
-
saveTriggerState(agentId, { ...loadTriggerState(agentId), lastRunAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
24016
|
+
const record = await runCodingAgent(agentId, { input });
|
|
24017
|
+
saveTriggerState(agentId, { ...loadTriggerState(agentId), lastRunAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
24441
24018
|
for (const fn of listeners) {
|
|
24442
24019
|
try {
|
|
24443
|
-
fn(record, { agentId, reason,
|
|
24020
|
+
fn(record, { agentId, reason, events, input });
|
|
24444
24021
|
} catch {
|
|
24445
24022
|
}
|
|
24446
24023
|
}
|
|
@@ -24448,9 +24025,13 @@ async function fire(agentId, reason, payload) {
|
|
|
24448
24025
|
logger.error(`[CodingAgent:${agentId}] trigger run failed: ${err?.message ?? err}`);
|
|
24449
24026
|
} finally {
|
|
24450
24027
|
firing.delete(agentId);
|
|
24451
|
-
|
|
24452
|
-
|
|
24453
|
-
|
|
24028
|
+
}
|
|
24029
|
+
const st = loadTriggerState(agentId);
|
|
24030
|
+
const queued = Object.entries(st.pending);
|
|
24031
|
+
if (queued.length) {
|
|
24032
|
+
saveTriggerState(agentId, { ...st, pending: {} });
|
|
24033
|
+
for (const [index, evs] of queued) {
|
|
24034
|
+
await fire(agentId, Number(index), "queued work from during the last run", evs);
|
|
24454
24035
|
}
|
|
24455
24036
|
}
|
|
24456
24037
|
}
|
|
@@ -24458,45 +24039,49 @@ function emitAgentEvent(event, payload) {
|
|
|
24458
24039
|
for (const { id } of listCodingAgents()) {
|
|
24459
24040
|
const def = getCodingAgent(id);
|
|
24460
24041
|
if (!def) continue;
|
|
24461
|
-
|
|
24042
|
+
asArray(def.trigger).forEach((trigger, index) => {
|
|
24462
24043
|
if (trigger.type === "event") {
|
|
24463
24044
|
const names = Array.isArray(trigger.on) ? trigger.on : [trigger.on];
|
|
24464
|
-
if (!names.includes(event))
|
|
24045
|
+
if (!names.includes(event)) return;
|
|
24046
|
+
const arrived = { name: event, payload };
|
|
24465
24047
|
if (!trigger.debounceMs) {
|
|
24466
|
-
void fire(id, `event ${event}`,
|
|
24467
|
-
|
|
24048
|
+
void fire(id, index, `event ${event}`, [arrived]);
|
|
24049
|
+
return;
|
|
24468
24050
|
}
|
|
24469
|
-
const key = `${id}:${
|
|
24051
|
+
const key = `${id}:${index}`;
|
|
24052
|
+
bursts.set(key, capEvents([...bursts.get(key) ?? [], arrived]));
|
|
24470
24053
|
const existing = debounces.get(key);
|
|
24471
24054
|
if (existing) clearTimeout(existing);
|
|
24472
24055
|
debounces.set(key, setTimeout(() => {
|
|
24473
24056
|
debounces.delete(key);
|
|
24474
|
-
|
|
24057
|
+
const batch = bursts.get(key) ?? [];
|
|
24058
|
+
bursts.delete(key);
|
|
24059
|
+
void fire(id, index, `event ${event} (settled, ${batch.length} event(s))`, batch);
|
|
24475
24060
|
}, trigger.debounceMs));
|
|
24476
|
-
|
|
24061
|
+
return;
|
|
24477
24062
|
}
|
|
24478
24063
|
if (trigger.type === "count" && trigger.on === event) {
|
|
24479
24064
|
const state = loadTriggerState(id);
|
|
24480
|
-
const
|
|
24481
|
-
if (
|
|
24482
|
-
saveTriggerState(id, { ...state, counts: { ...state.counts, [event]:
|
|
24483
|
-
|
|
24065
|
+
const banked = capEvents([...state.counts[event] ?? [], { name: event, payload }]);
|
|
24066
|
+
if (banked.length < trigger.every) {
|
|
24067
|
+
saveTriggerState(id, { ...state, counts: { ...state.counts, [event]: banked } });
|
|
24068
|
+
return;
|
|
24484
24069
|
}
|
|
24485
|
-
saveTriggerState(id, { ...state, counts: { ...state.counts, [event]:
|
|
24486
|
-
void fire(id, `${trigger.every}x ${event}`,
|
|
24070
|
+
saveTriggerState(id, { ...state, counts: { ...state.counts, [event]: [] } });
|
|
24071
|
+
void fire(id, index, `${trigger.every}x ${event}`, banked);
|
|
24487
24072
|
}
|
|
24488
|
-
}
|
|
24073
|
+
});
|
|
24489
24074
|
}
|
|
24490
24075
|
}
|
|
24491
24076
|
function startAgentTriggers() {
|
|
24492
24077
|
stopAgentTriggers();
|
|
24493
24078
|
for (const { id } of listCodingAgents()) {
|
|
24494
24079
|
const def = getCodingAgent(id);
|
|
24495
|
-
|
|
24496
|
-
if (trigger.type !== "interval")
|
|
24497
|
-
intervals.set(id
|
|
24080
|
+
asArray(def?.trigger).forEach((trigger, index) => {
|
|
24081
|
+
if (trigger.type !== "interval") return;
|
|
24082
|
+
intervals.set(`${id}:${index}`, setInterval(() => void fire(id, index, `interval ${trigger.everyMs}ms`), trigger.everyMs));
|
|
24498
24083
|
logger.info(`[CodingAgent:${id}] interval trigger every ${trigger.everyMs}ms`);
|
|
24499
|
-
}
|
|
24084
|
+
});
|
|
24500
24085
|
}
|
|
24501
24086
|
}
|
|
24502
24087
|
function stopAgentTriggers() {
|
|
@@ -24504,6 +24089,7 @@ function stopAgentTriggers() {
|
|
|
24504
24089
|
intervals.clear();
|
|
24505
24090
|
for (const t of debounces.values()) clearTimeout(t);
|
|
24506
24091
|
debounces.clear();
|
|
24092
|
+
bursts.clear();
|
|
24507
24093
|
}
|
|
24508
24094
|
function describeTriggers() {
|
|
24509
24095
|
return listCodingAgents().map(({ id }) => {
|
|
@@ -24520,6 +24106,9 @@ function describeTriggers() {
|
|
|
24520
24106
|
// src/codingAgent/collection.ts
|
|
24521
24107
|
var fs11 = __toESM(require("fs"));
|
|
24522
24108
|
var path11 = __toESM(require("path"));
|
|
24109
|
+
function isChattable(agent) {
|
|
24110
|
+
return agent.mode !== "task";
|
|
24111
|
+
}
|
|
24523
24112
|
function registerCodingAgentCollection(sdk, config2 = {}) {
|
|
24524
24113
|
const runtimeDir = config2.runtimeDir || process.env.CODING_AGENT_RUNTIME_DIR || path11.join(process.cwd(), ".coding-agent-runtime");
|
|
24525
24114
|
const defaultHarness = config2.harness || process.env.CODING_AGENT_HARNESS || "codex";
|
|
@@ -24543,7 +24132,19 @@ function registerCodingAgentCollection(sdk, config2 = {}) {
|
|
|
24543
24132
|
error: `Unknown agent "${agentId}". Available: ${listCodingAgents().map((a) => a.id).join(", ") || "(none registered)"}`
|
|
24544
24133
|
};
|
|
24545
24134
|
}
|
|
24135
|
+
if (!isChattable(def)) {
|
|
24136
|
+
return {
|
|
24137
|
+
success: false,
|
|
24138
|
+
error: `${def.title} runs as a scheduled task and is not available for chat.`
|
|
24139
|
+
};
|
|
24140
|
+
}
|
|
24546
24141
|
const record = await runCodingAgent(agentId, {
|
|
24142
|
+
// chat:true is what stops a typed message being treated as a job. A
|
|
24143
|
+
// task agent's prepare()/output/apply() set work up and consume it, so
|
|
24144
|
+
// without this every conversational turn failed for not writing a
|
|
24145
|
+
// deliverable nobody asked for — and, for a batching agent, quietly ate
|
|
24146
|
+
// a batch of work on the way.
|
|
24147
|
+
chat: true,
|
|
24547
24148
|
prompt,
|
|
24548
24149
|
projectId,
|
|
24549
24150
|
userId,
|
|
@@ -24563,7 +24164,10 @@ function registerCodingAgentCollection(sdk, config2 = {}) {
|
|
|
24563
24164
|
sessionId: record.sessionId,
|
|
24564
24165
|
...record.output !== void 0 ? { output: record.output } : {},
|
|
24565
24166
|
...record.applied ? { applied: record.applied } : {},
|
|
24566
|
-
|
|
24167
|
+
// A project-scoped agent serialises its runs, so a turn sent while it
|
|
24168
|
+
// is working is a normal outcome, not a fault. Say so in words a
|
|
24169
|
+
// person can act on.
|
|
24170
|
+
...record.status === "skipped" ? { error: `${def.title} is in the middle of a run \u2014 try again in a moment.` } : record.error ? { error: record.error } : {}
|
|
24567
24171
|
};
|
|
24568
24172
|
}
|
|
24569
24173
|
const cwd = path11.join(runtimeDir, "threads", threadId);
|
|
@@ -24610,7 +24214,10 @@ function registerCodingAgentCollection(sdk, config2 = {}) {
|
|
|
24610
24214
|
}
|
|
24611
24215
|
return { success: true };
|
|
24612
24216
|
});
|
|
24613
|
-
sdk.addCollection("coding-agent", "list", async () => ({
|
|
24217
|
+
sdk.addCollection("coding-agent", "list", async () => ({
|
|
24218
|
+
success: true,
|
|
24219
|
+
agents: listCodingAgents().map((a) => ({ ...a, chattable: isChattable(a) }))
|
|
24220
|
+
}));
|
|
24614
24221
|
console.log(`\u2713 coding-agent collection registered (harness: ${defaultHarness})`);
|
|
24615
24222
|
}
|
|
24616
24223
|
|
|
@@ -27744,11 +27351,6 @@ var SuperatomSDK = class {
|
|
|
27744
27351
|
logger.error("Failed to handle user prompt abort request:", error);
|
|
27745
27352
|
}
|
|
27746
27353
|
break;
|
|
27747
|
-
case "ACTIONS":
|
|
27748
|
-
handleActionsRequest(parsed, (msg) => this.send(msg), this.anthropicApiKey, this.groqApiKey, this.geminiApiKey, this.openaiApiKey, this.llmProviders).catch((error) => {
|
|
27749
|
-
logger.error("Failed to handle actions request:", error);
|
|
27750
|
-
});
|
|
27751
|
-
break;
|
|
27752
27354
|
case "USER_PROMPT_SUGGESTIONS_REQ":
|
|
27753
27355
|
handleUserPromptSuggestions(parsed, this.components, (msg) => this.send(msg), this.collections).catch((error) => {
|
|
27754
27356
|
logger.error("Failed to handle user prompt suggestions request:", error);
|