@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.js
CHANGED
|
@@ -1012,6 +1012,7 @@ var Thread = class {
|
|
|
1012
1012
|
let assistantResponse = "";
|
|
1013
1013
|
const hasComponent = metadata && Object.keys(metadata).length > 0 && metadata.type;
|
|
1014
1014
|
const hasTextResponse = textResponse && textResponse.trim().length > 0;
|
|
1015
|
+
const responseParts = [];
|
|
1015
1016
|
if (hasComponent) {
|
|
1016
1017
|
const parts = [];
|
|
1017
1018
|
if (metadata.type) {
|
|
@@ -1020,21 +1021,19 @@ var Thread = class {
|
|
|
1020
1021
|
if (metadata.name) {
|
|
1021
1022
|
parts.push(`Name: ${metadata.name}`);
|
|
1022
1023
|
}
|
|
1023
|
-
if (metadata.
|
|
1024
|
-
parts.push(`
|
|
1024
|
+
if (metadata.description) {
|
|
1025
|
+
parts.push(`Description: ${metadata.description}`);
|
|
1025
1026
|
}
|
|
1026
|
-
if (metadata.props
|
|
1027
|
-
|
|
1028
|
-
const truncatedQuery = query.length > 200 ? query.substring(0, 200) + "..." : query;
|
|
1029
|
-
parts.push(`Query: ${truncatedQuery}`);
|
|
1027
|
+
if (metadata.props) {
|
|
1028
|
+
parts.push(`Props: ${JSON.stringify(metadata.props)}`);
|
|
1030
1029
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
assistantResponse =
|
|
1030
|
+
responseParts.push(parts.join("\n"));
|
|
1031
|
+
}
|
|
1032
|
+
if (hasTextResponse) {
|
|
1033
|
+
responseParts.push(textResponse);
|
|
1034
|
+
}
|
|
1035
|
+
if (responseParts.length > 0) {
|
|
1036
|
+
assistantResponse = responseParts.join("\n");
|
|
1038
1037
|
} else {
|
|
1039
1038
|
assistantResponse = "No response generated";
|
|
1040
1039
|
}
|
|
@@ -2386,18 +2385,16 @@ Your job is to:
|
|
|
2386
2385
|
1. **Parse the component suggestions** from the text response (format: 1:component_type : reasoning)
|
|
2387
2386
|
2. **Match each suggestion with an actual component** from the available list
|
|
2388
2387
|
3. **Generate proper props** for each matched component to **visualize the analysis results** that were already fetched
|
|
2389
|
-
4. **
|
|
2388
|
+
4. **Generate title and description** for the dashboard container
|
|
2390
2389
|
5. **Generate intelligent follow-up questions (actions)** that the user might naturally ask next based on the data analysis
|
|
2391
2390
|
|
|
2392
2391
|
**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.
|
|
2393
2392
|
|
|
2394
|
-
**APPROACH**: First match all the components suggested in the text response, THEN find the layout that best fits those components.
|
|
2395
|
-
|
|
2396
2393
|
## Available Components
|
|
2397
2394
|
|
|
2398
2395
|
{{AVAILABLE_COMPONENTS}}
|
|
2399
2396
|
|
|
2400
|
-
## Component Matching Rules
|
|
2397
|
+
## Component Matching Rules
|
|
2401
2398
|
For each component suggestion (c1, c2, c3, etc.) from the text response:
|
|
2402
2399
|
|
|
2403
2400
|
1. **Match by type**: Find components whose \`type\` matches the suggested component type
|
|
@@ -2406,23 +2403,10 @@ For each component suggestion (c1, c2, c3, etc.) from the text response:
|
|
|
2406
2403
|
- Best fit for the data being visualized
|
|
2407
2404
|
3. **Fallback**: If no exact type match, find the closest alternative
|
|
2408
2405
|
|
|
2409
|
-
##
|
|
2410
|
-
|
|
2411
|
-
**
|
|
2412
|
-
|
|
2413
|
-
1. **Find layout components** by looking for components with \`type: "DashboardLayout"\` in the available components list
|
|
2414
|
-
2. **Read each layout's description** to understand:
|
|
2415
|
-
- What structure it provides
|
|
2416
|
-
- When it's best used (e.g., comprehensive analysis vs focused analysis)
|
|
2417
|
-
- The number and types of components it can accommodate
|
|
2418
|
-
3. **Select the best layout** based on:
|
|
2419
|
-
- Which layout can best display ALL the matched components
|
|
2420
|
-
- The layout's capacity (how many components it supports)
|
|
2421
|
-
- The types of matched components (KPI, charts, tables, etc.)
|
|
2422
|
-
- The user question and data complexity
|
|
2423
|
-
4. **If no specific layout fits**, fall back to "MultiComponentContainer" as the default layout
|
|
2424
|
-
|
|
2425
|
-
**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.
|
|
2406
|
+
## Dashboard Container
|
|
2407
|
+
All matched components will be placed in the default **MultiComponentContainer** layout. Your job is to:
|
|
2408
|
+
1. **Generate a clear title** for the dashboard that summarizes what it shows
|
|
2409
|
+
2. **Generate a brief description** explaining the dashboard's purpose and scope
|
|
2426
2410
|
|
|
2427
2411
|
## Props Generation Rules
|
|
2428
2412
|
|
|
@@ -2536,8 +2520,8 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
2536
2520
|
|
|
2537
2521
|
\`\`\`json
|
|
2538
2522
|
{
|
|
2539
|
-
"
|
|
2540
|
-
"
|
|
2523
|
+
"layoutTitle": "Clear, concise title for the overall dashboard/layout (5-10 words)",
|
|
2524
|
+
"layoutDescription": "Brief description of what the dashboard shows and its purpose (1-2 sentences)",
|
|
2541
2525
|
"matchedComponents": [
|
|
2542
2526
|
{
|
|
2543
2527
|
"componentId": "id_from_available_list",
|
|
@@ -2567,17 +2551,14 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
2567
2551
|
\`\`\`
|
|
2568
2552
|
|
|
2569
2553
|
**CRITICAL:**
|
|
2570
|
-
- \`matchedComponents\` MUST include ALL components suggested in the text response
|
|
2571
|
-
- \`
|
|
2572
|
-
-
|
|
2573
|
-
|
|
2574
|
-
-
|
|
2575
|
-
- Why this layout is the best fit for displaying these specific matched components
|
|
2576
|
-
- What makes this layout appropriate for the component types and count
|
|
2577
|
-
- The layout selection happens AFTER component matching - don't force components to fit a pre-selected layout
|
|
2554
|
+
- \`matchedComponents\` MUST include ALL components suggested in the text response
|
|
2555
|
+
- \`layoutTitle\` MUST be a clear, concise title (5-10 words) that summarizes what the entire dashboard shows
|
|
2556
|
+
- Examples: "Sales Performance Overview", "Customer Metrics Analysis", "Product Category Breakdown"
|
|
2557
|
+
- \`layoutDescription\` MUST be a brief description (1-2 sentences) explaining the purpose and scope of the dashboard
|
|
2558
|
+
- Should describe what insights the dashboard provides and what data it shows
|
|
2578
2559
|
- \`actions\` MUST be an array of 4-5 intelligent follow-up questions based on the analysis
|
|
2579
2560
|
- Return ONLY valid JSON (no markdown code blocks, no text before/after)
|
|
2580
|
-
- Generate complete props for each component
|
|
2561
|
+
- Generate complete props for each component including query, title, description, and config
|
|
2581
2562
|
|
|
2582
2563
|
|
|
2583
2564
|
`,
|
|
@@ -3673,12 +3654,13 @@ var BaseLLM = class {
|
|
|
3673
3654
|
/**
|
|
3674
3655
|
* Match components from text response suggestions and generate follow-up questions
|
|
3675
3656
|
* Takes a text response with component suggestions (c1:type format) and matches with available components
|
|
3676
|
-
* Also generates intelligent follow-up questions (actions) based on the analysis
|
|
3657
|
+
* Also generates title, description, and intelligent follow-up questions (actions) based on the analysis
|
|
3658
|
+
* All components are placed in a default MultiComponentContainer layout
|
|
3677
3659
|
* @param textResponse - The text response containing component suggestions
|
|
3678
3660
|
* @param components - List of available components
|
|
3679
3661
|
* @param apiKey - Optional API key
|
|
3680
3662
|
* @param logCollector - Optional log collector
|
|
3681
|
-
* @returns Object containing matched components,
|
|
3663
|
+
* @returns Object containing matched components, layout title/description, and follow-up actions
|
|
3682
3664
|
*/
|
|
3683
3665
|
async matchComponentsFromTextResponse(textResponse, components, apiKey, logCollector) {
|
|
3684
3666
|
try {
|
|
@@ -3721,24 +3703,17 @@ var BaseLLM = class {
|
|
|
3721
3703
|
);
|
|
3722
3704
|
logger.debug(`[${this.getProviderName()}] Component matching response parsed successfully`);
|
|
3723
3705
|
const matchedComponents = result.matchedComponents || [];
|
|
3724
|
-
const
|
|
3725
|
-
const
|
|
3706
|
+
const layoutTitle = result.layoutTitle || "Dashboard";
|
|
3707
|
+
const layoutDescription = result.layoutDescription || "Multi-component dashboard";
|
|
3726
3708
|
const rawActions = result.actions || [];
|
|
3727
3709
|
const actions = convertQuestionsToActions(rawActions);
|
|
3728
|
-
let selectedLayoutComponent = null;
|
|
3729
|
-
if (selectedLayoutId) {
|
|
3730
|
-
selectedLayoutComponent = components.find((c) => c.id === selectedLayoutId) || null;
|
|
3731
|
-
if (!selectedLayoutComponent) {
|
|
3732
|
-
logger.warn(`[${this.getProviderName()}] Layout component ${selectedLayoutId} not found in available components`);
|
|
3733
|
-
}
|
|
3734
|
-
}
|
|
3735
3710
|
logger.info(`[${this.getProviderName()}] Matched ${matchedComponents.length} components from text response`);
|
|
3736
|
-
logger.info(`[${this.getProviderName()}]
|
|
3737
|
-
logger.info(`[${this.getProviderName()}] Layout
|
|
3711
|
+
logger.info(`[${this.getProviderName()}] Layout title: "${layoutTitle}"`);
|
|
3712
|
+
logger.info(`[${this.getProviderName()}] Layout description: "${layoutDescription}"`);
|
|
3738
3713
|
logger.info(`[${this.getProviderName()}] Generated ${actions.length} follow-up actions`);
|
|
3739
3714
|
if (matchedComponents.length > 0) {
|
|
3740
|
-
logCollector?.info(`Matched ${matchedComponents.length} components for visualization
|
|
3741
|
-
logCollector?.info(`
|
|
3715
|
+
logCollector?.info(`Matched ${matchedComponents.length} components for visualization`);
|
|
3716
|
+
logCollector?.info(`Dashboard: "${layoutTitle}"`);
|
|
3742
3717
|
matchedComponents.forEach((comp, idx) => {
|
|
3743
3718
|
logCollector?.info(` ${idx + 1}. ${comp.componentName} (${comp.componentType}): ${comp.reasoning}`);
|
|
3744
3719
|
if (comp.props?.query) {
|
|
@@ -3772,9 +3747,8 @@ var BaseLLM = class {
|
|
|
3772
3747
|
}).filter(Boolean);
|
|
3773
3748
|
return {
|
|
3774
3749
|
components: finalComponents,
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
layoutReasoning,
|
|
3750
|
+
layoutTitle,
|
|
3751
|
+
layoutDescription,
|
|
3778
3752
|
actions
|
|
3779
3753
|
};
|
|
3780
3754
|
} catch (error) {
|
|
@@ -3783,9 +3757,8 @@ var BaseLLM = class {
|
|
|
3783
3757
|
logCollector?.error(`Failed to match components: ${errorMsg}`);
|
|
3784
3758
|
return {
|
|
3785
3759
|
components: [],
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
layoutReasoning: "Failed to match components due to parsing error",
|
|
3760
|
+
layoutTitle: "Dashboard",
|
|
3761
|
+
layoutDescription: "Failed to generate dashboard",
|
|
3789
3762
|
actions: []
|
|
3790
3763
|
};
|
|
3791
3764
|
}
|
|
@@ -4029,9 +4002,12 @@ ${errorMsg}
|
|
|
4029
4002
|
textLength: textResponse.length
|
|
4030
4003
|
}
|
|
4031
4004
|
);
|
|
4005
|
+
if (wrappedStreamCallback && components && components.length > 0) {
|
|
4006
|
+
wrappedStreamCallback("__TEXT_COMPLETE__COMPONENT_GENERATION_START__");
|
|
4007
|
+
}
|
|
4032
4008
|
let matchedComponents = [];
|
|
4033
|
-
let
|
|
4034
|
-
let
|
|
4009
|
+
let layoutTitle = "Dashboard";
|
|
4010
|
+
let layoutDescription = "Multi-component dashboard";
|
|
4035
4011
|
let actions = [];
|
|
4036
4012
|
if (components && components.length > 0) {
|
|
4037
4013
|
logger.info(`[${this.getProviderName()}] Matching components from text response...`);
|
|
@@ -4042,46 +4018,30 @@ ${errorMsg}
|
|
|
4042
4018
|
logCollector
|
|
4043
4019
|
);
|
|
4044
4020
|
matchedComponents = matchResult.components;
|
|
4045
|
-
|
|
4046
|
-
|
|
4021
|
+
layoutTitle = matchResult.layoutTitle;
|
|
4022
|
+
layoutDescription = matchResult.layoutDescription;
|
|
4047
4023
|
actions = matchResult.actions;
|
|
4048
4024
|
}
|
|
4049
4025
|
let container_componet = null;
|
|
4050
4026
|
if (matchedComponents.length > 0) {
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
}
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
}
|
|
4068
|
-
|
|
4069
|
-
id: `multi_container_${Date.now()}`,
|
|
4070
|
-
name: "MultiComponentContainer",
|
|
4071
|
-
type: "Container",
|
|
4072
|
-
description: layoutReasoning,
|
|
4073
|
-
category: "dynamic",
|
|
4074
|
-
keywords: ["dashboard", "layout", "container"],
|
|
4075
|
-
props: {
|
|
4076
|
-
config: {
|
|
4077
|
-
components: matchedComponents
|
|
4078
|
-
},
|
|
4079
|
-
actions
|
|
4080
|
-
}
|
|
4081
|
-
};
|
|
4082
|
-
logger.info(`[${this.getProviderName()}] Created fallback MultiComponentContainer with ${matchedComponents.length} components and ${actions.length} actions`);
|
|
4083
|
-
logCollector?.info(`Created MultiComponentContainer with ${matchedComponents.length} components and ${actions.length} actions: ${layoutReasoning}`);
|
|
4084
|
-
}
|
|
4027
|
+
container_componet = {
|
|
4028
|
+
id: `multi_container_${Date.now()}`,
|
|
4029
|
+
name: "MultiComponentContainer",
|
|
4030
|
+
type: "Container",
|
|
4031
|
+
description: layoutDescription,
|
|
4032
|
+
category: "dynamic",
|
|
4033
|
+
keywords: ["dashboard", "layout", "container"],
|
|
4034
|
+
props: {
|
|
4035
|
+
config: {
|
|
4036
|
+
components: matchedComponents,
|
|
4037
|
+
title: layoutTitle,
|
|
4038
|
+
description: layoutDescription
|
|
4039
|
+
},
|
|
4040
|
+
actions
|
|
4041
|
+
}
|
|
4042
|
+
};
|
|
4043
|
+
logger.info(`[${this.getProviderName()}] Created MultiComponentContainer: "${layoutTitle}" with ${matchedComponents.length} components and ${actions.length} actions`);
|
|
4044
|
+
logCollector?.info(`Created dashboard: "${layoutTitle}" with ${matchedComponents.length} components and ${actions.length} actions`);
|
|
4085
4045
|
}
|
|
4086
4046
|
return {
|
|
4087
4047
|
success: true,
|
|
@@ -4089,7 +4049,6 @@ ${errorMsg}
|
|
|
4089
4049
|
text: textResponse,
|
|
4090
4050
|
matchedComponents,
|
|
4091
4051
|
component: container_componet,
|
|
4092
|
-
layoutReasoning,
|
|
4093
4052
|
actions,
|
|
4094
4053
|
method: `${this.getProviderName()}-text-response`
|
|
4095
4054
|
},
|
|
@@ -4755,7 +4714,7 @@ var CONTEXT_CONFIG = {
|
|
|
4755
4714
|
* Set to 0 to disable conversation history
|
|
4756
4715
|
* Higher values provide more context but may increase token usage
|
|
4757
4716
|
*/
|
|
4758
|
-
MAX_CONVERSATION_CONTEXT_BLOCKS:
|
|
4717
|
+
MAX_CONVERSATION_CONTEXT_BLOCKS: 3
|
|
4759
4718
|
};
|
|
4760
4719
|
|
|
4761
4720
|
// src/handlers/user-prompt-request.ts
|