@superatomai/sdk-node 0.0.43 → 0.0.45

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.mjs CHANGED
@@ -1174,65 +1174,47 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
1174
1174
 
1175
1175
  ## Your Task
1176
1176
 
1177
- 1. **Create a filter component** based on the user's request (DatePicker, Dropdown, SearchBox, etc.)
1178
- 2. **Update all existing components** to use the filter values in their queries/params
1177
+ 1. **Create a filter component** based on the user's request
1178
+ 2. **Update existing components** with dynamic title/description interpolation if needed
1179
+ 3. **Preserve all existing props** - the filter system handles param merging at runtime
1179
1180
 
1180
- ## Filter Types
1181
+ ## How The Filter System Works
1181
1182
 
1182
- Choose the appropriate filter component based on user intent:
1183
- - **DateRangePicker**: For date range filtering (start date, end date)
1184
- - **DatePicker**: For single date filtering
1185
- - **Dropdown**: For categorical filtering (status, category, type, etc.)
1186
- - **MultiSelect**: For multiple value selection
1187
- - **SearchBox**: For text search filtering
1188
- - **NumberRange**: For numeric range filtering
1183
+ 1. Filter component has a \`filters\` array with preset options, each containing \`label\`, \`value\`, and \`params\`
1184
+ 2. When user selects a filter option, those \`params\` are broadcast to all listening components
1185
+ 3. Components automatically merge filter params with their existing params (filter values override defaults)
1186
+ 4. Component titles/descriptions can use \`{%filterKeyLabel%}\` syntax for dynamic text
1189
1187
 
1190
1188
  ## Filter Component Structure
1191
1189
 
1192
- Generate a filter component with these props:
1193
- \`\`\`json
1194
- {
1195
- "componentId": "unique_filter_id",
1196
- "componentType": "DateRangePicker | Dropdown | SearchBox | etc.",
1197
- "componentName": "Display Name",
1198
- "props": {
1199
- "filterId": "unique_filter_id",
1200
- "label": "Filter Label",
1201
- "defaultValue": "optional default value",
1202
- "options": []
1203
- }
1204
- }
1205
- \`\`\`
1190
+ The filter uses DynamicFilterDropdown with:
1191
+ - **filterKey**: Identifier for label interpolation (e.g., "period", "name", "category")
1192
+ - **filters**: Array of options with label, value, params, and optionally isDefault
1193
+ - **defaultValue**: The value of the initially selected option
1206
1194
 
1207
- ## Updating Existing Components
1195
+ ## Dynamic Title/Description Interpolation
1208
1196
 
1209
- For each existing component, update its query/externalTool to use the filter:
1197
+ Use \`{%filterKeyLabel%}\` syntax for dynamic text:
1198
+ - filterKey "period" \u2192 use \`{%periodLabel%}\` in titles/descriptions
1199
+ - filterKey "name" \u2192 use \`{%nameLabel%}\` in titles/descriptions
1200
+ - Example: \`"{%periodLabel%} Revenue"\` becomes "Q3 2025 Revenue" when user selects "Q3 2025"
1210
1201
 
1211
- ### For Database Queries:
1212
- - Add filter conditions to WHERE clause using \`$paramName\` placeholders
1213
- - Add the filter param to the \`params\` object with binding reference
1202
+ **CRITICAL Template Syntax:**
1203
+ - Use \`{%keyLabel%}\` format (percent signs, key + "Label" suffix)
1204
+ - Do NOT use \`{{...}}\` or \`$...\` syntax - these don't work
1214
1205
 
1215
- ### For External Tools:
1216
- - Add filter params to the tool's params object with binding reference
1217
-
1218
- ## Filter Bindings
1219
-
1220
- Use this binding format to connect filter values to component params:
1221
- \`\`\`json
1222
- {
1223
- "paramName": "$filter.filterId.value"
1224
- }
1225
- \`\`\`
1226
-
1227
- For DateRangePicker:
1228
- - \`$filter.filterId.startDate\`
1229
- - \`$filter.filterId.endDate\`
1206
+ ## Updating Existing Components
1230
1207
 
1231
- For Dropdown/MultiSelect:
1232
- - \`$filter.filterId.value\`
1208
+ **IMPORTANT - Parameter Handling:**
1209
+ - Do NOT change existing parameter values to placeholders
1210
+ - Keep all existing/default parameter values as they are
1211
+ - The filter system MERGES params at runtime: filter params override component defaults
1233
1212
 
1234
- For SearchBox:
1235
- - \`$filter.filterId.searchText\`
1213
+ **What to modify in existing components:**
1214
+ - Modify \`title\` for \`{%filterKeyLabel%}\` interpolation (only if title exists)
1215
+ - Modify \`description\` for interpolation (only if description exists)
1216
+ - Modify other props only if specifically needed for the filter to function
1217
+ - Copy ALL other props exactly as provided
1236
1218
 
1237
1219
  ### Database Query Rules
1238
1220
  {{DATABASE_RULES}}
@@ -1243,53 +1225,48 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
1243
1225
 
1244
1226
  {
1245
1227
  "filterComponent": {
1246
- "componentId": "filter_unique_id",
1247
- "componentType": "DateRangePicker | Dropdown | etc.",
1248
- "componentName": "Filter Display Name",
1228
+ "id": "filter-<descriptive-id>",
1229
+ "name": "DynamicFilterDropdown",
1230
+ "type": "FilterDropdown",
1249
1231
  "props": {
1250
- "filterId": "filter_unique_id",
1251
- "label": "Filter Label",
1252
- "defaultValue": null,
1253
- "options": []
1232
+ "title": "<Filter display title>",
1233
+ "filterKey": "<key_for_interpolation>",
1234
+ "defaultValue": "<default_option_value>",
1235
+ "filters": [
1236
+ {
1237
+ "label": "<Display label for option>",
1238
+ "value": "<unique_option_value>",
1239
+ "params": { "<param_key>": "<actual_value>", "...": "..." },
1240
+ "isDefault": true
1241
+ }
1242
+ ]
1254
1243
  }
1255
1244
  },
1256
1245
  "updatedComponents": [
1257
1246
  {
1258
- "componentId": "existing_component_id",
1259
- "componentType": "existing_type",
1260
- "componentName": "existing_name",
1247
+ "id": "<existing_component_id>",
1248
+ "name": "<existing_component_name>",
1249
+ "type": "<existing_type>",
1261
1250
  "props": {
1262
- // RETURN THE COMPLETE PROPS OBJECT
1263
- // Copy ALL existing props and only modify the necessary fields
1264
- "title": "Existing Title",
1265
- "description": "Existing Description",
1266
- "config": {},
1267
- "query": {
1268
- "sql": "SELECT ... WHERE column BETWEEN $startDate AND $endDate",
1269
- "params": {
1270
- "existingParam": "existing_value",
1271
- "startDate": "$filter.filterId.startDate",
1272
- "endDate": "$filter.filterId.endDate"
1273
- }
1274
- }
1251
+ "...all existing props preserved...",
1252
+ "title": "{%<filterKey>Label%} <rest of title>",
1253
+ "description": "<updated if needed>"
1275
1254
  }
1276
1255
  }
1277
1256
  ],
1278
1257
  "filterBindings": {
1279
- "startDate": "$filter.filterId.startDate",
1280
- "endDate": "$filter.filterId.endDate"
1258
+ "<param_key>": "Describes which filter param this binds to"
1281
1259
  },
1282
- "reasoning": "Explanation of filter choice and how components were updated"
1260
+ "reasoning": "Explanation of filter choice and what params it provides"
1283
1261
  }
1284
1262
 
1285
- **CRITICAL:**
1286
- - Return ONLY valid JSON (no markdown code blocks, no text before/after)
1287
- - **RETURN COMPLETE PROPS**: Copy ALL existing props from each component, only modify what's needed for the filter
1288
- - Do NOT omit existing props like title, description, config - include them unchanged
1289
- - Only modify query.sql (add WHERE conditions) and query.params (add filter bindings)
1290
- - For externalTool, only add filter params to the params object
1291
- - Use consistent param naming across all components
1292
- - Ensure SQL syntax is valid with the new filter conditions
1263
+ **CRITICAL RULES:**
1264
+ 1. Return ONLY valid JSON (no markdown code blocks)
1265
+ 2. **COPY ALL existing props** - modify title/description for interpolation only if they exist
1266
+ 3. **DO NOT change parameter values** - keep existing defaults, filter merges at runtime
1267
+ 4. Use \`{%filterKeyLabel%}\` for dynamic text (NOT \`{{...}}\` or \`$...\`)
1268
+ 5. Filter \`params\` must have ACTUAL values (real dates, strings), not placeholders
1269
+ 6. Each filter option needs: label, value, params (and optionally isDefault)
1293
1270
 
1294
1271
  ## Database Schema
1295
1272
  {{SCHEMA_DOC}}
@@ -5949,8 +5926,9 @@ ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
5949
5926
  /**
5950
5927
  * Adapt UI block parameters based on current user question
5951
5928
  * Takes a matched UI block from semantic search and modifies its props to answer the new question
5929
+ * Also adapts the cached text response to match the new question
5952
5930
  */
5953
- async adaptUIBlockParameters(currentUserPrompt, originalUserPrompt, matchedUIBlock, apiKey, logCollector) {
5931
+ async adaptUIBlockParameters(currentUserPrompt, originalUserPrompt, matchedUIBlock, apiKey, logCollector, cachedTextResponse) {
5954
5932
  try {
5955
5933
  const component = matchedUIBlock?.generatedComponentMetadata || matchedUIBlock?.component;
5956
5934
  if (!matchedUIBlock || !component) {
@@ -5966,6 +5944,7 @@ ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
5966
5944
  CURRENT_USER_PROMPT: currentUserPrompt,
5967
5945
  MATCHED_UI_BLOCK_COMPONENT: JSON.stringify(component, null, 2),
5968
5946
  COMPONENT_PROPS: JSON.stringify(component.props, null, 2),
5947
+ CACHED_TEXT_RESPONSE: cachedTextResponse || "No cached text response available",
5969
5948
  SCHEMA_DOC: schemaDoc || "No schema available",
5970
5949
  DATABASE_RULES: databaseRules
5971
5950
  });
@@ -6014,6 +5993,7 @@ ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
6014
5993
  return {
6015
5994
  success: true,
6016
5995
  adaptedComponent: result.adaptedComponent,
5996
+ adaptedTextResponse: result.adaptedTextResponse,
6017
5997
  parametersChanged: result.parametersChanged,
6018
5998
  explanation: result.explanation || "Parameters adapted successfully"
6019
5999
  };
@@ -6709,7 +6689,8 @@ ${errorMsg}
6709
6689
  originalPrompt,
6710
6690
  conversationMatch.uiBlock,
6711
6691
  apiKey,
6712
- logCollector
6692
+ logCollector,
6693
+ cachedTextResponse
6713
6694
  );
6714
6695
  if (adaptResult.success && adaptResult.adaptedComponent) {
6715
6696
  const elapsedTime2 = Date.now() - startTime;
@@ -6717,15 +6698,16 @@ ${errorMsg}
6717
6698
  logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
6718
6699
  logCollector?.info(`\u2713 UI block adapted successfully`);
6719
6700
  logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
6720
- if (streamCallback && cachedTextResponse) {
6721
- logger.info(`[${this.getProviderName()}] Streaming cached text response to frontend (adapted match)`);
6722
- streamCallback(cachedTextResponse);
6701
+ const textResponseToUse = adaptResult.adaptedTextResponse || cachedTextResponse;
6702
+ if (streamCallback && textResponseToUse) {
6703
+ logger.info(`[${this.getProviderName()}] Streaming ${adaptResult.adaptedTextResponse ? "adapted" : "cached"} text response to frontend`);
6704
+ streamCallback(textResponseToUse);
6723
6705
  }
6724
6706
  const cachedActions = conversationMatch.uiBlock?.actions || [];
6725
6707
  return {
6726
6708
  success: true,
6727
6709
  data: {
6728
- text: cachedTextResponse,
6710
+ text: textResponseToUse,
6729
6711
  component: adaptResult.adaptedComponent,
6730
6712
  matchedComponents: adaptResult.adaptedComponent?.props?.config?.components || [],
6731
6713
  actions: cachedActions,
@@ -10485,13 +10467,13 @@ async function pickComponentWithLLM(prompt, components, anthropicApiKey, groqApi
10485
10467
  });
10486
10468
  return { success: false, errors };
10487
10469
  }
10488
- const originalComponent = components.find((c) => c.id === result.componentId);
10470
+ const originalComponent = components.find((c) => c.name === result.componentName);
10489
10471
  if (!originalComponent) {
10490
- errors.push(`Component ${result.componentId} not found in available components`);
10472
+ errors.push(`Component ${result.componentName} not found in available components`);
10491
10473
  userPromptErrorLogger.logError("DASH_COMP_REQ", "Component not found", {
10492
10474
  prompt,
10493
- componentId: result.componentId,
10494
- availableComponentIds: components.map((c) => c.id)
10475
+ componentName: result.componentName,
10476
+ availableComponentNames: components.map((c) => c.name)
10495
10477
  });
10496
10478
  return { success: false, errors };
10497
10479
  }