@superatomai/sdk-node 0.0.63 → 0.0.65

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
@@ -2478,9 +2478,11 @@ var BookmarksRequestMessageSchema = z3.object({
2478
2478
  });
2479
2479
  var ArtifactsQueryFiltersSchema = z3.object({
2480
2480
  createdBy: z3.number().optional(),
2481
+ type: z3.string().optional(),
2481
2482
  status: z3.string().optional(),
2482
2483
  name: z3.string().optional(),
2483
- deleted: z3.boolean().optional()
2484
+ deleted: z3.boolean().optional(),
2485
+ createdAt: z3.string().optional()
2484
2486
  });
2485
2487
  var ArtifactsRequestPayloadSchema = z3.object({
2486
2488
  operation: z3.enum(["create", "update", "delete", "getAll", "getOne", "query"]),
@@ -2492,6 +2494,7 @@ var ArtifactsRequestPayloadSchema = z3.object({
2492
2494
  status: z3.string().optional(),
2493
2495
  deleted: z3.boolean().optional(),
2494
2496
  limit: z3.number().optional(),
2497
+ offset: z3.number().optional(),
2495
2498
  // Query operation fields
2496
2499
  filters: ArtifactsQueryFiltersSchema.optional(),
2497
2500
  sort: z3.enum(["ASC", "DESC"]).optional(),
@@ -6321,11 +6324,11 @@ Fixed SQL query:`;
6321
6324
  logger.info(`[${this.getProviderName()}] Passing ${deferredTools.length} deferred tools to component matching`);
6322
6325
  deferredToolsText = "The following external tools need user input via a Form component.\n**IMPORTANT: Use these EXACT values when generating Form externalTool prop.**\n\n" + deferredTools.map((tool, idx) => {
6323
6326
  return `${idx + 1}. **${tool.name}**
6324
- toolId: "${tool.id}" (USE THIS EXACT VALUE - do not modify!)
6325
- toolName: "${tool.name}"
6326
- parameters: ${JSON.stringify(tool.params || {})}
6327
- requiredFields:
6328
- ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
6327
+ toolId: "${tool.id}" (USE THIS EXACT VALUE - do not modify!)
6328
+ toolName: "${tool.name}"
6329
+ parameters: ${JSON.stringify(tool.params || {})}
6330
+ requiredFields:
6331
+ ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
6329
6332
  }).join("\n\n");
6330
6333
  }
6331
6334
  let executedToolsText = "No external tools were executed for data fetching.";
@@ -6341,8 +6344,8 @@ ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
6341
6344
  const numericFields = fields.filter((f) => f.type === "number").map((f) => f.name);
6342
6345
  const stringFields = fields.filter((f) => f.type === "string").map((f) => f.name);
6343
6346
  fieldNamesList = `
6344
- \u{1F4CA} NUMERIC FIELDS (use for yAxisKey, valueKey, aggregationField): ${numericFields.join(", ") || "none"}
6345
- \u{1F4DD} STRING FIELDS (use for xAxisKey, groupBy, nameKey): ${stringFields.join(", ") || "none"}`;
6347
+ \u{1F4CA} NUMERIC FIELDS (use for yAxisKey, valueKey, aggregationField): ${numericFields.join(", ") || "none"}
6348
+ \u{1F4DD} STRING FIELDS (use for xAxisKey, groupBy, nameKey): ${stringFields.join(", ") || "none"}`;
6346
6349
  const fieldsText = fields.map(
6347
6350
  (f) => ` "${f.name}" (${f.type}): ${f.description}`
6348
6351
  ).join("\n");
@@ -6351,11 +6354,11 @@ ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
6351
6354
  ${fieldsText}`;
6352
6355
  }
6353
6356
  return `${idx + 1}. **${tool.name}**
6354
- toolId: "${tool.id}"
6355
- toolName: "${tool.name}"
6356
- parameters: ${JSON.stringify(tool.params || {})}
6357
- recordCount: ${recordCount} rows returned
6358
- outputSchema: ${outputSchemaText}${fieldNamesList}`;
6357
+ toolId: "${tool.id}"
6358
+ toolName: "${tool.name}"
6359
+ parameters: ${JSON.stringify(tool.params || {})}
6360
+ recordCount: ${recordCount} rows returned
6361
+ outputSchema: ${outputSchemaText}${fieldNamesList}`;
6359
6362
  }).join("\n\n");
6360
6363
  }
6361
6364
  const schemaDoc = schema.generateSchemaDocumentation();
@@ -6406,6 +6409,7 @@ ${executedToolsText}`);
6406
6409
  logCollector?.info("Matching components from text response...");
6407
6410
  let fullResponseText = "";
6408
6411
  let answerComponentExtracted = false;
6412
+ let validatedAnswerComponent = null;
6409
6413
  const answerCallback = componentStreamCallback;
