@superatomai/sdk-node 0.0.49 → 0.0.52

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 CHANGED
@@ -5720,26 +5720,27 @@ ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
5720
5720
  if (executedTools && executedTools.length > 0) {
5721
5721
  logger.info(`[${this.getProviderName()}] Passing ${executedTools.length} executed tools to component matching`);
5722
5722
  executedToolsText = "The following external tools were executed to fetch data.\n**IMPORTANT: For components displaying this data, use externalTool prop instead of query.**\n**IMPORTANT: Use the outputSchema fields to set correct config keys (xAxisKey, yAxisKey, valueKey, nameKey, etc.)**\n**IMPORTANT: Use the result data to populate deferred tool parameters when applicable.**\n\n" + executedTools.map((tool, idx) => {
5723
- let resultPreview = "No result data";
5724
- if (tool.result) {
5725
- const resultStr = typeof tool.result === "string" ? tool.result : JSON.stringify(tool.result, null, 2);
5726
- resultPreview = resultStr.length > 2e3 ? resultStr.substring(0, 2e3) + "\n... (truncated)" : resultStr;
5727
- }
5728
5723
  let outputSchemaText = "Not available";
5724
+ let recordCount = "unknown";
5729
5725
  if (tool.outputSchema) {
5730
5726
  const fields = tool.outputSchema.fields || [];
5731
- const recordCount = tool.result?._recordCount || (Array.isArray(tool.result) ? tool.result.length : "unknown");
5732
- outputSchemaText = `Returns ARRAY of ${recordCount} records. ${tool.outputSchema.description}
5733
- Fields in EACH ROW (these are per-row values, NOT aggregates):
5734
- ${fields.map((f) => ` - ${f.name} (${f.type}): ${f.description}`).join("\n")}
5735
- NOTE: For aggregate values (SUM, COUNT, AVG across all rows), write SQL query instead.`;
5727
+ recordCount = tool.result?._recordCount || (Array.isArray(tool.result) ? tool.result.length : "unknown");
5728
+ const fieldsText = fields.map(
5729
+ (f) => ` - name: "${f.name}" \u2190 USE THIS EXACT VALUE in config
5730
+ type: ${f.type}
5731
+ description: ${f.description}`
5732
+ ).join("\n");
5733
+ outputSchemaText = `${tool.outputSchema.description}
5734
+ Fields (use the "name" value in your config):
5735
+ ${fieldsText}`;
5736
5736
  }
5737
5737
  return `${idx + 1}. **${tool.name}**
5738
5738
  toolId: "${tool.id}" (USE THIS EXACT VALUE for externalTool.toolId)
5739
5739
  toolName: "${tool.name}" (USE THIS EXACT VALUE for externalTool.toolName)
5740
5740
  parameters: ${JSON.stringify(tool.params || {})} (USE THESE for externalTool.parameters)
5741
+ recordCount: ${recordCount} rows returned
5741
5742
  outputSchema: ${outputSchemaText}
5742
- result preview: ${resultPreview}`;
5743
+ \u26A0\uFE0F DO NOT embed this tool's data in SQL - use externalTool prop OR query database tables`;
5743
5744
  }).join("\n\n");
5744
5745
  }
5745
5746
  const schemaDoc = schema.generateSchemaDocumentation();
@@ -5880,11 +5881,111 @@ ${fields.map((f) => ` - ${f.name} (${f.type}): ${f.description}`).join("\n")
5880
5881
  logger.warn(`[${this.getProviderName()}] Component ${mc.componentId} not found in available components`);
5881
5882
  return null;
5882
5883
  }
