@superatomai/sdk-node 0.0.15 → 0.0.16

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
@@ -565,10 +565,14 @@ var ReportsRequestMessageSchema = import_zod3.z.object({
565
565
  var UIBlockSchema = import_zod3.z.object({
566
566
  id: import_zod3.z.string().optional(),
567
567
  userQuestion: import_zod3.z.string().optional(),
568
+ user_prompt: import_zod3.z.string().optional(),
569
+ // DB field name
568
570
  text: import_zod3.z.string().optional(),
569
571
  textResponse: import_zod3.z.string().optional(),
572
+ analysis: import_zod3.z.string().optional(),
573
+ // DB field name for textResponse
570
574
  component: ComponentSchema.optional(),
571
- // Legacy field
575
+ // DB field name / Legacy field
572
576
  generatedComponentMetadata: ComponentSchema.optional(),
573
577
  // Actual field used by UIBlock class
574
578
  componentData: import_zod3.z.record(import_zod3.z.any()).optional(),
@@ -3814,8 +3818,9 @@ var BaseLLM = class {
3814
3818
  * @param collections - Collection registry for executing database queries via database.execute
3815
3819
  * @param components - Optional list of available components for matching suggestions
3816
3820
  * @param externalTools - Optional array of external tools (email, calendar, etc.) that can be called
3821
+ * @param category - Question category ('data_analysis' | 'data_modification' | 'general'). For data_modification, answer component streaming is skipped. For general, component generation is skipped entirely.
3817
3822
  */
3818
- async generateTextResponse(userPrompt, apiKey, logCollector, conversationHistory, streamCallback, collections, components, externalTools) {
3823
+ async generateTextResponse(userPrompt, apiKey, logCollector, conversationHistory, streamCallback, collections, components, externalTools, category) {
3819
3824
  const errors = [];
3820
3825
  logger.debug(`[${this.getProviderName()}] Starting text response generation`);
3821
3826
  logger.debug(`[${this.getProviderName()}] User prompt: "${userPrompt.substring(0, 50)}..."`);
@@ -4209,16 +4214,19 @@ ${errorMsg}
4209
4214
  textLength: textResponse.length
4210
4215
  }
4211
4216
  );
4212
- if (wrappedStreamCallback && components && components.length > 0) {
4217
+ if (wrappedStreamCallback && components && components.length > 0 && category !== "general") {
4213
4218
  wrappedStreamCallback("__TEXT_COMPLETE__COMPONENT_GENERATION_START__");
4214
4219
  }
4215
4220
  let matchedComponents = [];
4216
4221
  let layoutTitle = "Dashboard";
4217
4222
  let layoutDescription = "Multi-component dashboard";
4218
4223
  let actions = [];
4219
- if (components && components.length > 0) {
4224
+ if (category === "general") {
4225
+ logger.info(`[${this.getProviderName()}] Skipping component generation for general/conversational question`);
4226
+ logCollector?.info("Skipping component generation for general question");
4227
+ } else if (components && components.length > 0) {
4220
4228
  logger.info(`[${this.getProviderName()}] Matching components from text response...`);
4221
- const componentStreamCallback = wrappedStreamCallback ? (component) => {
4229
+ const componentStreamCallback = wrappedStreamCallback && category !== "data_modification" ? (component) => {
4222
4230
  const answerMarker = `__ANSWER_COMPONENT_START__${JSON.stringify(component)}__ANSWER_COMPONENT_END__`;
4223
4231
  wrappedStreamCallback(answerMarker);
4224
4232
  logger.info(`[${this.getProviderName()}] Streamed answer component to frontend: ${component.name} (${component.type})`);
@@ -4317,52 +4325,78 @@ ${errorMsg}
4317
4325
  logCollector?.info(
4318
4326
  `\u2713 Found similar conversation (${(conversationMatch.similarity * 100).toFixed(2)}% match)`
4319
4327
  );
4320
- if (conversationMatch.similarity >= 0.99) {
4321
- const elapsedTime2 = Date.now() - startTime;
4322
- logger.info(`[${this.getProviderName()}] \u2713 100% match - returning UI block directly without adaptation`);
4323
- logCollector?.info(`\u2713 Exact match (${(conversationMatch.similarity * 100).toFixed(2)}%) - returning cached result`);
4324
- logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4325
- const component = conversationMatch.uiBlock?.generatedComponentMetadata || conversationMatch.uiBlock?.component;
4326
- return {
4327
- success: true,
4328
- data: {
4329
- component,
4330
- reasoning: `Exact match from previous conversation (${(conversationMatch.similarity * 100).toFixed(2)}% similarity)`,
4331
- method: `${this.getProviderName()}-semantic-match-exact`,
4332
- semanticSimilarity: conversationMatch.similarity
4333
- },
4334
- errors: []
4335
- };
4336
- }
4337
- logCollector?.info(`Adapting parameters for similar question...`);
4338
- const originalPrompt = conversationMatch.metadata?.userPrompt || "Previous question";
4339
- const adaptResult = await this.adaptUIBlockParameters(
4340
- userPrompt,
4341
- originalPrompt,
4342
- conversationMatch.uiBlock,
4343
- apiKey,
4344
- logCollector
4345
- );
4346
- if (adaptResult.success && adaptResult.adaptedComponent) {
4347
- const elapsedTime2 = Date.now() - startTime;
4348
- logger.info(`[${this.getProviderName()}] \u2713 Successfully adapted UI block parameters`);
4349
- logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4350
- logCollector?.info(`\u2713 UI block adapted successfully`);
4351
- logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4352
- return {
4353
- success: true,
4354
- data: {
4355
- component: adaptResult.adaptedComponent,
4356
- reasoning: `Adapted from previous conversation: ${originalPrompt}`,
4357
- method: `${this.getProviderName()}-semantic-match`,
4358
- semanticSimilarity: conversationMatch.similarity,
4359
- parametersChanged: adaptResult.parametersChanged
4360
- },
4361
- errors: []
4362
- };
4328
+ const component = conversationMatch.uiBlock?.component || conversationMatch.uiBlock?.generatedComponentMetadata;
4329
+ const cachedTextResponse = conversationMatch.uiBlock?.analysis || conversationMatch.uiBlock?.textResponse || conversationMatch.uiBlock?.text || "";
4330
+ if (!component) {
4331
+ if (conversationMatch.similarity >= 0.99) {
4332
+ const elapsedTime2 = Date.now() - startTime;
4333
+ logger.info(`[${this.getProviderName()}] \u2713 Exact match for general question - returning cached text response`);
4334
+ logCollector?.info(`\u2713 Exact match for general question - returning cached response`);
4335
+ logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4336
+ return {
4337
+ success: true,
4338
+ data: {
4339
+ text: cachedTextResponse,
4340
+ component: null,
4341
+ matchedComponents: [],
4342
+ actions: conversationMatch.uiBlock?.actions || [],
4343
+ reasoning: `Exact match from previous general conversation`,
4344
+ method: `${this.getProviderName()}-semantic-match-general`,
4345
+ semanticSimilarity: conversationMatch.similarity
4346
+ },
4347
+ errors: []
4348
+ };
4349
+ } else {
4350
+ logger.info(`[${this.getProviderName()}] Similar match but no component (general question) - processing fresh`);
4351
+ logCollector?.info("Similar match found but was a general conversation - processing as new question");
4352
+ }
4363
4353
  } else {
4364
- logger.info(`[${this.getProviderName()}] Could not adapt matched conversation, continuing to category classification`);
4365
- logCollector?.warn(`Could not adapt matched conversation: ${adaptResult.explanation}`);
4354
+ if (conversationMatch.similarity >= 0.99) {
4355
+ const elapsedTime2 = Date.now() - startTime;
4356
+ logger.info(`[${this.getProviderName()}] \u2713 100% match - returning UI block directly without adaptation`);
4357
+ logCollector?.info(`\u2713 Exact match (${(conversationMatch.similarity * 100).toFixed(2)}%) - returning cached result`);
4358
+ logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4359
+ return {
4360
+ success: true,
4361
+ data: {
4362
+ component,
4363
+ reasoning: `Exact match from previous conversation (${(conversationMatch.similarity * 100).toFixed(2)}% similarity)`,
4364
+ method: `${this.getProviderName()}-semantic-match-exact`,
4365
+ semanticSimilarity: conversationMatch.similarity
4366
+ },
4367
+ errors: []
4368
+ };
4369
+ }
4370
+ logCollector?.info(`Adapting parameters for similar question...`);
4371
+ const originalPrompt = conversationMatch.metadata?.userPrompt || "Previous question";
4372
+ const adaptResult = await this.adaptUIBlockParameters(
4373
+ userPrompt,
4374
+ originalPrompt,
4375
+ conversationMatch.uiBlock,
4376
+ apiKey,
4377
+ logCollector
4378
+ );
4379
+ if (adaptResult.success && adaptResult.adaptedComponent) {
4380
+ const elapsedTime2 = Date.now() - startTime;
4381
+ logger.info(`[${this.getProviderName()}] \u2713 Successfully adapted UI block parameters`);
4382
+ logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4383
+ logCollector?.info(`\u2713 UI block adapted successfully`);
4384
+ logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4385
+ return {
4386
+ success: true,
4387
+ data: {
4388
+ component: adaptResult.adaptedComponent,
4389
+ reasoning: `Adapted from previous conversation: ${originalPrompt}`,
4390
+ method: `${this.getProviderName()}-semantic-match`,
4391
+ semanticSimilarity: conversationMatch.similarity,
4392
+ parametersChanged: adaptResult.parametersChanged
4393
+ },
4394
+ errors: []
4395
+ };
4396
+ } else {
4397
+ logger.info(`[${this.getProviderName()}] Could not adapt matched conversation, continuing to category classification`);
4398
+ logCollector?.warn(`Could not adapt matched conversation: ${adaptResult.explanation}`);
4399
+ }
4366
4400
  }
4367
4401
  } else {
4368
4402
  logger.info(`[${this.getProviderName()}] No matching previous conversations found, proceeding to category classification`);
@@ -4404,7 +4438,10 @@ ${errorMsg}
4404
4438
  })()
4405
4439
  })) || [];
4406
4440
  }
4407
- if (categoryClassification.category === "data_analysis") {
4441
+ if (categoryClassification.category === "general") {
4442
+ logger.info(`[${this.getProviderName()}] Routing to general conversation (no database operations)`);
4443
+ logCollector?.info("Routing to general conversation...");
4444
+ } else if (categoryClassification.category === "data_analysis") {
4408
4445
  logger.info(`[${this.getProviderName()}] Routing to data analysis (SELECT operations)`);
4409
4446
  logCollector?.info("Routing to data analysis...");
4410
4447
  } else if (categoryClassification.category === "data_modification") {
@@ -4419,7 +4456,8 @@ ${errorMsg}
4419
4456
  streamCallback,
4420
4457
  collections,
4421
4458
  components,
4422
- toolsToUse
4459
+ toolsToUse,
4460
+ categoryClassification.category
4423
4461
  );
4424
4462
  const elapsedTime = Date.now() - startTime;
4425
4463
  logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime}ms (${(elapsedTime / 1e3).toFixed(2)}s)`);
@@ -5076,8 +5114,10 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
5076
5114
  if ("component" in userResponse.data) {
5077
5115
  component = userResponse.data.component;
5078
5116
  }
5079
- if ("textResponse" in userResponse.data) {
5117
+ if ("text" in userResponse.data) {
5080
5118
  textResponse = userResponse.data.text;
5119
+ } else if ("textResponse" in userResponse.data) {
5120
+ textResponse = userResponse.data.textResponse;
5081
5121
  }
5082
5122
  if ("actions" in userResponse.data) {
5083
5123
  actions = userResponse.data.actions || [];