@superatomai/sdk-node 0.0.77 → 0.0.79
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.js +240 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +240 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -402,7 +402,8 @@ var UserQueryFiltersSchema = import_zod3.z.object({
|
|
|
402
402
|
username: import_zod3.z.string().optional(),
|
|
403
403
|
email: import_zod3.z.string().optional(),
|
|
404
404
|
role: import_zod3.z.string().optional(),
|
|
405
|
-
fullname: import_zod3.z.string().optional()
|
|
405
|
+
fullname: import_zod3.z.string().optional(),
|
|
406
|
+
id: import_zod3.z.number().optional()
|
|
406
407
|
});
|
|
407
408
|
var UsersRequestPayloadSchema = import_zod3.z.object({
|
|
408
409
|
operation: import_zod3.z.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
|
|
@@ -752,6 +753,67 @@ var DashCompRequestMessageSchema = import_zod3.z.object({
|
|
|
752
753
|
type: import_zod3.z.literal("DASH_COMP_REQ"),
|
|
753
754
|
payload: DashCompRequestPayloadSchema
|
|
754
755
|
});
|
|
756
|
+
var SchemaColumnStatisticsSchema = import_zod3.z.object({
|
|
757
|
+
distinct: import_zod3.z.number().optional(),
|
|
758
|
+
min: import_zod3.z.number().optional(),
|
|
759
|
+
max: import_zod3.z.number().optional()
|
|
760
|
+
});
|
|
761
|
+
var SchemaColumnSchema = import_zod3.z.object({
|
|
762
|
+
name: import_zod3.z.string(),
|
|
763
|
+
type: import_zod3.z.string(),
|
|
764
|
+
nativeType: import_zod3.z.string(),
|
|
765
|
+
nullable: import_zod3.z.boolean(),
|
|
766
|
+
description: import_zod3.z.string(),
|
|
767
|
+
statistics: SchemaColumnStatisticsSchema.optional(),
|
|
768
|
+
cardinality: import_zod3.z.enum(["unique", "high", "medium", "low"]).optional(),
|
|
769
|
+
sampleValues: import_zod3.z.array(import_zod3.z.string()).optional()
|
|
770
|
+
});
|
|
771
|
+
var SchemaTableSchema = import_zod3.z.object({
|
|
772
|
+
name: import_zod3.z.string(),
|
|
773
|
+
fullName: import_zod3.z.string(),
|
|
774
|
+
rowCount: import_zod3.z.number(),
|
|
775
|
+
description: import_zod3.z.string(),
|
|
776
|
+
columns: import_zod3.z.array(SchemaColumnSchema)
|
|
777
|
+
});
|
|
778
|
+
var SchemaRelationshipSchema = import_zod3.z.object({
|
|
779
|
+
from: import_zod3.z.string(),
|
|
780
|
+
to: import_zod3.z.string(),
|
|
781
|
+
type: import_zod3.z.string(),
|
|
782
|
+
keys: import_zod3.z.array(import_zod3.z.string())
|
|
783
|
+
});
|
|
784
|
+
var DatabaseSchemaSchema = import_zod3.z.object({
|
|
785
|
+
database: import_zod3.z.string(),
|
|
786
|
+
databaseType: import_zod3.z.string().optional(),
|
|
787
|
+
schema: import_zod3.z.string(),
|
|
788
|
+
description: import_zod3.z.string(),
|
|
789
|
+
tables: import_zod3.z.array(SchemaTableSchema),
|
|
790
|
+
relationships: import_zod3.z.array(SchemaRelationshipSchema).optional()
|
|
791
|
+
});
|
|
792
|
+
var SchemaRequestPayloadSchema = import_zod3.z.object({
|
|
793
|
+
/** If true, returns the formatted documentation string in addition to raw JSON */
|
|
794
|
+
formatted: import_zod3.z.boolean().optional()
|
|
795
|
+
});
|
|
796
|
+
var SchemaRequestMessageSchema = import_zod3.z.object({
|
|
797
|
+
id: import_zod3.z.string(),
|
|
798
|
+
from: MessageParticipantSchema,
|
|
799
|
+
type: import_zod3.z.literal("SCHEMA_REQ"),
|
|
800
|
+
payload: SchemaRequestPayloadSchema
|
|
801
|
+
});
|
|
802
|
+
var SchemaResponsePayloadSchema = import_zod3.z.object({
|
|
803
|
+
success: import_zod3.z.boolean(),
|
|
804
|
+
error: import_zod3.z.string().optional(),
|
|
805
|
+
data: import_zod3.z.object({
|
|
806
|
+
schema: DatabaseSchemaSchema,
|
|
807
|
+
/** Formatted schema documentation (only if formatted: true was requested) */
|
|
808
|
+
formatted: import_zod3.z.string().optional()
|
|
809
|
+
}).optional()
|
|
810
|
+
});
|
|
811
|
+
var SchemaResponseMessageSchema = import_zod3.z.object({
|
|
812
|
+
id: import_zod3.z.string(),
|
|
813
|
+
from: MessageParticipantSchema,
|
|
814
|
+
type: import_zod3.z.literal("SCHEMA_RES"),
|
|
815
|
+
payload: SchemaResponsePayloadSchema
|
|
816
|
+
});
|
|
755
817
|
|
|
756
818
|
// src/utils/logger.ts
|
|
757
819
|
var import_fs = __toESM(require("fs"));
|
|
@@ -3536,6 +3598,7 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
3536
3598
|
|
|
3537
3599
|
**CRITICAL:**
|
|
3538
3600
|
- Return ONLY valid JSON (no markdown code blocks, no text before/after)
|
|
3601
|
+
-\`componentName\`: MUST be the EXACT \`name\` field from the Available Components list. Never use a title or description as componentName.
|
|
3539
3602
|
- \`componentId\`: For new components, MUST match an ID from the available components list. For updates, preserve the existing component's ID
|
|
3540
3603
|
- \`isUpdate\`: Set to \`true\` if updating an existing component, \`false\` if creating new
|
|
3541
3604
|
- \`dataSourceType\` indicates whether data comes from database or external tool
|
|
@@ -6533,6 +6596,7 @@ var STREAM_PREVIEW_MAX_CHARS = 200;
|
|
|
6533
6596
|
var TOOL_TRACKING_MAX_ROWS = 5;
|
|
6534
6597
|
var TOOL_TRACKING_MAX_CHARS = 200;
|
|
6535
6598
|
var TOOL_TRACKING_SAMPLE_ROWS = 3;
|
|
6599
|
+
var DEFAULT_QUERY_LIMIT = 10;
|
|
6536
6600
|
var MAX_COMPONENT_QUERY_LIMIT = 10;
|
|
6537
6601
|
var EXACT_MATCH_SIMILARITY_THRESHOLD = 0.99;
|
|
6538
6602
|
var DEFAULT_CONVERSATION_SIMILARITY_THRESHOLD = 0.8;
|
|
@@ -12223,6 +12287,7 @@ function formatComponentsForPrompt(components) {
|
|
|
12223
12287
|
if (!components || components.length === 0) {
|
|
12224
12288
|
return "No components available";
|
|
12225
12289
|
}
|
|
12290
|
+
components = components.filter((c) => c.name !== "MultiComponentContainer");
|
|
12226
12291
|
return components.map((comp, idx) => {
|
|
12227
12292
|
const keywords = comp.keywords ? comp.keywords.join(", ") : "";
|
|
12228
12293
|
const propsPreview = comp.props ? JSON.stringify(comp.props, null, 2) : "No props";
|
|
@@ -12269,7 +12334,7 @@ function sendDashCompResponse(id, res, sendMessage, clientId) {
|
|
|
12269
12334
|
}
|
|
12270
12335
|
|
|
12271
12336
|
// src/dashComp/pick-component.ts
|
|
12272
|
-
async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders,
|
|
12337
|
+
async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, tools, dashCompModels) {
|
|
12273
12338
|
const errors = [];
|
|
12274
12339
|
const availableComponentsText = formatComponentsForPrompt(components);
|
|
12275
12340
|
const availableToolsText = formatToolsForPrompt(tools);
|
|
@@ -12325,7 +12390,8 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
|
|
|
12325
12390
|
outputSchema: tool.outputSchema
|
|
12326
12391
|
});
|
|
12327
12392
|
logger.info(`[DASH_COMP_REQ] Tool ${tool.name} executed successfully`);
|
|
12328
|
-
|
|
12393
|
+
const resultJson = JSON.stringify(result2, null, 2);
|
|
12394
|
+
return resultJson + "\n\n[REMINDER: The above is tool output for verification. You MUST still respond with ONLY the JSON component selection object. Do NOT summarize or describe these results.]";
|
|
12329
12395
|
};
|
|
12330
12396
|
const result = await LLM.streamWithTools(
|
|
12331
12397
|
{
|
|
@@ -12343,16 +12409,59 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
|
|
|
12343
12409
|
5
|
|
12344
12410
|
// max iterations
|
|
12345
12411
|
);
|
|
12346
|
-
|
|
12347
|
-
|
|
12412
|
+
let jsonMatch = result.match(/\{[\s\S]*\}/);
|
|
12413
|
+
let parsedResult = jsonMatch ? (() => {
|
|
12414
|
+
try {
|
|
12415
|
+
return JSON.parse(jsonMatch[0]);
|
|
12416
|
+
} catch {
|
|
12417
|
+
return null;
|
|
12418
|
+
}
|
|
12419
|
+
})() : null;
|
|
12420
|
+
const isValidComponent = parsedResult && parsedResult.componentId && parsedResult.props;
|
|
12421
|
+
if (!isValidComponent && executedTools.length > 0) {
|
|
12422
|
+
const toolDataSummary = executedTools.map(
|
|
12423
|
+
(t) => `Tool "${t.name}" was called with params ${JSON.stringify(t.params)} and returned:
|
|
12424
|
+
${JSON.stringify(t.result, null, 2).substring(0, 5e3)}`
|
|
12425
|
+
).join("\n\n");
|
|
12426
|
+
const retryUserPrompt = `Original user request: ${prompt}
|
|
12427
|
+
|
|
12428
|
+
The following tool was already called and returned data:
|
|
12429
|
+
${toolDataSummary}
|
|
12430
|
+
|
|
12431
|
+
Using this data, select the appropriate component and respond with ONLY the JSON component selection object. No explanation, no markdown, just JSON.`;
|
|
12432
|
+
const retryResult = await LLM.text(
|
|
12433
|
+
{
|
|
12434
|
+
sys: prompts.system,
|
|
12435
|
+
user: retryUserPrompt
|
|
12436
|
+
},
|
|
12437
|
+
{
|
|
12438
|
+
model,
|
|
12439
|
+
maxTokens: 4096,
|
|
12440
|
+
temperature: 0.1,
|
|
12441
|
+
apiKey
|
|
12442
|
+
}
|
|
12443
|
+
);
|
|
12444
|
+
jsonMatch = retryResult.match(/\{[\s\S]*\}/);
|
|
12445
|
+
parsedResult = jsonMatch ? (() => {
|
|
12446
|
+
try {
|
|
12447
|
+
return JSON.parse(jsonMatch[0]);
|
|
12448
|
+
} catch {
|
|
12449
|
+
return null;
|
|
12450
|
+
}
|
|
12451
|
+
})() : null;
|
|
12452
|
+
}
|
|
12348
12453
|
if (!parsedResult) {
|
|
12349
12454
|
errors.push("Failed to parse LLM response as JSON");
|
|
12455
|
+
errors.push(`LLM Response: ${result}`);
|
|
12456
|
+
logger.error(`[DASH_COMP_REQ] Failed to parse JSON from LLM response`);
|
|
12350
12457
|
return { success: false, errors };
|
|
12351
12458
|
}
|
|
12352
|
-
logger.
|
|
12459
|
+
logger.info(`[DASH_COMP_REQ] Parsed component: ${parsedResult.componentName} (${parsedResult.componentId})`);
|
|
12353
12460
|
logger.file("[DASH_COMP_REQ] LLM response:", JSON.stringify(parsedResult, null, 2));
|
|
12354
12461
|
if (!parsedResult.componentId || !parsedResult.props) {
|
|
12355
12462
|
errors.push("Invalid LLM response: missing componentId or props");
|
|
12463
|
+
errors.push(`LLM Response: ${result}`);
|
|
12464
|
+
logger.error(`[DASH_COMP_REQ] Invalid structure - missing componentId: ${!parsedResult.componentId}, missing props: ${!parsedResult.props}`);
|
|
12356
12465
|
userPromptErrorLogger.logError("DASH_COMP_REQ", "Invalid LLM response structure", {
|
|
12357
12466
|
prompt,
|
|
12358
12467
|
result: parsedResult,
|
|
@@ -12363,6 +12472,7 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
|
|
|
12363
12472
|
const originalComponent = components.find((c) => c.name === parsedResult.componentName);
|
|
12364
12473
|
if (!originalComponent) {
|
|
12365
12474
|
errors.push(`Component ${parsedResult.componentName} not found in available components`);
|
|
12475
|
+
errors.push(`LLM Response: ${result}`);
|
|
12366
12476
|
userPromptErrorLogger.logError("DASH_COMP_REQ", "Component not found", {
|
|
12367
12477
|
prompt,
|
|
12368
12478
|
componentName: parsedResult.componentName,
|
|
@@ -12370,14 +12480,72 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
|
|
|
12370
12480
|
});
|
|
12371
12481
|
return { success: false, errors };
|
|
12372
12482
|
}
|
|
12373
|
-
|
|
12483
|
+
let finalComponent = {
|
|
12374
12484
|
...originalComponent,
|
|
12375
12485
|
props: {
|
|
12376
12486
|
...originalComponent.props,
|
|
12377
12487
|
...parsedResult.props
|
|
12378
12488
|
}
|
|
12379
12489
|
};
|
|
12490
|
+
if (finalComponent.props?.query) {
|
|
12491
|
+
const query = finalComponent.props.query;
|
|
12492
|
+
if (typeof query === "string") {
|
|
12493
|
+
finalComponent.props.query = ensureQueryLimit(query, DEFAULT_QUERY_LIMIT, MAX_COMPONENT_QUERY_LIMIT);
|
|
12494
|
+
} else if (query?.sql) {
|
|
12495
|
+
finalComponent.props.query = {
|
|
12496
|
+
...query,
|
|
12497
|
+
sql: ensureQueryLimit(query.sql, DEFAULT_QUERY_LIMIT, MAX_COMPONENT_QUERY_LIMIT)
|
|
12498
|
+
};
|
|
12499
|
+
}
|
|
12500
|
+
}
|
|
12380
12501
|
logger.info(`[DASH_COMP_REQ] Successfully picked component: ${finalComponent.name} (${finalComponent.type})`);
|
|
12502
|
+
if (finalComponent.props?.query && collections?.["database"]?.["execute"]) {
|
|
12503
|
+
logger.info(`[DASH_COMP_REQ] Validating query for component: ${finalComponent.name}`);
|
|
12504
|
+
const queryService = new QueryExecutionService({
|
|
12505
|
+
defaultLimit: DEFAULT_QUERY_LIMIT,
|
|
12506
|
+
getModelForTask: () => model,
|
|
12507
|
+
// Use the same model for query fixes
|
|
12508
|
+
getApiKey: () => apiKey,
|
|
12509
|
+
providerName: "DASH_COMP_REQ"
|
|
12510
|
+
});
|
|
12511
|
+
try {
|
|
12512
|
+
const validationResult = await queryService.validateSingleQuery(
|
|
12513
|
+
finalComponent,
|
|
12514
|
+
collections,
|
|
12515
|
+
apiKey
|
|
12516
|
+
);
|
|
12517
|
+
if (!validationResult.validated) {
|
|
12518
|
+
logger.error(`[DASH_COMP_REQ] Query validation failed for component: ${finalComponent.name}`);
|
|
12519
|
+
errors.push(`Query validation failed for component ${finalComponent.name}. The generated SQL query could not be executed.`);
|
|
12520
|
+
return {
|
|
12521
|
+
success: false,
|
|
12522
|
+
errors,
|
|
12523
|
+
data: {
|
|
12524
|
+
reasoning: parsedResult.reasoning || "Component selected but query validation failed",
|
|
12525
|
+
rawResponse: parsedResult
|
|
12526
|
+
}
|
|
12527
|
+
};
|
|
12528
|
+
}
|
|
12529
|
+
if (validationResult.component) {
|
|
12530
|
+
finalComponent = validationResult.component;
|
|
12531
|
+
}
|
|
12532
|
+
logger.info(`[DASH_COMP_REQ] Query validated successfully for component: ${finalComponent.name}`);
|
|
12533
|
+
} catch (validationError) {
|
|
12534
|
+
const validationErrorMsg = validationError instanceof Error ? validationError.message : String(validationError);
|
|
12535
|
+
logger.error(`[DASH_COMP_REQ] Query validation error: ${validationErrorMsg}`);
|
|
12536
|
+
errors.push(`Query validation error: ${validationErrorMsg}`);
|
|
12537
|
+
return {
|
|
12538
|
+
success: false,
|
|
12539
|
+
errors,
|
|
12540
|
+
data: {
|
|
12541
|
+
reasoning: parsedResult.reasoning || "Component selected but query validation encountered an error",
|
|
12542
|
+
rawResponse: parsedResult
|
|
12543
|
+
}
|
|
12544
|
+
};
|
|
12545
|
+
}
|
|
12546
|
+
} else if (finalComponent.props?.query && !collections?.["database"]?.["execute"]) {
|
|
12547
|
+
logger.warn(`[DASH_COMP_REQ] Skipping query validation - database execute function not available`);
|
|
12548
|
+
}
|
|
12381
12549
|
if (parsedResult.props.query) {
|
|
12382
12550
|
logger.info(`[DASH_COMP_REQ] Data source: Database query`);
|
|
12383
12551
|
}
|
|
@@ -12487,12 +12655,14 @@ async function createFilterWithLLM(prompt, components, existingComponents, anthr
|
|
|
12487
12655
|
const result = jsonMatch ? JSON.parse(jsonMatch[0]) : null;
|
|
12488
12656
|
if (!result) {
|
|
12489
12657
|
errors.push("Failed to parse LLM response as JSON");
|
|
12658
|
+
errors.push(`LLM Response: ${rawResult}`);
|
|
12490
12659
|
return { success: false, errors };
|
|
12491
12660
|
}
|
|
12492
12661
|
logger.debug("[DASH_COMP_REQ:FILTER] LLM response received");
|
|
12493
12662
|
logger.file("[DASH_COMP_REQ:FILTER] LLM response:", JSON.stringify(result, null, 2));
|
|
12494
12663
|
if (!result.filterComponent) {
|
|
12495
12664
|
errors.push("Invalid LLM response: missing filterComponent");
|
|
12665
|
+
errors.push(`LLM Response: ${rawResult}`);
|
|
12496
12666
|
userPromptErrorLogger.logError("DASH_COMP_REQ:FILTER", "Invalid LLM response structure", {
|
|
12497
12667
|
prompt,
|
|
12498
12668
|
result,
|
|
@@ -12635,6 +12805,64 @@ async function handleDashCompRequest(data, components, sendMessage, anthropicApi
|
|
|
12635
12805
|
logger.info(`[DASH_COMP_REQ] Response sent to client ${response.wsId || data.from?.id}`);
|
|
12636
12806
|
}
|
|
12637
12807
|
|
|
12808
|
+
// src/handlers/schema-request.ts
|
|
12809
|
+
async function handleSchemaRequest(message, sendMessage) {
|
|
12810
|
+
const startTime = Date.now();
|
|
12811
|
+
try {
|
|
12812
|
+
const payload = message.payload;
|
|
12813
|
+
const formatted = payload?.formatted ?? false;
|
|
12814
|
+
logger.info(`[SchemaRequest] Processing schema request (formatted: ${formatted})`);
|
|
12815
|
+
const schemaData = schema.getSchema();
|
|
12816
|
+
if (!schemaData) {
|
|
12817
|
+
const response2 = {
|
|
12818
|
+
id: message.id,
|
|
12819
|
+
type: "SCHEMA_RES",
|
|
12820
|
+
from: { type: "data-agent" },
|
|
12821
|
+
to: message.from,
|
|
12822
|
+
payload: {
|
|
12823
|
+
success: false,
|
|
12824
|
+
error: "Schema not found or failed to load"
|
|
12825
|
+
}
|
|
12826
|
+
};
|
|
12827
|
+
sendMessage(response2);
|
|
12828
|
+
return;
|
|
12829
|
+
}
|
|
12830
|
+
const responseData = {
|
|
12831
|
+
schema: schemaData
|
|
12832
|
+
};
|
|
12833
|
+
if (formatted) {
|
|
12834
|
+
responseData.formatted = schema.generateSchemaDocumentation();
|
|
12835
|
+
}
|
|
12836
|
+
const executionMs = Date.now() - startTime;
|
|
12837
|
+
logger.info(`[SchemaRequest] Schema retrieved successfully in ${executionMs}ms`);
|
|
12838
|
+
const response = {
|
|
12839
|
+
id: message.id,
|
|
12840
|
+
type: "SCHEMA_RES",
|
|
12841
|
+
from: { type: "data-agent" },
|
|
12842
|
+
to: message.from,
|
|
12843
|
+
payload: {
|
|
12844
|
+
success: true,
|
|
12845
|
+
data: responseData
|
|
12846
|
+
}
|
|
12847
|
+
};
|
|
12848
|
+
sendMessage(response);
|
|
12849
|
+
} catch (error) {
|
|
12850
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
12851
|
+
logger.error(`[SchemaRequest] Error: ${errorMsg}`);
|
|
12852
|
+
const response = {
|
|
12853
|
+
id: message.id,
|
|
12854
|
+
type: "SCHEMA_RES",
|
|
12855
|
+
from: { type: "data-agent" },
|
|
12856
|
+
to: message.from,
|
|
12857
|
+
payload: {
|
|
12858
|
+
success: false,
|
|
12859
|
+
error: errorMsg
|
|
12860
|
+
}
|
|
12861
|
+
};
|
|
12862
|
+
sendMessage(response);
|
|
12863
|
+
}
|
|
12864
|
+
}
|
|
12865
|
+
|
|
12638
12866
|
// src/auth/user-manager.ts
|
|
12639
12867
|
var import_fs6 = __toESM(require("fs"));
|
|
12640
12868
|
var import_path5 = __toESM(require("path"));
|
|
@@ -13883,6 +14111,11 @@ var SuperatomSDK = class {
|
|
|
13883
14111
|
logger.error("Failed to handle dash comp request:", error);
|
|
13884
14112
|
});
|
|
13885
14113
|
break;
|
|
14114
|
+
case "SCHEMA_REQ":
|
|
14115
|
+
handleSchemaRequest(parsed, (msg) => this.send(msg)).catch((error) => {
|
|
14116
|
+
logger.error("Failed to handle schema request:", error);
|
|
14117
|
+
});
|
|
14118
|
+
break;
|
|
13886
14119
|
default:
|
|
13887
14120
|
const handler = this.messageTypeHandlers.get(message.type);
|
|
13888
14121
|
if (handler) {
|