@superatomai/sdk-node 0.0.14 → 0.0.16
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.js +230 -82
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +230 -82
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -565,10 +565,14 @@ var ReportsRequestMessageSchema = import_zod3.z.object({
|
|
|
565
565
|
var UIBlockSchema = import_zod3.z.object({
|
|
566
566
|
id: import_zod3.z.string().optional(),
|
|
567
567
|
userQuestion: import_zod3.z.string().optional(),
|
|
568
|
+
user_prompt: import_zod3.z.string().optional(),
|
|
569
|
+
// DB field name
|
|
568
570
|
text: import_zod3.z.string().optional(),
|
|
569
571
|
textResponse: import_zod3.z.string().optional(),
|
|
572
|
+
analysis: import_zod3.z.string().optional(),
|
|
573
|
+
// DB field name for textResponse
|
|
570
574
|
component: ComponentSchema.optional(),
|
|
571
|
-
// Legacy field
|
|
575
|
+
// DB field name / Legacy field
|
|
572
576
|
generatedComponentMetadata: ComponentSchema.optional(),
|
|
573
577
|
// Actual field used by UIBlock class
|
|
574
578
|
componentData: import_zod3.z.record(import_zod3.z.any()).optional(),
|
|
@@ -589,9 +593,11 @@ var BookmarkDataSchema = import_zod3.z.object({
|
|
|
589
593
|
updated_at: import_zod3.z.string().optional()
|
|
590
594
|
});
|
|
591
595
|
var BookmarksRequestPayloadSchema = import_zod3.z.object({
|
|
592
|
-
operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne"]),
|
|
596
|
+
operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne", "getByUser", "getByThread"]),
|
|
593
597
|
data: import_zod3.z.object({
|
|
594
598
|
id: import_zod3.z.number().optional(),
|
|
599
|
+
userId: import_zod3.z.number().optional(),
|
|
600
|
+
threadId: import_zod3.z.string().optional(),
|
|
595
601
|
uiblock: import_zod3.z.any().optional()
|
|
596
602
|
}).optional()
|
|
597
603
|
});
|
|
@@ -1419,7 +1425,7 @@ async function cleanupUserStorage() {
|
|
|
1419
1425
|
}
|
|
1420
1426
|
|
|
1421
1427
|
// src/auth/validator.ts
|
|
1422
|
-
function validateUser(credentials) {
|
|
1428
|
+
async function validateUser(credentials, collections) {
|
|
1423
1429
|
const { username, email, password } = credentials;
|
|
1424
1430
|
const identifier = username || email;
|
|
1425
1431
|
logger.debug("[validateUser] Starting user validation");
|
|
@@ -1431,7 +1437,39 @@ function validateUser(credentials) {
|
|
|
1431
1437
|
error: "Username or email and password are required"
|
|
1432
1438
|
};
|
|
1433
1439
|
}
|
|
1434
|
-
|
|
1440
|
+
if (collections && collections["users"] && collections["users"]["authenticate"]) {
|
|
1441
|
+
logger.debug(`[validateUser] Attempting database authentication for: ${identifier}`);
|
|
1442
|
+
try {
|
|
1443
|
+
const dbResult = await collections["users"]["authenticate"]({
|
|
1444
|
+
identifier,
|
|
1445
|
+
password
|
|
1446
|
+
});
|
|
1447
|
+
logger.info("[validateUser] Database authentication attempt completed", dbResult);
|
|
1448
|
+
if (dbResult && dbResult.success && dbResult.data) {
|
|
1449
|
+
logger.info(`[validateUser] \u2713 User authenticated via database: ${dbResult.data.username}`);
|
|
1450
|
+
return {
|
|
1451
|
+
success: true,
|
|
1452
|
+
data: dbResult.data.username,
|
|
1453
|
+
username: dbResult.data.username,
|
|
1454
|
+
userId: dbResult.data.id
|
|
1455
|
+
};
|
|
1456
|
+
} else {
|
|
1457
|
+
logger.debug(`[validateUser] Database auth failed for ${identifier}: ${dbResult?.error || "Invalid credentials"}`);
|
|
1458
|
+
if (dbResult && dbResult.error === "Invalid credentials") {
|
|
1459
|
+
return {
|
|
1460
|
+
success: false,
|
|
1461
|
+
error: "Invalid credentials"
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
} catch (error) {
|
|
1466
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
1467
|
+
logger.debug(`[validateUser] Database lookup error: ${errorMsg}, falling back to file storage`);
|
|
1468
|
+
}
|
|
1469
|
+
} else {
|
|
1470
|
+
logger.debug("[validateUser] No users collection available, using file storage only");
|
|
1471
|
+
}
|
|
1472
|
+
logger.info(`[validateUser] Attempting file-based validation for: ${identifier}`);
|
|
1435
1473
|
const user = findUserByUsernameOrEmail(identifier);
|
|
1436
1474
|
if (!user) {
|
|
1437
1475
|
logger.warn(`[validateUser] Validation failed: User not found - ${identifier}`);
|
|
@@ -1440,7 +1478,7 @@ function validateUser(credentials) {
|
|
|
1440
1478
|
error: "Invalid username or email"
|
|
1441
1479
|
};
|
|
1442
1480
|
}
|
|
1443
|
-
logger.debug(`[validateUser] User found: ${user.username}, verifying password`);
|
|
1481
|
+
logger.debug(`[validateUser] User found in file storage: ${user.username}, verifying password`);
|
|
1444
1482
|
const hashedPassword = hashPassword(user.password);
|
|
1445
1483
|
if (hashedPassword !== password) {
|
|
1446
1484
|
logger.warn(`[validateUser] Validation failed: Invalid password for user - ${user.username}`);
|
|
@@ -1450,19 +1488,18 @@ function validateUser(credentials) {
|
|
|
1450
1488
|
error: "Invalid password"
|
|
1451
1489
|
};
|
|
1452
1490
|
}
|
|
1453
|
-
logger.info(`[validateUser] \u2713 User validated
|
|
1454
|
-
logger.debug(`[validateUser] Returning user data for: ${user.username}`);
|
|
1491
|
+
logger.info(`[validateUser] \u2713 User validated via file storage: ${user.username}`);
|
|
1455
1492
|
return {
|
|
1456
1493
|
success: true,
|
|
1457
1494
|
data: user.username,
|
|
1458
1495
|
username: user.username
|
|
1459
1496
|
};
|
|
1460
1497
|
}
|
|
1461
|
-
function authenticateAndStoreWsId(credentials, wsId) {
|
|
1498
|
+
async function authenticateAndStoreWsId(credentials, wsId, collections) {
|
|
1462
1499
|
const identifier = credentials.username || credentials.email;
|
|
1463
1500
|
logger.debug("[authenticateAndStoreWsId] Starting authentication and WebSocket ID storage");
|
|
1464
1501
|
logger.debug("[authenticateAndStoreWsId] Validating user credentials");
|
|
1465
|
-
const validationResult = validateUser(credentials);
|
|
1502
|
+
const validationResult = await validateUser(credentials, collections);
|
|
1466
1503
|
if (!validationResult.success) {
|
|
1467
1504
|
logger.warn(`[authenticateAndStoreWsId] User validation failed for: ${identifier}`);
|
|
1468
1505
|
return validationResult;
|
|
@@ -1474,7 +1511,7 @@ function authenticateAndStoreWsId(credentials, wsId) {
|
|
|
1474
1511
|
logger.debug(`[authenticateAndStoreWsId] WebSocket ID ${wsId} associated with user ${username}`);
|
|
1475
1512
|
return validationResult;
|
|
1476
1513
|
}
|
|
1477
|
-
function verifyAuthToken(authToken) {
|
|
1514
|
+
async function verifyAuthToken(authToken, collections) {
|
|
1478
1515
|
try {
|
|
1479
1516
|
logger.debug("[verifyAuthToken] Starting token verification");
|
|
1480
1517
|
logger.debug("[verifyAuthToken] Decoding base64 token");
|
|
@@ -1484,7 +1521,7 @@ function verifyAuthToken(authToken) {
|
|
|
1484
1521
|
logger.debug("[verifyAuthToken] Token decoded and parsed successfully");
|
|
1485
1522
|
logger.debug(`[verifyAuthToken] Token contains username: ${credentials.username ? "\u2713" : "\u2717"}`);
|
|
1486
1523
|
logger.debug("[verifyAuthToken] Validating credentials from token");
|
|
1487
|
-
const result = validateUser(credentials);
|
|
1524
|
+
const result = await validateUser(credentials, collections);
|
|
1488
1525
|
if (result.success) {
|
|
1489
1526
|
logger.info(`[verifyAuthToken] \u2713 Token verified successfully for user: ${credentials.username || "unknown"}`);
|
|
1490
1527
|
} else {
|
|
@@ -1503,7 +1540,7 @@ function verifyAuthToken(authToken) {
|
|
|
1503
1540
|
}
|
|
1504
1541
|
|
|
1505
1542
|
// src/handlers/auth-login-requests.ts
|
|
1506
|
-
async function handleAuthLoginRequest(data, sendMessage) {
|
|
1543
|
+
async function handleAuthLoginRequest(data, collections, sendMessage) {
|
|
1507
1544
|
try {
|
|
1508
1545
|
logger.debug("[AUTH_LOGIN_REQ] Parsing incoming auth login request");
|
|
1509
1546
|
const authRequest = AuthLoginRequestMessageSchema.parse(data);
|
|
@@ -1562,12 +1599,12 @@ async function handleAuthLoginRequest(data, sendMessage) {
|
|
|
1562
1599
|
}, sendMessage, wsId);
|
|
1563
1600
|
return;
|
|
1564
1601
|
}
|
|
1565
|
-
logger.info(`[AUTH_LOGIN_REQ ${id}] Credentials validated, authenticating user: ${identifier}`);
|
|
1566
|
-
logger.debug(`[AUTH_LOGIN_REQ ${id}] WebSocket ID: ${wsId}`);
|
|
1602
|
+
logger.info(`[AUTH_LOGIN_REQ ${id}] Credentials validated, authenticating user: ${identifier} username: ${username} email: ${email} password: ${password}`);
|
|
1567
1603
|
logger.debug(`[AUTH_LOGIN_REQ ${id}] Calling authenticateAndStoreWsId for user: ${identifier}`);
|
|
1568
|
-
const authResult = authenticateAndStoreWsId(
|
|
1604
|
+
const authResult = await authenticateAndStoreWsId(
|
|
1569
1605
|
{ username, email, password },
|
|
1570
|
-
wsId
|
|
1606
|
+
wsId,
|
|
1607
|
+
collections
|
|
1571
1608
|
);
|
|
1572
1609
|
logger.info(`[AUTH_LOGIN_REQ ${id}] Authentication result for ${identifier}: ${authResult.success ? "success" : "failed"}`);
|
|
1573
1610
|
if (!authResult.success) {
|
|
@@ -1619,7 +1656,7 @@ function sendDataResponse2(id, res, sendMessage, clientId) {
|
|
|
1619
1656
|
}
|
|
1620
1657
|
|
|
1621
1658
|
// src/handlers/auth-verify-request.ts
|
|
1622
|
-
async function handleAuthVerifyRequest(data, sendMessage) {
|
|
1659
|
+
async function handleAuthVerifyRequest(data, collections, sendMessage) {
|
|
1623
1660
|
try {
|
|
1624
1661
|
logger.debug("[AUTH_VERIFY_REQ] Parsing incoming auth verify request");
|
|
1625
1662
|
const authRequest = AuthVerifyRequestMessageSchema.parse(data);
|
|
@@ -1649,7 +1686,7 @@ async function handleAuthVerifyRequest(data, sendMessage) {
|
|
|
1649
1686
|
logger.debug(`[AUTH_VERIFY_REQ ${id}] WebSocket ID: ${wsId}`);
|
|
1650
1687
|
logger.debug(`[AUTH_VERIFY_REQ ${id}] Calling verifyAuthToken`);
|
|
1651
1688
|
const startTime = Date.now();
|
|
1652
|
-
const authResult = verifyAuthToken(token);
|
|
1689
|
+
const authResult = await verifyAuthToken(token, collections);
|
|
1653
1690
|
const verificationTime = Date.now() - startTime;
|
|
1654
1691
|
logger.info(`[AUTH_VERIFY_REQ ${id}] Token verification completed in ${verificationTime}ms - ${authResult.success ? "valid" : "invalid"}`);
|
|
1655
1692
|
if (!authResult.success) {
|
|
@@ -3699,13 +3736,13 @@ var BaseLLM = class {
|
|
|
3699
3736
|
*/
|
|
3700
3737
|
async adaptUIBlockParameters(currentUserPrompt, originalUserPrompt, matchedUIBlock, apiKey, logCollector) {
|
|
3701
3738
|
try {
|
|
3702
|
-
|
|
3739
|
+
const component = matchedUIBlock?.generatedComponentMetadata || matchedUIBlock?.component;
|
|
3740
|
+
if (!matchedUIBlock || !component) {
|
|
3703
3741
|
return {
|
|
3704
3742
|
success: false,
|
|
3705
3743
|
explanation: "No component found in matched UI block"
|
|
3706
3744
|
};
|
|
3707
3745
|
}
|
|
3708
|
-
const component = matchedUIBlock.generatedComponentMetadata;
|
|
3709
3746
|
const schemaDoc = schema.generateSchemaDocumentation();
|
|
3710
3747
|
const prompts = await promptLoader.loadPrompts("adapt-ui-block-params", {
|
|
3711
3748
|
ORIGINAL_USER_PROMPT: originalUserPrompt,
|
|
@@ -3781,8 +3818,9 @@ var BaseLLM = class {
|
|
|
3781
3818
|
* @param collections - Collection registry for executing database queries via database.execute
|
|
3782
3819
|
* @param components - Optional list of available components for matching suggestions
|
|
3783
3820
|
* @param externalTools - Optional array of external tools (email, calendar, etc.) that can be called
|
|
3821
|
+
* @param category - Question category ('data_analysis' | 'data_modification' | 'general'). For data_modification, answer component streaming is skipped. For general, component generation is skipped entirely.
|
|
3784
3822
|
*/
|
|
3785
|
-
async generateTextResponse(userPrompt, apiKey, logCollector, conversationHistory, streamCallback, collections, components, externalTools) {
|
|
3823
|
+
async generateTextResponse(userPrompt, apiKey, logCollector, conversationHistory, streamCallback, collections, components, externalTools, category) {
|
|
3786
3824
|
const errors = [];
|
|
3787
3825
|
logger.debug(`[${this.getProviderName()}] Starting text response generation`);
|
|
3788
3826
|
logger.debug(`[${this.getProviderName()}] User prompt: "${userPrompt.substring(0, 50)}..."`);
|
|
@@ -4176,16 +4214,19 @@ ${errorMsg}
|
|
|
4176
4214
|
textLength: textResponse.length
|
|
4177
4215
|
}
|
|
4178
4216
|
);
|
|
4179
|
-
if (wrappedStreamCallback && components && components.length > 0) {
|
|
4217
|
+
if (wrappedStreamCallback && components && components.length > 0 && category !== "general") {
|
|
4180
4218
|
wrappedStreamCallback("__TEXT_COMPLETE__COMPONENT_GENERATION_START__");
|
|
4181
4219
|
}
|
|
4182
4220
|
let matchedComponents = [];
|
|
4183
4221
|
let layoutTitle = "Dashboard";
|
|
4184
4222
|
let layoutDescription = "Multi-component dashboard";
|
|
4185
4223
|
let actions = [];
|
|
4186
|
-
if (
|
|
4224
|
+
if (category === "general") {
|
|
4225
|
+
logger.info(`[${this.getProviderName()}] Skipping component generation for general/conversational question`);
|
|
4226
|
+
logCollector?.info("Skipping component generation for general question");
|
|
4227
|
+
} else if (components && components.length > 0) {
|
|
4187
4228
|
logger.info(`[${this.getProviderName()}] Matching components from text response...`);
|
|
4188
|
-
const componentStreamCallback = wrappedStreamCallback ? (component) => {
|
|
4229
|
+
const componentStreamCallback = wrappedStreamCallback && category !== "data_modification" ? (component) => {
|
|
4189
4230
|
const answerMarker = `__ANSWER_COMPONENT_START__${JSON.stringify(component)}__ANSWER_COMPONENT_END__`;
|
|
4190
4231
|
wrappedStreamCallback(answerMarker);
|
|
4191
4232
|
logger.info(`[${this.getProviderName()}] Streamed answer component to frontend: ${component.name} (${component.type})`);
|
|
@@ -4284,52 +4325,78 @@ ${errorMsg}
|
|
|
4284
4325
|
logCollector?.info(
|
|
4285
4326
|
`\u2713 Found similar conversation (${(conversationMatch.similarity * 100).toFixed(2)}% match)`
|
|
4286
4327
|
);
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
);
|
|
4313
|
-
if (adaptResult.success && adaptResult.adaptedComponent) {
|
|
4314
|
-
const elapsedTime2 = Date.now() - startTime;
|
|
4315
|
-
logger.info(`[${this.getProviderName()}] \u2713 Successfully adapted UI block parameters`);
|
|
4316
|
-
logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
|
|
4317
|
-
logCollector?.info(`\u2713 UI block adapted successfully`);
|
|
4318
|
-
logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
|
|
4319
|
-
return {
|
|
4320
|
-
success: true,
|
|
4321
|
-
data: {
|
|
4322
|
-
component: adaptResult.adaptedComponent,
|
|
4323
|
-
reasoning: `Adapted from previous conversation: ${originalPrompt}`,
|
|
4324
|
-
method: `${this.getProviderName()}-semantic-match`,
|
|
4325
|
-
semanticSimilarity: conversationMatch.similarity,
|
|
4326
|
-
parametersChanged: adaptResult.parametersChanged
|
|
4327
|
-
},
|
|
4328
|
-
errors: []
|
|
4329
|
-
};
|
|
4328
|
+
const component = conversationMatch.uiBlock?.component || conversationMatch.uiBlock?.generatedComponentMetadata;
|
|
4329
|
+
const cachedTextResponse = conversationMatch.uiBlock?.analysis || conversationMatch.uiBlock?.textResponse || conversationMatch.uiBlock?.text || "";
|
|
4330
|
+
if (!component) {
|
|
4331
|
+
if (conversationMatch.similarity >= 0.99) {
|
|
4332
|
+
const elapsedTime2 = Date.now() - startTime;
|
|
4333
|
+
logger.info(`[${this.getProviderName()}] \u2713 Exact match for general question - returning cached text response`);
|
|
4334
|
+
logCollector?.info(`\u2713 Exact match for general question - returning cached response`);
|
|
4335
|
+
logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
|
|
4336
|
+
return {
|
|
4337
|
+
success: true,
|
|
4338
|
+
data: {
|
|
4339
|
+
text: cachedTextResponse,
|
|
4340
|
+
component: null,
|
|
4341
|
+
matchedComponents: [],
|
|
4342
|
+
actions: conversationMatch.uiBlock?.actions || [],
|
|
4343
|
+
reasoning: `Exact match from previous general conversation`,
|
|
4344
|
+
method: `${this.getProviderName()}-semantic-match-general`,
|
|
4345
|
+
semanticSimilarity: conversationMatch.similarity
|
|
4346
|
+
},
|
|
4347
|
+
errors: []
|
|
4348
|
+
};
|
|
4349
|
+
} else {
|
|
4350
|
+
logger.info(`[${this.getProviderName()}] Similar match but no component (general question) - processing fresh`);
|
|
4351
|
+
logCollector?.info("Similar match found but was a general conversation - processing as new question");
|
|
4352
|
+
}
|
|
4330
4353
|
} else {
|
|
4331
|
-
|
|
4332
|
-
|
|
4354
|
+
if (conversationMatch.similarity >= 0.99) {
|
|
4355
|
+
const elapsedTime2 = Date.now() - startTime;
|
|
4356
|
+
logger.info(`[${this.getProviderName()}] \u2713 100% match - returning UI block directly without adaptation`);
|
|
4357
|
+
logCollector?.info(`\u2713 Exact match (${(conversationMatch.similarity * 100).toFixed(2)}%) - returning cached result`);
|
|
4358
|
+
logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
|
|
4359
|
+
return {
|
|
4360
|
+
success: true,
|
|
4361
|
+
data: {
|
|
4362
|
+
component,
|
|
4363
|
+
reasoning: `Exact match from previous conversation (${(conversationMatch.similarity * 100).toFixed(2)}% similarity)`,
|
|
4364
|
+
method: `${this.getProviderName()}-semantic-match-exact`,
|
|
4365
|
+
semanticSimilarity: conversationMatch.similarity
|
|
4366
|
+
},
|
|
4367
|
+
errors: []
|
|
4368
|
+
};
|
|
4369
|
+
}
|
|
4370
|
+
logCollector?.info(`Adapting parameters for similar question...`);
|
|
4371
|
+
const originalPrompt = conversationMatch.metadata?.userPrompt || "Previous question";
|
|
4372
|
+
const adaptResult = await this.adaptUIBlockParameters(
|
|
4373
|
+
userPrompt,
|
|
4374
|
+
originalPrompt,
|
|
4375
|
+
conversationMatch.uiBlock,
|
|
4376
|
+
apiKey,
|
|
4377
|
+
logCollector
|
|
4378
|
+
);
|
|
4379
|
+
if (adaptResult.success && adaptResult.adaptedComponent) {
|
|
4380
|
+
const elapsedTime2 = Date.now() - startTime;
|
|
4381
|
+
logger.info(`[${this.getProviderName()}] \u2713 Successfully adapted UI block parameters`);
|
|
4382
|
+
logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
|
|
4383
|
+
logCollector?.info(`\u2713 UI block adapted successfully`);
|
|
4384
|
+
logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
|
|
4385
|
+
return {
|
|
4386
|
+
success: true,
|
|
4387
|
+
data: {
|
|
4388
|
+
component: adaptResult.adaptedComponent,
|
|
4389
|
+
reasoning: `Adapted from previous conversation: ${originalPrompt}`,
|
|
4390
|
+
method: `${this.getProviderName()}-semantic-match`,
|
|
4391
|
+
semanticSimilarity: conversationMatch.similarity,
|
|
4392
|
+
parametersChanged: adaptResult.parametersChanged
|
|
4393
|
+
},
|
|
4394
|
+
errors: []
|
|
4395
|
+
};
|
|
4396
|
+
} else {
|
|
4397
|
+
logger.info(`[${this.getProviderName()}] Could not adapt matched conversation, continuing to category classification`);
|
|
4398
|
+
logCollector?.warn(`Could not adapt matched conversation: ${adaptResult.explanation}`);
|
|
4399
|
+
}
|
|
4333
4400
|
}
|
|
4334
4401
|
} else {
|
|
4335
4402
|
logger.info(`[${this.getProviderName()}] No matching previous conversations found, proceeding to category classification`);
|
|
@@ -4371,7 +4438,10 @@ ${errorMsg}
|
|
|
4371
4438
|
})()
|
|
4372
4439
|
})) || [];
|
|
4373
4440
|
}
|
|
4374
|
-
if (categoryClassification.category === "
|
|
4441
|
+
if (categoryClassification.category === "general") {
|
|
4442
|
+
logger.info(`[${this.getProviderName()}] Routing to general conversation (no database operations)`);
|
|
4443
|
+
logCollector?.info("Routing to general conversation...");
|
|
4444
|
+
} else if (categoryClassification.category === "data_analysis") {
|
|
4375
4445
|
logger.info(`[${this.getProviderName()}] Routing to data analysis (SELECT operations)`);
|
|
4376
4446
|
logCollector?.info("Routing to data analysis...");
|
|
4377
4447
|
} else if (categoryClassification.category === "data_modification") {
|
|
@@ -4386,7 +4456,8 @@ ${errorMsg}
|
|
|
4386
4456
|
streamCallback,
|
|
4387
4457
|
collections,
|
|
4388
4458
|
components,
|
|
4389
|
-
toolsToUse
|
|
4459
|
+
toolsToUse,
|
|
4460
|
+
categoryClassification.category
|
|
4390
4461
|
);
|
|
4391
4462
|
const elapsedTime = Date.now() - startTime;
|
|
4392
4463
|
logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime}ms (${(elapsedTime / 1e3).toFixed(2)}s)`);
|
|
@@ -4810,6 +4881,15 @@ var UILogCollector = class {
|
|
|
4810
4881
|
};
|
|
4811
4882
|
|
|
4812
4883
|
// src/utils/conversation-saver.ts
|
|
4884
|
+
function transformUIBlockForDB(uiblock, userPrompt, uiBlockId) {
|
|
4885
|
+
const component = uiblock?.generatedComponentMetadata && Object.keys(uiblock.generatedComponentMetadata).length > 0 ? uiblock.generatedComponentMetadata : null;
|
|
4886
|
+
return {
|
|
4887
|
+
id: uiBlockId || uiblock?.id || "",
|
|
4888
|
+
component,
|
|
4889
|
+
analysis: uiblock?.textResponse || null,
|
|
4890
|
+
user_prompt: userPrompt || uiblock?.userQuestion || ""
|
|
4891
|
+
};
|
|
4892
|
+
}
|
|
4813
4893
|
async function saveConversation(params) {
|
|
4814
4894
|
const { userId, userPrompt, uiblock, uiBlockId, threadId, collections } = params;
|
|
4815
4895
|
if (!userId) {
|
|
@@ -4864,10 +4944,12 @@ async function saveConversation(params) {
|
|
|
4864
4944
|
error: `Invalid userId: ${userId} (not a valid number)`
|
|
4865
4945
|
};
|
|
4866
4946
|
}
|
|
4947
|
+
const dbUIBlock = transformUIBlockForDB(uiblock, userPrompt, uiBlockId);
|
|
4948
|
+
logger.debug(`[CONVERSATION_SAVER] Transformed UIBlock for DB: ${JSON.stringify(dbUIBlock)}`);
|
|
4867
4949
|
const saveResult = await collections["user-conversations"]["create"]({
|
|
4868
4950
|
userId: userIdNumber,
|
|
4869
4951
|
userPrompt,
|
|
4870
|
-
uiblock,
|
|
4952
|
+
uiblock: dbUIBlock,
|
|
4871
4953
|
threadId
|
|
4872
4954
|
});
|
|
4873
4955
|
if (!saveResult?.success) {
|
|
@@ -4884,7 +4966,8 @@ async function saveConversation(params) {
|
|
|
4884
4966
|
const embedResult = await collections["conversation-history"]["embed"]({
|
|
4885
4967
|
uiBlockId,
|
|
4886
4968
|
userPrompt,
|
|
4887
|
-
uiBlock:
|
|
4969
|
+
uiBlock: dbUIBlock,
|
|
4970
|
+
// Use the transformed UIBlock
|
|
4888
4971
|
userId: userIdNumber
|
|
4889
4972
|
});
|
|
4890
4973
|
if (embedResult?.success) {
|
|
@@ -5031,8 +5114,10 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
|
|
|
5031
5114
|
if ("component" in userResponse.data) {
|
|
5032
5115
|
component = userResponse.data.component;
|
|
5033
5116
|
}
|
|
5034
|
-
if ("
|
|
5117
|
+
if ("text" in userResponse.data) {
|
|
5035
5118
|
textResponse = userResponse.data.text;
|
|
5119
|
+
} else if ("textResponse" in userResponse.data) {
|
|
5120
|
+
textResponse = userResponse.data.textResponse;
|
|
5036
5121
|
}
|
|
5037
5122
|
if ("actions" in userResponse.data) {
|
|
5038
5123
|
actions = userResponse.data.actions || [];
|
|
@@ -6184,13 +6269,15 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
|
|
|
6184
6269
|
const { id, payload, from } = request;
|
|
6185
6270
|
const { operation, data: requestData } = payload;
|
|
6186
6271
|
const bookmarkId = requestData?.id;
|
|
6272
|
+
const userId = requestData?.userId;
|
|
6273
|
+
const threadId = requestData?.threadId;
|
|
6187
6274
|
const uiblock = requestData?.uiblock;
|
|
6188
6275
|
switch (operation) {
|
|
6189
6276
|
case "create":
|
|
6190
|
-
await handleCreate4(id, uiblock, executeCollection, sendMessage, from.id);
|
|
6277
|
+
await handleCreate4(id, userId, threadId, uiblock, executeCollection, sendMessage, from.id);
|
|
6191
6278
|
break;
|
|
6192
6279
|
case "update":
|
|
6193
|
-
await handleUpdate4(id, bookmarkId, uiblock, executeCollection, sendMessage, from.id);
|
|
6280
|
+
await handleUpdate4(id, bookmarkId, threadId, uiblock, executeCollection, sendMessage, from.id);
|
|
6194
6281
|
break;
|
|
6195
6282
|
case "delete":
|
|
6196
6283
|
await handleDelete4(id, bookmarkId, executeCollection, sendMessage, from.id);
|
|
@@ -6201,6 +6288,12 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
|
|
|
6201
6288
|
case "getOne":
|
|
6202
6289
|
await handleGetOne4(id, bookmarkId, executeCollection, sendMessage, from.id);
|
|
6203
6290
|
break;
|
|
6291
|
+
case "getByUser":
|
|
6292
|
+
await handleGetByUser(id, userId, threadId, executeCollection, sendMessage, from.id);
|
|
6293
|
+
break;
|
|
6294
|
+
case "getByThread":
|
|
6295
|
+
await handleGetByThread(id, threadId, executeCollection, sendMessage, from.id);
|
|
6296
|
+
break;
|
|
6204
6297
|
default:
|
|
6205
6298
|
sendResponse6(id, {
|
|
6206
6299
|
success: false,
|
|
@@ -6215,7 +6308,14 @@ async function handleBookmarksRequest(data, collections, sendMessage) {
|
|
|
6215
6308
|
}, sendMessage);
|
|
6216
6309
|
}
|
|
6217
6310
|
}
|
|
6218
|
-
async function handleCreate4(id, uiblock, executeCollection, sendMessage, clientId) {
|
|
6311
|
+
async function handleCreate4(id, userId, threadId, uiblock, executeCollection, sendMessage, clientId) {
|
|
6312
|
+
if (!userId) {
|
|
6313
|
+
sendResponse6(id, {
|
|
6314
|
+
success: false,
|
|
6315
|
+
error: "userId is required"
|
|
6316
|
+
}, sendMessage, clientId);
|
|
6317
|
+
return;
|
|
6318
|
+
}
|
|
6219
6319
|
if (!uiblock) {
|
|
6220
6320
|
sendResponse6(id, {
|
|
6221
6321
|
success: false,
|
|
@@ -6224,7 +6324,7 @@ async function handleCreate4(id, uiblock, executeCollection, sendMessage, client
|
|
|
6224
6324
|
return;
|
|
6225
6325
|
}
|
|
6226
6326
|
try {
|
|
6227
|
-
const result = await executeCollection("bookmarks", "create", { uiblock });
|
|
6327
|
+
const result = await executeCollection("bookmarks", "create", { userId, threadId, uiblock });
|
|
6228
6328
|
sendResponse6(id, {
|
|
6229
6329
|
success: true,
|
|
6230
6330
|
data: result.data,
|
|
@@ -6238,7 +6338,7 @@ async function handleCreate4(id, uiblock, executeCollection, sendMessage, client
|
|
|
6238
6338
|
}, sendMessage, clientId);
|
|
6239
6339
|
}
|
|
6240
6340
|
}
|
|
6241
|
-
async function handleUpdate4(id, bookmarkId, uiblock, executeCollection, sendMessage, clientId) {
|
|
6341
|
+
async function handleUpdate4(id, bookmarkId, threadId, uiblock, executeCollection, sendMessage, clientId) {
|
|
6242
6342
|
if (!bookmarkId) {
|
|
6243
6343
|
sendResponse6(id, {
|
|
6244
6344
|
success: false,
|
|
@@ -6254,7 +6354,7 @@ async function handleUpdate4(id, bookmarkId, uiblock, executeCollection, sendMes
|
|
|
6254
6354
|
return;
|
|
6255
6355
|
}
|
|
6256
6356
|
try {
|
|
6257
|
-
const result = await executeCollection("bookmarks", "update", { id: bookmarkId, uiblock });
|
|
6357
|
+
const result = await executeCollection("bookmarks", "update", { id: bookmarkId, threadId, uiblock });
|
|
6258
6358
|
sendResponse6(id, {
|
|
6259
6359
|
success: true,
|
|
6260
6360
|
data: result.data,
|
|
@@ -6331,6 +6431,54 @@ async function handleGetOne4(id, bookmarkId, executeCollection, sendMessage, cli
|
|
|
6331
6431
|
}, sendMessage, clientId);
|
|
6332
6432
|
}
|
|
6333
6433
|
}
|
|
6434
|
+
async function handleGetByUser(id, userId, threadId, executeCollection, sendMessage, clientId) {
|
|
6435
|
+
if (!userId) {
|
|
6436
|
+
sendResponse6(id, {
|
|
6437
|
+
success: false,
|
|
6438
|
+
error: "userId is required"
|
|
6439
|
+
}, sendMessage, clientId);
|
|
6440
|
+
return;
|
|
6441
|
+
}
|
|
6442
|
+
try {
|
|
6443
|
+
const result = await executeCollection("bookmarks", "getByUser", { userId, threadId });
|
|
6444
|
+
sendResponse6(id, {
|
|
6445
|
+
success: true,
|
|
6446
|
+
data: result.data,
|
|
6447
|
+
count: result.count,
|
|
6448
|
+
message: `Retrieved ${result.count} bookmarks for user ${userId}`
|
|
6449
|
+
}, sendMessage, clientId);
|
|
6450
|
+
logger.info(`Retrieved bookmarks for user ${userId} (count: ${result.count})`);
|
|
6451
|
+
} catch (error) {
|
|
6452
|
+
sendResponse6(id, {
|
|
6453
|
+
success: false,
|
|
6454
|
+
error: error instanceof Error ? error.message : "Failed to get bookmarks by user"
|
|
6455
|
+
}, sendMessage, clientId);
|
|
6456
|
+
}
|
|
6457
|
+
}
|
|
6458
|
+
async function handleGetByThread(id, threadId, executeCollection, sendMessage, clientId) {
|
|
6459
|
+
if (!threadId) {
|
|
6460
|
+
sendResponse6(id, {
|
|
6461
|
+
success: false,
|
|
6462
|
+
error: "threadId is required"
|
|
6463
|
+
}, sendMessage, clientId);
|
|
6464
|
+
return;
|
|
6465
|
+
}
|
|
6466
|
+
try {
|
|
6467
|
+
const result = await executeCollection("bookmarks", "getByThread", { threadId });
|
|
6468
|
+
sendResponse6(id, {
|
|
6469
|
+
success: true,
|
|
6470
|
+
data: result.data,
|
|
6471
|
+
count: result.count,
|
|
6472
|
+
message: `Retrieved ${result.count} bookmarks for thread ${threadId}`
|
|
6473
|
+
}, sendMessage, clientId);
|
|
6474
|
+
logger.info(`Retrieved bookmarks for thread ${threadId} (count: ${result.count})`);
|
|
6475
|
+
} catch (error) {
|
|
6476
|
+
sendResponse6(id, {
|
|
6477
|
+
success: false,
|
|
6478
|
+
error: error instanceof Error ? error.message : "Failed to get bookmarks by thread"
|
|
6479
|
+
}, sendMessage, clientId);
|
|
6480
|
+
}
|
|
6481
|
+
}
|
|
6334
6482
|
function sendResponse6(id, res, sendMessage, clientId) {
|
|
6335
6483
|
const response = {
|
|
6336
6484
|
id: id || "unknown",
|
|
@@ -7317,12 +7465,12 @@ var SuperatomSDK = class {
|
|
|
7317
7465
|
});
|
|
7318
7466
|
break;
|
|
7319
7467
|
case "AUTH_LOGIN_REQ":
|
|
7320
|
-
handleAuthLoginRequest(parsed, (msg) => this.send(msg)).catch((error) => {
|
|
7468
|
+
handleAuthLoginRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
|
|
7321
7469
|
logger.error("Failed to handle auth login request:", error);
|
|
7322
7470
|
});
|
|
7323
7471
|
break;
|
|
7324
7472
|
case "AUTH_VERIFY_REQ":
|
|
7325
|
-
handleAuthVerifyRequest(parsed, (msg) => this.send(msg)).catch((error) => {
|
|
7473
|
+
handleAuthVerifyRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
|
|
7326
7474
|
logger.error("Failed to handle auth verify request:", error);
|
|
7327
7475
|
});
|
|
7328
7476
|
break;
|