@superatomai/sdk-node 0.0.1-mds → 0.0.1-s

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.d.ts CHANGED
@@ -741,6 +741,10 @@ declare const ToolSchema: z.ZodObject<{
741
741
  id: z.ZodString;
742
742
  name: z.ZodString;
743
743
  description: z.ZodString;
744
+ /** Tool type: "source" = routed through SourceAgent, "direct" = called directly by MainAgent */
745
+ toolType: z.ZodOptional<z.ZodEnum<["source", "direct"]>>;
746
+ /** Full untruncated schema for source agent (all columns visible) */
747
+ fullSchema: z.ZodOptional<z.ZodString>;
744
748
  params: z.ZodRecord<z.ZodString, z.ZodString>;
745
749
  fn: z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodAny>;
746
750
  outputSchema: z.ZodOptional<z.ZodObject<{
@@ -779,6 +783,8 @@ declare const ToolSchema: z.ZodObject<{
779
783
  name: string;
780
784
  description: string;
781
785
  fn: (args_0: any, ...args: unknown[]) => any;
786
+ toolType?: "source" | "direct" | undefined;
787
+ fullSchema?: string | undefined;
782
788
  outputSchema?: {
783
789
  description: string;
784
790
  fields: {
@@ -793,6 +799,8 @@ declare const ToolSchema: z.ZodObject<{
793
799
  name: string;
794
800
  description: string;
795
801
  fn: (args_0: any, ...args: unknown[]) => any;
802
+ toolType?: "source" | "direct" | undefined;
803
+ fullSchema?: string | undefined;
796
804
  outputSchema?: {
797
805
  description: string;
798
806
  fields: {
@@ -852,6 +860,18 @@ interface SuperatomSDKConfig {
852
860
  * - 'balanced': Use best model for complex tasks, fast model for simple tasks (default)
853
861
  */
854
862
  modelStrategy?: ModelStrategy;
863
+ /**
864
+ * Model for the main agent (routing + analysis).
865
+ * Format: "provider/model-name" (e.g., "anthropic/claude-haiku-4-5-20251001")
866
+ * If not set, uses the provider's default model.
867
+ */
868
+ mainAgentModel?: string;
869
+ /**
870
+ * Model for source agents (per-source query generation).
871
+ * Format: "provider/model-name" (e.g., "anthropic/claude-haiku-4-5-20251001")
872
+ * If not set, uses the provider's default model.
873
+ */
874
+ sourceAgentModel?: string;
855
875
  /**
856
876
  * Separate model configuration for DASH_COMP flow (dashboard component picking)
857
877
  * If not provided, falls back to provider-based model selection
@@ -870,6 +890,12 @@ interface SuperatomSDKConfig {
870
890
  * Default: 5 minutes
871
891
  */
872
892
  queryCacheTTL?: number;
893
+ /**
894
+ * Dashboard conversation history TTL (Time To Live) in minutes
895
+ * Per-dashboard conversation histories expire after this duration
896
+ * Default: 30 minutes
897
+ */
898
+ dashboardHistoryTTL?: number;
873
899
  }
874
900
 
875
901
  declare const KbNodesQueryFiltersSchema: z.ZodObject<{
@@ -877,18 +903,18 @@ declare const KbNodesQueryFiltersSchema: z.ZodObject<{
877
903
  category: z.ZodOptional<z.ZodString>;
878
904
  tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
879
905
  type: z.ZodOptional<z.ZodEnum<["global", "user", "query"]>>;
880
- createdBy: z.ZodOptional<z.ZodNumber>;
906
+ createdBy: z.ZodOptional<z.ZodString>;
881
907
  }, "strip", z.ZodTypeAny, {
882
908
  type?: "query" | "user" | "global" | undefined;
883
909
  query?: string | undefined;
884
910
  category?: string | undefined;
885
- createdBy?: number | undefined;
911
+ createdBy?: string | undefined;
886
912
  tags?: string[] | undefined;
887
913
  }, {
888
914
  type?: "query" | "user" | "global" | undefined;
889
915
  query?: string | undefined;
890
916
  category?: string | undefined;
891
- createdBy?: number | undefined;
917
+ createdBy?: string | undefined;
892
918
  tags?: string[] | undefined;
893
919
  }>;
894
920
  type KbNodesQueryFilters = z.infer<typeof KbNodesQueryFiltersSchema>;
@@ -901,27 +927,27 @@ declare const KbNodesRequestPayloadSchema: z.ZodObject<{
901
927
  category: z.ZodOptional<z.ZodString>;
902
928
  tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
903
929
  type: z.ZodOptional<z.ZodEnum<["global", "user", "query"]>>;
904
- createdBy: z.ZodOptional<z.ZodNumber>;
905
- updatedBy: z.ZodOptional<z.ZodNumber>;
906
- userId: z.ZodOptional<z.ZodNumber>;
930
+ createdBy: z.ZodOptional<z.ZodString>;
931
+ updatedBy: z.ZodOptional<z.ZodString>;
932
+ userId: z.ZodOptional<z.ZodString>;
907
933
  query: z.ZodOptional<z.ZodString>;
908
934
  filters: z.ZodOptional<z.ZodObject<{
909
935
  query: z.ZodOptional<z.ZodString>;
910
936
  category: z.ZodOptional<z.ZodString>;
911
937
  tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
912
938
  type: z.ZodOptional<z.ZodEnum<["global", "user", "query"]>>;
913
- createdBy: z.ZodOptional<z.ZodNumber>;
939
+ createdBy: z.ZodOptional<z.ZodString>;
914
940
  }, "strip", z.ZodTypeAny, {
915
941
  type?: "query" | "user" | "global" | undefined;
916
942
  query?: string | undefined;
917
943
  category?: string | undefined;
918
- createdBy?: number | undefined;
944
+ createdBy?: string | undefined;
919
945
  tags?: string[] | undefined;
920
946
  }, {
921
947
  type?: "query" | "user" | "global" | undefined;
922
948
  query?: string | undefined;
923
949
  category?: string | undefined;
924
- createdBy?: number | undefined;
950
+ createdBy?: string | undefined;
925
951
  tags?: string[] | undefined;
926
952
  }>>;
927
953
  limit: z.ZodOptional<z.ZodNumber>;
@@ -932,17 +958,17 @@ declare const KbNodesRequestPayloadSchema: z.ZodObject<{
932
958
  query?: string | undefined;
933
959
  title?: string | undefined;
934
960
  category?: string | undefined;
935
- userId?: number | undefined;
961
+ userId?: string | undefined;
936
962
  limit?: number | undefined;
937
963
  filters?: {
938
964
  type?: "query" | "user" | "global" | undefined;
939
965
  query?: string | undefined;
940
966
  category?: string | undefined;
941
- createdBy?: number | undefined;
967
+ createdBy?: string | undefined;
942
968
  tags?: string[] | undefined;
943
969
  } | undefined;
944
- createdBy?: number | undefined;
945
- updatedBy?: number | undefined;
970
+ createdBy?: string | undefined;
971
+ updatedBy?: string | undefined;
946
972
  offset?: number | undefined;
947
973
  tags?: string[] | undefined;
948
974
  content?: string | undefined;
@@ -952,17 +978,17 @@ declare const KbNodesRequestPayloadSchema: z.ZodObject<{
952
978
  query?: string | undefined;
953
979
  title?: string | undefined;
954
980
  category?: string | undefined;
955
- userId?: number | undefined;
981
+ userId?: string | undefined;
956
982
  limit?: number | undefined;
957
983
  filters?: {
958
984
  type?: "query" | "user" | "global" | undefined;
959
985
  query?: string | undefined;
960
986
  category?: string | undefined;
961
- createdBy?: number | undefined;
987
+ createdBy?: string | undefined;
962
988
  tags?: string[] | undefined;
963
989
  } | undefined;
964
- createdBy?: number | undefined;
965
- updatedBy?: number | undefined;
990
+ createdBy?: string | undefined;
991
+ updatedBy?: string | undefined;
966
992
  offset?: number | undefined;
967
993
  tags?: string[] | undefined;
968
994
  content?: string | undefined;
@@ -975,17 +1001,17 @@ declare const KbNodesRequestPayloadSchema: z.ZodObject<{
975
1001
  query?: string | undefined;
976
1002
  title?: string | undefined;
977
1003
  category?: string | undefined;
978
- userId?: number | undefined;
1004
+ userId?: string | undefined;
979
1005
  limit?: number | undefined;
980
1006
  filters?: {
981
1007
  type?: "query" | "user" | "global" | undefined;
982
1008
  query?: string | undefined;
983
1009
  category?: string | undefined;
984
- createdBy?: number | undefined;
1010
+ createdBy?: string | undefined;
985
1011
  tags?: string[] | undefined;
986
1012
  } | undefined;
987
- createdBy?: number | undefined;
988
- updatedBy?: number | undefined;
1013
+ createdBy?: string | undefined;
1014
+ updatedBy?: string | undefined;
989
1015
  offset?: number | undefined;
990
1016
  tags?: string[] | undefined;
991
1017
  content?: string | undefined;
@@ -998,17 +1024,17 @@ declare const KbNodesRequestPayloadSchema: z.ZodObject<{
998
1024
  query?: string | undefined;
999
1025
  title?: string | undefined;
1000
1026
  category?: string | undefined;
1001
- userId?: number | undefined;
1027
+ userId?: string | undefined;
1002
1028
  limit?: number | undefined;
1003
1029
  filters?: {
1004
1030
  type?: "query" | "user" | "global" | undefined;
1005
1031
  query?: string | undefined;
1006
1032
  category?: string | undefined;
1007
- createdBy?: number | undefined;
1033
+ createdBy?: string | undefined;
1008
1034
  tags?: string[] | undefined;
1009
1035
  } | undefined;
1010
- createdBy?: number | undefined;
1011
- updatedBy?: number | undefined;
1036
+ createdBy?: string | undefined;
1037
+ updatedBy?: string | undefined;
1012
1038
  offset?: number | undefined;
1013
1039
  tags?: string[] | undefined;
1014
1040
  content?: string | undefined;
@@ -1626,12 +1652,20 @@ declare class Thread {
1626
1652
 
1627
1653
  /**
1628
1654
  * ThreadManager manages all threads globally
1629
- * Provides methods to create, retrieve, and delete threads
1655
+ * Provides methods to create, retrieve, and delete threads.
1656
+ * Includes automatic cleanup to prevent unbounded memory growth.
1630
1657
  */
1631
1658
  declare class ThreadManager {
1632
1659
  private static instance;
1633
1660
  private threads;
1661
+ private cleanupInterval;
1662
+ private readonly threadTtlMs;
1634
1663
  private constructor();
1664
+ /**
1665
+ * Periodically remove threads older than 7 days.
1666
+ * Runs every hour to avoid frequent iteration over the map.
1667
+ */
1668
+ private startCleanup;
1635
1669
  /**
1636
1670
  * Get singleton instance of ThreadManager
1637
1671
  */
@@ -2116,6 +2150,98 @@ declare class QueryExecutionService {
2116
2150
  validateComponentQueries(components: Component[], collections: any, apiKey?: string): Promise<BatchValidationResult>;
2117
2151
  }
2118
2152
 
2153
+ /**
2154
+ * StreamBuffer - Buffered streaming utility for smoother text delivery
2155
+ * Batches small chunks together and flushes at regular intervals
2156
+ */
2157
+ type StreamCallback = (chunk: string) => void;
2158
+ /**
2159
+ * StreamBuffer class for managing buffered streaming output
2160
+ * Provides smooth text delivery by batching small chunks
2161
+ */
2162
+ declare class StreamBuffer {
2163
+ private buffer;
2164
+ private flushTimer;
2165
+ private callback;
2166
+ private fullText;
2167
+ constructor(callback?: StreamCallback);
2168
+ /**
2169
+ * Check if the buffer has a callback configured
2170
+ */
2171
+ hasCallback(): boolean;
2172
+ /**
2173
+ * Get all text that has been written (including already flushed)
2174
+ */
2175
+ getFullText(): string;
2176
+ /**
2177
+ * Write a chunk to the buffer
2178
+ * Large chunks or chunks with newlines are flushed immediately
2179
+ * Small chunks are batched and flushed after a short interval
2180
+ *
2181
+ * @param chunk - Text chunk to write
2182
+ */
2183
+ write(chunk: string): void;
2184
+ /**
2185
+ * Flush the buffer immediately
2186
+ * Call this before tool execution or other operations that need clean output
2187
+ */
2188
+ flush(): void;
2189
+ /**
2190
+ * Internal flush implementation
2191
+ */
2192
+ private flushNow;
2193
+ /**
2194
+ * Clean up resources
2195
+ * Call this when done with the buffer
2196
+ */
2197
+ dispose(): void;
2198
+ }
2199
+
2200
+ /**
2201
+ * ToolExecutorService - Handles execution of SQL queries and external tools
2202
+ * Extracted from BaseLLM.generateTextResponse for better separation of concerns
2203
+ */
2204
+
2205
+ /**
2206
+ * External tool definition
2207
+ */
2208
+ interface ExternalTool {
2209
+ id: string;
2210
+ name: string;
2211
+ description?: string;
2212
+ /** Tool type: "source" = routed through SourceAgent, "direct" = called directly by MainAgent */
2213
+ toolType?: 'source' | 'direct';
2214
+ /** Full untruncated schema for source agent (all columns visible) */
2215
+ fullSchema?: string;
2216
+ /** Schema size tier: small (≤50 tables), medium (51-200), large (201-500), very_large (500+) */
2217
+ schemaTier?: string;
2218
+ /** Schema search function for very_large tier — keyword search over entities */
2219
+ schemaSearchFn?: (keywords: string[]) => string;
2220
+ fn: (input: any) => Promise<any>;
2221
+ limit?: number;
2222
+ outputSchema?: any;
2223
+ executionType?: 'immediate' | 'deferred';
2224
+ userProvidedData?: any;
2225
+ params?: Record<string, any>;
2226
+ }
2227
+ /**
2228
+ * Executed tool tracking info
2229
+ */
2230
+ interface ExecutedToolInfo {
2231
+ id: string;
2232
+ name: string;
2233
+ params: any;
2234
+ result: {
2235
+ _totalRecords: number;
2236
+ _recordsShown: number;
2237
+ _metadata?: any;
2238
+ _sampleData: any[];
2239
+ };
2240
+ outputSchema?: any;
2241
+ sourceSchema?: string;
2242
+ sourceType?: string;
2243
+ }
2244
+
2119
2245
  /**
2120
2246
  * Task types for model selection
2121
2247
  * - 'complex': Text generation, component matching, parameter adaptation (uses best model in balanced mode)
@@ -2331,17 +2457,29 @@ declare class OpenAILLM extends BaseLLM {
2331
2457
  declare const openaiLLM: OpenAILLM;
2332
2458
 
2333
2459
  /**
2334
- * Query Cache - Stores query results with configurable TTL
2335
- * Used to avoid re-executing queries that were already validated
2460
+ * Query Cache Two mechanisms:
2461
+ *
2462
+ * 1. `cache` (query string → result data) — TTL-based with max size, for avoiding re-execution
2463
+ * of recently validated queries. LRU eviction when max size exceeded.
2464
+ *
2465
+ * 2. Encrypted queryId tokens — SQL is encrypted into the queryId itself (self-contained).
2466
+ * No server-side storage needed for SQL mappings. The token is decrypted on each request.
2467
+ * This eliminates the unbounded queryIdCache that previously grew forever and caused
2468
+ * memory bloat (hundreds of MBs after thousands of queries).
2469
+ *
2470
+ * Result data can still be cached temporarily via the data cache (mechanism 1).
2336
2471
  */
2337
2472
  declare class QueryCache {
2338
2473
  private cache;
2339
2474
  private ttlMs;
2475
+ private maxCacheSize;
2340
2476
  private cleanupInterval;
2477
+ private readonly algorithm;
2478
+ private encryptionKey;
2341
2479
  constructor();
2342
2480
  /**
2343
2481
  * Set the cache TTL (Time To Live)
2344
- * @param minutes - TTL in minutes (default: 5)
2482
+ * @param minutes - TTL in minutes (default: 10)
2345
2483
  */
2346
2484
  setTTL(minutes: number): void;
2347
2485
  /**
@@ -2349,8 +2487,7 @@ declare class QueryCache {
2349
2487
  */
2350
2488
  getTTL(): number;
2351
2489
  /**
2352
- * Store query result in cache
2353
- * Key is the exact query string (or JSON for parameterized queries)
2490
+ * Store query result in data cache
2354
2491
  */
2355
2492
  set(query: string, data: any): void;
2356
2493
  /**
@@ -2374,12 +2511,39 @@ declare class QueryCache {
2374
2511
  */
2375
2512
  getStats(): {
2376
2513
  size: number;
2514
+ queryIdCount: number;
2377
2515
  oldestEntryAge: number | null;
2378
2516
  };
2379
2517
  /**
2380
- * Start periodic cleanup of expired entries
2518
+ * Start periodic cleanup of expired data cache entries.
2381
2519
  */
2382
2520
  private startCleanup;
2521
+ /**
2522
+ * Encrypt a payload into a self-contained token.
2523
+ */
2524
+ private encrypt;
2525
+ /**
2526
+ * Decrypt a token back to the original payload.
2527
+ */
2528
+ private decrypt;
2529
+ /**
2530
+ * Store a query by generating an encrypted token as queryId.
2531
+ * The SQL is encrypted INTO the token — nothing stored in memory.
2532
+ * If data is provided, it's cached temporarily in the data cache.
2533
+ */
2534
+ storeQuery(query: any, data?: any): string;
2535
+ /**
2536
+ * Get a stored query by decrypting its token.
2537
+ * Returns the SQL + any cached result data.
2538
+ */
2539
+ getQuery(queryId: string): {
2540
+ query: any;
2541
+ data: any;
2542
+ } | null;
2543
+ /**
2544
+ * Update cached data for a queryId token
2545
+ */
2546
+ setQueryData(queryId: string, data: any): void;
2383
2547
  /**
2384
2548
  * Stop cleanup interval (for graceful shutdown)
2385
2549
  */
@@ -2387,6 +2551,580 @@ declare class QueryCache {
2387
2551
  }
2388
2552
  declare const queryCache: QueryCache;
2389
2553
 
2554
+ /**
2555
+ * Manages conversation history scoped per user + dashboard.
2556
+ * Each user-dashboard pair has its own isolated history that expires after a configurable TTL.
2557
+ */
2558
+ declare class DashboardConversationHistory {
2559
+ private histories;
2560
+ private ttlMs;
2561
+ private maxEntries;
2562
+ private cleanupInterval;
2563
+ constructor();
2564
+ /**
2565
+ * Set the TTL for dashboard histories
2566
+ * @param minutes - TTL in minutes
2567
+ */
2568
+ setTTL(minutes: number): void;
2569
+ /**
2570
+ * Set max entries per dashboard
2571
+ */
2572
+ setMaxEntries(max: number): void;
2573
+ /**
2574
+ * Add a conversation entry for a user's dashboard
2575
+ */
2576
+ addEntry(dashboardId: string, userPrompt: string, componentSummary: string, userId?: string): void;
2577
+ /**
2578
+ * Get formatted conversation history for a user's dashboard
2579
+ */
2580
+ getHistory(dashboardId: string, userId?: string): string;
2581
+ /**
2582
+ * Clear history for a specific user's dashboard
2583
+ */
2584
+ clearDashboard(dashboardId: string, userId?: string): void;
2585
+ /**
2586
+ * Clear all dashboard histories
2587
+ */
2588
+ clearAll(): void;
2589
+ /**
2590
+ * Start periodic cleanup of expired histories
2591
+ */
2592
+ private startCleanup;
2593
+ /**
2594
+ * Stop cleanup interval (for graceful shutdown)
2595
+ */
2596
+ destroy(): void;
2597
+ }
2598
+ declare const dashboardConversationHistory: DashboardConversationHistory;
2599
+
2600
+ /**
2601
+ * Multi-Agent Architecture Types
2602
+ *
2603
+ * Defines interfaces for the hierarchical agent system:
2604
+ * - Main Agent: ONE LLM.streamWithTools() call with source agent tools
2605
+ * - Source Agents: independent agents that query individual data sources
2606
+ *
2607
+ * The main agent sees only source summaries. When it calls a source tool,
2608
+ * the SourceAgent runs independently (own LLM, own retries) and returns clean data.
2609
+ */
2610
+
2611
+ /**
2612
+ * Per-entity detail: name, row count, and column names.
2613
+ * Gives the main agent enough context to route to the right source.
2614
+ */
2615
+ interface EntityDetail {
2616
+ /** Entity name (table, sheet, endpoint) */
2617
+ name: string;
2618
+ /** Approximate row count */
2619
+ rowCount?: number;
2620
+ /** Column/field names */
2621
+ columns: string[];
2622
+ }
2623
+ /**
2624
+ * Representation of a data source for the main agent.
2625
+ * Contains entity names WITH column names so the LLM can route accurately.
2626
+ */
2627
+ interface SourceSummary {
2628
+ /** Source ID (matches tool ID prefix) */
2629
+ id: string;
2630
+ /** Human-readable source name */
2631
+ name: string;
2632
+ /** Source type: postgres, excel, rest_api, etc. */
2633
+ type: string;
2634
+ /** Brief description of what data this source contains */
2635
+ description: string;
2636
+ /** Detailed entity info with column names for routing */
2637
+ entityDetails: EntityDetail[];
2638
+ /** The tool ID associated with this source */
2639
+ toolId: string;
2640
+ }
2641
+ /**
2642
+ * What a source agent returns after querying its data source.
2643
+ * The main agent uses this to analyze and compose the final response.
2644
+ */
2645
+ interface SourceAgentResult {
2646
+ /** Source ID */
2647
+ sourceId: string;
2648
+ /** Source name */
2649
+ sourceName: string;
2650
+ /** Whether the query succeeded */
2651
+ success: boolean;
2652
+ /** Result data rows */
2653
+ data: any[];
2654
+ /** Metadata about the query execution */
2655
+ metadata: SourceAgentMetadata;
2656
+ /** Tool execution info for the last successful query (backward compat) */
2657
+ executedTool: ExecutedToolInfo;
2658
+ /** All successful tool executions (primary + follow-up queries) */
2659
+ allExecutedTools?: ExecutedToolInfo[];
2660
+ /** Error message if failed */
2661
+ error?: string;
2662
+ }
2663
+ interface SourceAgentMetadata {
2664
+ /** Total rows that matched the query (before limit) */
2665
+ totalRowsMatched: number;
2666
+ /** Rows actually returned (after limit) */
2667
+ rowsReturned: number;
2668
+ /** Whether the result was truncated by the row limit */
2669
+ isLimited: boolean;
2670
+ /** The query/params that were executed */
2671
+ queryExecuted?: string;
2672
+ /** Execution time in milliseconds */
2673
+ executionTimeMs: number;
2674
+ }
2675
+ /**
2676
+ * The complete response from the multi-agent system.
2677
+ * Contains everything needed for text display + component generation.
2678
+ */
2679
+ interface AgentResponse {
2680
+ /** Generated text response (analysis of the data) */
2681
+ text: string;
2682
+ /** All executed tools across all source agents (for component generation) */
2683
+ executedTools: ExecutedToolInfo[];
2684
+ /** Individual results from each source agent */
2685
+ sourceResults: SourceAgentResult[];
2686
+ /**
2687
+ * Populated when MainAgent wrote AND successfully executed a script during its turn.
2688
+ * Caller (agent-user-response.ts) persists it via ScriptStore.save().
2689
+ * Absent when MainAgent didn't write one (trivial question / all attempts failed).
2690
+ */
2691
+ savedScript?: AgentWrittenScript;
2692
+ }
2693
+ /**
2694
+ * A script MainAgent authored + verified during its turn. Shape aligns with
2695
+ * what ScriptStore.save() needs — minus store-assigned fields (id, timestamps, counts).
2696
+ */
2697
+ interface AgentWrittenScript {
2698
+ /**
2699
+ * `ScriptRecipe.id` of the draft that was authored + verified during this turn.
2700
+ * The caller passes this to `ScriptStore.promoteToVerified(recipeId, …)` to
2701
+ * flip the draft to verified status and (when possible) drop the turn-suffix
2702
+ * from its filename.
2703
+ */
2704
+ recipeId: string;
2705
+ name: string;
2706
+ intentDescription: string;
2707
+ tags: string[];
2708
+ parameters: Array<{
2709
+ name: string;
2710
+ type: 'string' | 'number' | 'date' | 'date_range' | 'enum' | 'boolean';
2711
+ required: boolean;
2712
+ default?: any;
2713
+ enumValues?: Record<string, string>;
2714
+ description: string;
2715
+ }>;
2716
+ scriptBody: string;
2717
+ /** Source IDs referenced by the script (extracted from ctx.query calls) */
2718
+ sourceIds: string[];
2719
+ /** Tables referenced in the script's SQL (regex-extracted) */
2720
+ tables: string[];
2721
+ /** Executed queries from the verified run — fed to component generation */
2722
+ executedQueries: Array<{
2723
+ sourceId: string;
2724
+ sourceName: string;
2725
+ sql: string;
2726
+ data: any[];
2727
+ count: number;
2728
+ totalCount?: number;
2729
+ executionTimeMs: number;
2730
+ /**
2731
+ * True for synthetic entries (ctx.emit datasets, the computed:_final
2732
+ * post-JS data). The component generator routes virtual sources through
2733
+ * the script_dataset sentinel toolId so the frontend resolves them via
2734
+ * queryCache instead of attempting to re-execute SQL.
2735
+ */
2736
+ virtual?: boolean;
2737
+ }>;
2738
+ }
2739
+ /**
2740
+ * Configuration for the multi-agent system.
2741
+ * Controls limits, models, and behavior.
2742
+ */
2743
+ interface AgentConfig {
2744
+ /** Max rows a source agent can return (default: 50) */
2745
+ maxRowsPerSource: number;
2746
+ /** Model for the main agent (routing + analysis in one LLM call) */
2747
+ mainAgentModel: string;
2748
+ /** Model for source agent query generation */
2749
+ sourceAgentModel: string;
2750
+ /** API key for LLM calls */
2751
+ apiKey?: string;
2752
+ /** Max retry attempts per source agent */
2753
+ maxRetries: number;
2754
+ /** Max tool calling iterations for the main agent loop */
2755
+ maxIterations: number;
2756
+ /** Global knowledge base context (static, same for all users/questions — cached in system prompt) */
2757
+ globalKnowledgeBase?: string;
2758
+ /** Per-request knowledge base context (user-specific + query-matched — dynamic, not cached) */
2759
+ knowledgeBaseContext?: string;
2760
+ /** Collections registry (ChromaDB search hooks) for embedding-based schema + source search */
2761
+ collections?: any;
2762
+ /** Optional project ID for scoping embedding searches */
2763
+ projectId?: string;
2764
+ }
2765
+ /**
2766
+ * Default agent configuration
2767
+ */
2768
+ declare const DEFAULT_AGENT_CONFIG: AgentConfig;
2769
+
2770
+ /**
2771
+ * Script Flow Types
2772
+ *
2773
+ * Defines interfaces for the script-based query architecture:
2774
+ * - ScriptRecipe: metadata for matching, validation, and quality tracking
2775
+ * - ScriptResult: output from executing a script
2776
+ * - ScriptMatch: result from the LLM-based script matcher
2777
+ */
2778
+ /**
2779
+ * Recipe metadata stored alongside each script.
2780
+ * Used for matching, validation, and quality tracking.
2781
+ */
2782
+ interface ScriptRecipe {
2783
+ /** Unique script identifier */
2784
+ id: string;
2785
+ /** Version number (incremented on regeneration) */
2786
+ version: number;
2787
+ /** Human-readable name (e.g., "Revenue by Dimension") */
2788
+ name: string;
2789
+ /** Natural language description of what this script does */
2790
+ intentDescription: string;
2791
+ /** Keyword tags for quick filtering */
2792
+ tags: string[];
2793
+ /** Source tool IDs this script queries (e.g., ["mssql-abc123_query"]) */
2794
+ sourceIds: string[];
2795
+ /** Table names used (for future schema drift detection) */
2796
+ tables: string[];
2797
+ /** Parameter definitions — what can vary */
2798
+ parameters: ScriptParameter[];
2799
+ /** The script function body as a string */
2800
+ scriptBody: string;
2801
+ /** Times this script was used successfully */
2802
+ successCount: number;
2803
+ /** Times this script failed */
2804
+ failureCount: number;
2805
+ /** ISO timestamp of last usage */
2806
+ lastUsed: string;
2807
+ /** Original user question that created this script */
2808
+ createdFrom: string;
2809
+ /** ISO timestamp */
2810
+ createdAt: string;
2811
+ /** ISO timestamp */
2812
+ updatedAt: string;
2813
+ /**
2814
+ * `recipe.id` of the parent this script was forked from.
2815
+ * Undefined for root scripts (those written from scratch by MainAgent).
2816
+ * See backend/docs/SCRIPT-FLOW-FORK-ADAPT.md.
2817
+ */
2818
+ parentId?: string;
2819
+ /** 0 for root scripts; `parent.forkDepth + 1` for forks. Capped at 3. */
2820
+ forkDepth?: number;
2821
+ /**
2822
+ * Brief description of what this fork changed vs its parent
2823
+ * (sourced from the matcher's `modificationHint`).
2824
+ */
2825
+ forkReason?: string;
2826
+ /**
2827
+ * Lifecycle stage of this recipe on disk.
2828
+ * - 'draft': written by MainAgent's write_script during a turn; filtered out
2829
+ * of `ScriptStore.getAll()` so the matcher never picks it.
2830
+ * Filename is suffixed with `turnId` to keep concurrent turns
2831
+ * from clobbering each other's drafts.
2832
+ * - 'verified': promoted after `execute_script` succeeded; the matcher sees it.
2833
+ * Filename drops the turn suffix unless a verified file with
2834
+ * the same slug already exists (collision case keeps the suffix).
2835
+ *
2836
+ * Recipes loaded from disk without this field default to 'verified' so
2837
+ * existing scripts keep working unchanged.
2838
+ */
2839
+ status?: 'draft' | 'verified';
2840
+ /**
2841
+ * Per-turn unique suffix used for draft filenames (e.g. `1714745623-x9k2`).
2842
+ * Set when the draft is saved; carried until the recipe is promoted.
2843
+ */
2844
+ turnId?: string;
2845
+ /**
2846
+ * Last execution error captured by `recordDraftError` while the recipe was
2847
+ * still a draft. Lets users open the draft .json file and see why it failed
2848
+ * without grepping logs. Cleared on promotion to 'verified'.
2849
+ */
2850
+ lastError?: {
2851
+ phase: 'compile' | 'runtime' | 'timeout' | 'ipc';
2852
+ message: string;
2853
+ at: string;
2854
+ attempt: number;
2855
+ };
2856
+ }
2857
+ interface ScriptParameter {
2858
+ /** Parameter name (used in script body as params.name) */
2859
+ name: string;
2860
+ /** Parameter type */
2861
+ type: 'string' | 'number' | 'date' | 'date_range' | 'enum' | 'boolean';
2862
+ /** Whether this parameter is required */
2863
+ required: boolean;
2864
+ /** Default value if not provided */
2865
+ default?: any;
2866
+ /** For enum type — maps user-facing values to internal values */
2867
+ enumValues?: Record<string, string>;
2868
+ /** Human-readable description (used in the matcher LLM prompt) */
2869
+ description: string;
2870
+ }
2871
+
2872
+ /**
2873
+ * ScriptStore — Persistent Storage for Script Recipes
2874
+ *
2875
+ * Layout:
2876
+ * scripts-store/
2877
+ * metadata/<name>.json ← recipe metadata (params, tables, counts, ...)
2878
+ * <name>.ts ← the getData() function body, editable in your IDE
2879
+ *
2880
+ * Each VM deployment is a single project, so no project ID prefix needed.
2881
+ * Legacy single-file format (JSON with embedded scriptBody) is still loadable
2882
+ * for backwards compatibility and auto-migrated to the split format on next save.
2883
+ */
2884
+
2885
+ /**
2886
+ * Input for `ScriptStore.saveDraft()`. Identifies the draft by `recipeId` so
2887
+ * retries within the same turn overwrite the same files (or omit `recipeId`
2888
+ * on the first call to mint a fresh draft).
2889
+ */
2890
+ interface SaveDraftInput {
2891
+ /** Reuse an existing draft (retry); omit to mint a new one. */
2892
+ recipeId?: string;
2893
+ /** Per-turn unique suffix, stable across retries within the turn. */
2894
+ turnId: string;
2895
+ name: string;
2896
+ intentDescription: string;
2897
+ tags: string[];
2898
+ parameters: ScriptParameter[];
2899
+ scriptBody: string;
2900
+ createdFrom: string;
2901
+ }
2902
+ /**
2903
+ * Lineage + provenance fields applied when a draft is promoted to verified.
2904
+ * MainAgent gathers `sourceIds` and `tables` from the verified execution; the
2905
+ * caller (agent-user-response.ts) supplies the optional fork lineage.
2906
+ */
2907
+ interface PromoteToVerifiedInput {
2908
+ sourceIds: string[];
2909
+ tables: string[];
2910
+ parentId?: string;
2911
+ forkDepth?: number;
2912
+ forkReason?: string;
2913
+ }
2914
+ declare class ScriptStore {
2915
+ private recipes;
2916
+ private storeDir;
2917
+ private loaded;
2918
+ constructor(baseDir?: string);
2919
+ private metadataDir;
2920
+ /**
2921
+ * Filename base for a recipe. Drafts include the per-turn suffix so two
2922
+ * concurrent turns can never clobber each other's draft files; verified
2923
+ * recipes use the bare slug.
2924
+ */
2925
+ private fileBaseName;
2926
+ /**
2927
+ * Absolute path to the .ts file for a recipe. Callers (e.g. ScriptRunner,
2928
+ * MainAgent's execute_script) use this to hand off the path to the tsx child.
2929
+ */
2930
+ getScriptPath(recipe: ScriptRecipe): string;
2931
+ /**
2932
+ * Absolute path to the metadata JSON for a recipe.
2933
+ */
2934
+ private getMetadataPath;
2935
+ /**
2936
+ * Get all VERIFIED recipes — drafts are filtered out so the matcher never
2937
+ * considers an unverified script. Loads from disk on first access.
2938
+ */
2939
+ getAll(): ScriptRecipe[];
2940
+ /**
2941
+ * Get a recipe by ID — returns drafts as well as verified scripts.
2942
+ * Used by MainAgent and the promotion path.
2943
+ */
2944
+ get(id: string): ScriptRecipe | null;
2945
+ /**
2946
+ * Number of verified recipes (matches `getAll().length`).
2947
+ */
2948
+ count(): number;
2949
+ /**
2950
+ * Save a recipe (create or update).
2951
+ * File is named after the script: "order-status-distribution.json"
2952
+ */
2953
+ save(recipe: ScriptRecipe): void;
2954
+ /**
2955
+ * Persist (or update) a draft recipe to disk. Always writes immediately so
2956
+ * the `.ts` body is visible in the IDE the moment MainAgent calls
2957
+ * `write_script`. Within one turn, retries that pass the same `recipeId`
2958
+ * overwrite the same files (the LLM rewriting itself); a fresh `recipeId`
2959
+ * is minted only on the first call of the turn.
2960
+ *
2961
+ * Filename includes the `turnId` suffix so concurrent turns never collide.
2962
+ */
2963
+ saveDraft(input: SaveDraftInput): ScriptRecipe;
2964
+ /**
2965
+ * Stamp the draft with the most recent execution failure so it is visible
2966
+ * in the metadata JSON without grepping logs. No-op if the recipe doesn't
2967
+ * exist or has already been promoted.
2968
+ */
2969
+ recordDraftError(recipeId: string, err: {
2970
+ phase: 'compile' | 'runtime' | 'timeout' | 'ipc';
2971
+ message: string;
2972
+ attempt: number;
2973
+ }): void;
2974
+ /**
2975
+ * Promote a successfully-executed draft into a verified script.
2976
+ *
2977
+ * - Renames the on-disk files from `<slug>-<turnId>.{ts,json}` to the bare
2978
+ * `<slug>.{ts,json}`. If a verified file with the same slug already exists
2979
+ * (concurrent turn won the race, or a prior session has it), the recipe
2980
+ * keeps its turn-suffixed filename so we never overwrite verified work —
2981
+ * the matcher keys on `recipe.id`, so two siblings with similar slugs is fine.
2982
+ * - Flips `status: 'verified'`, clears `lastError`, applies provenance
2983
+ * (`sourceIds`, `tables`) and optional fork lineage.
2984
+ */
2985
+ promoteToVerified(recipeId: string, input: PromoteToVerifiedInput): ScriptRecipe | null;
2986
+ /**
2987
+ * Drop a draft from disk + memory (e.g. when an outer error path wants to
2988
+ * clean up). Per the agreed policy, MainAgent's normal failure path does
2989
+ * NOT call this — failed drafts are kept on disk for the user to inspect.
2990
+ */
2991
+ discardDraft(recipeId: string): void;
2992
+ /**
2993
+ * Delete a recipe by ID.
2994
+ */
2995
+ delete(id: string): void;
2996
+ /**
2997
+ * Record a successful execution for a recipe.
2998
+ */
2999
+ recordSuccess(id: string): void;
3000
+ /**
3001
+ * Record a failed execution for a recipe.
3002
+ */
3003
+ recordFailure(id: string): void;
3004
+ /**
3005
+ * Get the failure rate for a recipe (0 to 1).
3006
+ * Returns 0 if the recipe has fewer than 5 total uses.
3007
+ */
3008
+ getFailureRate(id: string): number;
3009
+ private ensureLoaded;
3010
+ /**
3011
+ * Convert a script name to a safe filename.
3012
+ * "Order Status Distribution" → "order-status-distribution"
3013
+ */
3014
+ private toFileName;
3015
+ /**
3016
+ * Load all script files from disk.
3017
+ *
3018
+ * Supports two layouts:
3019
+ * - New (preferred): metadata/<name>.json + <name>.ts
3020
+ * - Legacy: <name>.json with embedded scriptBody (auto-migrated on next save)
3021
+ */
3022
+ private loadAllFromDisk;
3023
+ /**
3024
+ * Save a recipe to disk in split format:
3025
+ * metadata/<name>.json (metadata, no scriptBody)
3026
+ * <name>.ts (just the function body)
3027
+ *
3028
+ * If a legacy top-level <name>.json exists for the same recipe, remove it
3029
+ * so we don't end up with duplicate sources of truth.
3030
+ */
3031
+ private saveRecipeToDisk;
3032
+ /**
3033
+ * Delete a recipe's files from disk (both metadata + body, plus any legacy file).
3034
+ */
3035
+ private deleteRecipeFromDisk;
3036
+ }
3037
+
3038
+ /**
3039
+ * Main Agent (Orchestrator)
3040
+ *
3041
+ * A single LLM.streamWithTools() call that handles everything:
3042
+ * - Routing: decides which source(s) to query based on summaries
3043
+ * - Querying: calls source tools (each wraps an independent SourceAgent)
3044
+ * - Direct tools: calls pre-built function tools directly with LLM-provided params
3045
+ * - Re-querying: if data is wrong/incomplete, calls tools again with modified intent
3046
+ * - Analysis: generates final text response from the data
3047
+ *
3048
+ * Two tool types:
3049
+ * - "source" tools: main agent sees summaries, SourceAgent handles SQL generation independently
3050
+ * - "direct" tools: main agent calls fn() directly with structured params (no SourceAgent)
3051
+ */
3052
+
3053
+ declare class MainAgent {
3054
+ private externalTools;
3055
+ private config;
3056
+ private streamBuffer;
3057
+ /**
3058
+ * Optional: when provided, MainAgent exposes the `write_script` /
3059
+ * `execute_script` tools to the LLM and persists drafts to disk via the
3060
+ * store. Headless callers (alert analyzer, metric resolver) omit these to
3061
+ * suppress script authoring entirely — drafts would otherwise leak onto
3062
+ * disk with no caller to promote or clean them up.
3063
+ */
3064
+ private scriptStore;
3065
+ private turnId;
3066
+ private createdFromPrompt;
3067
+ private scriptState;
3068
+ constructor(externalTools: ExternalTool[], config: AgentConfig, scriptStore?: ScriptStore, turnId?: string, streamBuffer?: StreamBuffer);
3069
+ private get scriptingEnabled();
3070
+ /**
3071
+ * Handle a user question using the multi-agent system.
3072
+ *
3073
+ * This is ONE LLM.streamWithTools() call. The LLM:
3074
+ * 1. Sees source summaries + direct tool descriptions in system prompt
3075
+ * 2. Decides which tool(s) to call (routing)
3076
+ * 3. Source tools → SourceAgent runs independently → returns data
3077
+ * 4. Direct tools → fn() called directly with LLM params → returns data
3078
+ * 5. Generates final analysis text
3079
+ */
3080
+ handleQuestion(userPrompt: string, apiKey?: string, conversationHistory?: string, streamCallback?: (chunk: string) => void): Promise<AgentResponse>;
3081
+ private handleWriteScript;
3082
+ private handleExecuteScript;
3083
+ /**
3084
+ * Build the AgentWrittenScript payload the caller will hand to
3085
+ * `ScriptStore.promoteToVerified()`. Only returned when a verified
3086
+ * successful execution is on record.
3087
+ */
3088
+ private buildSavedScript;
3089
+ private normalizeParameterList;
3090
+ /**
3091
+ * Use the schema embedding collection to pre-select relevant tables for
3092
+ * this source + intent. Returns a formatted schema block if confidence is
3093
+ * high (top match ≥ 0.55 and ≥3 candidates), otherwise null.
3094
+ *
3095
+ * When this returns a block, we can skip the SourceAgent's `search_schema`
3096
+ * loop and reduce iteration budget. When it returns null, the SourceAgent
3097
+ * falls back to the existing LLM-driven keyword search (same as today).
3098
+ */
3099
+ private preResolveSchema;
3100
+ /**
3101
+ * Execute a direct tool — call fn() with LLM-provided params, no SourceAgent.
3102
+ */
3103
+ private handleDirectTool;
3104
+ /**
3105
+ * Build the main agent's system prompt with source summaries and direct tool descriptions.
3106
+ */
3107
+ private buildSystemPrompt;
3108
+ /**
3109
+ * Build tool definitions for source tools — summary-only descriptions.
3110
+ * The full schema is inside the SourceAgent which runs independently.
3111
+ */
3112
+ private buildSourceToolDefinitions;
3113
+ /**
3114
+ * Build tool definitions for direct tools — expose their actual params.
3115
+ * These are called directly by the main agent LLM, no SourceAgent.
3116
+ */
3117
+ private buildDirectToolDefinitions;
3118
+ /**
3119
+ * Format a source agent's result as a clean string for the main agent LLM.
3120
+ */
3121
+ private formatResultForMainAgent;
3122
+ /**
3123
+ * Get source summaries (for external inspection/debugging).
3124
+ */
3125
+ getSourceSummaries(): SourceSummary[];
3126
+ }
3127
+
2390
3128
  type MessageTypeHandler = (message: IncomingMessage) => void | Promise<void>;
2391
3129
  declare class SuperatomSDK {
2392
3130
  private ws;
@@ -2410,6 +3148,9 @@ declare class SuperatomSDK {
2410
3148
  private llmProviders;
2411
3149
  private databaseType;
2412
3150
  private modelStrategy;
3151
+ private mainAgentModel;
3152
+ private sourceAgentModel;
3153
+ private dashCompModels?;
2413
3154
  private conversationSimilarityThreshold;
2414
3155
  private userManager;
2415
3156
  private dashboardManager;
@@ -2457,9 +3198,11 @@ declare class SuperatomSDK {
2457
3198
  */
2458
3199
  private handleMessage;
2459
3200
  /**
2460
- * Send a message to the Superatom service
3201
+ * Send a message to the Superatom service.
3202
+ * Returns true if the message was sent, false if the WebSocket is not connected.
3203
+ * Does NOT throw on closed connections — callers can check the return value if needed.
2461
3204
  */
2462
- send(message: Message): void;
3205
+ send(message: Message): boolean;
2463
3206
  /**
2464
3207
  * Register a message handler to receive all messages
2465
3208
  */
@@ -2537,4 +3280,4 @@ declare class SuperatomSDK {
2537
3280
  getConversationSimilarityThreshold(): number;
2538
3281
  }
2539
3282
 
2540
- export { type Action, BM25L, type BM25LOptions, type BaseLLMConfig, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CollectionHandler, type CollectionOperation, type DBUIBlock, type DatabaseType, type HybridSearchOptions, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, type Message, type ModelStrategy, type OutputField, type RerankedResult, STORAGE_CONFIG, SuperatomSDK, type SuperatomSDKConfig, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, UIBlock, UILogCollector, type User, UserManager, type UsersData, anthropicLLM, geminiLLM, groqLLM, hybridRerank, llmUsageLogger, logger, openaiLLM, queryCache, rerankChromaResults, rerankConversationResults, userPromptErrorLogger };
3283
+ export { type Action, type AgentConfig, type AgentResponse, BM25L, type BM25LOptions, type BaseLLMConfig, CONTEXT_CONFIG, type CapturedLog, CleanupService, type CollectionHandler, type CollectionOperation, type DBUIBlock, DEFAULT_AGENT_CONFIG, type DatabaseType, type HybridSearchOptions, type IncomingMessage, type KbNodesQueryFilters, type KbNodesRequestPayload, LLM, type LLMUsageEntry, type LogLevel, MainAgent, type Message, type ModelStrategy, type OutputField, type RerankedResult, STORAGE_CONFIG, SuperatomSDK, type SuperatomSDKConfig, type TaskType, Thread, ThreadManager, type Tool$1 as Tool, type ToolOutputSchema, UIBlock, UILogCollector, type User, UserManager, type UsersData, anthropicLLM, dashboardConversationHistory, geminiLLM, groqLLM, hybridRerank, llmUsageLogger, logger, openaiLLM, queryCache, rerankChromaResults, rerankConversationResults, userPromptErrorLogger };