@superatomai/sdk-node 0.0.10 → 0.0.11
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 +65 -106
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +65 -106
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -972,6 +972,7 @@ var Thread = class {
|
|
|
972
972
|
let assistantResponse = "";
|
|
973
973
|
const hasComponent = metadata && Object.keys(metadata).length > 0 && metadata.type;
|
|
974
974
|
const hasTextResponse = textResponse && textResponse.trim().length > 0;
|
|
975
|
+
const responseParts = [];
|
|
975
976
|
if (hasComponent) {
|
|
976
977
|
const parts = [];
|
|
977
978
|
if (metadata.type) {
|
|
@@ -980,21 +981,19 @@ var Thread = class {
|
|
|
980
981
|
if (metadata.name) {
|
|
981
982
|
parts.push(`Name: ${metadata.name}`);
|
|
982
983
|
}
|
|
983
|
-
if (metadata.
|
|
984
|
-
parts.push(`
|
|
984
|
+
if (metadata.description) {
|
|
985
|
+
parts.push(`Description: ${metadata.description}`);
|
|
985
986
|
}
|
|
986
|
-
if (metadata.props
|
|
987
|
-
|
|
988
|
-
const truncatedQuery = query.length > 200 ? query.substring(0, 200) + "..." : query;
|
|
989
|
-
parts.push(`Query: ${truncatedQuery}`);
|
|
987
|
+
if (metadata.props) {
|
|
988
|
+
parts.push(`Props: ${JSON.stringify(metadata.props)}`);
|
|
990
989
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
assistantResponse =
|
|
990
|
+
responseParts.push(parts.join("\n"));
|
|
991
|
+
}
|
|
992
|
+
if (hasTextResponse) {
|
|
993
|
+
responseParts.push(textResponse);
|
|
994
|
+
}
|
|
995
|
+
if (responseParts.length > 0) {
|
|
996
|
+
assistantResponse = responseParts.join("\n");
|
|
998
997
|
} else {
|
|
999
998
|
assistantResponse = "No response generated";
|
|
1000
999
|
}
|
|
@@ -2346,18 +2345,16 @@ Your job is to:
|
|
|
2346
2345
|
1. **Parse the component suggestions** from the text response (format: 1:component_type : reasoning)
|
|
2347
2346
|
2. **Match each suggestion with an actual component** from the available list
|
|
2348
2347
|
3. **Generate proper props** for each matched component to **visualize the analysis results** that were already fetched
|
|
2349
|
-
4. **
|
|
2348
|
+
4. **Generate title and description** for the dashboard container
|
|
2350
2349
|
5. **Generate intelligent follow-up questions (actions)** that the user might naturally ask next based on the data analysis
|
|
2351
2350
|
|
|
2352
2351
|
**CRITICAL GOAL**: Create dashboard components that display the **same data that was already analyzed** - NOT new data. The queries already ran and got results. You're just creating different visualizations of those results.
|
|
2353
2352
|
|
|
2354
|
-
**APPROACH**: First match all the components suggested in the text response, THEN find the layout that best fits those components.
|
|
2355
|
-
|
|
2356
2353
|
## Available Components
|
|
2357
2354
|
|
|
2358
2355
|
{{AVAILABLE_COMPONENTS}}
|
|
2359
2356
|
|
|
2360
|
-
## Component Matching Rules
|
|
2357
|
+
## Component Matching Rules
|
|
2361
2358
|
For each component suggestion (c1, c2, c3, etc.) from the text response:
|
|
2362
2359
|
|
|
2363
2360
|
1. **Match by type**: Find components whose \`type\` matches the suggested component type
|
|
@@ -2366,23 +2363,10 @@ For each component suggestion (c1, c2, c3, etc.) from the text response:
|
|
|
2366
2363
|
- Best fit for the data being visualized
|
|
2367
2364
|
3. **Fallback**: If no exact type match, find the closest alternative
|
|
2368
2365
|
|
|
2369
|
-
##
|
|
2370
|
-
|
|
2371
|
-
**
|
|
2372
|
-
|
|
2373
|
-
1. **Find layout components** by looking for components with \`type: "DashboardLayout"\` in the available components list
|
|
2374
|
-
2. **Read each layout's description** to understand:
|
|
2375
|
-
- What structure it provides
|
|
2376
|
-
- When it's best used (e.g., comprehensive analysis vs focused analysis)
|
|
2377
|
-
- The number and types of components it can accommodate
|
|
2378
|
-
3. **Select the best layout** based on:
|
|
2379
|
-
- Which layout can best display ALL the matched components
|
|
2380
|
-
- The layout's capacity (how many components it supports)
|
|
2381
|
-
- The types of matched components (KPI, charts, tables, etc.)
|
|
2382
|
-
- The user question and data complexity
|
|
2383
|
-
4. **If no specific layout fits**, fall back to "MultiComponentContainer" as the default layout
|
|
2384
|
-
|
|
2385
|
-
**IMPORTANT:** The layout should be chosen to FIT the matched components, not the other way around. Don't force components to fit a layout - find a layout that accommodates your components.
|
|
2366
|
+
## Dashboard Container
|
|
2367
|
+
All matched components will be placed in the default **MultiComponentContainer** layout. Your job is to:
|
|
2368
|
+
1. **Generate a clear title** for the dashboard that summarizes what it shows
|
|
2369
|
+
2. **Generate a brief description** explaining the dashboard's purpose and scope
|
|
2386
2370
|
|
|
2387
2371
|
## Props Generation Rules
|
|
2388
2372
|
|
|
@@ -2496,8 +2480,8 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
2496
2480
|
|
|
2497
2481
|
\`\`\`json
|
|
2498
2482
|
{
|
|
2499
|
-
"
|
|
2500
|
-
"
|
|
2483
|
+
"layoutTitle": "Clear, concise title for the overall dashboard/layout (5-10 words)",
|
|
2484
|
+
"layoutDescription": "Brief description of what the dashboard shows and its purpose (1-2 sentences)",
|
|
2501
2485
|
"matchedComponents": [
|
|
2502
2486
|
{
|
|
2503
2487
|
"componentId": "id_from_available_list",
|
|
@@ -2527,17 +2511,14 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
2527
2511
|
\`\`\`
|
|
2528
2512
|
|
|
2529
2513
|
**CRITICAL:**
|
|
2530
|
-
- \`matchedComponents\` MUST include ALL components suggested in the text response
|
|
2531
|
-
- \`
|
|
2532
|
-
-
|
|
2533
|
-
|
|
2534
|
-
-
|
|
2535
|
-
- Why this layout is the best fit for displaying these specific matched components
|
|
2536
|
-
- What makes this layout appropriate for the component types and count
|
|
2537
|
-
- The layout selection happens AFTER component matching - don't force components to fit a pre-selected layout
|
|
2514
|
+
- \`matchedComponents\` MUST include ALL components suggested in the text response
|
|
2515
|
+
- \`layoutTitle\` MUST be a clear, concise title (5-10 words) that summarizes what the entire dashboard shows
|
|
2516
|
+
- Examples: "Sales Performance Overview", "Customer Metrics Analysis", "Product Category Breakdown"
|
|
2517
|
+
- \`layoutDescription\` MUST be a brief description (1-2 sentences) explaining the purpose and scope of the dashboard
|
|
2518
|
+
- Should describe what insights the dashboard provides and what data it shows
|
|
2538
2519
|
- \`actions\` MUST be an array of 4-5 intelligent follow-up questions based on the analysis
|
|
2539
2520
|
- Return ONLY valid JSON (no markdown code blocks, no text before/after)
|
|
2540
|
-
- Generate complete props for each component
|
|
2521
|
+
- Generate complete props for each component including query, title, description, and config
|
|
2541
2522
|
|
|
2542
2523
|
|
|
2543
2524
|
`,
|
|
@@ -3633,12 +3614,13 @@ var BaseLLM = class {
|
|
|
3633
3614
|
/**
|
|
3634
3615
|
* Match components from text response suggestions and generate follow-up questions
|
|
3635
3616
|
* Takes a text response with component suggestions (c1:type format) and matches with available components
|
|
3636
|
-
* Also generates intelligent follow-up questions (actions) based on the analysis
|
|
3617
|
+
* Also generates title, description, and intelligent follow-up questions (actions) based on the analysis
|
|
3618
|
+
* All components are placed in a default MultiComponentContainer layout
|
|
3637
3619
|
* @param textResponse - The text response containing component suggestions
|
|
3638
3620
|
* @param components - List of available components
|
|
3639
3621
|
* @param apiKey - Optional API key
|
|
3640
3622
|
* @param logCollector - Optional log collector
|
|
3641
|
-
* @returns Object containing matched components,
|
|
3623
|
+
* @returns Object containing matched components, layout title/description, and follow-up actions
|
|
3642
3624
|
*/
|
|
3643
3625
|
async matchComponentsFromTextResponse(textResponse, components, apiKey, logCollector) {
|
|
3644
3626
|
try {
|
|
@@ -3681,24 +3663,17 @@ var BaseLLM = class {
|
|
|
3681
3663
|
);
|
|
3682
3664
|
logger.debug(`[${this.getProviderName()}] Component matching response parsed successfully`);
|
|
3683
3665
|
const matchedComponents = result.matchedComponents || [];
|
|
3684
|
-
const
|
|
3685
|
-
const
|
|
3666
|
+
const layoutTitle = result.layoutTitle || "Dashboard";
|
|
3667
|
+
const layoutDescription = result.layoutDescription || "Multi-component dashboard";
|
|
3686
3668
|
const rawActions = result.actions || [];
|
|
3687
3669
|
const actions = convertQuestionsToActions(rawActions);
|
|
3688
|
-
let selectedLayoutComponent = null;
|
|
3689
|
-
if (selectedLayoutId) {
|
|
3690
|
-
selectedLayoutComponent = components.find((c) => c.id === selectedLayoutId) || null;
|
|
3691
|
-
if (!selectedLayoutComponent) {
|
|
3692
|
-
logger.warn(`[${this.getProviderName()}] Layout component ${selectedLayoutId} not found in available components`);
|
|
3693
|
-
}
|
|
3694
|
-
}
|
|
3695
3670
|
logger.info(`[${this.getProviderName()}] Matched ${matchedComponents.length} components from text response`);
|
|
3696
|
-
logger.info(`[${this.getProviderName()}]
|
|
3697
|
-
logger.info(`[${this.getProviderName()}] Layout
|
|
3671
|
+
logger.info(`[${this.getProviderName()}] Layout title: "${layoutTitle}"`);
|
|
3672
|
+
logger.info(`[${this.getProviderName()}] Layout description: "${layoutDescription}"`);
|
|
3698
3673
|
logger.info(`[${this.getProviderName()}] Generated ${actions.length} follow-up actions`);
|
|
3699
3674
|
if (matchedComponents.length > 0) {
|
|
3700
|
-
logCollector?.info(`Matched ${matchedComponents.length} components for visualization
|
|
3701
|
-
logCollector?.info(`
|
|
3675
|
+
logCollector?.info(`Matched ${matchedComponents.length} components for visualization`);
|
|
3676
|
+
logCollector?.info(`Dashboard: "${layoutTitle}"`);
|
|
3702
3677
|
matchedComponents.forEach((comp, idx) => {
|
|
3703
3678
|
logCollector?.info(` ${idx + 1}. ${comp.componentName} (${comp.componentType}): ${comp.reasoning}`);
|
|
3704
3679
|
if (comp.props?.query) {
|
|
@@ -3732,9 +3707,8 @@ var BaseLLM = class {
|
|
|
3732
3707
|
}).filter(Boolean);
|
|
3733
3708
|
return {
|
|
3734
3709
|
components: finalComponents,
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
layoutReasoning,
|
|
3710
|
+
layoutTitle,
|
|
3711
|
+
layoutDescription,
|
|
3738
3712
|
actions
|
|
3739
3713
|
};
|
|
3740
3714
|
} catch (error) {
|
|
@@ -3743,9 +3717,8 @@ var BaseLLM = class {
|
|
|
3743
3717
|
logCollector?.error(`Failed to match components: ${errorMsg}`);
|
|
3744
3718
|
return {
|
|
3745
3719
|
components: [],
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
layoutReasoning: "Failed to match components due to parsing error",
|
|
3720
|
+
layoutTitle: "Dashboard",
|
|
3721
|
+
layoutDescription: "Failed to generate dashboard",
|
|
3749
3722
|
actions: []
|
|
3750
3723
|
};
|
|
3751
3724
|
}
|
|
@@ -3989,9 +3962,12 @@ ${errorMsg}
|
|
|
3989
3962
|
textLength: textResponse.length
|
|
3990
3963
|
}
|
|
3991
3964
|
);
|
|
3965
|
+
if (wrappedStreamCallback && components && components.length > 0) {
|
|
3966
|
+
wrappedStreamCallback("__TEXT_COMPLETE__COMPONENT_GENERATION_START__");
|
|
3967
|
+
}
|
|
3992
3968
|
let matchedComponents = [];
|
|
3993
|
-
let
|
|
3994
|
-
let
|
|
3969
|
+
let layoutTitle = "Dashboard";
|
|
3970
|
+
let layoutDescription = "Multi-component dashboard";
|
|
3995
3971
|
let actions = [];
|
|
3996
3972
|
if (components && components.length > 0) {
|
|
3997
3973
|
logger.info(`[${this.getProviderName()}] Matching components from text response...`);
|
|
@@ -4002,46 +3978,30 @@ ${errorMsg}
|
|
|
4002
3978
|
logCollector
|
|
4003
3979
|
);
|
|
4004
3980
|
matchedComponents = matchResult.components;
|
|
4005
|
-
|
|
4006
|
-
|
|
3981
|
+
layoutTitle = matchResult.layoutTitle;
|
|
3982
|
+
layoutDescription = matchResult.layoutDescription;
|
|
4007
3983
|
actions = matchResult.actions;
|
|
4008
3984
|
}
|
|
4009
3985
|
let container_componet = null;
|
|
4010
3986
|
if (matchedComponents.length > 0) {
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
}
|
|
4024
|
-
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
}
|
|
4028
|
-
|
|
4029
|
-
id: `multi_container_${Date.now()}`,
|
|
4030
|
-
name: "MultiComponentContainer",
|
|
4031
|
-
type: "Container",
|
|
4032
|
-
description: layoutReasoning,
|
|
4033
|
-
category: "dynamic",
|
|
4034
|
-
keywords: ["dashboard", "layout", "container"],
|
|
4035
|
-
props: {
|
|
4036
|
-
config: {
|
|
4037
|
-
components: matchedComponents
|
|
4038
|
-
},
|
|
4039
|
-
actions
|
|
4040
|
-
}
|
|
4041
|
-
};
|
|
4042
|
-
logger.info(`[${this.getProviderName()}] Created fallback MultiComponentContainer with ${matchedComponents.length} components and ${actions.length} actions`);
|
|
4043
|
-
logCollector?.info(`Created MultiComponentContainer with ${matchedComponents.length} components and ${actions.length} actions: ${layoutReasoning}`);
|
|
4044
|
-
}
|
|
3987
|
+
container_componet = {
|
|
3988
|
+
id: `multi_container_${Date.now()}`,
|
|
3989
|
+
name: "MultiComponentContainer",
|
|
3990
|
+
type: "Container",
|
|
3991
|
+
description: layoutDescription,
|
|
3992
|
+
category: "dynamic",
|
|
3993
|
+
keywords: ["dashboard", "layout", "container"],
|
|
3994
|
+
props: {
|
|
3995
|
+
config: {
|
|
3996
|
+
components: matchedComponents,
|
|
3997
|
+
title: layoutTitle,
|
|
3998
|
+
description: layoutDescription
|
|
3999
|
+
},
|
|
4000
|
+
actions
|
|
4001
|
+
}
|
|
4002
|
+
};
|
|
4003
|
+
logger.info(`[${this.getProviderName()}] Created MultiComponentContainer: "${layoutTitle}" with ${matchedComponents.length} components and ${actions.length} actions`);
|
|
4004
|
+
logCollector?.info(`Created dashboard: "${layoutTitle}" with ${matchedComponents.length} components and ${actions.length} actions`);
|
|
4045
4005
|
}
|
|
4046
4006
|
return {
|
|
4047
4007
|
success: true,
|
|
@@ -4049,7 +4009,6 @@ ${errorMsg}
|
|
|
4049
4009
|
text: textResponse,
|
|
4050
4010
|
matchedComponents,
|
|
4051
4011
|
component: container_componet,
|
|
4052
|
-
layoutReasoning,
|
|
4053
4012
|
actions,
|
|
4054
4013
|
method: `${this.getProviderName()}-text-response`
|
|
4055
4014
|
},
|
|
@@ -4715,7 +4674,7 @@ var CONTEXT_CONFIG = {
|
|
|
4715
4674
|
* Set to 0 to disable conversation history
|
|
4716
4675
|
* Higher values provide more context but may increase token usage
|
|
4717
4676
|
*/
|
|
4718
|
-
MAX_CONVERSATION_CONTEXT_BLOCKS:
|
|
4677
|
+
MAX_CONVERSATION_CONTEXT_BLOCKS: 3
|
|
4719
4678
|
};
|
|
4720
4679
|
|
|
4721
4680
|
// src/handlers/user-prompt-request.ts
|