@superatomai/sdk-node 0.0.77 → 0.0.78
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 +192 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +192 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -752,6 +752,67 @@ var DashCompRequestMessageSchema = import_zod3.z.object({
|
|
|
752
752
|
type: import_zod3.z.literal("DASH_COMP_REQ"),
|
|
753
753
|
payload: DashCompRequestPayloadSchema
|
|
754
754
|
});
|
|
755
|
+
var SchemaColumnStatisticsSchema = import_zod3.z.object({
|
|
756
|
+
distinct: import_zod3.z.number().optional(),
|
|
757
|
+
min: import_zod3.z.number().optional(),
|
|
758
|
+
max: import_zod3.z.number().optional()
|
|
759
|
+
});
|
|
760
|
+
var SchemaColumnSchema = import_zod3.z.object({
|
|
761
|
+
name: import_zod3.z.string(),
|
|
762
|
+
type: import_zod3.z.string(),
|
|
763
|
+
nativeType: import_zod3.z.string(),
|
|
764
|
+
nullable: import_zod3.z.boolean(),
|
|
765
|
+
description: import_zod3.z.string(),
|
|
766
|
+
statistics: SchemaColumnStatisticsSchema.optional(),
|
|
767
|
+
cardinality: import_zod3.z.enum(["unique", "high", "medium", "low"]).optional(),
|
|
768
|
+
sampleValues: import_zod3.z.array(import_zod3.z.string()).optional()
|
|
769
|
+
});
|
|
770
|
+
var SchemaTableSchema = import_zod3.z.object({
|
|
771
|
+
name: import_zod3.z.string(),
|
|
772
|
+
fullName: import_zod3.z.string(),
|
|
773
|
+
rowCount: import_zod3.z.number(),
|
|
774
|
+
description: import_zod3.z.string(),
|
|
775
|
+
columns: import_zod3.z.array(SchemaColumnSchema)
|
|
776
|
+
});
|
|
777
|
+
var SchemaRelationshipSchema = import_zod3.z.object({
|
|
778
|
+
from: import_zod3.z.string(),
|
|
779
|
+
to: import_zod3.z.string(),
|
|
780
|
+
type: import_zod3.z.string(),
|
|
781
|
+
keys: import_zod3.z.array(import_zod3.z.string())
|
|
782
|
+
});
|
|
783
|
+
var DatabaseSchemaSchema = import_zod3.z.object({
|
|
784
|
+
database: import_zod3.z.string(),
|
|
785
|
+
databaseType: import_zod3.z.string().optional(),
|
|
786
|
+
schema: import_zod3.z.string(),
|
|
787
|
+
description: import_zod3.z.string(),
|
|
788
|
+
tables: import_zod3.z.array(SchemaTableSchema),
|
|
789
|
+
relationships: import_zod3.z.array(SchemaRelationshipSchema).optional()
|
|
790
|
+
});
|
|
791
|
+
var SchemaRequestPayloadSchema = import_zod3.z.object({
|
|
792
|
+
/** If true, returns the formatted documentation string in addition to raw JSON */
|
|
793
|
+
formatted: import_zod3.z.boolean().optional()
|
|
794
|
+
});
|
|
795
|
+
var SchemaRequestMessageSchema = import_zod3.z.object({
|
|
796
|
+
id: import_zod3.z.string(),
|
|
797
|
+
from: MessageParticipantSchema,
|
|
798
|
+
type: import_zod3.z.literal("SCHEMA_REQ"),
|
|
799
|
+
payload: SchemaRequestPayloadSchema
|
|
800
|
+
});
|
|
801
|
+
var SchemaResponsePayloadSchema = import_zod3.z.object({
|
|
802
|
+
success: import_zod3.z.boolean(),
|
|
803
|
+
error: import_zod3.z.string().optional(),
|
|
804
|
+
data: import_zod3.z.object({
|
|
805
|
+
schema: DatabaseSchemaSchema,
|
|
806
|
+
/** Formatted schema documentation (only if formatted: true was requested) */
|
|
807
|
+
formatted: import_zod3.z.string().optional()
|
|
808
|
+
}).optional()
|
|
809
|
+
});
|
|
810
|
+
var SchemaResponseMessageSchema = import_zod3.z.object({
|
|
811
|
+
id: import_zod3.z.string(),
|
|
812
|
+
from: MessageParticipantSchema,
|
|
813
|
+
type: import_zod3.z.literal("SCHEMA_RES"),
|
|
814
|
+
payload: SchemaResponsePayloadSchema
|
|
815
|
+
});
|
|
755
816
|
|
|
756
817
|
// src/utils/logger.ts
|
|
757
818
|
var import_fs = __toESM(require("fs"));
|
|
@@ -3536,6 +3597,7 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
3536
3597
|
|
|
3537
3598
|
**CRITICAL:**
|
|
3538
3599
|
- Return ONLY valid JSON (no markdown code blocks, no text before/after)
|
|
3600
|
+
-\`componentName\`: MUST be the EXACT \`name\` field from the Available Components list. Never use a title or description as componentName.
|
|
3539
3601
|
- \`componentId\`: For new components, MUST match an ID from the available components list. For updates, preserve the existing component's ID
|
|
3540
3602
|
- \`isUpdate\`: Set to \`true\` if updating an existing component, \`false\` if creating new
|
|
3541
3603
|
- \`dataSourceType\` indicates whether data comes from database or external tool
|
|
@@ -6533,6 +6595,7 @@ var STREAM_PREVIEW_MAX_CHARS = 200;
|
|
|
6533
6595
|
var TOOL_TRACKING_MAX_ROWS = 5;
|
|
6534
6596
|
var TOOL_TRACKING_MAX_CHARS = 200;
|
|
6535
6597
|
var TOOL_TRACKING_SAMPLE_ROWS = 3;
|
|
6598
|
+
var DEFAULT_QUERY_LIMIT = 10;
|
|
6536
6599
|
var MAX_COMPONENT_QUERY_LIMIT = 10;
|
|
6537
6600
|
var EXACT_MATCH_SIMILARITY_THRESHOLD = 0.99;
|
|
6538
6601
|
var DEFAULT_CONVERSATION_SIMILARITY_THRESHOLD = 0.8;
|
|
@@ -12223,6 +12286,7 @@ function formatComponentsForPrompt(components) {
|
|
|
12223
12286
|
if (!components || components.length === 0) {
|
|
12224
12287
|
return "No components available";
|
|
12225
12288
|
}
|
|
12289
|
+
components = components.filter((c) => c.name !== "MultiComponentContainer");
|
|
12226
12290
|
return components.map((comp, idx) => {
|
|
12227
12291
|
const keywords = comp.keywords ? comp.keywords.join(", ") : "";
|
|
12228
12292
|
const propsPreview = comp.props ? JSON.stringify(comp.props, null, 2) : "No props";
|
|
@@ -12269,7 +12333,7 @@ function sendDashCompResponse(id, res, sendMessage, clientId) {
|
|
|
12269
12333
|
}
|
|
12270
12334
|
|
|
12271
12335
|
// src/dashComp/pick-component.ts
|
|
12272
|
-
async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders,
|
|
12336
|
+
async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, tools, dashCompModels) {
|
|
12273
12337
|
const errors = [];
|
|
12274
12338
|
const availableComponentsText = formatComponentsForPrompt(components);
|
|
12275
12339
|
const availableToolsText = formatToolsForPrompt(tools);
|
|
@@ -12347,12 +12411,14 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
|
|
|
12347
12411
|
const parsedResult = jsonMatch ? JSON.parse(jsonMatch[0]) : null;
|
|
12348
12412
|
if (!parsedResult) {
|
|
12349
12413
|
errors.push("Failed to parse LLM response as JSON");
|
|
12414
|
+
errors.push(`LLM Response: ${result}`);
|
|
12350
12415
|
return { success: false, errors };
|
|
12351
12416
|
}
|
|
12352
12417
|
logger.debug("[DASH_COMP_REQ] LLM response received");
|
|
12353
12418
|
logger.file("[DASH_COMP_REQ] LLM response:", JSON.stringify(parsedResult, null, 2));
|
|
12354
12419
|
if (!parsedResult.componentId || !parsedResult.props) {
|
|
12355
12420
|
errors.push("Invalid LLM response: missing componentId or props");
|
|
12421
|
+
errors.push(`LLM Response: ${result}`);
|
|
12356
12422
|
userPromptErrorLogger.logError("DASH_COMP_REQ", "Invalid LLM response structure", {
|
|
12357
12423
|
prompt,
|
|
12358
12424
|
result: parsedResult,
|
|
@@ -12363,6 +12429,7 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
|
|
|
12363
12429
|
const originalComponent = components.find((c) => c.name === parsedResult.componentName);
|
|
12364
12430
|
if (!originalComponent) {
|
|
12365
12431
|
errors.push(`Component ${parsedResult.componentName} not found in available components`);
|
|
12432
|
+
errors.push(`LLM Response: ${result}`);
|
|
12366
12433
|
userPromptErrorLogger.logError("DASH_COMP_REQ", "Component not found", {
|
|
12367
12434
|
prompt,
|
|
12368
12435
|
componentName: parsedResult.componentName,
|
|
@@ -12370,14 +12437,72 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
|
|
|
12370
12437
|
});
|
|
12371
12438
|
return { success: false, errors };
|
|
12372
12439
|
}
|
|
12373
|
-
|
|
12440
|
+
let finalComponent = {
|
|
12374
12441
|
...originalComponent,
|
|
12375
12442
|
props: {
|
|
12376
12443
|
...originalComponent.props,
|
|
12377
12444
|
...parsedResult.props
|
|
12378
12445
|
}
|
|
12379
12446
|
};
|
|
12447
|
+
if (finalComponent.props?.query) {
|
|
12448
|
+
const query = finalComponent.props.query;
|
|
12449
|
+
if (typeof query === "string") {
|
|
12450
|
+
finalComponent.props.query = ensureQueryLimit(query, DEFAULT_QUERY_LIMIT, MAX_COMPONENT_QUERY_LIMIT);
|
|
12451
|
+
} else if (query?.sql) {
|
|
12452
|
+
finalComponent.props.query = {
|
|
12453
|
+
...query,
|
|
12454
|
+
sql: ensureQueryLimit(query.sql, DEFAULT_QUERY_LIMIT, MAX_COMPONENT_QUERY_LIMIT)
|
|
12455
|
+
};
|
|
12456
|
+
}
|
|
12457
|
+
}
|
|
12380
12458
|
logger.info(`[DASH_COMP_REQ] Successfully picked component: ${finalComponent.name} (${finalComponent.type})`);
|
|
12459
|
+
if (finalComponent.props?.query && collections?.["database"]?.["execute"]) {
|
|
12460
|
+
logger.info(`[DASH_COMP_REQ] Validating query for component: ${finalComponent.name}`);
|
|
12461
|
+
const queryService = new QueryExecutionService({
|
|
12462
|
+
defaultLimit: DEFAULT_QUERY_LIMIT,
|
|
12463
|
+
getModelForTask: () => model,
|
|
12464
|
+
// Use the same model for query fixes
|
|
12465
|
+
getApiKey: () => apiKey,
|
|
12466
|
+
providerName: "DASH_COMP_REQ"
|
|
12467
|
+
});
|
|
12468
|
+
try {
|
|
12469
|
+
const validationResult = await queryService.validateSingleQuery(
|
|
12470
|
+
finalComponent,
|
|
12471
|
+
collections,
|
|
12472
|
+
apiKey
|
|
12473
|
+
);
|
|
12474
|
+
if (!validationResult.validated) {
|
|
12475
|
+
logger.error(`[DASH_COMP_REQ] Query validation failed for component: ${finalComponent.name}`);
|
|
12476
|
+
errors.push(`Query validation failed for component ${finalComponent.name}. The generated SQL query could not be executed.`);
|
|
12477
|
+
return {
|
|
12478
|
+
success: false,
|
|
12479
|
+
errors,
|
|
12480
|
+
data: {
|
|
12481
|
+
reasoning: parsedResult.reasoning || "Component selected but query validation failed",
|
|
12482
|
+
rawResponse: parsedResult
|
|
12483
|
+
}
|
|
12484
|
+
};
|
|
12485
|
+
}
|
|
12486
|
+
if (validationResult.component) {
|
|
12487
|
+
finalComponent = validationResult.component;
|
|
12488
|
+
}
|
|
12489
|
+
logger.info(`[DASH_COMP_REQ] Query validated successfully for component: ${finalComponent.name}`);
|
|
12490
|
+
} catch (validationError) {
|
|
12491
|
+
const validationErrorMsg = validationError instanceof Error ? validationError.message : String(validationError);
|
|
12492
|
+
logger.error(`[DASH_COMP_REQ] Query validation error: ${validationErrorMsg}`);
|
|
12493
|
+
errors.push(`Query validation error: ${validationErrorMsg}`);
|
|
12494
|
+
return {
|
|
12495
|
+
success: false,
|
|
12496
|
+
errors,
|
|
12497
|
+
data: {
|
|
12498
|
+
reasoning: parsedResult.reasoning || "Component selected but query validation encountered an error",
|
|
12499
|
+
rawResponse: parsedResult
|
|
12500
|
+
}
|
|
12501
|
+
};
|
|
12502
|
+
}
|
|
12503
|
+
} else if (finalComponent.props?.query && !collections?.["database"]?.["execute"]) {
|
|
12504
|
+
logger.warn(`[DASH_COMP_REQ] Skipping query validation - database execute function not available`);
|
|
12505
|
+
}
|
|
12381
12506
|
if (parsedResult.props.query) {
|
|
12382
12507
|
logger.info(`[DASH_COMP_REQ] Data source: Database query`);
|
|
12383
12508
|
}
|
|
@@ -12487,12 +12612,14 @@ async function createFilterWithLLM(prompt, components, existingComponents, anthr
|
|
|
12487
12612
|
const result = jsonMatch ? JSON.parse(jsonMatch[0]) : null;
|
|
12488
12613
|
if (!result) {
|
|
12489
12614
|
errors.push("Failed to parse LLM response as JSON");
|
|
12615
|
+
errors.push(`LLM Response: ${rawResult}`);
|
|
12490
12616
|
return { success: false, errors };
|
|
12491
12617
|
}
|
|
12492
12618
|
logger.debug("[DASH_COMP_REQ:FILTER] LLM response received");
|
|
12493
12619
|
logger.file("[DASH_COMP_REQ:FILTER] LLM response:", JSON.stringify(result, null, 2));
|
|
12494
12620
|
if (!result.filterComponent) {
|
|
12495
12621
|
errors.push("Invalid LLM response: missing filterComponent");
|
|
12622
|
+
errors.push(`LLM Response: ${rawResult}`);
|
|
12496
12623
|
userPromptErrorLogger.logError("DASH_COMP_REQ:FILTER", "Invalid LLM response structure", {
|
|
12497
12624
|
prompt,
|
|
12498
12625
|
result,
|
|
@@ -12635,6 +12762,64 @@ async function handleDashCompRequest(data, components, sendMessage, anthropicApi
|
|
|
12635
12762
|
logger.info(`[DASH_COMP_REQ] Response sent to client ${response.wsId || data.from?.id}`);
|
|
12636
12763
|
}
|
|
12637
12764
|
|
|
12765
|
+
// src/handlers/schema-request.ts
|
|
12766
|
+
async function handleSchemaRequest(message, sendMessage) {
|
|
12767
|
+
const startTime = Date.now();
|
|
12768
|
+
try {
|
|
12769
|
+
const payload = message.payload;
|
|
12770
|
+
const formatted = payload?.formatted ?? false;
|
|
12771
|
+
logger.info(`[SchemaRequest] Processing schema request (formatted: ${formatted})`);
|
|
12772
|
+
const schemaData = schema.getSchema();
|
|
12773
|
+
if (!schemaData) {
|
|
12774
|
+
const response2 = {
|
|
12775
|
+
id: message.id,
|
|
12776
|
+
type: "SCHEMA_RES",
|
|
12777
|
+
from: { type: "data-agent" },
|
|
12778
|
+
to: message.from,
|
|
12779
|
+
payload: {
|
|
12780
|
+
success: false,
|
|
12781
|
+
error: "Schema not found or failed to load"
|
|
12782
|
+
}
|
|
12783
|
+
};
|
|
12784
|
+
sendMessage(response2);
|
|
12785
|
+
return;
|
|
12786
|
+
}
|
|
12787
|
+
const responseData = {
|
|
12788
|
+
schema: schemaData
|
|
12789
|
+
};
|
|
12790
|
+
if (formatted) {
|
|
12791
|
+
responseData.formatted = schema.generateSchemaDocumentation();
|
|
12792
|
+
}
|
|
12793
|
+
const executionMs = Date.now() - startTime;
|
|
12794
|
+
logger.info(`[SchemaRequest] Schema retrieved successfully in ${executionMs}ms`);
|
|
12795
|
+
const response = {
|
|
12796
|
+
id: message.id,
|
|
12797
|
+
type: "SCHEMA_RES",
|
|
12798
|
+
from: { type: "data-agent" },
|
|
12799
|
+
to: message.from,
|
|
12800
|
+
payload: {
|
|
12801
|
+
success: true,
|
|
12802
|
+
data: responseData
|
|
12803
|
+
}
|
|
12804
|
+
};
|
|
12805
|
+
sendMessage(response);
|
|
12806
|
+
} catch (error) {
|
|
12807
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
12808
|
+
logger.error(`[SchemaRequest] Error: ${errorMsg}`);
|
|
12809
|
+
const response = {
|
|
12810
|
+
id: message.id,
|
|
12811
|
+
type: "SCHEMA_RES",
|
|
12812
|
+
from: { type: "data-agent" },
|
|
12813
|
+
to: message.from,
|
|
12814
|
+
payload: {
|
|
12815
|
+
success: false,
|
|
12816
|
+
error: errorMsg
|
|
12817
|
+
}
|
|
12818
|
+
};
|
|
12819
|
+
sendMessage(response);
|
|
12820
|
+
}
|
|
12821
|
+
}
|
|
12822
|
+
|
|
12638
12823
|
// src/auth/user-manager.ts
|
|
12639
12824
|
var import_fs6 = __toESM(require("fs"));
|
|
12640
12825
|
var import_path5 = __toESM(require("path"));
|
|
@@ -13883,6 +14068,11 @@ var SuperatomSDK = class {
|
|
|
13883
14068
|
logger.error("Failed to handle dash comp request:", error);
|
|
13884
14069
|
});
|
|
13885
14070
|
break;
|
|
14071
|
+
case "SCHEMA_REQ":
|
|
14072
|
+
handleSchemaRequest(parsed, (msg) => this.send(msg)).catch((error) => {
|
|
14073
|
+
logger.error("Failed to handle schema request:", error);
|
|
14074
|
+
});
|
|
14075
|
+
break;
|
|
13886
14076
|
default:
|
|
13887
14077
|
const handler = this.messageTypeHandlers.get(message.type);
|
|
13888
14078
|
if (handler) {
|