6410
6414
  const partialCallback = answerCallback ? (chunk) => {
6411
6415
  fullResponseText += chunk;
@@ -6464,8 +6468,8 @@ ${executedToolsText}`);
6464
6468
  }
6465
6469
  };
6466
6470
  const streamTime = (/* @__PURE__ */ new Date()).toISOString();
6467
- logger.info(`[${this.getProviderName()}] \u2713 [${streamTime}] Answer component detected in stream: ${answerComponent.name} (${answerComponent.type}) - STREAMING TO FRONTEND NOW`);
6468
- logCollector?.info(`\u2713 Answer component: ${answerComponent.name} (${answerComponent.type}) - streaming to frontend at ${streamTime}`);
6471
+ logger.info(`[${this.getProviderName()}] \u2713 [${streamTime}] Answer component detected in stream: ${answerComponent.name} (${answerComponent.type})`);
6472
+ logCollector?.info(`\u2713 Answer component: ${answerComponent.name} (${answerComponent.type}) - detected at ${streamTime}`);
6469
6473
  if (answerComponentData.props?.query) {
6470
6474
  logCollector?.logQuery(
6471
6475
  "Answer component query",
@@ -6473,7 +6477,79 @@ ${executedToolsText}`);
6473
6477
  { componentName: answerComponent.name, componentType: answerComponent.type, reasoning: answerComponentData.reasoning }
6474
6478
  );
6475
6479
  }
6476
- answerCallback(answerComponent);
6480
+ const answerQuery = answerComponent.props?.query;
6481
+ logger.info(`[${this.getProviderName()}] Answer component detected: ${answerComponent.name} (${answerComponent.type}), hasQuery: ${!!answerQuery}, hasDbExecute: ${!!collections?.["database"]?.["execute"]}`);
6482
+ if (answerQuery && collections?.["database"]?.["execute"]) {
6483
+ (async () => {
6484
+ const MAX_RETRIES = 3;
6485
+ let attempts = 0;
6486
+ let validated = false;
6487
+ let currentQuery = answerQuery;
6488
+ let currentQueryStr = typeof answerQuery === "string" ? answerQuery : answerQuery?.sql || "";
6489
+ let lastError = "";
6490
+ logger.info(`[${this.getProviderName()}] Validating answer component query before streaming...`);
6491
+ while (attempts < MAX_RETRIES && !validated) {
6492
+ attempts++;
6493
+ try {
6494
+ const cacheKey = this.getQueryCacheKey(currentQuery);
6495
+ if (cacheKey) {
6496
+ logger.debug(`[${this.getProviderName()}] Answer component query validation attempt ${attempts}/${MAX_RETRIES}`);
6497
+ const result2 = await collections["database"]["execute"]({ sql: cacheKey });
6498
+ queryCache.set(cacheKey, result2);
6499
+ validated = true;
6500
+ if (currentQuery !== answerQuery) {
6501
+ answerComponent.props.query = currentQuery;
6502
+ }
6503
+ validatedAnswerComponent = {
6504
+ componentId: answerComponentData.componentId,
6505
+ validatedQuery: currentQuery
6506
+ };
6507
+ logger.info(`[${this.getProviderName()}] \u2713 Answer component query validated (attempt ${attempts}) - STREAMING TO FRONTEND NOW`);
6508
+ logCollector?.info(`\u2713 Answer component query validated - streaming to frontend`);
6509
+ logger.info(`[${this.getProviderName()}] Calling answerCallback for: ${answerComponent.name}`);
6510
+ answerCallback(answerComponent);
6511
+ logger.info(`[${this.getProviderName()}] answerCallback completed for: ${answerComponent.name}`);
6512
+ }
6513
+ } catch (validationError) {
6514
+ lastError = validationError instanceof Error ? validationError.message : String(validationError);
6515
+ logger.warn(`[${this.getProviderName()}] Answer component query validation failed (attempt ${attempts}/${MAX_RETRIES}): ${lastError}`);
6516
+ if (attempts < MAX_RETRIES) {
6517
+ try {
6518
+ logger.info(`[${this.getProviderName()}] Requesting LLM to fix answer component query...`);
6519
+ const fixedQueryStr = await this.requestQueryFix(
6520
+ currentQueryStr,
6521
+ lastError,
6522
+ {
6523
+ name: answerComponent.name,
6524
+ type: answerComponent.type,
6525
+ title: answerComponent.props?.title
6526
+ },
6527
+ apiKey
6528
+ );
6529
+ if (typeof currentQuery === "string") {
6530
+ currentQuery = fixedQueryStr;
6531
+ } else {
6532
+ currentQuery = { ...currentQuery, sql: fixedQueryStr };
6533
+ }
6534
+ currentQueryStr = fixedQueryStr;
6535
+ logger.info(`[${this.getProviderName()}] LLM provided fixed query for answer component, retrying...`);
6536
+ } catch (fixError) {
6537
+ const fixErrorMsg = fixError instanceof Error ? fixError.message : String(fixError);
6538
+ logger.error(`[${this.getProviderName()}] Failed to get LLM query fix for answer component: ${fixErrorMsg}`);
6539
+ break;
6540
+ }
6541
+ }
6542
+ }
6543
+ }
6544
+ if (!validated) {
6545
+ logger.warn(`[${this.getProviderName()}] Answer component query validation failed after ${attempts} attempts - skipping early stream`);
6546
+ logCollector?.warn(`Answer component query validation failed: ${lastError} - will be handled in batch validation`);
6547
+ }
6548
+ })();
6549
+ } else {
6550
+ logger.info(`[${this.getProviderName()}] Answer component has no query - STREAMING TO FRONTEND NOW`);
6551
+ answerCallback(answerComponent);
6552
+ }
6477
6553
  answerComponentExtracted = true;
