@superatomai/sdk-node 0.0.76 → 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/dist/index.js +209 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +209 -8
- 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
|
|
@@ -4297,13 +4359,13 @@ var PRICING = {
|
|
|
4297
4359
|
"gpt-4-turbo": { input: 10, output: 30 },
|
|
4298
4360
|
"gpt-4": { input: 30, output: 60 },
|
|
4299
4361
|
"gpt-3.5-turbo": { input: 0.5, output: 1.5 },
|
|
4300
|
-
// Google Gemini (
|
|
4362
|
+
// Google Gemini (January 2026)
|
|
4301
4363
|
"gemini-3-pro-preview": { input: 2, output: 12 },
|
|
4302
4364
|
// New Gemini 3
|
|
4303
4365
|
"gemini-3-flash-preview": { input: 0.5, output: 3 },
|
|
4304
4366
|
// For prompts ≤200K tokens, 2x for >200K
|
|
4305
|
-
"gemini-2.5-flash": { input: 0.
|
|
4306
|
-
//
|
|
4367
|
+
"gemini-2.5-flash": { input: 0.3, output: 2.5 },
|
|
4368
|
+
// Paid tier: $0.30 input (text/image/video), $2.50 output (includes thinking)
|
|
4307
4369
|
"gemini-2.5-flash-lite": { input: 0.1, output: 0.4 },
|
|
4308
4370
|
"gemini-2.0-flash": { input: 0.1, output: 0.4 },
|
|
4309
4371
|
"gemini-2.0-flash-lite": { input: 0.075, output: 0.3 },
|
|
@@ -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;
|
|
@@ -7272,8 +7335,15 @@ Please try rephrasing your request or contact support.
|
|
|
7272
7335
|
}
|
|
7273
7336
|
await streamDelay();
|
|
7274
7337
|
}
|
|
7338
|
+
const cappedToolInput = { ...toolInput };
|
|
7339
|
+
if (cappedToolInput.limit !== void 0 && cappedToolInput.limit > MAX_COMPONENT_QUERY_LIMIT) {
|
|
7340
|
+
logger.info(`[${providerName}] Capping external tool limit from ${cappedToolInput.limit} to ${MAX_COMPONENT_QUERY_LIMIT}`);
|
|
7341
|
+
cappedToolInput.limit = MAX_COMPONENT_QUERY_LIMIT;
|
|
7342
|
+
} else if (cappedToolInput.limit === void 0) {
|
|
7343
|
+
cappedToolInput.limit = MAX_COMPONENT_QUERY_LIMIT;
|
|
7344
|
+
}
|
|
7275
7345
|
const result = await withProgressHeartbeat(
|
|
7276
|
-
() => externalTool.fn(
|
|
7346
|
+
() => externalTool.fn(cappedToolInput),
|
|
7277
7347
|
`Running ${externalTool.name}`,
|
|
7278
7348
|
streamBuffer
|
|
7279
7349
|
);
|
|
@@ -7287,7 +7357,7 @@ Please try rephrasing your request or contact support.
|
|
|
7287
7357
|
this.executedToolsList.push({
|
|
7288
7358
|
id: externalTool.id,
|
|
7289
7359
|
name: externalTool.name,
|
|
7290
|
-
params:
|
|
7360
|
+
params: cappedToolInput,
|
|
7291
7361
|
result: {
|
|
7292
7362
|
_totalRecords: formattedForTracking.summary.totalRecords,
|
|
7293
7363
|
_recordsShown: formattedForTracking.summary.recordsShown,
|
|
@@ -8162,8 +8232,12 @@ ${executedToolsText}`);
|
|
|
8162
8232
|
if (deferredTools.length > 0) {
|
|
8163
8233
|
logger.info(`[${this.getProviderName()}] Passing ${deferredTools.length} deferred tools for Form generation`);
|
|
8164
8234
|
}
|
|
8235
|
+
const sanitizedTextResponse = textResponse.replace(
|
|
8236
|
+
/<DataTable>[\s\S]*?<\/DataTable>/g,
|
|
8237
|
+
"<DataTable>[Data preview removed - for table components, REUSE the exact SQL query shown above (the one that returned these results). Do NOT write a new query or embed data in props.]</DataTable>"
|
|
8238
|
+
);
|
|
8165
8239
|
const matchResult = await this.matchComponentsFromAnalysis(
|
|
8166
|
-
|
|
8240
|
+
sanitizedTextResponse,
|
|
8167
8241
|
components,
|
|
8168
8242
|
userPrompt,
|
|
8169
8243
|
apiKey,
|
|
@@ -12212,6 +12286,7 @@ function formatComponentsForPrompt(components) {
|
|
|
12212
12286
|
if (!components || components.length === 0) {
|
|
12213
12287
|
return "No components available";
|
|
12214
12288
|
}
|
|
12289
|
+
components = components.filter((c) => c.name !== "MultiComponentContainer");
|
|
12215
12290
|
return components.map((comp, idx) => {
|
|
12216
12291
|
const keywords = comp.keywords ? comp.keywords.join(", ") : "";
|
|
12217
12292
|
const propsPreview = comp.props ? JSON.stringify(comp.props, null, 2) : "No props";
|
|
@@ -12258,7 +12333,7 @@ function sendDashCompResponse(id, res, sendMessage, clientId) {
|
|
|
12258
12333
|
}
|
|
12259
12334
|
|
|
12260
12335
|
// src/dashComp/pick-component.ts
|
|
12261
|
-
async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders,
|
|
12336
|
+
async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApiKey, geminiApiKey, openaiApiKey, llmProviders, collections, tools, dashCompModels) {
|
|
12262
12337
|
const errors = [];
|
|
12263
12338
|
const availableComponentsText = formatComponentsForPrompt(components);
|
|
12264
12339
|
const availableToolsText = formatToolsForPrompt(tools);
|
|
@@ -12336,12 +12411,14 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
|
|
|
12336
12411
|
const parsedResult = jsonMatch ? JSON.parse(jsonMatch[0]) : null;
|
|
12337
12412
|
if (!parsedResult) {
|
|
12338
12413
|
errors.push("Failed to parse LLM response as JSON");
|
|
12414
|
+
errors.push(`LLM Response: ${result}`);
|
|
12339
12415
|
return { success: false, errors };
|
|
12340
12416
|
}
|
|
12341
12417
|
logger.debug("[DASH_COMP_REQ] LLM response received");
|
|
12342
12418
|
logger.file("[DASH_COMP_REQ] LLM response:", JSON.stringify(parsedResult, null, 2));
|
|
12343
12419
|
if (!parsedResult.componentId || !parsedResult.props) {
|
|
12344
12420
|
errors.push("Invalid LLM response: missing componentId or props");
|
|
12421
|
+
errors.push(`LLM Response: ${result}`);
|
|
12345
12422
|
userPromptErrorLogger.logError("DASH_COMP_REQ", "Invalid LLM response structure", {
|
|
12346
12423
|
prompt,
|
|
12347
12424
|
result: parsedResult,
|
|
@@ -12352,6 +12429,7 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
|
|
|
12352
12429
|
const originalComponent = components.find((c) => c.name === parsedResult.componentName);
|
|
12353
12430
|
if (!originalComponent) {
|
|
12354
12431
|
errors.push(`Component ${parsedResult.componentName} not found in available components`);
|
|
12432
|
+
errors.push(`LLM Response: ${result}`);
|
|
12355
12433
|
userPromptErrorLogger.logError("DASH_COMP_REQ", "Component not found", {
|
|
12356
12434
|
prompt,
|
|
12357
12435
|
componentName: parsedResult.componentName,
|
|
@@ -12359,14 +12437,72 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
|
|
|
12359
12437
|
});
|
|
12360
12438
|
return { success: false, errors };
|
|
12361
12439
|
}
|
|
12362
|
-
|
|
12440
|
+
let finalComponent = {
|
|
12363
12441
|
...originalComponent,
|
|
12364
12442
|
props: {
|
|
12365
12443
|
...originalComponent.props,
|
|
12366
12444
|
...parsedResult.props
|
|
12367
12445
|
}
|
|
12368
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
|
+
}
|
|
12369
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
|
+
}
|
|
12370
12506
|
if (parsedResult.props.query) {
|
|
12371
12507
|
logger.info(`[DASH_COMP_REQ] Data source: Database query`);
|
|
12372
12508
|
}
|
|
@@ -12476,12 +12612,14 @@ async function createFilterWithLLM(prompt, components, existingComponents, anthr
|
|
|
12476
12612
|
const result = jsonMatch ? JSON.parse(jsonMatch[0]) : null;
|
|
12477
12613
|
if (!result) {
|
|
12478
12614
|
errors.push("Failed to parse LLM response as JSON");
|
|
12615
|
+
errors.push(`LLM Response: ${rawResult}`);
|
|
12479
12616
|
return { success: false, errors };
|
|
12480
12617
|
}
|
|
12481
12618
|
logger.debug("[DASH_COMP_REQ:FILTER] LLM response received");
|
|
12482
12619
|
logger.file("[DASH_COMP_REQ:FILTER] LLM response:", JSON.stringify(result, null, 2));
|
|
12483
12620
|
if (!result.filterComponent) {
|
|
12484
12621
|
errors.push("Invalid LLM response: missing filterComponent");
|
|
12622
|
+
errors.push(`LLM Response: ${rawResult}`);
|
|
12485
12623
|
userPromptErrorLogger.logError("DASH_COMP_REQ:FILTER", "Invalid LLM response structure", {
|
|
12486
12624
|
prompt,
|
|
12487
12625
|
result,
|
|
@@ -12624,6 +12762,64 @@ async function handleDashCompRequest(data, components, sendMessage, anthropicApi
|
|
|
12624
12762
|
logger.info(`[DASH_COMP_REQ] Response sent to client ${response.wsId || data.from?.id}`);
|
|
12625
12763
|
}
|
|
12626
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
|
+
|
|
12627
12823
|
// src/auth/user-manager.ts
|
|
12628
12824
|
var import_fs6 = __toESM(require("fs"));
|
|
12629
12825
|
var import_path5 = __toESM(require("path"));
|
|
@@ -13872,6 +14068,11 @@ var SuperatomSDK = class {
|
|
|
13872
14068
|
logger.error("Failed to handle dash comp request:", error);
|
|
13873
14069
|
});
|
|
13874
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;
|
|
13875
14076
|
default:
|
|
13876
14077
|
const handler = this.messageTypeHandlers.get(message.type);
|
|
13877
14078
|
if (handler) {
|