@superatomai/sdk-node 0.0.40 → 0.0.41

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
@@ -3386,30 +3386,47 @@ import { jsonrepair } from "jsonrepair";
3386
3386
  import fs5 from "fs";
3387
3387
  import path4 from "path";
3388
3388
  var PRICING = {
3389
- // Anthropic
3390
- "claude-3-5-sonnet-20241022": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
3389
+ // Anthropic (December 2025)
3390
+ "claude-opus-4-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
3391
+ "claude-opus-4-5-20251101": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
3391
3392
  "claude-sonnet-4-5": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
3392
3393
  "claude-sonnet-4-5-20250929": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
3393
- "claude-3-5-haiku-20241022": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
3394
- "claude-haiku-4-5-20251001": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
3394
+ "claude-haiku-4-5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 },
3395
+ "claude-haiku-4-5-20251001": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 },
3396
+ "claude-3-5-sonnet-20241022": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
3397
+ "claude-3-5-haiku-20241022": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 },
3395
3398
  "claude-3-opus-20240229": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
3396
3399
  "claude-3-sonnet-20240229": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
3397
3400
  "claude-3-haiku-20240307": { input: 0.25, output: 1.25, cacheRead: 0.03, cacheWrite: 0.3 },
3398
- // OpenAI
3399
- "gpt-4o": { input: 2.5, output: 10 },
3401
+ // OpenAI (December 2025)
3402
+ "gpt-5": { input: 1.25, output: 10 },
3403
+ "gpt-5-mini": { input: 0.25, output: 2 },
3404
+ "gpt-4o": { input: 5, output: 15 },
3405
+ // Updated pricing as of late 2025
3400
3406
  "gpt-4o-mini": { input: 0.15, output: 0.6 },
3401
3407
  "gpt-4-turbo": { input: 10, output: 30 },
3402
3408
  "gpt-4": { input: 30, output: 60 },
3403
3409
  "gpt-3.5-turbo": { input: 0.5, output: 1.5 },
3404
- // Gemini
3410
+ // Google Gemini (December 2025)
3411
+ "gemini-3-pro": { input: 2, output: 8 },
3412
+ // New Gemini 3
3413
+ "gemini-2.5-pro": { input: 1.25, output: 10 },
3414
+ // For prompts ≤200K tokens, 2x for >200K
3415
+ "gemini-2.5-flash": { input: 0.15, output: 0.6 },
3416
+ // Standard mode (thinking disabled: $0.60, thinking enabled: $3.50)
3417
+ "gemini-2.5-flash-lite": { input: 0.1, output: 0.4 },
3418
+ "gemini-2.0-flash": { input: 0.1, output: 0.4 },
3419
+ "gemini-2.0-flash-lite": { input: 0.075, output: 0.3 },
3405
3420
  "gemini-1.5-pro": { input: 1.25, output: 5 },
3406
3421
  "gemini-1.5-flash": { input: 0.075, output: 0.3 },
3407
- "gemini-2.0-flash-exp": { input: 0.1, output: 0.4 },
3408
- // Groq (very cheap)
3422
+ // Groq (December 2025)
3409
3423
  "llama-3.3-70b-versatile": { input: 0.59, output: 0.79 },
3410
3424
  "llama-3.1-70b-versatile": { input: 0.59, output: 0.79 },
3411
3425
  "llama-3.1-8b-instant": { input: 0.05, output: 0.08 },
3412
- "mixtral-8x7b-32768": { input: 0.24, output: 0.24 }
3426
+ "llama-4-scout-17b-16e": { input: 0.11, output: 0.34 },
3427
+ "llama-4-maverick-17b-128e": { input: 0.2, output: 0.6 },
3428
+ "mixtral-8x7b-32768": { input: 0.27, output: 0.27 },
3429
+ "qwen3-32b": { input: 0.29, output: 0.59 }
3413
3430
  };
3414
3431
  var DEFAULT_PRICING = { input: 3, output: 15 };
