@superatomai/sdk-node 0.0.57 → 0.0.59
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 +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +265 -26
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +265 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1620,6 +1620,7 @@ __export(utils_exports, {
|
|
|
1620
1620
|
fixScalarSubqueries: () => fixScalarSubqueries,
|
|
1621
1621
|
getDatabaseType: () => getDatabaseType,
|
|
1622
1622
|
getJsonSizeInBytes: () => getJsonSizeInBytes,
|
|
1623
|
+
validateAndFixSqlQuery: () => validateAndFixSqlQuery,
|
|
1623
1624
|
validateMessageSize: () => validateMessageSize
|
|
1624
1625
|
});
|
|
1625
1626
|
function getDatabaseType() {
|
|
@@ -1795,6 +1796,105 @@ function validateMessageSize(message, maxSize = 1048576) {
|
|
|
1795
1796
|
maxSize
|
|
1796
1797
|
};
|
|
1797
1798
|
}
|
|
1799
|
+
function validateAndFixSqlQuery(query, dbType) {
|
|
1800
|
+
if (!query || query.trim().length === 0) {
|
|
1801
|
+
return { query, fixed: false, fixes: [] };
|
|
1802
|
+
}
|
|
1803
|
+
const databaseType = dbType || getDatabaseType();
|
|
1804
|
+
const _isMssql = databaseType === "mssql";
|
|
1805
|
+
let fixedQuery = query;
|
|
1806
|
+
const fixes = [];
|
|
1807
|
+
const aggregateFunctions = ["SUM", "COUNT", "AVG", "MIN", "MAX"];
|
|
1808
|
+
const aggregateInWherePattern = new RegExp(
|
|
1809
|
+
`\\bWHERE\\b[^]*?\\b(${aggregateFunctions.join("|")})\\s*\\([^)]*\\)\\s*(?:=|>|<|>=|<=|<>|!=)`,
|
|
1810
|
+
"i"
|
|
1811
|
+
);
|
|
1812
|
+
if (aggregateInWherePattern.test(fixedQuery)) {
|
|
1813
|
+
const aggregateConditionPattern = new RegExp(
|
|
1814
|
+
`\\s+(AND|OR)\\s+((?:COALESCE\\s*\\(\\s*)?(?:${aggregateFunctions.join("|")})\\s*\\([^)]+\\)[^)]*(?:\\))?\\s*(?:=|>|<|>=|<=|<>|!=)\\s*[^\\s,)]+)`,
|
|
1815
|
+
"gi"
|
|
1816
|
+
);
|
|
1817
|
+
const aggregateConditions = [];
|
|
1818
|
+
let match;
|
|
1819
|
+
while ((match = aggregateConditionPattern.exec(fixedQuery)) !== null) {
|
|
1820
|
+
aggregateConditions.push(match[2].trim());
|
|
1821
|
+
}
|
|
1822
|
+
if (aggregateConditions.length > 0) {
|
|
1823
|
+
fixedQuery = fixedQuery.replace(aggregateConditionPattern, "");
|
|
1824
|
+
fixedQuery = fixedQuery.replace(/\bWHERE\s+(AND|OR)\s+/gi, "WHERE ");
|
|
1825
|
+
fixedQuery = fixedQuery.replace(/\bWHERE\s+(GROUP\s+BY|ORDER\s+BY|HAVING|$)/gi, "$1");
|
|
1826
|
+
const hasGroupBy = /\bGROUP\s+BY\b/i.test(fixedQuery);
|
|
1827
|
+
if (hasGroupBy) {
|
|
1828
|
+
const hasHaving = /\bHAVING\b/i.test(fixedQuery);
|
|
1829
|
+
const havingClause = aggregateConditions.join(" AND ");
|
|
1830
|
+
if (hasHaving) {
|
|
1831
|
+
fixedQuery = fixedQuery.replace(
|
|
1832
|
+
/\bHAVING\b/i,
|
|
1833
|
+
`HAVING ${havingClause} AND`
|
|
1834
|
+
);
|
|
1835
|
+
} else {
|
|
1836
|
+
const orderByMatch = fixedQuery.match(/(\s+ORDER\s+BY\s+)/i);
|
|
1837
|
+
if (orderByMatch) {
|
|
1838
|
+
fixedQuery = fixedQuery.replace(
|
|
1839
|
+
orderByMatch[1],
|
|
1840
|
+
` HAVING ${havingClause}${orderByMatch[1]}`
|
|
1841
|
+
);
|
|
1842
|
+
} else {
|
|
1843
|
+
fixedQuery = fixedQuery.trimEnd() + ` HAVING ${havingClause}`;
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
fixes.push(`Moved aggregate condition(s) from WHERE to HAVING: ${havingClause}`);
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
let openCount = 0;
|
|
1851
|
+
let closeCount = 0;
|
|
1852
|
+
let inString = false;
|
|
1853
|
+
let stringChar = "";
|
|
1854
|
+
for (let i = 0; i < fixedQuery.length; i++) {
|
|
1855
|
+
const char = fixedQuery[i];
|
|
1856
|
+
const prevChar = i > 0 ? fixedQuery[i - 1] : "";
|
|
1857
|
+
if ((char === "'" || char === '"') && prevChar !== "\\") {
|
|
1858
|
+
if (!inString) {
|
|
1859
|
+
inString = true;
|
|
1860
|
+
stringChar = char;
|
|
1861
|
+
} else if (char === stringChar) {
|
|
1862
|
+
if (i + 1 < fixedQuery.length && fixedQuery[i + 1] === char) {
|
|
1863
|
+
i++;
|
|
1864
|
+
} else {
|
|
1865
|
+
inString = false;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
continue;
|
|
1869
|
+
}
|
|
1870
|
+
if (!inString) {
|
|
1871
|
+
if (char === "(") openCount++;
|
|
1872
|
+
else if (char === ")") closeCount++;
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
if (openCount > closeCount) {
|
|
1876
|
+
const missingClose = openCount - closeCount;
|
|
1877
|
+
fixedQuery = fixedQuery.trimEnd();
|
|
1878
|
+
const hasSemicolon = fixedQuery.endsWith(";");
|
|
1879
|
+
if (hasSemicolon) {
|
|
1880
|
+
fixedQuery = fixedQuery.slice(0, -1);
|
|
1881
|
+
}
|
|
1882
|
+
fixedQuery = fixedQuery + ")".repeat(missingClose);
|
|
1883
|
+
if (hasSemicolon) {
|
|
1884
|
+
fixedQuery = fixedQuery + ";";
|
|
1885
|
+
}
|
|
1886
|
+
fixes.push(`Added ${missingClose} missing closing parenthesis(es)`);
|
|
1887
|
+
}
|
|
1888
|
+
const originalLength = fixedQuery.length;
|
|
1889
|
+
fixedQuery = fixedQuery.replace(/\s+/g, " ").trim();
|
|
1890
|
+
if (fixedQuery.length !== originalLength) {
|
|
1891
|
+
}
|
|
1892
|
+
return {
|
|
1893
|
+
query: fixedQuery,
|
|
1894
|
+
fixed: fixes.length > 0,
|
|
1895
|
+
fixes
|
|
1896
|
+
};
|
|
1897
|
+
}
|
|
1798
1898
|
var init_utils = __esm({
|
|
1799
1899
|
"src/userResponse/utils.ts"() {
|
|
1800
1900
|
"use strict";
|
|
@@ -2359,8 +2459,14 @@ var BookmarksRequestMessageSchema = z3.object({
|
|
|
2359
2459
|
type: z3.literal("BOOKMARKS"),
|
|
2360
2460
|
payload: BookmarksRequestPayloadSchema
|
|
2361
2461
|
});
|
|
2462
|
+
var ArtifactsQueryFiltersSchema = z3.object({
|
|
2463
|
+
createdBy: z3.number().optional(),
|
|
2464
|
+
status: z3.string().optional(),
|
|
2465
|
+
name: z3.string().optional(),
|
|
2466
|
+
deleted: z3.boolean().optional()
|
|
2467
|
+
});
|
|
2362
2468
|
var ArtifactsRequestPayloadSchema = z3.object({
|
|
2363
|
-
operation: z3.enum(["create", "update", "delete", "getAll", "getOne"]),
|
|
2469
|
+
operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
|
|
2364
2470
|
data: z3.object({
|
|
2365
2471
|
id: z3.number().optional(),
|
|
2366
2472
|
name: z3.string().optional(),
|
|
@@ -2368,7 +2474,10 @@ var ArtifactsRequestPayloadSchema = z3.object({
|
|
|
2368
2474
|
dsl: z3.record(z3.any()).optional(),
|
|
2369
2475
|
status: z3.string().optional(),
|
|
2370
2476
|
deleted: z3.boolean().optional(),
|
|
2371
|
-
limit: z3.number().optional()
|
|
2477
|
+
limit: z3.number().optional(),
|
|
2478
|
+
// Query operation fields
|
|
2479
|
+
filters: ArtifactsQueryFiltersSchema.optional(),
|
|
2480
|
+
sort: z3.enum(["ASC", "DESC"]).optional()
|
|
2372
2481
|
}).optional()
|
|
2373
2482
|
});
|
|
2374
2483
|
var ArtifactsRequestMessageSchema = z3.object({
|
|
@@ -5896,7 +6005,10 @@ var BaseLLM = class {
|
|
|
5896
6005
|
* @param componentStreamCallback - Optional callback to stream primary KPI component as soon as it's identified
|
|
5897
6006
|
* @returns Object containing matched components, layout title/description, and follow-up actions
|
|
5898
6007
|
*/
|
|
5899
|
-
async matchComponentsFromAnalysis(analysisContent, components, apiKey, logCollector, componentStreamCallback, deferredTools, executedTools) {
|
|
6008
|
+
async matchComponentsFromAnalysis(analysisContent, components, apiKey, logCollector, componentStreamCallback, deferredTools, executedTools, collections, userId, userPrompt) {
|
|
6009
|
+
const methodStartTime = Date.now();
|
|
6010
|
+
const methodName = "matchComponentsFromAnalysis";
|
|
6011
|
+
logger.info(`[${this.getProviderName()}] [TIMING] START ${methodName} | model: ${this.getModelForTask("complex")}`);
|
|
5900
6012
|
try {
|
|
5901
6013
|
logger.debug(`[${this.getProviderName()}] Starting component matching from text response`);
|
|
5902
6014
|
let availableComponentsText = "No components available";
|
|
@@ -5956,6 +6068,16 @@ ${fieldsText}`;
|
|
|
5956
6068
|
}
|
|
5957
6069
|
const schemaDoc = schema.generateSchemaDocumentation();
|
|
5958
6070
|
const databaseRules = await promptLoader.loadDatabaseRules();
|
|
6071
|
+
let knowledgeBaseContext = "No additional knowledge base context available.";
|
|
6072
|
+
if (collections) {
|
|
6073
|
+
const kbResult = await knowledge_base_default.getAllKnowledgeBase({
|
|
6074
|
+
prompt: userPrompt || analysisContent,
|
|
6075
|
+
collections,
|
|
6076
|
+
userId,
|
|
6077
|
+
topK: 3
|
|
6078
|
+
});
|
|
6079
|
+
knowledgeBaseContext = kbResult.combinedContext || knowledgeBaseContext;
|
|
6080
|
+
}
|
|
5959
6081
|
const prompts = await promptLoader.loadPrompts("match-text-components", {
|
|
5960
6082
|
ANALYSIS_CONTENT: analysisContent,
|
|
5961
6083
|
AVAILABLE_COMPONENTS: availableComponentsText,
|
|
@@ -5963,11 +6085,27 @@ ${fieldsText}`;
|
|
|
5963
6085
|
DATABASE_RULES: databaseRules,
|
|
5964
6086
|
DEFERRED_TOOLS: deferredToolsText,
|
|
5965
6087
|
EXECUTED_TOOLS: executedToolsText,
|
|
6088
|
+
KNOWLEDGE_BASE_CONTEXT: knowledgeBaseContext,
|
|
5966
6089
|
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
5967
6090
|
});
|
|
5968
6091
|
logger.debug(`[${this.getProviderName()}] Loaded match-text-components prompts`);
|
|
5969
|
-
const
|
|
5970
|
-
|
|
6092
|
+
const extractPromptText = (content) => {
|
|
6093
|
+
if (typeof content === "string") return content;
|
|
6094
|
+
if (Array.isArray(content)) {
|
|
6095
|
+
return content.map((item) => {
|
|
6096
|
+
if (typeof item === "string") return item;
|
|
6097
|
+
if (item && typeof item.text === "string") return item.text;
|
|
6098
|
+
if (item && item.content && typeof item.content === "string") return item.content;
|
|
6099
|
+
return JSON.stringify(item, null, 2);
|
|
6100
|
+
}).join("\n\n---\n\n");
|
|
6101
|
+
}
|
|
6102
|
+
if (content && typeof content === "object") {
|
|
6103
|
+
if (typeof content.text === "string") return content.text;
|
|
6104
|
+
return JSON.stringify(content, null, 2);
|
|
6105
|
+
}
|
|
6106
|
+
return String(content);
|
|
6107
|
+
};
|
|
6108
|
+
logger.logLLMPrompt("matchComponentsFromAnalysis", "system", extractPromptText(prompts.system));
|
|
5971
6109
|
logger.logLLMPrompt("matchComponentsFromAnalysis", "user", `Text Analysis:
|
|
5972
6110
|
${analysisContent}
|
|
5973
6111
|
|
|
@@ -6192,6 +6330,18 @@ ${executedToolsText}`);
|
|
|
6192
6330
|
cleanedProps.query = null;
|
|
6193
6331
|
}
|
|
6194
6332
|
}
|
|
6333
|
+
if (cleanedProps.query) {
|
|
6334
|
+
const queryStr = typeof cleanedProps.query === "string" ? cleanedProps.query : cleanedProps.query?.sql || "";
|
|
6335
|
+
const { query: fixedQuery, fixed, fixes } = validateAndFixSqlQuery(queryStr);
|
|
6336
|
+
if (fixed) {
|
|
6337
|
+
logger.warn(`[${this.getProviderName()}] SQL fixes applied to component query: ${fixes.join("; ")}`);
|
|
6338
|
+
if (typeof cleanedProps.query === "string") {
|
|
6339
|
+
cleanedProps.query = fixedQuery;
|
|
6340
|
+
} else if (cleanedProps.query?.sql) {
|
|
6341
|
+
cleanedProps.query.sql = fixedQuery;
|
|
6342
|
+
}
|
|
6343
|
+
}
|
|
6344
|
+
}
|
|
6195
6345
|
if (cleanedProps.query && cleanedProps.externalTool) {
|
|
6196
6346
|
logger.info(`[${this.getProviderName()}] Both query and externalTool exist, keeping both - frontend will decide`);
|
|
6197
6347
|
}
|
|
@@ -6203,6 +6353,8 @@ ${executedToolsText}`);
|
|
|
6203
6353
|
}
|
|
6204
6354
|
};
|
|
6205
6355
|
}).filter(Boolean);
|
|
6356
|
+
const methodDuration = Date.now() - methodStartTime;
|
|
6357
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | components: ${finalComponents.length} | actions: ${actions.length}`);
|
|
6206
6358
|
return {
|
|
6207
6359
|
components: finalComponents,
|
|
6208
6360
|
layoutTitle,
|
|
@@ -6210,8 +6362,9 @@ ${executedToolsText}`);
|
|
|
6210
6362
|
actions
|
|
6211
6363
|
};
|
|
6212
6364
|
} catch (error) {
|
|
6365
|
+
const methodDuration = Date.now() - methodStartTime;
|
|
6213
6366
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
6214
|
-
logger.error(`[${this.getProviderName()}]
|
|
6367
|
+
logger.error(`[${this.getProviderName()}] [TIMING] FAILED ${methodName} in ${methodDuration}ms | error: ${errorMsg}`);
|
|
6215
6368
|
logCollector?.error(`Failed to match components: ${errorMsg}`);
|
|
6216
6369
|
return {
|
|
6217
6370
|
components: [],
|
|
@@ -6226,6 +6379,10 @@ ${executedToolsText}`);
|
|
|
6226
6379
|
* Determines if question is for data analysis, requires external tools, or needs text response
|
|
6227
6380
|
*/
|
|
6228
6381
|
async classifyQuestionCategory(userPrompt, apiKey, logCollector, conversationHistory, externalTools) {
|
|
6382
|
+
const methodStartTime = Date.now();
|
|
6383
|
+
const methodName = "classifyQuestionCategory";
|
|
6384
|
+
const promptPreview = userPrompt.substring(0, 50) + (userPrompt.length > 50 ? "..." : "");
|
|
6385
|
+
logger.info(`[${this.getProviderName()}] [TIMING] START ${methodName} | model: ${this.getModelForTask("simple")} | prompt: "${promptPreview}"`);
|
|
6229
6386
|
try {
|
|
6230
6387
|
const schemaDoc = schema.generateSchemaDocumentation();
|
|
6231
6388
|
const availableToolsDoc = externalTools && externalTools.length > 0 ? externalTools.map((tool) => {
|
|
@@ -6241,10 +6398,24 @@ ${executedToolsText}`);
|
|
|
6241
6398
|
SCHEMA_DOC: schemaDoc || "No database schema available",
|
|
6242
6399
|
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
6243
6400
|
});
|
|
6244
|
-
const
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6401
|
+
const extractTextContent = (content) => {
|
|
6402
|
+
if (typeof content === "string") return content;
|
|
6403
|
+
if (Array.isArray(content)) {
|
|
6404
|
+
return content.map((item) => {
|
|
6405
|
+
if (typeof item === "string") return item;
|
|
6406
|
+
if (item && typeof item.text === "string") return item.text;
|
|
6407
|
+
if (item && item.content && typeof item.content === "string") return item.content;
|
|
6408
|
+
return JSON.stringify(item, null, 2);
|
|
6409
|
+
}).join("\n\n---\n\n");
|
|
6410
|
+
}
|
|
6411
|
+
if (content && typeof content === "object") {
|
|
6412
|
+
if (typeof content.text === "string") return content.text;
|
|
6413
|
+
return JSON.stringify(content, null, 2);
|
|
6414
|
+
}
|
|
6415
|
+
return String(content);
|
|
6416
|
+
};
|
|
6417
|
+
logger.logLLMPrompt("classifyQuestionCategory", "system", extractTextContent(prompts.system));
|
|
6418
|
+
logger.logLLMPrompt("classifyQuestionCategory", "user", extractTextContent(prompts.user));
|
|
6248
6419
|
const result = await LLM.stream(
|
|
6249
6420
|
{
|
|
6250
6421
|
sys: prompts.system,
|
|
@@ -6269,6 +6440,8 @@ ${executedToolsText}`);
|
|
|
6269
6440
|
confidence: result.confidence
|
|
6270
6441
|
}
|
|
6271
6442
|
);
|
|
6443
|
+
const methodDuration = Date.now() - methodStartTime;
|
|
6444
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | category: ${result.category} | confidence: ${result.confidence}% | tools: ${(result.externalTools || []).length}`);
|
|
6272
6445
|
return {
|
|
6273
6446
|
category: result.category || "data_analysis",
|
|
6274
6447
|
externalTools: result.externalTools || [],
|
|
@@ -6277,8 +6450,9 @@ ${executedToolsText}`);
|
|
|
6277
6450
|
confidence: result.confidence || 0
|
|
6278
6451
|
};
|
|
6279
6452
|
} catch (error) {
|
|
6453
|
+
const methodDuration = Date.now() - methodStartTime;
|
|
6280
6454
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
6281
|
-
logger.error(`[${this.getProviderName()}]
|
|
6455
|
+
logger.error(`[${this.getProviderName()}] [TIMING] FAILED ${methodName} in ${methodDuration}ms | error: ${errorMsg}`);
|
|
6282
6456
|
logger.debug(`[${this.getProviderName()}] Category classification error details:`, error);
|
|
6283
6457
|
throw error;
|
|
6284
6458
|
}
|
|
@@ -6289,9 +6463,15 @@ ${executedToolsText}`);
|
|
|
6289
6463
|
* Also adapts the cached text response to match the new question
|
|
6290
6464
|
*/
|
|
6291
6465
|
async adaptUIBlockParameters(currentUserPrompt, originalUserPrompt, matchedUIBlock, apiKey, logCollector, cachedTextResponse) {
|
|
6466
|
+
const methodStartTime = Date.now();
|
|
6467
|
+
const methodName = "adaptUIBlockParameters";
|
|
6468
|
+
const promptPreview = currentUserPrompt.substring(0, 50) + (currentUserPrompt.length > 50 ? "..." : "");
|
|
6469
|
+
logger.info(`[${this.getProviderName()}] [TIMING] START ${methodName} | model: ${this.getModelForTask("complex")} | prompt: "${promptPreview}"`);
|
|
6292
6470
|
try {
|
|
6293
6471
|
const component = matchedUIBlock?.generatedComponentMetadata || matchedUIBlock?.component;
|
|
6294
6472
|
if (!matchedUIBlock || !component) {
|
|
6473
|
+
const methodDuration2 = Date.now() - methodStartTime;
|
|
6474
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration2}ms | result: no component found`);
|
|
6295
6475
|
return {
|
|
6296
6476
|
success: false,
|
|
6297
6477
|
explanation: "No component found in matched UI block"
|
|
@@ -6324,9 +6504,8 @@ ${executedToolsText}`);
|
|
|
6324
6504
|
// Parse as JSON
|
|
6325
6505
|
);
|
|
6326
6506
|
if (!result.success) {
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
);
|
|
6507
|
+
const methodDuration2 = Date.now() - methodStartTime;
|
|
6508
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration2}ms | result: adaptation failed - ${result.reason}`);
|
|
6330
6509
|
logCollector?.warn(
|
|
6331
6510
|
"Could not adapt matched UI block",
|
|
6332
6511
|
"explanation",
|
|
@@ -6351,6 +6530,8 @@ ${executedToolsText}`);
|
|
|
6351
6530
|
componentType: result.adaptedComponent?.type
|
|
6352
6531
|
}
|
|
6353
6532
|
);
|
|
6533
|
+
const methodDuration = Date.now() - methodStartTime;
|
|
6534
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | result: success | changes: ${(result.parametersChanged || []).length}`);
|
|
6354
6535
|
return {
|
|
6355
6536
|
success: true,
|
|
6356
6537
|
adaptedComponent: result.adaptedComponent,
|
|
@@ -6359,8 +6540,9 @@ ${executedToolsText}`);
|
|
|
6359
6540
|
explanation: result.explanation || "Parameters adapted successfully"
|
|
6360
6541
|
};
|
|
6361
6542
|
} catch (error) {
|
|
6543
|
+
const methodDuration = Date.now() - methodStartTime;
|
|
6362
6544
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
6363
|
-
logger.error(`[${this.getProviderName()}]
|
|
6545
|
+
logger.error(`[${this.getProviderName()}] [TIMING] FAILED ${methodName} in ${methodDuration}ms | error: ${errorMsg}`);
|
|
6364
6546
|
logger.debug(`[${this.getProviderName()}] Adaptation error details:`, error);
|
|
6365
6547
|
return {
|
|
6366
6548
|
success: false,
|
|
@@ -6381,6 +6563,10 @@ ${executedToolsText}`);
|
|
|
6381
6563
|
* @param userId - Optional user ID for fetching user-specific knowledge base nodes
|
|
6382
6564
|
*/
|
|
6383
6565
|
async generateTextResponse(userPrompt, apiKey, logCollector, conversationHistory, streamCallback, collections, components, externalTools, category, userId) {
|
|
6566
|
+
const methodStartTime = Date.now();
|
|
6567
|
+
const methodName = "generateTextResponse";
|
|
6568
|
+
const promptPreview = userPrompt.substring(0, 50) + (userPrompt.length > 50 ? "..." : "");
|
|
6569
|
+
logger.info(`[${this.getProviderName()}] [TIMING] START ${methodName} | model: ${this.getModelForTask("complex")} | category: ${category} | prompt: "${promptPreview}"`);
|
|
6384
6570
|
const errors = [];
|
|
6385
6571
|
logger.debug(`[${this.getProviderName()}] Starting text response generation`);
|
|
6386
6572
|
logger.debug(`[${this.getProviderName()}] User prompt: "${userPrompt.substring(0, 50)}..."`);
|
|
@@ -6445,10 +6631,24 @@ ${executedToolsText}`);
|
|
|
6445
6631
|
AVAILABLE_EXTERNAL_TOOLS: availableToolsDoc,
|
|
6446
6632
|
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
6447
6633
|
});
|
|
6448
|
-
const
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6634
|
+
const extractText = (content) => {
|
|
6635
|
+
if (typeof content === "string") return content;
|
|
6636
|
+
if (Array.isArray(content)) {
|
|
6637
|
+
return content.map((item) => {
|
|
6638
|
+
if (typeof item === "string") return item;
|
|
6639
|
+
if (item && typeof item.text === "string") return item.text;
|
|
6640
|
+
if (item && item.content && typeof item.content === "string") return item.content;
|
|
6641
|
+
return JSON.stringify(item, null, 2);
|
|
6642
|
+
}).join("\n\n---\n\n");
|
|
6643
|
+
}
|
|
6644
|
+
if (content && typeof content === "object") {
|
|
6645
|
+
if (typeof content.text === "string") return content.text;
|
|
6646
|
+
return JSON.stringify(content, null, 2);
|
|
6647
|
+
}
|
|
6648
|
+
return String(content);
|
|
6649
|
+
};
|
|
6650
|
+
logger.logLLMPrompt("generateTextResponse", "system", extractText(prompts.system));
|
|
6651
|
+
logger.logLLMPrompt("generateTextResponse", "user", extractText(prompts.user));
|
|
6452
6652
|
logger.debug(`[${this.getProviderName()}] Loaded text-response prompts with schema`);
|
|
6453
6653
|
logger.debug(`[${this.getProviderName()}] System prompt length: ${prompts.system.length}, User prompt length: ${prompts.user.length}`);
|
|
6454
6654
|
logCollector?.info("Generating text response with query execution capability...");
|
|
@@ -6894,7 +7094,8 @@ ${errorMsg}
|
|
|
6894
7094
|
logger.info(`[${this.getProviderName()}] Text response stream completed`);
|
|
6895
7095
|
const textResponse = fullStreamedText || result || "I apologize, but I was unable to generate a response.";
|
|
6896
7096
|
if (maxAttemptsReached) {
|
|
6897
|
-
|
|
7097
|
+
const methodDuration2 = Date.now() - methodStartTime;
|
|
7098
|
+
logger.warn(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration2}ms | result: max attempts reached`);
|
|
6898
7099
|
logCollector?.error("Failed to generate valid query after maximum attempts");
|
|
6899
7100
|
return {
|
|
6900
7101
|
success: false,
|
|
@@ -6971,7 +7172,10 @@ ${errorMsg}
|
|
|
6971
7172
|
logCollector,
|
|
6972
7173
|
componentStreamCallback,
|
|
6973
7174
|
deferredTools,
|
|
6974
|
-
executedToolsList
|
|
7175
|
+
executedToolsList,
|
|
7176
|
+
collections,
|
|
7177
|
+
userId,
|
|
7178
|
+
userPrompt
|
|
6975
7179
|
);
|
|
6976
7180
|
matchedComponents = matchResult.components;
|
|
6977
7181
|
layoutTitle = matchResult.layoutTitle;
|
|
@@ -6997,6 +7201,8 @@ ${errorMsg}
|
|
|
6997
7201
|
}
|
|
6998
7202
|
};
|
|
6999
7203
|
}
|
|
7204
|
+
const methodDuration = Date.now() - methodStartTime;
|
|
7205
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | result: success | components: ${matchedComponents.length} | actions: ${actions.length}`);
|
|
7000
7206
|
return {
|
|
7001
7207
|
success: true,
|
|
7002
7208
|
data: {
|
|
@@ -7008,8 +7214,9 @@ ${errorMsg}
|
|
|
7008
7214
|
errors: []
|
|
7009
7215
|
};
|
|
7010
7216
|
} catch (error) {
|
|
7217
|
+
const methodDuration = Date.now() - methodStartTime;
|
|
7011
7218
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
7012
|
-
logger.error(`[${this.getProviderName()}]
|
|
7219
|
+
logger.error(`[${this.getProviderName()}] [TIMING] FAILED ${methodName} in ${methodDuration}ms | error: ${errorMsg}`);
|
|
7013
7220
|
logCollector?.error(`Error generating text response: ${errorMsg}`);
|
|
7014
7221
|
userPromptErrorLogger.logLlmError(
|
|
7015
7222
|
this.getProviderName(),
|
|
@@ -7051,7 +7258,6 @@ ${errorMsg}
|
|
|
7051
7258
|
logger.logLLMPrompt("handleUserRequest", "user", `User Prompt: ${userPrompt}`);
|
|
7052
7259
|
try {
|
|
7053
7260
|
logger.info(`[${this.getProviderName()}] Step 1: Searching previous conversations...`);
|
|
7054
|
-
logCollector?.info("Step 1: Searching for similar previous conversations...");
|
|
7055
7261
|
const conversationMatch = await conversation_search_default.searchConversationsWithReranking({
|
|
7056
7262
|
userPrompt,
|
|
7057
7263
|
collections,
|
|
@@ -7263,6 +7469,10 @@ ${errorMsg}
|
|
|
7263
7469
|
* For general/conversational questions without components, pass textResponse instead
|
|
7264
7470
|
*/
|
|
7265
7471
|
async generateNextQuestions(originalUserPrompt, component, componentData, apiKey, logCollector, conversationHistory, textResponse) {
|
|
7472
|
+
const methodStartTime = Date.now();
|
|
7473
|
+
const methodName = "generateNextQuestions";
|
|
7474
|
+
const promptPreview = originalUserPrompt.substring(0, 50) + (originalUserPrompt.length > 50 ? "..." : "");
|
|
7475
|
+
logger.info(`[${this.getProviderName()}] [TIMING] START ${methodName} | model: ${this.getModelForTask("simple")} | prompt: "${promptPreview}"`);
|
|
7266
7476
|
try {
|
|
7267
7477
|
let component_info;
|
|
7268
7478
|
if (component) {
|
|
@@ -7311,10 +7521,13 @@ ${errorMsg}
|
|
|
7311
7521
|
questions: nextQuestions
|
|
7312
7522
|
}
|
|
7313
7523
|
);
|
|
7524
|
+
const methodDuration = Date.now() - methodStartTime;
|
|
7525
|
+
logger.info(`[${this.getProviderName()}] [TIMING] DONE ${methodName} in ${methodDuration}ms | questions: ${nextQuestions.length}`);
|
|
7314
7526
|
return nextQuestions;
|
|
7315
7527
|
} catch (error) {
|
|
7528
|
+
const methodDuration = Date.now() - methodStartTime;
|
|
7316
7529
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
7317
|
-
logger.error(`[${this.getProviderName()}]
|
|
7530
|
+
logger.error(`[${this.getProviderName()}] [TIMING] FAILED ${methodName} in ${methodDuration}ms | error: ${errorMsg}`);
|
|
7318
7531
|
logger.debug(`[${this.getProviderName()}] Next questions generation error details:`, error);
|
|
7319
7532
|
logCollector?.error(`Error generating next questions: ${errorMsg}`);
|
|
7320
7533
|
return [];
|
|
@@ -10322,6 +10535,8 @@ async function handleArtifactsRequest(data, collections, sendMessage) {
|
|
|
10322
10535
|
const status = requestData?.status;
|
|
10323
10536
|
const deleted = requestData?.deleted;
|
|
10324
10537
|
const limit = requestData?.limit;
|
|
10538
|
+
const filters = requestData?.filters;
|
|
10539
|
+
const sort = requestData?.sort;
|
|
10325
10540
|
switch (operation) {
|
|
10326
10541
|
case "create":
|
|
10327
10542
|
await handleCreate6(id, name, createdBy, dsl, status, executeCollection, sendMessage, from.id);
|
|
@@ -10338,6 +10553,9 @@ async function handleArtifactsRequest(data, collections, sendMessage) {
|
|
|
10338
10553
|
case "getOne":
|
|
10339
10554
|
await handleGetOne6(id, artifactId, executeCollection, sendMessage, from.id);
|
|
10340
10555
|
break;
|
|
10556
|
+
case "query":
|
|
10557
|
+
await handleQuery6(id, { filters, limit, sort }, executeCollection, sendMessage, from.id);
|
|
10558
|
+
break;
|
|
10341
10559
|
default:
|
|
10342
10560
|
sendResponse8(id, {
|
|
10343
10561
|
success: false,
|
|
@@ -10461,6 +10679,27 @@ async function handleGetOne6(id, artifactId, executeCollection, sendMessage, cli
|
|
|
10461
10679
|
}, sendMessage, clientId);
|
|
10462
10680
|
}
|
|
10463
10681
|
}
|
|
10682
|
+
async function handleQuery6(id, queryParams, executeCollection, sendMessage, clientId) {
|
|
10683
|
+
try {
|
|
10684
|
+
const result = await executeCollection("artifacts", "query", {
|
|
10685
|
+
filters: queryParams.filters,
|
|
10686
|
+
limit: queryParams.limit || 50,
|
|
10687
|
+
sort: queryParams.sort || "DESC"
|
|
10688
|
+
});
|
|
10689
|
+
sendResponse8(id, {
|
|
10690
|
+
success: true,
|
|
10691
|
+
data: result.data,
|
|
10692
|
+
count: result.count,
|
|
10693
|
+
message: `Query returned ${result.count} artifacts`
|
|
10694
|
+
}, sendMessage, clientId);
|
|
10695
|
+
logger.info(`Query artifacts (count: ${result.count})`);
|
|
10696
|
+
} catch (error) {
|
|
10697
|
+
sendResponse8(id, {
|
|
10698
|
+
success: false,
|
|
10699
|
+
error: error instanceof Error ? error.message : "Failed to query artifacts"
|
|
10700
|
+
}, sendMessage, clientId);
|
|
10701
|
+
}
|
|
10702
|
+
}
|
|
10464
10703
|
function sendResponse8(id, res, sendMessage, clientId) {
|
|
10465
10704
|
const response = {
|
|
10466
10705
|
id: id || "unknown",
|
|
@@ -10987,7 +11226,7 @@ async function handleMenusRequest(data, collections, sendMessage) {
|
|
|
10987
11226
|
await handleGetHierarchy(id, executeCollection, sendMessage, from.id);
|
|
10988
11227
|
break;
|
|
10989
11228
|
case "query":
|
|
10990
|
-
await
|
|
11229
|
+
await handleQuery7(id, filters, limit, sort, executeCollection, sendMessage, from.id);
|
|
10991
11230
|
break;
|
|
10992
11231
|
case "reorder":
|
|
10993
11232
|
await handleReorder(id, items, executeCollection, sendMessage, from.id);
|
|
@@ -11199,7 +11438,7 @@ async function handleGetHierarchy(id, executeCollection, sendMessage, clientId)
|
|
|
11199
11438
|
}, sendMessage, clientId);
|
|
11200
11439
|
}
|
|
11201
11440
|
}
|
|
11202
|
-
async function
|
|
11441
|
+
async function handleQuery7(id, filters, limit, sort, executeCollection, sendMessage, clientId) {
|
|
11203
11442
|
try {
|
|
11204
11443
|
const result = await executeCollection("menus", "query", {
|
|
11205
11444
|
filters: filters || {},
|