@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.mjs CHANGED
@@ -525,10 +525,14 @@ var ReportsRequestMessageSchema = z3.object({
525
525
  var UIBlockSchema = z3.object({
526
526
  id: z3.string().optional(),
527
527
  userQuestion: z3.string().optional(),
528
+ user_prompt: z3.string().optional(),
529
+ // DB field name
528
530
  text: z3.string().optional(),
529
531
  textResponse: z3.string().optional(),
532
+ analysis: z3.string().optional(),
533
+ // DB field name for textResponse
530
534
  component: ComponentSchema.optional(),
531
- // Legacy field
535
+ // DB field name / Legacy field
532
536
  generatedComponentMetadata: ComponentSchema.optional(),
533
537
  // Actual field used by UIBlock class
534
538
  componentData: z3.record(z3.any()).optional(),
@@ -3774,8 +3778,9 @@ var BaseLLM = class {
3774
3778
  * @param collections - Collection registry for executing database queries via database.execute
3775
3779
  * @param components - Optional list of available components for matching suggestions
3776
3780
  * @param externalTools - Optional array of external tools (email, calendar, etc.) that can be called
3781
+ * @param category - Question category ('data_analysis' | 'data_modification' | 'general'). For data_modification, answer component streaming is skipped. For general, component generation is skipped entirely.
3777
3782
  */
3778
- async generateTextResponse(userPrompt, apiKey, logCollector, conversationHistory, streamCallback, collections, components, externalTools) {
3783
+ async generateTextResponse(userPrompt, apiKey, logCollector, conversationHistory, streamCallback, collections, components, externalTools, category) {
3779
3784
  const errors = [];
3780
3785
  logger.debug(`[${this.getProviderName()}] Starting text response generation`);
3781
3786
  logger.debug(`[${this.getProviderName()}] User prompt: "${userPrompt.substring(0, 50)}..."`);
@@ -4169,16 +4174,19 @@ ${errorMsg}
4169
4174
  textLength: textResponse.length
4170
4175
  }
4171
4176
  );
4172
- if (wrappedStreamCallback && components && components.length > 0) {
4177
+ if (wrappedStreamCallback && components && components.length > 0 && category !== "general") {
4173
4178
  wrappedStreamCallback("__TEXT_COMPLETE__COMPONENT_GENERATION_START__");
4174
4179
  }
4175
4180
  let matchedComponents = [];
4176
4181
  let layoutTitle = "Dashboard";
4177
4182
  let layoutDescription = "Multi-component dashboard";
4178
4183
  let actions = [];
4179
- if (components && components.length > 0) {
4184
+ if (category === "general") {
4185
+ logger.info(`[${this.getProviderName()}] Skipping component generation for general/conversational question`);
4186
+ logCollector?.info("Skipping component generation for general question");
4187
+ } else if (components && components.length > 0) {
4180
4188
  logger.info(`[${this.getProviderName()}] Matching components from text response...`);
4181
- const componentStreamCallback = wrappedStreamCallback ? (component) => {
4189
+ const componentStreamCallback = wrappedStreamCallback && category !== "data_modification" ? (component) => {
4182
4190
  const answerMarker = `__ANSWER_COMPONENT_START__${JSON.stringify(component)}__ANSWER_COMPONENT_END__`;
4183
4191
  wrappedStreamCallback(answerMarker);
4184
4192
  logger.info(`[${this.getProviderName()}] Streamed answer component to frontend: ${component.name} (${component.type})`);
@@ -4277,52 +4285,78 @@ ${errorMsg}
4277
4285
  logCollector?.info(
4278
4286
  `\u2713 Found similar conversation (${(conversationMatch.similarity * 100).toFixed(2)}% match)`
4279
4287
  );
4280
- if (conversationMatch.similarity >= 0.99) {
4281
- const elapsedTime2 = Date.now() - startTime;
4282
- logger.info(`[${this.getProviderName()}] \u2713 100% match - returning UI block directly without adaptation`);
4283
- logCollector?.info(`\u2713 Exact match (${(conversationMatch.similarity * 100).toFixed(2)}%) - returning cached result`);
4284
- logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4285
- const component = conversationMatch.uiBlock?.generatedComponentMetadata || conversationMatch.uiBlock?.component;
4286
- return {
4287
- success: true,
4288
- data: {
4289
- component,
4290
- reasoning: `Exact match from previous conversation (${(conversationMatch.similarity * 100).toFixed(2)}% similarity)`,
4291
- method: `${this.getProviderName()}-semantic-match-exact`,
4292
- semanticSimilarity: conversationMatch.similarity
4293
- },
4294
- errors: []
4295
- };
4296
- }
4297
- logCollector?.info(`Adapting parameters for similar question...`);
4298
- const originalPrompt = conversationMatch.metadata?.userPrompt || "Previous question";
4299
- const adaptResult = await this.adaptUIBlockParameters(
4300
- userPrompt,
4301
- originalPrompt,
4302
- conversationMatch.uiBlock,
4303
- apiKey,
4304
- logCollector
4305
- );
4306
- if (adaptResult.success && adaptResult.adaptedComponent) {
4307
- const elapsedTime2 = Date.now() - startTime;
4308
- logger.info(`[${this.getProviderName()}] \u2713 Successfully adapted UI block parameters`);
4309
- logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4310
- logCollector?.info(`\u2713 UI block adapted successfully`);
4311
- logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4312
- return {
4313
- success: true,
4314
- data: {
4315
- component: adaptResult.adaptedComponent,
4316
- reasoning: `Adapted from previous conversation: ${originalPrompt}`,
4317
- method: `${this.getProviderName()}-semantic-match`,
4318
- semanticSimilarity: conversationMatch.similarity,
4319
- parametersChanged: adaptResult.parametersChanged
4320
- },
4321
- errors: []
4322
- };
4288
+ const component = conversationMatch.uiBlock?.component || conversationMatch.uiBlock?.generatedComponentMetadata;
4289
+ const cachedTextResponse = conversationMatch.uiBlock?.analysis || conversationMatch.uiBlock?.textResponse || conversationMatch.uiBlock?.text || "";
4290
+ if (!component) {
4291
+ if (conversationMatch.similarity >= 0.99) {
4292
+ const elapsedTime2 = Date.now() - startTime;
4293
+ logger.info(`[${this.getProviderName()}] \u2713 Exact match for general question - returning cached text response`);
4294
+ logCollector?.info(`\u2713 Exact match for general question - returning cached response`);
4295
+ logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4296
+ return {
4297
+ success: true,
4298
+ data: {
4299
+ text: cachedTextResponse,
4300
+ component: null,
4301
+ matchedComponents: [],
4302
+ actions: conversationMatch.uiBlock?.actions || [],
4303
+ reasoning: `Exact match from previous general conversation`,
4304
+ method: `${this.getProviderName()}-semantic-match-general`,
4305
+ semanticSimilarity: conversationMatch.similarity
4306
+ },
4307
+ errors: []
4308
+ };
4309
+ } else {
4310
+ logger.info(`[${this.getProviderName()}] Similar match but no component (general question) - processing fresh`);
4311
+ logCollector?.info("Similar match found but was a general conversation - processing as new question");
4312
+ }
4323
4313
  } else {
4324
- logger.info(`[${this.getProviderName()}] Could not adapt matched conversation, continuing to category classification`);
4325
- logCollector?.warn(`Could not adapt matched conversation: ${adaptResult.explanation}`);
4314
+ if (conversationMatch.similarity >= 0.99) {
4315
+ const elapsedTime2 = Date.now() - startTime;
4316
+ logger.info(`[${this.getProviderName()}] \u2713 100% match - returning UI block directly without adaptation`);
4317
+ logCollector?.info(`\u2713 Exact match (${(conversationMatch.similarity * 100).toFixed(2)}%) - returning cached result`);
4318
+ logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4319
+ return {
4320
+ success: true,
4321
+ data: {
4322
+ component,
4323
+ reasoning: `Exact match from previous conversation (${(conversationMatch.similarity * 100).toFixed(2)}% similarity)`,
4324
+ method: `${this.getProviderName()}-semantic-match-exact`,
4325
+ semanticSimilarity: conversationMatch.similarity
4326
+ },
4327
+ errors: []
4328
+ };
4329
+ }
4330
+ logCollector?.info(`Adapting parameters for similar question...`);
4331
+ const originalPrompt = conversationMatch.metadata?.userPrompt || "Previous question";
4332
+ const adaptResult = await this.adaptUIBlockParameters(
4333
+ userPrompt,
4334
+ originalPrompt,
4335
+ conversationMatch.uiBlock,
4336
+ apiKey,
4337
+ logCollector
4338
+ );
4339
+ if (adaptResult.success && adaptResult.adaptedComponent) {
4340
+ const elapsedTime2 = Date.now() - startTime;
4341
+ logger.info(`[${this.getProviderName()}] \u2713 Successfully adapted UI block parameters`);
4342
+ logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4343
+ logCollector?.info(`\u2713 UI block adapted successfully`);
4344
+ logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
4345
+ return {
4346
+ success: true,
4347
+ data: {
4348
+ component: adaptResult.adaptedComponent,
4349
+ reasoning: `Adapted from previous conversation: ${originalPrompt}`,
4350
+ method: `${this.getProviderName()}-semantic-match`,
4351
+ semanticSimilarity: conversationMatch.similarity,
4352
+ parametersChanged: adaptResult.parametersChanged
4353
+ },
4354
+ errors: []
4355
+ };
4356
+ } else {
4357
+ logger.info(`[${this.getProviderName()}] Could not adapt matched conversation, continuing to category classification`);
4358
+ logCollector?.warn(`Could not adapt matched conversation: ${adaptResult.explanation}`);
4359
+ }
4326
4360
  }
4327
4361
  } else {
4328
4362
  logger.info(`[${this.getProviderName()}] No matching previous conversations found, proceeding to category classification`);
@@ -4364,7 +4398,10 @@ ${errorMsg}
4364
4398
  })()
4365
4399
  })) || [];
4366
4400
  }
4367
- if (categoryClassification.category === "data_analysis") {
4401
+ if (categoryClassification.category === "general") {
4402
+ logger.info(`[${this.getProviderName()}] Routing to general conversation (no database operations)`);
4403
+ logCollector?.info("Routing to general conversation...");
4404
+ } else if (categoryClassification.category === "data_analysis") {
4368
4405
  logger.info(`[${this.getProviderName()}] Routing to data analysis (SELECT operations)`);
4369
4406
  logCollector?.info("Routing to data analysis...");
4370
4407
  } else if (categoryClassification.category === "data_modification") {
@@ -4379,7 +4416,8 @@ ${errorMsg}
4379
4416
  streamCallback,
4380
4417
  collections,
4381
4418
  components,
4382
- toolsToUse
4419
+ toolsToUse,
4420
+ categoryClassification.category
4383
4421
  );
4384
4422
  const elapsedTime = Date.now() - startTime;
4385
4423
  logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime}ms (${(elapsedTime / 1e3).toFixed(2)}s)`);
@@ -5036,8 +5074,10 @@ var get_user_request = async (data, components, sendMessage, anthropicApiKey, gr
5036
5074
  if ("component" in userResponse.data) {
5037
5075
  component = userResponse.data.component;
5038
5076
  }
5039
- if ("textResponse" in userResponse.data) {
5077
+ if ("text" in userResponse.data) {
5040
5078
  textResponse = userResponse.data.text;
5079
+ } else if ("textResponse" in userResponse.data) {
5080
+ textResponse = userResponse.data.textResponse;
5041
5081
  }
5042
5082
  if ("actions" in userResponse.data) {
5043
5083
  actions = userResponse.data.actions || [];