5884
+ let cleanedProps = { ...mc.props };
5885
+ if (cleanedProps.externalTool) {
5886
+ const toolId = cleanedProps.externalTool.toolId;
5887
+ const validToolIds = (executedTools || []).map((t) => t.id);
5888
+ const isValidTool = toolId && typeof toolId === "string" && validToolIds.includes(toolId);
5889
+ if (!isValidTool) {
5890
+ logger.warn(`[${this.getProviderName()}] externalTool.toolId "${toolId}" not found in executed tools [${validToolIds.join(", ")}], setting to null`);
5891
+ cleanedProps.externalTool = null;
5892
+ } else {
5893
+ const executedTool = executedTools?.find((t) => t.id === toolId);
5894
+ if (executedTool?.outputSchema?.fields && cleanedProps.config) {
5895
+ const validFieldNames = executedTool.outputSchema.fields.map((f) => f.name);
5896
+ const validFieldNamesLower = validFieldNames.map((n) => n.toLowerCase());
5897
+ const findMatchingField = (fieldName) => {
5898
+ if (!fieldName) return null;
5899
+ const lowerField = fieldName.toLowerCase();
5900
+ const exactIdx = validFieldNamesLower.indexOf(lowerField);
5901
+ if (exactIdx !== -1) return validFieldNames[exactIdx];
5902
+ const partialMatches = [];
5903
+ for (let i = 0; i < validFieldNames.length; i++) {
5904
+ const validName = validFieldNames[i];
5905
+ const validLower = validFieldNamesLower[i];
5906
+ if (validLower.endsWith(lowerField)) {
5907
+ const score = lowerField.length / validLower.length;
5908
+ partialMatches.push({ name: validName, score });
5909
+ continue;
5910
+ }
5911
+ if (lowerField.endsWith(validLower)) {
5912
+ const score = validLower.length / lowerField.length;
5913
+ partialMatches.push({ name: validName, score });
5914
+ continue;
5915
+ }
5916
+ if (validLower.endsWith(lowerField) || lowerField.length <= 5 && validLower.includes(lowerField)) {
5917
+ const score = lowerField.length <= 5 ? 0.3 : 0.5;
5918
+ partialMatches.push({ name: validName, score });
5919
+ }
5920
+ }
5921
+ if (partialMatches.length > 0) {
5922
+ partialMatches.sort((a, b) => b.score - a.score);
5923
+ if (partialMatches.length === 1 || partialMatches[0].score > partialMatches[1].score + 0.1) {
5924
+ return partialMatches[0].name;
5925
+ } else {
5926
+ logger.warn(`[${this.getProviderName()}] Ambiguous field match for "${fieldName}": ${partialMatches.map((m) => m.name).join(", ")}`);
5927
+ return null;
5928
+ }
5929
+ }
5930
+ return null;
5931
+ };
5932
+ const configFieldsToValidate = [
5933
+ "xAxisKey",
5934
+ "yAxisKey",
5935
+ "valueKey",
5936
+ "nameKey",
5937
+ "labelKey",
5938
+ "groupBy",
5939
+ "aggregationField",
5940
+ "seriesKey",
5941
+ "sizeKey",
5942
+ "xAggregationField",
5943
+ "yAggregationField"
5944
+ ];
5945
+ for (const configKey of configFieldsToValidate) {
5946
+ const fieldValue = cleanedProps.config[configKey];
5947
+ if (fieldValue && typeof fieldValue === "string") {
5948
+ if (!validFieldNames.includes(fieldValue)) {
5949
+ const correctedField = findMatchingField(fieldValue);
5950
+ if (correctedField) {
5951
+ logger.warn(`[${this.getProviderName()}] Correcting config.${configKey}: "${fieldValue}" \u2192 "${correctedField}"`);
5952
+ cleanedProps.config[configKey] = correctedField;
5953
+ } else {
5954
+ logger.warn(`[${this.getProviderName()}] config.${configKey}="${fieldValue}" not found in outputSchema [${validFieldNames.join(", ")}]`);
5955
+ }
5956
+ }
5957
+ }
5958
+ }
5959
+ if (Array.isArray(cleanedProps.config.series)) {
5960
+ cleanedProps.config.series = cleanedProps.config.series.map((s) => {
5961
+ if (s.dataKey && typeof s.dataKey === "string" && !validFieldNames.includes(s.dataKey)) {
5962
+ const correctedField = findMatchingField(s.dataKey);
5963
+ if (correctedField) {
5964
+ logger.warn(`[${this.getProviderName()}] Correcting series.dataKey: "${s.dataKey}" \u2192 "${correctedField}"`);
5965
+ return { ...s, dataKey: correctedField };
5966
+ }
5967
+ }
5968
+ return s;
5969
+ });
5970
+ }
5971
+ }
5972
+ }
5973
+ }
5974
+ if (cleanedProps.query) {
5975
+ const queryStr = typeof cleanedProps.query === "string" ? cleanedProps.query : cleanedProps.query?.sql || "";
5976
+ if (queryStr.includes("OPENJSON") || queryStr.includes("JSON_VALUE")) {
5977
+ logger.warn(`[${this.getProviderName()}] Query contains OPENJSON/JSON_VALUE (invalid - cannot parse tool result), setting query to null`);
5978
+ cleanedProps.query = null;
5979
+ }
5980
+ }
5981
+ if (cleanedProps.query && cleanedProps.externalTool) {
5982
+ logger.info(`[${this.getProviderName()}] Both query and externalTool exist, keeping both - frontend will decide`);
5983
+ }
5883
5984
  return {
5884
5985
  ...originalComponent,
5885
5986
  props: {
5886
5987
  ...originalComponent.props,
5887
- ...mc.props
5988
+ ...cleanedProps
5888
5989
  }
5889
5990
  };
5890
5991
  }).filter(Boolean);