@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.d.mts
CHANGED
|
@@ -2097,7 +2097,7 @@ declare abstract class BaseLLM {
|
|
|
2097
2097
|
* @param componentStreamCallback - Optional callback to stream primary KPI component as soon as it's identified
|
|
2098
2098
|
* @returns Object containing matched components, layout title/description, and follow-up actions
|
|
2099
2099
|
*/
|
|
2100
|
-
matchComponentsFromAnalysis(analysisContent: string, components: Component[], apiKey?: string, logCollector?: any, componentStreamCallback?: (component: Component) => void, deferredTools?: any[], executedTools?: any[]): Promise<{
|
|
2100
|
+
matchComponentsFromAnalysis(analysisContent: string, components: Component[], apiKey?: string, logCollector?: any, componentStreamCallback?: (component: Component) => void, deferredTools?: any[], executedTools?: any[], collections?: any, userId?: string, userPrompt?: string): Promise<{
|
|
2101
2101
|
components: Component[];
|
|
2102
2102
|
layoutTitle: string;
|
|
2103
2103
|
layoutDescription: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -2097,7 +2097,7 @@ declare abstract class BaseLLM {
|
|
|
2097
2097
|
* @param componentStreamCallback - Optional callback to stream primary KPI component as soon as it's identified
|
|
2098
2098
|
* @returns Object containing matched components, layout title/description, and follow-up actions
|
|
2099
2099
|
*/
|
|
2100
|
-
matchComponentsFromAnalysis(analysisContent: string, components: Component[], apiKey?: string, logCollector?: any, componentStreamCallback?: (component: Component) => void, deferredTools?: any[], executedTools?: any[]): Promise<{
|
|
2100
|
+
matchComponentsFromAnalysis(analysisContent: string, components: Component[], apiKey?: string, logCollector?: any, componentStreamCallback?: (component: Component) => void, deferredTools?: any[], executedTools?: any[], collections?: any, userId?: string, userPrompt?: string): Promise<{
|
|
2101
2101
|
components: Component[];
|
|
2102
2102
|
layoutTitle: string;
|
|
2103
2103
|
layoutDescription: string;
|
package/dist/index.js
CHANGED
|
@@ -1642,6 +1642,7 @@ __export(utils_exports, {
|
|
|
1642
1642
|
fixScalarSubqueries: () => fixScalarSubqueries,
|
|
1643
1643
|
getDatabaseType: () => getDatabaseType,
|
|
1644
1644
|
getJsonSizeInBytes: () => getJsonSizeInBytes,
|
|
1645
|
+
validateAndFixSqlQuery: () => validateAndFixSqlQuery,
|
|
1645
1646
|
validateMessageSize: () => validateMessageSize
|
|
1646
1647
|
});
|
|
1647
1648
|
function getDatabaseType() {
|
|
@@ -1817,6 +1818,105 @@ function validateMessageSize(message, maxSize = 1048576) {
|
|
|
1817
1818
|
maxSize
|
|
1818
1819
|
};
|
|
1819
1820
|
}
|
|
1821
|
+
function validateAndFixSqlQuery(query, dbType) {
|
|
1822
|
+
if (!query || query.trim().length === 0) {
|
|
1823
|
+
return { query, fixed: false, fixes: [] };
|
|
1824
|
+
}
|
|
1825
|
+
const databaseType = dbType || getDatabaseType();
|
|
1826
|
+
const _isMssql = databaseType === "mssql";
|
|
1827
|
+
let fixedQuery = query;
|
|
1828
|
+
const fixes = [];
|
|
1829
|
+
const aggregateFunctions = ["SUM", "COUNT", "AVG", "MIN", "MAX"];
|
|
1830
|
+
const aggregateInWherePattern = new RegExp(
|
|
1831
|
+
`\\bWHERE\\b[^]*?\\b(${aggregateFunctions.join("|")})\\s*\\([^)]*\\)\\s*(?:=|>|<|>=|<=|<>|!=)`,
|
|
1832
|
+
"i"
|
|
1833
|
+
);
|
|
1834
|
+
if (aggregateInWherePattern.test(fixedQuery)) {
|
|
1835
|
+
const aggregateConditionPattern = new RegExp(
|
|
1836
|
+
`\\s+(AND|OR)\\s+((?:COALESCE\\s*\\(\\s*)?(?:${aggregateFunctions.join("|")})\\s*\\([^)]+\\)[^)]*(?:\\))?\\s*(?:=|>|<|>=|<=|<>|!=)\\s*[^\\s,)]+)`,
|
|
1837
|
+
"gi"
|
|
1838
|
+
);
|
|
1839
|
+
const aggregateConditions = [];
|
|
1840
|
+
let match;
|
|
1841
|
+
while ((match = aggregateConditionPattern.exec(fixedQuery)) !== null) {
|
|
1842
|
+
aggregateConditions.push(match[2].trim());
|
|
1843
|
+
}
|
|
1844
|
+
if (aggregateConditions.length > 0) {
|
|
1845
|
+
fixedQuery = fixedQuery.replace(aggregateConditionPattern, "");
|
|
1846
|
+
fixedQuery = fixedQuery.replace(/\bWHERE\s+(AND|OR)\s+/gi, "WHERE ");
|
|
1847
|
+
fixedQuery = fixedQuery.replace(/\bWHERE\s+(GROUP\s+BY|ORDER\s+BY|HAVING|$)/gi, "$1");
|
|
1848
|
+
const hasGroupBy = /\bGROUP\s+BY\b/i.test(fixedQuery);
|
|
1849
|
+
if (hasGroupBy) {
|
|
1850
|
+
const hasHaving = /\bHAVING\b/i.test(fixedQuery);
|
|
1851
|
+
const havingClause = aggregateConditions.join(" AND ");
|
|
1852
|
+
if (hasHaving) {
|
|
1853
|
+
fixedQuery = fixedQuery.replace(
|
|
1854
|
+
/\bHAVING\b/i,
|
|
1855
|
+
`HAVING ${havingClause} AND`
|
|
1856
|
+
);
|
|
1857
|
+
} else {
|
|
1858
|
+
const orderByMatch = fixedQuery.match(/(\s+ORDER\s+BY\s+)/i);
|
|
1859
|
+
if (orderByMatch) {
|
|
1860
|
+
fixedQuery = fixedQuery.replace(
|
|
1861
|
+
orderByMatch[1],
|
|
1862
|
+
` HAVING ${havingClause}${orderByMatch[1]}`
|
|
1863
|
+
);
|
|
1864
|
+
} else {
|
|
1865
|
+
fixedQuery = fixedQuery.trimEnd() + ` HAVING ${havingClause}`;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
fixes.push(`Moved aggregate condition(s) from WHERE to HAVING: ${havingClause}`);
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
let openCount = 0;
|
|
1873
|
+
let closeCount = 0;
|
|
1874
|
+
let inString = false;
|
|
1875
|
+
let stringChar = "";
|
|
1876
|
+
for (let i = 0; i < fixedQuery.length; i++) {
|
|
1877
|
+
const char = fixedQuery[i];
|
|
1878
|
+
const prevChar = i > 0 ? fixedQuery[i - 1] : "";
|
|
1879
|
+
if ((char === "'" || char === '"') && prevChar !== "\\") {
|
|
1880
|
+
if (!inString) {
|
|
1881
|
+
inString = true;
|
|
1882
|
+
stringChar = char;
|
|
1883
|
+
} else if (char === stringChar) {
|
|
1884
|
+
if (i + 1 < fixedQuery.length && fixedQuery[i + 1] === char) {
|
|
1885
|
+
i++;
|
|
1886
|
+
} else {
|
|
1887
|
+
inString = false;
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1890
|
+
continue;
|
|
1891
|
+
}
|
|
1892
|
+
if (!inString) {
|
|
1893
|
+
if (char === "(") openCount++;
|
|
1894
|
+
else if (char === ")") closeCount++;
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
if (openCount > closeCount) {
|
|
1898
|
+
const missingClose = openCount - closeCount;
|
|
1899
|
+
fixedQuery = fixedQuery.trimEnd();
|
|
1900
|
+
const hasSemicolon = fixedQuery.endsWith(";");
|
|
1901
|
+
if (hasSemicolon) {
|
|
1902
|
+
fixedQuery = fixedQuery.slice(0, -1);
|
|
1903
|
+
}
|
|
1904
|
+
fixedQuery = fixedQuery + ")".repeat(missingClose);
|
|
1905
|
+
if (hasSemicolon) {
|
|
1906
|
+
fixedQuery = fixedQuery + ";";
|
|
1907
|
+
}
|
|
1908
|
+
fixes.push(`Added ${missingClose} missing closing parenthesis(es)`);
|
|
1909
|
+
}
|
|
1910
|
+
const originalLength = fixedQuery.length;
|
|
1911
|
+
fixedQuery = fixedQuery.replace(/\s+/g, " ").trim();
|
|
1912
|
+
if (fixedQuery.length !== originalLength) {
|
|
1913
|
+
}
|
|
1914
|
+
return {
|
|
1915
|
+
query: fixedQuery,
|
|
1916
|
+
fixed: fixes.length > 0,
|
|
1917
|
+
fixes
|
|
1918
|
+
};
|
|
1919
|
+
}
|
|
1820
1920
|
var init_utils = __esm({
|
|
1821
1921
|
"src/userResponse/utils.ts"() {
|
|
1822
1922
|
"use strict";
|
|
@@ -5955,7 +6055,7 @@ var BaseLLM = class {
|
|
|
5955
6055
|
* @param componentStreamCallback - Optional callback to stream primary KPI component as soon as it's identified
|
|
5956
6056
|
* @returns Object containing matched components, layout title/description, and follow-up actions
|
|
5957
6057
|
*/
|
|
5958
|
-
async matchComponentsFromAnalysis(analysisContent, components, apiKey, logCollector, componentStreamCallback, deferredTools, executedTools) {
|
|
6058
|
+
async matchComponentsFromAnalysis(analysisContent, components, apiKey, logCollector, componentStreamCallback, deferredTools, executedTools, collections, userId, userPrompt) {
|
|
5959
6059
|
const methodStartTime = Date.now();
|
|
5960
6060
|
const methodName = "matchComponentsFromAnalysis";
|
|
5961
6061
|
logger.info(`[${this.getProviderName()}] [TIMING] START ${methodName} | model: ${this.getModelForTask("complex")}`);
|
|
@@ -6018,6 +6118,16 @@ ${fieldsText}`;
|
|
|
6018
6118
|
}
|
|
6019
6119
|
const schemaDoc = schema.generateSchemaDocumentation();
|
|
6020
6120
|
const databaseRules = await promptLoader.loadDatabaseRules();
|
|
6121
|
+
let knowledgeBaseContext = "No additional knowledge base context available.";
|
|
6122
|
+
if (collections) {
|
|
6123
|
+
const kbResult = await knowledge_base_default.getAllKnowledgeBase({
|
|
6124
|
+
prompt: userPrompt || analysisContent,
|
|
6125
|
+
collections,
|
|
6126
|
+
userId,
|
|
6127
|
+
topK: 3
|
|
6128
|
+
});
|
|
6129
|
+
knowledgeBaseContext = kbResult.combinedContext || knowledgeBaseContext;
|
|
6130
|
+
}
|
|
6021
6131
|
const prompts = await promptLoader.loadPrompts("match-text-components", {
|
|
6022
6132
|
ANALYSIS_CONTENT: analysisContent,
|
|
6023
6133
|
AVAILABLE_COMPONENTS: availableComponentsText,
|
|
@@ -6025,11 +6135,27 @@ ${fieldsText}`;
|
|
|
6025
6135
|
DATABASE_RULES: databaseRules,
|
|
6026
6136
|
DEFERRED_TOOLS: deferredToolsText,
|
|
6027
6137
|
EXECUTED_TOOLS: executedToolsText,
|
|
6138
|
+
KNOWLEDGE_BASE_CONTEXT: knowledgeBaseContext,
|
|
6028
6139
|
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
6029
6140
|
});
|
|
6030
6141
|
logger.debug(`[${this.getProviderName()}] Loaded match-text-components prompts`);
|
|
6031
|
-
const
|
|
6032
|
-
|
|
6142
|
+
const extractPromptText = (content) => {
|
|
6143
|
+
if (typeof content === "string") return content;
|
|
6144
|
+
if (Array.isArray(content)) {
|
|
6145
|
+
return content.map((item) => {
|
|
6146
|
+
if (typeof item === "string") return item;
|
|
6147
|
+
if (item && typeof item.text === "string") return item.text;
|
|
6148
|
+
if (item && item.content && typeof item.content === "string") return item.content;
|
|
6149
|
+
return JSON.stringify(item, null, 2);
|
|
6150
|
+
}).join("\n\n---\n\n");
|
|
6151
|
+
}
|
|
6152
|
+
if (content && typeof content === "object") {
|
|
6153
|
+
if (typeof content.text === "string") return content.text;
|
|
6154
|
+
return JSON.stringify(content, null, 2);
|
|
6155
|
+
}
|
|
6156
|
+
return String(content);
|
|
6157
|
+
};
|
|
6158
|
+
logger.logLLMPrompt("matchComponentsFromAnalysis", "system", extractPromptText(prompts.system));
|
|
6033
6159
|
logger.logLLMPrompt("matchComponentsFromAnalysis", "user", `Text Analysis:
|
|
6034
6160
|
${analysisContent}
|
|
6035
6161
|
|
|
@@ -6254,6 +6380,18 @@ ${executedToolsText}`);
|
|
|
6254
6380
|
cleanedProps.query = null;
|
|
6255
6381
|
}
|
|
6256
6382
|
}
|
|
6383
|
+
if (cleanedProps.query) {
|
|
6384
|
+
const queryStr = typeof cleanedProps.query === "string" ? cleanedProps.query : cleanedProps.query?.sql || "";
|
|
6385
|
+
const { query: fixedQuery, fixed, fixes } = validateAndFixSqlQuery(queryStr);
|
|
6386
|
+
if (fixed) {
|
|
6387
|
+
logger.warn(`[${this.getProviderName()}] SQL fixes applied to component query: ${fixes.join("; ")}`);
|
|
6388
|
+
if (typeof cleanedProps.query === "string") {
|
|
6389
|
+
cleanedProps.query = fixedQuery;
|
|
6390
|
+
} else if (cleanedProps.query?.sql) {
|
|
6391
|
+
cleanedProps.query.sql = fixedQuery;
|
|
6392
|
+
}
|
|
6393
|
+
}
|
|
6394
|
+
}
|
|
6257
6395
|
if (cleanedProps.query && cleanedProps.externalTool) {
|
|
6258
6396
|
logger.info(`[${this.getProviderName()}] Both query and externalTool exist, keeping both - frontend will decide`);
|
|
6259
6397
|
}
|
|
@@ -6310,10 +6448,24 @@ ${executedToolsText}`);
|
|
|
6310
6448
|
SCHEMA_DOC: schemaDoc || "No database schema available",
|
|
6311
6449
|
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
6312
6450
|
});
|
|
6313
|
-
const
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6451
|
+
const extractTextContent = (content) => {
|
|
6452
|
+
if (typeof content === "string") return content;
|
|
6453
|
+
if (Array.isArray(content)) {
|
|
6454
|
+
return content.map((item) => {
|
|
6455
|
+
if (typeof item === "string") return item;
|
|
6456
|
+
if (item && typeof item.text === "string") return item.text;
|
|
6457
|
+
if (item && item.content && typeof item.content === "string") return item.content;
|
|
6458
|
+
return JSON.stringify(item, null, 2);
|
|
6459
|
+
}).join("\n\n---\n\n");
|
|
6460
|
+
}
|
|
6461
|
+
if (content && typeof content === "object") {
|
|
6462
|
+
if (typeof content.text === "string") return content.text;
|
|
6463
|
+
return JSON.stringify(content, null, 2);
|
|
6464
|
+
}
|
|
6465
|
+
return String(content);
|
|
6466
|
+
};
|
|
6467
|
+
logger.logLLMPrompt("classifyQuestionCategory", "system", extractTextContent(prompts.system));
|
|
6468
|
+
logger.logLLMPrompt("classifyQuestionCategory", "user", extractTextContent(prompts.user));
|
|
6317
6469
|
const result = await LLM.stream(
|
|
6318
6470
|
{
|
|
6319
6471
|
sys: prompts.system,
|
|
@@ -6529,10 +6681,24 @@ ${executedToolsText}`);
|
|
|
6529
6681
|
AVAILABLE_EXTERNAL_TOOLS: availableToolsDoc,
|
|
6530
6682
|
CURRENT_DATETIME: getCurrentDateTimeForPrompt()
|
|
6531
6683
|
});
|
|
6532
|
-
const
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6684
|
+
const extractText = (content) => {
|
|
6685
|
+
if (typeof content === "string") return content;
|
|
6686
|
+
if (Array.isArray(content)) {
|
|
6687
|
+
return content.map((item) => {
|
|
6688
|
+
if (typeof item === "string") return item;
|
|
6689
|
+
if (item && typeof item.text === "string") return item.text;
|
|
6690
|
+
if (item && item.content && typeof item.content === "string") return item.content;
|
|
6691
|
+
return JSON.stringify(item, null, 2);
|
|
6692
|
+
}).join("\n\n---\n\n");
|
|
6693
|
+
}
|
|
6694
|
+
if (content && typeof content === "object") {
|
|
6695
|
+
if (typeof content.text === "string") return content.text;
|
|
6696
|
+
return JSON.stringify(content, null, 2);
|
|
6697
|
+
}
|
|
6698
|
+
return String(content);
|
|
6699
|
+
};
|
|
6700
|
+
logger.logLLMPrompt("generateTextResponse", "system", extractText(prompts.system));
|
|
6701
|
+
logger.logLLMPrompt("generateTextResponse", "user", extractText(prompts.user));
|
|
6536
6702
|
logger.debug(`[${this.getProviderName()}] Loaded text-response prompts with schema`);
|
|
6537
6703
|
logger.debug(`[${this.getProviderName()}] System prompt length: ${prompts.system.length}, User prompt length: ${prompts.user.length}`);
|
|
6538
6704
|
logCollector?.info("Generating text response with query execution capability...");
|
|
@@ -7056,7 +7222,10 @@ ${errorMsg}
|
|
|
7056
7222
|
logCollector,
|
|
7057
7223
|
componentStreamCallback,
|
|
7058
7224
|
deferredTools,
|
|
7059
|
-
executedToolsList
|
|
7225
|
+
executedToolsList,
|
|
7226
|
+
collections,
|
|
7227
|
+
userId,
|
|
7228
|
+
userPrompt
|
|
7060
7229
|
);
|
|
7061
7230
|
matchedComponents = matchResult.components;
|
|
7062
7231
|
layoutTitle = matchResult.layoutTitle;
|
|
@@ -7139,7 +7308,6 @@ ${errorMsg}
|
|
|
7139
7308
|
logger.logLLMPrompt("handleUserRequest", "user", `User Prompt: ${userPrompt}`);
|
|
7140
7309
|
try {
|
|
7141
7310
|
logger.info(`[${this.getProviderName()}] Step 1: Searching previous conversations...`);
|
|
7142
|
-
logCollector?.info("Step 1: Searching for similar previous conversations...");
|
|
7143
7311
|
const conversationMatch = await conversation_search_default.searchConversationsWithReranking({
|
|
7144
7312
|
userPrompt,
|
|
7145
7313
|
collections,
|