6478
6554
  }
6479
6555
  }
@@ -6527,6 +6603,10 @@ ${executedToolsText}`);
6527
6603
  return null;
6528
6604
  }
6529
6605
  let cleanedProps = { ...mc.props };
6606
+ if (validatedAnswerComponent && mc.componentId === validatedAnswerComponent.componentId) {
6607
+ logger.info(`[${this.getProviderName()}] Using pre-validated query for answer component: ${mc.componentId}`);
6608
+ cleanedProps.query = validatedAnswerComponent.validatedQuery;
6609
+ }
6530
6610
  if (cleanedProps.externalTool) {
6531
6611
  const toolId = cleanedProps.externalTool.toolId;
6532
6612
  const validToolIds = (executedTools || []).map((t) => t.id);
@@ -7572,11 +7652,14 @@ ${errorMsg}
7572
7652
  logger.info(`[${this.getProviderName()}] Generated ${actions.length} follow-up actions for general question`);
7573
7653
  } else if (components && components.length > 0) {
7574
7654
  logger.info(`[${this.getProviderName()}] Matching components from text response...`);
7655
+ logger.info(`[${this.getProviderName()}] componentStreamCallback setup: wrappedStreamCallback=${!!wrappedStreamCallback}, category=${category}`);
7575
7656
  const componentStreamCallback = wrappedStreamCallback && category !== "data_modification" ? (component) => {
7657
+ logger.info(`[${this.getProviderName()}] componentStreamCallback INVOKED for: ${component.name} (${component.type})`);
7576
7658
  const answerMarker = `__ANSWER_COMPONENT_START__${JSON.stringify(component)}__ANSWER_COMPONENT_END__`;
7577
7659
  wrappedStreamCallback(answerMarker);
7578
7660
  logger.info(`[${this.getProviderName()}] Streamed answer component to frontend: ${component.name} (${component.type})`);
7579
7661
  } : void 0;
7662
+ logger.info(`[${this.getProviderName()}] componentStreamCallback created: ${!!componentStreamCallback}`);
7580
7663
  const deferredTools = externalTools?.filter((t) => {
7581
7664
  if (t.executionType === "deferred" && !t.userProvidedData) return true;
7582
7665
  if (category === "data_modification" && !t.userProvidedData) {
@@ -10944,30 +11027,25 @@ async function handleArtifactsRequest(data, collections, sendMessage) {
10944
11027
  const name = requestData?.name;
10945
11028
  const createdBy = requestData?.createdBy;
10946
11029
  const dsl = requestData?.dsl;
11030
+ const type = requestData?.type;
11031
+ const filters = requestData?.filters;
10947
11032
  const status = requestData?.status;
10948
11033
  const deleted = requestData?.deleted;
10949
11034
  const limit = requestData?.limit;
10950
- const filters = requestData?.filters;
11035
+ const offset = requestData?.offset;
10951
11036
  const sort = requestData?.sort;
10952
- const type = requestData?.type;
10953
- const menuId = requestData?.menuId;
10954
- const artifactGroupName = requestData?.artifactGroupName;
10955
- const artifactGroupId = requestData?.artifactGroupId;
10956
- const artifactGroupIcon = requestData?.artifactGroupIcon;
10957
- logger.info("[SDK-NODEJS] Extracted params for create:", JSON.stringify({
11037
+ logger.info("[SDK-NODEJS] Extracted params:", JSON.stringify({
10958
11038
  name,
10959
11039
  type,
10960
- menuId,
10961
- artifactGroupName,
10962
- artifactGroupId,
10963
- artifactGroupIcon
11040
+ filters: filters ? "present" : "undefined"
10964
11041
  }, null, 2));
11042
+ logger.info("[SDK-NODEJS] Full requestData.filters:", JSON.stringify(filters, null, 2));
10965
11043
  switch (operation) {
10966
11044
  case "create":
10967
- await handleCreate6(id, name, createdBy, dsl, status, type, menuId, artifactGroupName, artifactGroupId, artifactGroupIcon, executeCollection, sendMessage, from.id);
11045
+ await handleCreate6(id, name, createdBy, dsl, type, filters, status, executeCollection, sendMessage, from.id);
10968
11046
  break;
10969
11047
  case "update":
10970
- await handleUpdate6(id, artifactId, name, dsl, status, deleted, executeCollection, sendMessage, from.id);
11048
+ await handleUpdate6(id, artifactId, name, dsl, type, filters, status, deleted, executeCollection, sendMessage, from.id);
10971
11049
  break;
10972
11050
  case "delete":
10973
11051
  await handleDelete6(id, artifactId, executeCollection, sendMessage, from.id);
@@ -10979,7 +11057,7 @@ async function handleArtifactsRequest(data, collections, sendMessage) {
10979
11057
  await handleGetOne6(id, artifactId, executeCollection, sendMessage, from.id);
10980
11058
  break;
10981
11059
  case "query":
10982
- await handleQuery6(id, { filters, limit, sort }, executeCollection, sendMessage, from.id);
11060
+ await handleQuery6(id, { filters, limit, offset, sort }, executeCollection, sendMessage, from.id);
10983
11061
  break;
10984
11062
  default:
10985
11063
  sendResponse8(id, {
@@ -10995,7 +11073,7 @@ async function handleArtifactsRequest(data, collections, sendMessage) {
10995
11073
  }, sendMessage);
10996
11074
  }
10997
11075
  }
10998
- async function handleCreate6(id, name, createdBy, dsl, status, type, menuId, artifactGroupName, artifactGroupId, artifactGroupIcon, executeCollection, sendMessage, clientId) {
11076
+ async function handleCreate6(id, name, createdBy, dsl, type, filters, status, executeCollection, sendMessage, clientId) {
10999
11077
  if (!name) {
11000
11078
  sendResponse8(id, {
11001
11079
  success: false,
@@ -11008,12 +11086,9 @@ async function handleCreate6(id, name, createdBy, dsl, status, type, menuId, art
11008
11086
  name,
11009
11087
  createdBy,
11010
11088
  dsl,
11011
- status,
11012
11089
  type,
11013
- menuId,
11014
- artifactGroupName,
11015
- artifactGroupId,
11016
- artifactGroupIcon
11090
+ filters,
11091
+ status
11017
11092
  });
11018
11093
  sendResponse8(id, {
11019
11094
  success: true,
@@ -11028,7 +11103,7 @@ async function handleCreate6(id, name, createdBy, dsl, status, type, menuId, art
11028
11103
  }, sendMessage, clientId);
11029
11104
  }
11030
11105
  }
11031
- async function handleUpdate6(id, artifactId, name, dsl, status, deleted, executeCollection, sendMessage, clientId) {
11106
+ async function handleUpdate6(id, artifactId, name, dsl, type, filters, status, deleted, executeCollection, sendMessage, clientId) {
11032
11107
  if (!artifactId) {
11033
11108
  sendResponse8(id, {
11034
11109
  success: false,
@@ -11037,7 +11112,7 @@ async function handleUpdate6(id, artifactId, name, dsl, status, deleted, execute
11037
11112
  return;
11038
11113
  }
11039
11114
  try {
11040
- const result = await executeCollection("artifacts", "update", { id: artifactId, name, dsl, status, deleted });
11115
+ const result = await executeCollection("artifacts", "update", { id: artifactId, name, dsl, type, filters, status, deleted });
11041
11116
  sendResponse8(id, {
11042
11117
  success: true,
11043
11118
  data: result.data,
@@ -11116,11 +11191,15 @@ async function handleGetOne6(id, artifactId, executeCollection, sendMessage, cli
11116
11191
  }
11117
11192
  async function handleQuery6(id, queryParams, executeCollection, sendMessage, clientId) {
11118
11193
  try {
11194
+ logger.info("[SDK-NODEJS] handleQuery - queryParams:", JSON.stringify(queryParams, null, 2));
11195
+ logger.info("[SDK-NODEJS] handleQuery - filters.type:", queryParams.filters?.type);
11119
11196
  const result = await executeCollection("artifacts", "query", {
11120
11197
  filters: queryParams.filters,
11121
11198
  limit: queryParams.limit || 50,
11199
+ offset: queryParams.offset || 0,
11122
11200
  sort: queryParams.sort || "DESC"
11123
11201
  });
11202
+ logger.info("[SDK-NODEJS] handleQuery - executeCollection result count:", result.count);
11124
11203
  sendResponse8(id, {
11125
11204
  success: true,
11126
11205
  data: result.data,