3415
3432
  var LLMUsageLogger = class {
@@ -5336,6 +5353,38 @@ var BaseLLM = class {
5336
5353
  this.fastModel = config?.fastModel || this.getDefaultFastModel();
5337
5354
  this.defaultLimit = config?.defaultLimit || 50;
5338
5355
  this.apiKey = config?.apiKey;
5356
+ this.modelStrategy = config?.modelStrategy || "fast";
5357
+ }
5358
+ /**
5359
+ * Get the appropriate model based on task type and model strategy
5360
+ * @param taskType - 'complex' for text generation/matching, 'simple' for classification/actions
5361
+ * @returns The model string to use for this task
5362
+ */
5363
+ getModelForTask(taskType) {
5364
+ switch (this.modelStrategy) {
5365
+ case "best":
5366
+ return this.model;
5367
+ case "fast":
5368
+ return this.fastModel;
5369
+ case "balanced":
5370
+ default:
5371
+ return taskType === "complex" ? this.model : this.fastModel;
5372
+ }
5373
+ }
5374
+ /**
5375
+ * Set the model strategy at runtime
5376
+ * @param strategy - 'best', 'fast', or 'balanced'
5377
+ */
5378
+ setModelStrategy(strategy) {
5379
+ this.modelStrategy = strategy;
5380
+ logger.info(`[${this.getProviderName()}] Model strategy set to: ${strategy}`);
5381
+ }
5382
+ /**
5383
+ * Get the current model strategy
5384
+ * @returns The current model strategy
5385
+ */
5386
+ getModelStrategy() {
5387
+ return this.modelStrategy;
5339
5388
  }
5340
5389
  /**
5341
5390
  * Get the API key (from instance, parameter, or environment)
@@ -5520,7 +5569,7 @@ ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
5520
5569
  user: prompts.user
5521
5570
  },
5522
5571
  {
5523
- model: this.model,
5572
+ model: this.getModelForTask("complex"),
5524
5573
  maxTokens: 8192,
5525
5574
  temperature: 0.2,
5526
5575
  apiKey: this.getApiKey(apiKey),
@@ -5643,7 +5692,7 @@ ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
5643
5692
  user: prompts.user
5644
5693
  },
5645
5694
  {
5646
- model: this.fastModel,
5695
+ model: this.getModelForTask("simple"),
5647
5696
  maxTokens: 1500,
5648
5697
  temperature: 0.2,
5649
5698
  apiKey: this.getApiKey(apiKey)
@@ -5704,7 +5753,7 @@ ${JSON.stringify(tool.requiredFields || [], null, 2)}`;
5704
5753
  user: prompts.user
5705
5754
  },
5706
5755
  {
5707
- model: this.model,
5756
+ model: this.getModelForTask("complex"),
5708
5757
  maxTokens: 3e3,
5709
5758
  temperature: 0.2,
5710
5759
  apiKey: this.getApiKey(apiKey)
@@ -6194,7 +6243,7 @@ ${errorMsg}
6194
6243
  tools,
6195
6244
  toolHandler,
6196
6245
  {
6197
- model: this.model,
6246
+ model: this.getModelForTask("complex"),
6198
6247
  maxTokens: 4e3,
6199
6248
  temperature: 0.7,
6200
6249
  apiKey: this.getApiKey(apiKey),
@@ -6239,6 +6288,21 @@ ${errorMsg}
6239
6288
  if (category === "general") {
6240
6289
  logger.info(`[${this.getProviderName()}] Skipping component generation for general/conversational question`);
6241
6290
  logCollector?.info("Skipping component generation for general question");
6291
+ logger.info(`[${this.getProviderName()}] Generating actions for general question...`);
6292
+ const nextQuestions = await this.generateNextQuestions(
6293
+ userPrompt,
6294
+ null,
6295
+ // no component
6296
+ void 0,
6297
+ // no component data
6298
+ apiKey,
6299
+ logCollector,
6300
+ conversationHistory,
6301
+ textResponse
6302
+ // pass text response as context
6303
+ );
6304
+ actions = convertQuestionsToActions(nextQuestions);
6305
+ logger.info(`[${this.getProviderName()}] Generated ${actions.length} follow-up actions for general question`);
6242
6306
  } else if (components && components.length > 0) {
6243
6307
  logger.info(`[${this.getProviderName()}] Matching components from text response...`);
6244
6308
  const componentStreamCallback = wrappedStreamCallback && category !== "data_modification" ? (component) => {
@@ -6397,10 +6461,18 @@ ${errorMsg}
6397
6461
  logger.info(`[${this.getProviderName()}] \u2713 100% match - returning UI block directly without adaptation`);
6398
6462
  logCollector?.info(`\u2713 Exact match (${(conversationMatch.similarity * 100).toFixed(2)}%) - returning cached result`);
6399
6463
  logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
6464
+ if (streamCallback && cachedTextResponse) {
6465
+ logger.info(`[${this.getProviderName()}] Streaming cached text response to frontend`);
6466
+ streamCallback(cachedTextResponse);
6467
+ }
6468
+ const cachedActions = conversationMatch.uiBlock?.actions || [];
6400
6469
  return {
6401
6470
  success: true,
6402
6471
  data: {
6472
+ text: cachedTextResponse,
6403
6473
  component,
6474
+ matchedComponents: component?.props?.config?.components || [],
6475
+ actions: cachedActions,
6404
6476
  reasoning: `Exact match from previous conversation (${(conversationMatch.similarity * 100).toFixed(2)}% similarity)`,
6405
6477
  method: `${this.getProviderName()}-semantic-match-exact`,
6406
6478
  semanticSimilarity: conversationMatch.similarity
@@ -6423,10 +6495,18 @@ ${errorMsg}
6423
6495
  logger.info(`[${this.getProviderName()}] Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
6424
6496
  logCollector?.info(`\u2713 UI block adapted successfully`);
6425
6497
  logCollector?.info(`Total time taken: ${elapsedTime2}ms (${(elapsedTime2 / 1e3).toFixed(2)}s)`);
6498
+ if (streamCallback && cachedTextResponse) {
6499
+ logger.info(`[${this.getProviderName()}] Streaming cached text response to frontend (adapted match)`);
6500
+ streamCallback(cachedTextResponse);
6501
+ }
6502
+ const cachedActions = conversationMatch.uiBlock?.actions || [];
6426
6503
  return {
6427
6504
  success: true,
6428
6505
  data: {
6506
+ text: cachedTextResponse,
6429
6507
  component: adaptResult.adaptedComponent,
6508
+ matchedComponents: adaptResult.adaptedComponent?.props?.config?.components || [],
6509
+ actions: cachedActions,
6430
6510
  reasoning: `Adapted from previous conversation: ${originalPrompt}`,
6431
6511
  method: `${this.getProviderName()}-semantic-match`,
6432
6512
  semanticSimilarity: conversationMatch.similarity,
@@ -6539,15 +6619,26 @@ ${errorMsg}
6539
6619
  /**
6540
6620
  * Generate next questions that the user might ask based on the original prompt and generated component
6541
6621
  * This helps provide intelligent suggestions for follow-up queries
6622
+ * For general/conversational questions without components, pass textResponse instead
6542
6623
  */
6543
- async generateNextQuestions(originalUserPrompt, component, componentData, apiKey, logCollector, conversationHistory) {
6624
+ async generateNextQuestions(originalUserPrompt, component, componentData, apiKey, logCollector, conversationHistory, textResponse) {
6544
6625
  try {
6545
- const component_info = `
6626
+ let component_info;
6627
+ if (component) {
6628
+ component_info = `
6546
6629
  Component Name: ${component.name}
6547
6630
  Component Type: ${component.type}
6548
6631
  Component Description: ${component.description || "No description"}
6549
6632
  Component Props: ${component.props ? JSON.stringify(component.props, null, 2) : "No props"}
6550
6633
  `;
6634
+ } else if (textResponse) {
6635
+ component_info = `
6636
+ Response Type: Text/Conversational Response
6637
+ Response Content: ${textResponse.substring(0, 1e3)}${textResponse.length > 1e3 ? "..." : ""}
6638
+ `;
6639
+ } else {
6640
+ component_info = "No component or response context available";
6641
+ }
6551
6642
  const component_data = componentData ? `Component Data: ${JSON.stringify(componentData, null, 2)}` : "";
6552
6643
  const prompts = await promptLoader.loadPrompts("actions", {
6553
6644
  ORIGINAL_USER_PROMPT: originalUserPrompt,
@@ -6561,7 +6652,7 @@ ${errorMsg}
6561
6652
  user: prompts.user
6562
6653
  },
6563
6654
  {
6564
- model: this.fastModel,
6655
+ model: this.getModelForTask("simple"),
6565
6656
  maxTokens: 1200,
6566
6657
  temperature: 0.7,
6567
6658
  apiKey: this.getApiKey(apiKey)
@@ -11088,7 +11179,9 @@ var SuperatomSDK = class {
11088
11179
  this.openaiApiKey = config.OPENAI_API_KEY || process.env.OPENAI_API_KEY || "";
11089
11180
  this.llmProviders = config.LLM_PROVIDERS || getLLMProviders();
11090
11181
  this.databaseType = config.databaseType || "postgresql";
11091
- logger.info(`Initializing Superatom SDK v${SDK_VERSION} for project ${this.projectId}, llm providers: ${this.llmProviders.join(", ")}, database type: ${this.databaseType}`);
11182
+ this.modelStrategy = config.modelStrategy || "fast";
11183
+ this.applyModelStrategy(this.modelStrategy);
11184
+ logger.info(`Initializing Superatom SDK v${SDK_VERSION} for project ${this.projectId}, llm providers: ${this.llmProviders.join(", ")}, database type: ${this.databaseType}, model strategy: ${this.modelStrategy}`);
11092
11185
  this.userManager = new UserManager(this.projectId, 5e3);
11093
11186
  this.dashboardManager = new DashboardManager(this.projectId);
11094
11187
  this.reportManager = new ReportManager(this.projectId);
@@ -11467,6 +11560,31 @@ var SuperatomSDK = class {
11467
11560
  getTools() {
11468
11561
  return this.tools;
11469
11562
  }
11563
+ /**
11564
+ * Apply model strategy to all LLM provider singletons
11565
+ * @param strategy - 'best', 'fast', or 'balanced'
11566
+ */
11567
+ applyModelStrategy(strategy) {
11568
+ anthropicLLM.setModelStrategy(strategy);
11569
+ groqLLM.setModelStrategy(strategy);
11570
+ geminiLLM.setModelStrategy(strategy);
11571
+ openaiLLM.setModelStrategy(strategy);
11572
+ logger.info(`Model strategy '${strategy}' applied to all LLM providers`);
11573
+ }
11574
+ /**
11575
+ * Set model strategy at runtime
11576
+ * @param strategy - 'best', 'fast', or 'balanced'
11577
+ */
11578
+ setModelStrategy(strategy) {
11579
+ this.modelStrategy = strategy;
11580
+ this.applyModelStrategy(strategy);
11581
+ }
11582
+ /**
11583
+ * Get current model strategy
11584
+ */
11585
+ getModelStrategy() {
11586
+ return this.modelStrategy;
11587
+ }
11470
11588
  };
11471
11589
  export {
11472
11590
  BM25L,
@@ -11481,9 +11599,13 @@ export {
11481
11599
  UIBlock,
11482
11600
  UILogCollector,
11483
11601
  UserManager,
11602
+ anthropicLLM,
11603
+ geminiLLM,
11604
+ groqLLM,
11484
11605
  hybridRerank,
11485
11606
  llmUsageLogger,
11486
11607
  logger,
11608
+ openaiLLM,
11487
11609
  rerankChromaResults,
11488
11610
  rerankConversationResults,
11489
11611
  userPromptErrorLogger