@superatomai/sdk-node 0.0.58 → 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/README.md +942 -942
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +181 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +181 -13
- 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";
|
|
@@ -5905,7 +6005,7 @@ var BaseLLM = class {
|
|
|
5905
6005
|
* @param componentStreamCallback - Optional callback to stream primary KPI component as soon as it's identified
|
|
5906
6006
|
* @returns Object containing matched components, layout title/description, and follow-up actions
|
|
5907
6007
|
*/
|
|
5908
|
-
async matchComponentsFromAnalysis(analysisContent, components, apiKey, logCollector, componentStreamCallback, deferredTools, executedTools) {
|
|
6008
|
+
async matchComponentsFromAnalysis(analysisContent, components, apiKey, logCollector, componentStreamCallback, deferredTools, executedTools, collections, userId, userPrompt) {
|
|
5909
6009
|
const methodStartTime = Date.now();
|
|
5910
6010
|
const methodName = "matchComponentsFromAnalysis";
|
|
5911
6011
|
logger.info(`[${this.getProviderName()}] [TIMING] START ${methodName} | model: ${this.getModelForTask("complex")}`);
|
|
@@ -5968,6 +6068,16 @@ ${fieldsText}`;
|
|
|
5968
6068
|
}
|
|
5969
6069
|
const schemaDoc = schema.generateSchemaDocumentation();
|
|
5970
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
|
+
}
|
|
5971
6081
|
const prompts = await promptLoader.loadPrompts("match-text-components", {
|
|
5972
6082
|
ANALYSIS_CONTENT: analysisContent,
|
|
5973
6083
|
AVAILABLE_COMPONENTS: availableComponentsText,
|
|
@@ -5975,11 +6085,27 @@ ${fieldsText}`;
|
|
|
5975
6085
|
DATABASE_RULES: databaseRules,
|
|
5976
6086
|
DEFERRED_TOOLS: deferredToolsText,
|
|
5977
6087
|
EXECUTED_TOOLS: executedToolsText,
|
|
6088
|
+
KNOWLEDGE_BASE_CONTEXT: knowledgeBaseContext,
|
|
5978
6089
|
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
5979
6090
|
});
|
|
5980
6091
|
logger.debug(`[${this.getProviderName()}] Loaded match-text-components prompts`);
|
|
5981
|
-
const
|
|
5982
|
-
|
|
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));
|
|
5983
6109
|
logger.logLLMPrompt("matchComponentsFromAnalysis", "user", `Text Analysis:
|
|
5984
6110
|
${analysisContent}
|
|
5985
6111
|
|
|
@@ -6204,6 +6330,18 @@ ${executedToolsText}`);
|
|
|
6204
6330
|
cleanedProps.query = null;
|
|
6205
6331
|
}
|
|
6206
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
|
+
}
|
|
6207
6345
|
if (cleanedProps.query && cleanedProps.externalTool) {
|
|
6208
6346
|
logger.info(`[${this.getProviderName()}] Both query and externalTool exist, keeping both - frontend will decide`);
|
|
6209
6347
|
}
|
|
@@ -6260,10 +6398,24 @@ ${executedToolsText}`);
|
|
|
6260
6398
|
SCHEMA_DOC: schemaDoc || "No database schema available",
|
|
6261
6399
|
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
6262
6400
|
});
|
|
6263
|
-
const
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
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));
|
|
6267
6419
|
const result = await LLM.stream(
|
|
6268
6420
|
{
|
|
6269
6421
|
sys: prompts.system,
|
|
@@ -6479,10 +6631,24 @@ ${executedToolsText}`);
|
|
|
6479
6631
|
AVAILABLE_EXTERNAL_TOOLS: availableToolsDoc,
|
|
6480
6632
|
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
6481
6633
|
});
|
|
6482
|
-
const
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
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));
|
|
6486
6652
|
logger.debug(`[${this.getProviderName()}] Loaded text-response prompts with schema`);
|
|
6487
6653
|
logger.debug(`[${this.getProviderName()}] System prompt length: ${prompts.system.length}, User prompt length: ${prompts.user.length}`);
|
|
6488
6654
|
logCollector?.info("Generating text response with query execution capability...");
|
|
@@ -7006,7 +7172,10 @@ ${errorMsg}
|
|
|
7006
7172
|
logCollector,
|
|
7007
7173
|
componentStreamCallback,
|
|
7008
7174
|
deferredTools,
|
|
7009
|
-
executedToolsList
|
|
7175
|
+
executedToolsList,
|
|
7176
|
+
collections,
|
|
7177
|
+
userId,
|
|
7178
|
+
userPrompt
|
|
7010
7179
|
);
|
|
7011
7180
|
matchedComponents = matchResult.components;
|
|
7012
7181
|
layoutTitle = matchResult.layoutTitle;
|
|
@@ -7089,7 +7258,6 @@ ${errorMsg}
|
|
|
7089
7258
|
logger.logLLMPrompt("handleUserRequest", "user", `User Prompt: ${userPrompt}`);
|
|
7090
7259
|
try {
|
|
7091
7260
|
logger.info(`[${this.getProviderName()}] Step 1: Searching previous conversations...`);
|
|
7092
|
-
logCollector?.info("Step 1: Searching for similar previous conversations...");
|
|
7093
7261
|
const conversationMatch = await conversation_search_default.searchConversationsWithReranking({
|
|
7094
7262
|
userPrompt,
|
|
7095
7263
|
collections,
|