@superatomai/sdk-node 0.0.36 → 0.0.37

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/README.md CHANGED
@@ -1,942 +1,942 @@
1
- # @superatomai/sdk-node
2
-
3
- A TypeScript/Node.js SDK for building AI-powered data applications with Superatom - a platform for creating data-driven, intelligent applications with real-time WebSocket communication, LLM integration, and comprehensive user management.
4
-
5
- ## Features
6
-
7
- - **WebSocket Communication** - Real-time bidirectional messaging with automatic reconnection
8
- - **AI-Powered Component Generation** - Automatically generate dashboard components and visualizations from user questions
9
- - **Intelligent Text Responses** - LLM-powered conversational responses with SQL query execution and retry logic
10
- - **Component Matching & Classification** - Smart component selection based on question type and visualization needs
11
- - **Collection Handlers** - Register custom data operation handlers (CRUD, queries, mutations)
12
- - **User Management** - Built-in authentication and user storage with file-based persistence
13
- - **Dashboard & Report Management** - Create and manage dashboards and reports with DSL-based rendering
14
- - **Multi-Provider LLM Integration** - Unified interface for Anthropic Claude and Groq models with automatic fallback
15
- - **Thread & UI Block Management** - Organize conversations and UI components with automatic cleanup
16
- - **Log Collection** - Capture and send runtime logs to the UI with configurable log levels
17
- - **Prompt Loader** - Load and cache custom prompts from the file system with template variable support
18
- - **Database Schema Management** - Automatic schema documentation generation for LLM context
19
- - **Cleanup Service** - Automatic memory management and old data removal
20
- - **TypeScript First** - Full type safety with comprehensive type definitions
21
-
22
- ## Installation
23
-
24
- ```bash
25
- npm install @superatomai/sdk-node
26
- ```
27
-
28
- Or with pnpm:
29
-
30
- ```bash
31
- pnpm add @superatomai/sdk-node
32
- ```
33
-
34
- ## Quick Start
35
-
36
- ```typescript
37
- import { SuperatomSDK } from '@superatomai/sdk-node';
38
-
39
- // Initialize the SDK
40
- const sdk = new SuperatomSDK({
41
- apiKey: 'your-api-key',
42
- projectId: 'your-project-id',
43
- userId: 'user-123', // optional, defaults to 'anonymous'
44
- type: 'data-agent', // optional, defaults to 'data-agent'
45
- });
46
-
47
- // The SDK automatically connects to the Superatom WebSocket service
48
- // Wait for connection before using
49
- await sdk.connect();
50
-
51
- // Register a collection handler for data operations
52
- sdk.addCollection('users', 'getMany', async (params) => {
53
- return {
54
- data: [
55
- { id: 1, name: 'John Doe', email: 'john@example.com' },
56
- { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
57
- ],
58
- };
59
- });
60
-
61
- // Listen to messages
62
- sdk.onMessage((message) => {
63
- console.log('Received:', message.type);
64
- });
65
-
66
- // Cleanup when done
67
- await sdk.destroy();
68
- ```
69
-
70
- ## Configuration
71
-
72
- ### SuperatomSDKConfig
73
-
74
- ```typescript
75
- interface SuperatomSDKConfig {
76
- apiKey: string; // Required: Your Superatom API key
77
- projectId: string; // Required: Your project ID
78
- userId?: string; // Optional: User identifier (default: 'anonymous')
79
- type?: string; // Optional: Agent type (default: 'data-agent')
80
- url?: string; // Optional: Custom WebSocket URL
81
- bundleDir?: string; // Optional: Directory for bundle requests
82
- promptsDir?: string; // Optional: Custom prompts directory (default: .prompts)
83
- ANTHROPIC_API_KEY?: string; // Optional: Anthropic API key for LLM
84
- GROQ_API_KEY?: string; // Optional: Groq API key for LLM
85
- LLM_PROVIDERS?: LLMProvider[]; // Optional: Custom LLM providers
86
- logLevel?: LogLevel; // Optional: Log level (errors, warnings, info, verbose) (default: 'info')
87
- }
88
- ```
89
-
90
- ### Environment Variables
91
-
92
- - `SA_WEBSOCKET_URL` - WebSocket URL (default: `wss://ws.superatom.ai/websocket`)
93
- - `ANTHROPIC_API_KEY` - Anthropic API key for Claude models
94
- - `GROQ_API_KEY` - Groq API key for open-source models
95
- - `SUPERATOM_LOG_LEVEL` - Log level for SDK logging (errors, warnings, info, verbose) (default: 'info')
96
-
97
- ## Core Features
98
-
99
- ### 1. Collection Handlers
100
-
101
- Register custom handlers for data operations. Supports standard CRUD operations and custom operations.
102
-
103
- ```typescript
104
- // Register a getMany handler
105
- sdk.addCollection<ParamsType, ResultType>(
106
- 'products',
107
- 'getMany',
108
- async (params) => {
109
- // params includes filters, pagination, etc.
110
- const products = await database.products.find(params);
111
- return { data: products };
112
- }
113
- );
114
-
115
- // Register a createOne handler
116
- sdk.addCollection('products', 'createOne', async (params) => {
117
- const newProduct = await database.products.create(params);
118
- return { data: newProduct };
119
- });
120
-
121
- // Register a custom query handler
122
- sdk.addCollection('analytics', 'query', async (params) => {
123
- const results = await runAnalyticsQuery(params);
124
- return { data: results };
125
- });
126
- ```
127
-
128
- **Supported Operations:**
129
- - `getMany` - Fetch multiple records
130
- - `getOne` - Fetch single record
131
- - `createOne` - Create a record
132
- - `updateOne` - Update a record
133
- - `deleteOne` - Delete a record
134
- - `query` - Custom queries
135
- - `mutation` - Custom mutations
136
-
137
- ### 2. Message Handling
138
-
139
- Listen to all messages or specific message types:
140
-
141
- ```typescript
142
- // Listen to all messages
143
- const unsubscribe = sdk.onMessage((message) => {
144
- console.log('Message:', message.type, message.payload);
145
- });
146
-
147
- // Listen to specific message types
148
- sdk.onMessageType('DATA_REQ', (message) => {
149
- console.log('Data request received:', message.payload);
150
- });
151
-
152
- // Unsubscribe when needed
153
- unsubscribe();
154
-
155
- // Send messages
156
- sdk.send({
157
- type: 'CUSTOM_MESSAGE',
158
- from: { id: 'sdk', type: 'agent' },
159
- payload: { data: 'Hello' },
160
- });
161
- ```
162
-
163
- **Built-in Message Types:**
164
- - `DATA_REQ` - Data request from runtime
165
- - `BUNDLE_REQ` - Bundle/asset request
166
- - `AUTH_LOGIN_REQ` - Authentication login request
167
- - `AUTH_VERIFY_REQ` - Token verification request
168
- - `USER_PROMPT_REQ` - User prompt for LLM processing
169
- - `USER_PROMPT_SUGGESTIONS_REQ` - Request for prompt suggestions
170
- - `ACTIONS` - Component actions request
171
- - `COMPONENT_LIST_RES` - Available components list
172
- - `USERS` - User management operations
173
- - `DASHBOARDS` - Dashboard CRUD operations
174
- - `REPORTS` - Report CRUD operations
175
-
176
- ### 3. User Management
177
-
178
- Built-in user authentication and management with file-based storage:
179
-
180
- ```typescript
181
- const userManager = sdk.getUserManager();
182
-
183
- // Create a user
184
- await userManager.createUser({
185
- username: 'john_doe',
186
- password: 'secure_password',
187
- });
188
-
189
- // Get a user
190
- const user = await userManager.getUser('john_doe');
191
-
192
- // Update a user
193
- await userManager.updateUser('john_doe', {
194
- password: 'new_password',
195
- });
196
-
197
- // Delete a user
198
- await userManager.deleteUser('john_doe');
199
-
200
- // Get all users
201
- const users = await userManager.getAllUsers();
202
- ```
203
-
204
- **Features:**
205
- - Automatic password hashing with bcrypt
206
- - File-based storage (JSON)
207
- - Token-based authentication
208
- - Auto-save on changes
209
- - Memory management with configurable limits
210
-
211
- ### 4. Dashboard Management
212
-
213
- Create and manage dashboards with DSL-based rendering:
214
-
215
- ```typescript
216
- const dashboardManager = sdk.getDashboardManager();
217
-
218
- // Create a dashboard
219
- const dashboard = {
220
- id: 'dashboard-1',
221
- title: 'Sales Dashboard',
222
- description: 'Overview of sales metrics',
223
- dsl: {
224
- type: 'container',
225
- children: [
226
- { type: 'chart', props: { chartType: 'line', data: [...] } },
227
- { type: 'table', props: { columns: [...], data: [...] } },
228
- ],
229
- },
230
- };
231
-
232
- await dashboardManager.createDashboard(dashboard);
233
-
234
- // Get a dashboard
235
- const retrieved = await dashboardManager.getDashboard('dashboard-1');
236
-
237
- // Update a dashboard
238
- await dashboardManager.updateDashboard('dashboard-1', {
239
- title: 'Updated Sales Dashboard',
240
- });
241
-
242
- // Delete a dashboard
243
- await dashboardManager.deleteDashboard('dashboard-1');
244
-
245
- // Get all dashboards
246
- const allDashboards = await dashboardManager.getAllDashboards();
247
- ```
248
-
249
- ### 5. Report Management
250
-
251
- Similar to dashboards, but for reports:
252
-
253
- ```typescript
254
- const reportManager = sdk.getReportManager();
255
-
256
- // Create a report
257
- const report = {
258
- id: 'report-1',
259
- title: 'Monthly Report',
260
- description: 'Monthly performance report',
261
- dsl: {
262
- type: 'report',
263
- sections: [
264
- { type: 'summary', content: '...' },
265
- { type: 'charts', data: [...] },
266
- ],
267
- },
268
- };
269
-
270
- await reportManager.createReport(report);
271
-
272
- // CRUD operations work the same as dashboards
273
- const retrieved = await reportManager.getReport('report-1');
274
- await reportManager.updateReport('report-1', { title: 'Q1 Report' });
275
- await reportManager.deleteReport('report-1');
276
- const allReports = await reportManager.getAllReports();
277
- ```
278
-
279
- ### 6. LLM Integration
280
-
281
- Unified interface for multiple LLM providers with streaming support:
282
-
283
- ```typescript
284
- import { LLM } from '@superatomai/sdk-node';
285
-
286
- // Text generation
287
- const response = await LLM.text(
288
- {
289
- sys: 'You are a helpful assistant.',
290
- user: 'What is the meaning of life?',
291
- },
292
- {
293
- model: 'anthropic/claude-sonnet-4-5', // or 'groq/llama3-70b'
294
- apiKey: 'your-api-key',
295
- maxTokens: 1000,
296
- temperature: 0.7,
297
- }
298
- );
299
-
300
- // Streaming responses
301
- const result = await LLM.stream(
302
- {
303
- sys: 'You are a storyteller.',
304
- user: 'Tell me a short story.',
305
- },
306
- {
307
- model: 'anthropic/claude-sonnet-4-5',
308
- apiKey: 'your-api-key',
309
- partial: (chunk) => {
310
- // Called for each chunk
311
- process.stdout.write(chunk);
312
- },
313
- }
314
- );
315
-
316
- // JSON output
317
- const jsonResult = await LLM.stream(
318
- {
319
- sys: 'Return a JSON object with user data.',
320
- user: 'Create a user profile for John Doe.',
321
- },
322
- {
323
- model: 'groq/llama3-70b',
324
- apiKey: 'your-api-key',
325
- },
326
- true // Enable JSON parsing
327
- );
328
- ```
329
-
330
- **Supported Models:**
331
- - **Anthropic:** `claude-sonnet-4-5`, `claude-opus-4`, etc.
332
- - **Groq:** `llama3-70b`, `mixtral-8x7b`, etc.
333
-
334
- **Model Format:**
335
- - With provider: `anthropic/model-name` or `groq/model-name`
336
- - Without provider: Defaults to Anthropic
337
-
338
- ### 7. AI-Powered User Response System
339
-
340
- The SDK includes a powerful AI system for generating intelligent responses to user questions with two modes: **component generation** and **text responses**.
341
-
342
- #### Component Generation Mode
343
-
344
- Automatically match and generate dashboard components based on user questions:
345
-
346
- ```typescript
347
- import { get_user_response } from '@superatomai/sdk-node/userResponse';
348
-
349
- const components = [
350
- { id: 'sales-chart', name: 'SalesChart', type: 'BarChart', /* ... */ },
351
- { id: 'kpi-card', name: 'RevenueKPI', type: 'KPICard', /* ... */ },
352
- // ... more components
353
- ];
354
-
355
- const result = await get_user_response(
356
- 'Show me sales by region',
357
- components,
358
- anthropicApiKey,
359
- groqApiKey,
360
- ['anthropic', 'groq'], // Provider fallback order
361
- logCollector,
362
- conversationHistory,
363
- 'component' // Component generation mode
364
- );
365
-
366
- if (result.success) {
367
- console.log('Generated component:', result.data.component);
368
- console.log('Reasoning:', result.data.reasoning);
369
- }
370
- ```
371
-
372
- **Features:**
373
- - **Question Classification** - Automatically determines question type (analytical, data_modification, general)
374
- - **Visualization Type Detection** - Identifies required visualization types (charts, tables, KPIs)
375
- - **Multi-Component Dashboards** - Generates multiple components for comprehensive analysis
376
- - **Props Modification** - Intelligently modifies component props including SQL queries
377
- - **SQL Query Validation** - Ensures queries have proper LIMIT clauses and fixes scalar subqueries
378
-
379
- #### Text Response Mode
380
-
381
- Generate conversational text responses with SQL query execution:
382
-
383
- ```typescript
384
- const result = await get_user_response(
385
- 'What were the top 5 selling products last month?',
386
- components,
387
- anthropicApiKey,
388
- groqApiKey,
389
- ['anthropic', 'groq'],
390
- logCollector,
391
- conversationHistory,
392
- 'text', // Text response mode
393
- (chunk) => {
394
- // Stream text chunks in real-time
395
- process.stdout.write(chunk);
396
- },
397
- collections // Required for query execution
398
- );
399
-
400
- if (result.success) {
401
- console.log('Text response:', result.data.text);
402
- console.log('Matched components:', result.data.matchedComponents);
403
- console.log('Container component:', result.data.component);
404
- }
405
- ```
406
-
407
- **Features:**
408
- - **SQL Query Execution** - Automatically generates and executes SQL queries via tool calling
409
- - **Automatic Retry Logic** - Up to 6 retry attempts with query correction on errors
410
- - **Streaming Responses** - Real-time text streaming with query execution status updates
411
- - **Component Suggestions** - Parses component suggestions from text and matches with available components
412
- - **Layout Discovery** - Automatically selects appropriate dashboard layouts based on component metadata
413
- - **Performance Tracking** - Measures and logs total time taken for request processing
414
-
415
- #### Using BaseLLM Classes Directly
416
-
417
- For more control, use the BaseLLM implementations directly:
418
-
419
- ```typescript
420
- import { anthropicLLM, groqLLM } from '@superatomai/sdk-node/userResponse';
421
-
422
- // Classify user question
423
- const classification = await anthropicLLM.classifyUserQuestion(
424
- 'Show me sales trends',
425
- apiKey,
426
- logCollector,
427
- conversationHistory
428
- );
429
-
430
- console.log('Question type:', classification.questionType);
431
- console.log('Visualizations needed:', classification.visualizations);
432
-
433
- // Generate analytical component
434
- const result = await anthropicLLM.generateAnalyticalComponent(
435
- 'Show me sales by region',
436
- components,
437
- 'BarChart', // Preferred visualization type
438
- apiKey,
439
- logCollector,
440
- conversationHistory
441
- );
442
-
443
- // Match existing component
444
- const matchResult = await anthropicLLM.matchComponent(
445
- 'Update the sales dashboard',
446
- components,
447
- apiKey,
448
- logCollector,
449
- conversationHistory
450
- );
451
-
452
- // Generate next questions
453
- const nextQuestions = await anthropicLLM.generateNextQuestions(
454
- originalPrompt,
455
- generatedComponent,
456
- componentData,
457
- apiKey,
458
- logCollector,
459
- conversationHistory
460
- );
461
- ```
462
-
463
- **BaseLLM Methods:**
464
- - `handleUserRequest()` - Main orchestration method (supports both component and text modes)
465
- - `classifyUserQuestion()` - Classify question type and identify visualizations
466
- - `generateAnalyticalComponent()` - Generate single analytical component
467
- - `generateMultipleAnalyticalComponents()` - Generate multiple components in parallel
468
- - `matchComponent()` - Match and modify existing component
469
- - `validateAndModifyProps()` - Validate and modify component props
470
- - `generateTextResponse()` - Generate text with tool calling support
471
- - `matchComponentsFromTextResponse()` - Match components from text suggestions
472
- - `generateNextQuestions()` - Generate follow-up question suggestions
473
-
474
- ### 8. Prompt Loader System
475
-
476
- The SDK includes a sophisticated prompt loading system with caching and template variable support:
477
-
478
- ```typescript
479
- import { promptLoader } from '@superatomai/sdk-node/userResponse';
480
-
481
- // Initialize with custom directory (default: .prompts)
482
- const sdk = new SuperatomSDK({
483
- apiKey: 'your-api-key',
484
- projectId: 'your-project-id',
485
- promptsDir: './my-custom-prompts',
486
- });
487
-
488
- // Prompts are automatically loaded and cached on initialization
489
- // Access prompt cache size
490
- const cacheSize = promptLoader.getCacheSize();
491
- console.log(`Loaded ${cacheSize} prompts`);
492
-
493
- // Load specific prompts with variables
494
- const prompts = await promptLoader.loadPrompts('classify', {
495
- USER_PROMPT: userQuestion,
496
- CONVERSATION_HISTORY: history || 'No previous conversation'
497
- });
498
-
499
- console.log('System prompt:', prompts.system);
500
- console.log('User prompt:', prompts.user);
501
- ```
502
-
503
- **Prompt Directory Structure:**
504
- ```
505
- .prompts/
506
- ├── classify/
507
- │ ├── system.md # System prompt for classification
508
- │ └── user.md # User prompt template
509
- ├── match-component/
510
- │ ├── system.md
511
- │ └── user.md
512
- ├── modify-props/
513
- │ ├── system.md
514
- │ └── user.md
515
- ├── text-response/
516
- │ ├── system.md
517
- │ └── user.md
518
- └── match-text-components/
519
- ├── system.md
520
- └── user.md
521
- ```
522
-
523
- **Template Variables:**
524
- Variables in prompts are replaced using the `{{VARIABLE_NAME}}` syntax:
525
-
526
- ```markdown
527
- # system.md
528
- You are analyzing this question: {{USER_PROMPT}}
529
-
530
- Previous conversation:
531
- {{CONVERSATION_HISTORY}}
532
-
533
- Available components:
534
- {{AVAILABLE_COMPONENTS}}
535
- ```
536
-
537
- **Built-in Prompt Types:**
538
- - `classify` - Question classification and visualization type detection
539
- - `match-component` - Component matching and selection
540
- - `modify-props` - Props validation and modification
541
- - `single-component` - Single analytical component generation
542
- - `text-response` - Text response with tool calling
543
- - `match-text-components` - Component matching from text suggestions
544
- - `container-metadata` - Container title and description generation
545
- - `actions` - Next question generation
546
-
547
- ### 9. Thread & UI Block Management
548
-
549
- Organize conversations and UI components:
550
-
551
- ```typescript
552
- import { Thread, UIBlock, ThreadManager } from '@superatomai/sdk-node';
553
-
554
- const threadManager = ThreadManager.getInstance();
555
-
556
- // Create a thread
557
- const thread = threadManager.createThread({
558
- userId: 'user-123',
559
- metadata: { source: 'chat' },
560
- });
561
-
562
- // Add UI blocks
563
- const block1 = new UIBlock(
564
- 'block-1',
565
- 'text',
566
- { content: 'Hello!' }
567
- );
568
- thread.addBlock(block1);
569
-
570
- const block2 = new UIBlock(
571
- 'block-2',
572
- 'table',
573
- {
574
- columns: ['Name', 'Age'],
575
- data: [['John', 30], ['Jane', 25]]
576
- }
577
- );
578
- thread.addBlock(block2);
579
-
580
- // Get thread
581
- const retrieved = threadManager.getThread(thread.getId());
582
-
583
- // Get all threads
584
- const allThreads = threadManager.getAllThreads();
585
-
586
- // Delete thread
587
- threadManager.deleteThread(thread.getId());
588
- ```
589
-
590
- **UI Block Types:**
591
- - `text` - Text content
592
- - `table` - Tabular data
593
- - `chart` - Charts and visualizations
594
- - `form` - Interactive forms
595
- - Custom types as needed
596
-
597
- ### 10. Logging System
598
-
599
- The SDK includes a comprehensive logging system with environment-based log levels for both terminal and UI log collection.
600
-
601
- #### Log Levels
602
-
603
- The SDK supports hierarchical log levels:
604
-
605
- - **`errors`** - Only error logs are shown
606
- - **`warnings`** - Warning and error logs are shown
607
- - **`info`** - Info, warning, and error logs are shown (default)
608
- - **`verbose`** - All logs including debug messages are shown
609
-
610
- #### Configuring Log Level
611
-
612
- You can set the log level in three ways:
613
-
614
- **1. Via environment variable (recommended for deployment):**
615
-
616
- ```bash
617
- export SUPERATOM_LOG_LEVEL=verbose
618
- node your-app.js
619
- ```
620
-
621
- **2. Via SDK configuration (overrides environment variable):**
622
-
623
- ```typescript
624
- import { SuperatomSDK } from '@superatomai/sdk-node';
625
-
626
- const sdk = new SuperatomSDK({
627
- apiKey: 'your-api-key',
628
- projectId: 'your-project-id',
629
- logLevel: 'verbose', // errors | warnings | info | verbose
630
- });
631
- ```
632
-
633
- **3. Programmatically at runtime:**
634
-
635
- ```typescript
636
- import { logger } from '@superatomai/sdk-node';
637
-
638
- // Change log level at runtime
639
- logger.setLogLevel('verbose');
640
-
641
- // Get current log level
642
- const currentLevel = logger.getLogLevel(); // returns 'verbose'
643
- ```
644
-
645
- #### Using the Logger
646
-
647
- ```typescript
648
- import { logger } from '@superatomai/sdk-node';
649
-
650
- // These will be filtered based on the configured log level
651
- logger.error('Critical error occurred'); // Shown at all levels
652
- logger.warn('Something might be wrong'); // Hidden when level is 'errors'
653
- logger.info('Processing completed'); // Hidden when level is 'errors' or 'warnings'
654
- logger.debug('Detailed debug information'); // Only shown when level is 'verbose'
655
- ```
656
-
657
- #### UI Log Collection
658
-
659
- The `UILogCollector` also respects the log level configuration. Logs are sent to the frontend and displayed in the terminal based on the configured level.
660
-
661
- ```typescript
662
- import { UILogCollector } from '@superatomai/sdk-node';
663
-
664
- const collector = new UILogCollector(
665
- clientId,
666
- (msg) => sdk.send(msg),
667
- 'uiblock-123'
668
- );
669
-
670
- // These logs are filtered based on log level before being sent to UI
671
- collector.error('Error message'); // Always sent
672
- collector.warn('Warning message'); // Sent unless level is 'errors'
673
- collector.info('Info message'); // Sent unless level is 'errors' or 'warnings'
674
- collector.debug('Debug message'); // Only sent when level is 'verbose'
675
-
676
- // Get all collected logs
677
- const logs = collector.getLogs();
678
- ```
679
-
680
- **Note:** The log level affects both terminal output and UI log collection, ensuring consistent logging behavior across your application.
681
-
682
- ### 11. Cleanup Service
683
-
684
- Automatic memory management for threads and UI blocks:
685
-
686
- ```typescript
687
- import { CleanupService } from '@superatomai/sdk-node';
688
-
689
- const cleanupService = CleanupService.getInstance();
690
-
691
- // Start automatic cleanup (runs every 24 hours by default)
692
- cleanupService.startAutoCleanup(24);
693
-
694
- // Manual cleanup
695
- const stats = cleanupService.runFullCleanup();
696
- console.log('Cleanup stats:', stats);
697
- // Output: { threadsDeleted: 5, uiblocksDeleted: {...}, dataCleared: 10 }
698
-
699
- // Get memory statistics
700
- const memStats = cleanupService.getMemoryStats();
701
- console.log('Memory:', memStats);
702
- // Output: { threadCount: 42, totalUIBlocks: 156, avgUIBlocksPerThread: 3.7 }
703
-
704
- // Stop automatic cleanup
705
- cleanupService.stopAutoCleanup();
706
- ```
707
-
708
- **Configuration:**
709
-
710
- ```typescript
711
- import { STORAGE_CONFIG } from '@superatomai/sdk-node';
712
-
713
- // Thread retention (default: 30 days)
714
- STORAGE_CONFIG.THREAD_RETENTION_DAYS = 60;
715
-
716
- // UI block retention (default: 7 days)
717
- STORAGE_CONFIG.UIBLOCK_RETENTION_DAYS = 14;
718
-
719
- // Max component data size (default: 100KB)
720
- STORAGE_CONFIG.MAX_COMPONENT_DATA_SIZE = 200 * 1024;
721
- ```
722
-
723
- ## API Reference
724
-
725
- ### SuperatomSDK
726
-
727
- #### Methods
728
-
729
- - `connect(): Promise<void>` - Connect to WebSocket service
730
- - `disconnect(): void` - Disconnect from WebSocket
731
- - `destroy(): Promise<void>` - Cleanup and disconnect permanently
732
- - `isConnected(): boolean` - Check connection status
733
- - `send(message: Message): void` - Send a message
734
- - `onMessage(handler): () => void` - Register message handler (returns unsubscribe function)
735
- - `onMessageType(type, handler): () => void` - Register type-specific handler
736
- - `addCollection(name, operation, handler): void` - Register collection handler
737
- - `getUserManager(): UserManager` - Get user manager instance
738
- - `getDashboardManager(): DashboardManager` - Get dashboard manager instance
739
- - `getReportManager(): ReportManager` - Get report manager instance
740
-
741
- ### UserManager
742
-
743
- #### Methods
744
-
745
- - `createUser(data): Promise<User>` - Create a new user
746
- - `getUser(username): Promise<User | null>` - Get user by username
747
- - `updateUser(username, data): Promise<User>` - Update user
748
- - `deleteUser(username): Promise<boolean>` - Delete user
749
- - `getAllUsers(): Promise<User[]>` - Get all users
750
- - `verifyPassword(username, password): Promise<boolean>` - Verify password
751
- - `generateToken(username): Promise<string>` - Generate auth token
752
- - `verifyToken(token): Promise<User | null>` - Verify auth token
753
-
754
- ### DashboardManager
755
-
756
- #### Methods
757
-
758
- - `createDashboard(dashboard): Promise<DSLRendererProps>` - Create dashboard
759
- - `getDashboard(id): Promise<DSLRendererProps | null>` - Get dashboard
760
- - `updateDashboard(id, updates): Promise<DSLRendererProps>` - Update dashboard
761
- - `deleteDashboard(id): Promise<boolean>` - Delete dashboard
762
- - `getAllDashboards(): Promise<DSLRendererProps[]>` - Get all dashboards
763
-
764
- ### ReportManager
765
-
766
- Same methods as DashboardManager but for reports.
767
-
768
- ### LLM (Static Class)
769
-
770
- #### Methods
771
-
772
- - `text(messages, options): Promise<string>` - Generate text response
773
- - `stream(messages, options, json?): Promise<string | object>` - Stream response
774
-
775
- ### ThreadManager
776
-
777
- #### Methods
778
-
779
- - `getInstance(): ThreadManager` - Get singleton instance
780
- - `createThread(options): Thread` - Create new thread
781
- - `getThread(id): Thread | undefined` - Get thread by ID
782
- - `getAllThreads(): Thread[]` - Get all threads
783
- - `deleteThread(id): boolean` - Delete thread
784
-
785
- ### CleanupService
786
-
787
- #### Methods
788
-
789
- - `getInstance(): CleanupService` - Get singleton instance
790
- - `startAutoCleanup(intervalHours?): void` - Start automatic cleanup
791
- - `stopAutoCleanup(): void` - Stop automatic cleanup
792
- - `runFullCleanup(): CleanupStats` - Run manual cleanup
793
- - `getMemoryStats(): MemoryStats` - Get current memory statistics
794
-
795
- ### UILogCollector
796
-
797
- #### Methods
798
-
799
- - `start(): void` - Start collecting logs
800
- - `stop(): void` - Stop collecting
801
- - `clear(): void` - Clear collected logs
802
- - `getLogs(): CapturedLog[]` - Get all logs
803
- - `addLog(log): void` - Add custom log
804
- - `createMessage(uiBlockId): UILogsMessage` - Create message for SDK
805
-
806
- ## Advanced Usage
807
-
808
- ### Custom Message Handlers
809
-
810
- ```typescript
811
- // Handle custom message types
812
- sdk.onMessageType('CUSTOM_EVENT', async (message) => {
813
- console.log('Custom event:', message.payload);
814
-
815
- // Process and respond
816
- sdk.send({
817
- type: 'CUSTOM_RESPONSE',
818
- from: { id: 'sdk', type: 'agent' },
819
- payload: { result: 'processed' },
820
- });
821
- });
822
- ```
823
-
824
- ### Error Handling
825
-
826
- ```typescript
827
- try {
828
- await sdk.connect();
829
- } catch (error) {
830
- console.error('Connection failed:', error);
831
- }
832
-
833
- // Handle WebSocket errors
834
- sdk.onMessageType('error', (message) => {
835
- console.error('Error message:', message.payload);
836
- });
837
- ```
838
-
839
- ### Reconnection
840
-
841
- The SDK automatically handles reconnection with exponential backoff:
842
- - Max attempts: 5
843
- - Delay: 1s, 2s, 4s, 8s, 10s (capped at 10s)
844
-
845
- ### Bundle Requests
846
-
847
- Serve static files via bundle requests:
848
-
849
- ```typescript
850
- const sdk = new SuperatomSDK({
851
- apiKey: 'your-api-key',
852
- projectId: 'your-project-id',
853
- bundleDir: './public', // Directory to serve files from
854
- });
855
-
856
- // Files in ./public will be served when requested
857
- ```
858
-
859
- ## TypeScript Support
860
-
861
- This SDK is written in TypeScript and includes full type definitions. All exports are fully typed for the best development experience.
862
-
863
- ```typescript
864
- import type {
865
- Message,
866
- IncomingMessage,
867
- SuperatomSDKConfig,
868
- CollectionHandler,
869
- CollectionOperation,
870
- User,
871
- UsersData,
872
- Component,
873
- T_RESPONSE,
874
- LLMProvider,
875
- LogLevel,
876
- CapturedLog,
877
- Action,
878
- } from '@superatomai/sdk-node';
879
-
880
- // Import LLM and utility classes
881
- import {
882
- LLM,
883
- UserManager,
884
- UILogCollector,
885
- Thread,
886
- UIBlock,
887
- ThreadManager,
888
- CleanupService,
889
- logger,
890
- } from '@superatomai/sdk-node';
891
-
892
- // Import user response utilities
893
- import {
894
- get_user_response,
895
- anthropicLLM,
896
- groqLLM,
897
- } from '@superatomai/sdk-node/userResponse';
898
- ```
899
-
900
- ## Examples
901
-
902
- Check out the [examples](./examples) directory for complete examples:
903
- - Basic WebSocket communication
904
- - Data collection handlers
905
- - User authentication flow
906
- - LLM integration with streaming
907
- - AI-powered component generation
908
- - Text response with query execution
909
- - Component matching and classification
910
- - Thread management
911
- - Dashboard creation
912
- - Prompt customization
913
-
914
- ## Development
915
-
916
- ```bash
917
- # Install dependencies
918
- pnpm install
919
-
920
- # Build the SDK
921
- pnpm run build
922
-
923
- # Watch mode
924
- pnpm run dev
925
-
926
- # Run tests
927
- pnpm test
928
- ```
929
-
930
- ## License
931
-
932
- MIT
933
-
934
- ## Support
935
-
936
- For issues and questions:
937
- - **GitHub Issues:** [Report an issue](https://github.com/superatomai/sdk-nodejs/issues)
938
- - **Email:** ashish@superatom.ai
939
-
940
- ## Contributing
941
-
942
- Contributions are welcome! Please feel free to submit a Pull Request.
1
+ # @superatomai/sdk-node
2
+
3
+ A TypeScript/Node.js SDK for building AI-powered data applications with Superatom - a platform for creating data-driven, intelligent applications with real-time WebSocket communication, LLM integration, and comprehensive user management.
4
+
5
+ ## Features
6
+
7
+ - **WebSocket Communication** - Real-time bidirectional messaging with automatic reconnection
8
+ - **AI-Powered Component Generation** - Automatically generate dashboard components and visualizations from user questions
9
+ - **Intelligent Text Responses** - LLM-powered conversational responses with SQL query execution and retry logic
10
+ - **Component Matching & Classification** - Smart component selection based on question type and visualization needs
11
+ - **Collection Handlers** - Register custom data operation handlers (CRUD, queries, mutations)
12
+ - **User Management** - Built-in authentication and user storage with file-based persistence
13
+ - **Dashboard & Report Management** - Create and manage dashboards and reports with DSL-based rendering
14
+ - **Multi-Provider LLM Integration** - Unified interface for Anthropic Claude and Groq models with automatic fallback
15
+ - **Thread & UI Block Management** - Organize conversations and UI components with automatic cleanup
16
+ - **Log Collection** - Capture and send runtime logs to the UI with configurable log levels
17
+ - **Prompt Loader** - Load and cache custom prompts from the file system with template variable support
18
+ - **Database Schema Management** - Automatic schema documentation generation for LLM context
19
+ - **Cleanup Service** - Automatic memory management and old data removal
20
+ - **TypeScript First** - Full type safety with comprehensive type definitions
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @superatomai/sdk-node
26
+ ```
27
+
28
+ Or with pnpm:
29
+
30
+ ```bash
31
+ pnpm add @superatomai/sdk-node
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```typescript
37
+ import { SuperatomSDK } from '@superatomai/sdk-node';
38
+
39
+ // Initialize the SDK
40
+ const sdk = new SuperatomSDK({
41
+ apiKey: 'your-api-key',
42
+ projectId: 'your-project-id',
43
+ userId: 'user-123', // optional, defaults to 'anonymous'
44
+ type: 'data-agent', // optional, defaults to 'data-agent'
45
+ });
46
+
47
+ // The SDK automatically connects to the Superatom WebSocket service
48
+ // Wait for connection before using
49
+ await sdk.connect();
50
+
51
+ // Register a collection handler for data operations
52
+ sdk.addCollection('users', 'getMany', async (params) => {
53
+ return {
54
+ data: [
55
+ { id: 1, name: 'John Doe', email: 'john@example.com' },
56
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
57
+ ],
58
+ };
59
+ });
60
+
61
+ // Listen to messages
62
+ sdk.onMessage((message) => {
63
+ console.log('Received:', message.type);
64
+ });
65
+
66
+ // Cleanup when done
67
+ await sdk.destroy();
68
+ ```
69
+
70
+ ## Configuration
71
+
72
+ ### SuperatomSDKConfig
73
+
74
+ ```typescript
75
+ interface SuperatomSDKConfig {
76
+ apiKey: string; // Required: Your Superatom API key
77
+ projectId: string; // Required: Your project ID
78
+ userId?: string; // Optional: User identifier (default: 'anonymous')
79
+ type?: string; // Optional: Agent type (default: 'data-agent')
80
+ url?: string; // Optional: Custom WebSocket URL
81
+ bundleDir?: string; // Optional: Directory for bundle requests
82
+ promptsDir?: string; // Optional: Custom prompts directory (default: .prompts)
83
+ ANTHROPIC_API_KEY?: string; // Optional: Anthropic API key for LLM
84
+ GROQ_API_KEY?: string; // Optional: Groq API key for LLM
85
+ LLM_PROVIDERS?: LLMProvider[]; // Optional: Custom LLM providers
86
+ logLevel?: LogLevel; // Optional: Log level (errors, warnings, info, verbose) (default: 'info')
87
+ }
88
+ ```
89
+
90
+ ### Environment Variables
91
+
92
+ - `SA_WEBSOCKET_URL` - WebSocket URL (default: `wss://ws.superatom.ai/websocket`)
93
+ - `ANTHROPIC_API_KEY` - Anthropic API key for Claude models
94
+ - `GROQ_API_KEY` - Groq API key for open-source models
95
+ - `SUPERATOM_LOG_LEVEL` - Log level for SDK logging (errors, warnings, info, verbose) (default: 'info')
96
+
97
+ ## Core Features
98
+
99
+ ### 1. Collection Handlers
100
+
101
+ Register custom handlers for data operations. Supports standard CRUD operations and custom operations.
102
+
103
+ ```typescript
104
+ // Register a getMany handler
105
+ sdk.addCollection<ParamsType, ResultType>(
106
+ 'products',
107
+ 'getMany',
108
+ async (params) => {
109
+ // params includes filters, pagination, etc.
110
+ const products = await database.products.find(params);
111
+ return { data: products };
112
+ }
113
+ );
114
+
115
+ // Register a createOne handler
116
+ sdk.addCollection('products', 'createOne', async (params) => {
117
+ const newProduct = await database.products.create(params);
118
+ return { data: newProduct };
119
+ });
120
+
121
+ // Register a custom query handler
122
+ sdk.addCollection('analytics', 'query', async (params) => {
123
+ const results = await runAnalyticsQuery(params);
124
+ return { data: results };
125
+ });
126
+ ```
127
+
128
+ **Supported Operations:**
129
+ - `getMany` - Fetch multiple records
130
+ - `getOne` - Fetch single record
131
+ - `createOne` - Create a record
132
+ - `updateOne` - Update a record
133
+ - `deleteOne` - Delete a record
134
+ - `query` - Custom queries
135
+ - `mutation` - Custom mutations
136
+
137
+ ### 2. Message Handling
138
+
139
+ Listen to all messages or specific message types:
140
+
141
+ ```typescript
142
+ // Listen to all messages
143
+ const unsubscribe = sdk.onMessage((message) => {
144
+ console.log('Message:', message.type, message.payload);
145
+ });
146
+
147
+ // Listen to specific message types
148
+ sdk.onMessageType('DATA_REQ', (message) => {
149
+ console.log('Data request received:', message.payload);
150
+ });
151
+
152
+ // Unsubscribe when needed
153
+ unsubscribe();
154
+
155
+ // Send messages
156
+ sdk.send({
157
+ type: 'CUSTOM_MESSAGE',
158
+ from: { id: 'sdk', type: 'agent' },
159
+ payload: { data: 'Hello' },
160
+ });
161
+ ```
162
+
163
+ **Built-in Message Types:**
164
+ - `DATA_REQ` - Data request from runtime
165
+ - `BUNDLE_REQ` - Bundle/asset request
166
+ - `AUTH_LOGIN_REQ` - Authentication login request
167
+ - `AUTH_VERIFY_REQ` - Token verification request
168
+ - `USER_PROMPT_REQ` - User prompt for LLM processing
169
+ - `USER_PROMPT_SUGGESTIONS_REQ` - Request for prompt suggestions
170
+ - `ACTIONS` - Component actions request
171
+ - `COMPONENT_LIST_RES` - Available components list
172
+ - `USERS` - User management operations
173
+ - `DASHBOARDS` - Dashboard CRUD operations
174
+ - `REPORTS` - Report CRUD operations
175
+
176
+ ### 3. User Management
177
+
178
+ Built-in user authentication and management with file-based storage:
179
+
180
+ ```typescript
181
+ const userManager = sdk.getUserManager();
182
+
183
+ // Create a user
184
+ await userManager.createUser({
185
+ username: 'john_doe',
186
+ password: 'secure_password',
187
+ });
188
+
189
+ // Get a user
190
+ const user = await userManager.getUser('john_doe');
191
+
192
+ // Update a user
193
+ await userManager.updateUser('john_doe', {
194
+ password: 'new_password',
195
+ });
196
+
197
+ // Delete a user
198
+ await userManager.deleteUser('john_doe');
199
+
200
+ // Get all users
201
+ const users = await userManager.getAllUsers();
202
+ ```
203
+
204
+ **Features:**
205
+ - Automatic password hashing with bcrypt
206
+ - File-based storage (JSON)
207
+ - Token-based authentication
208
+ - Auto-save on changes
209
+ - Memory management with configurable limits
210
+
211
+ ### 4. Dashboard Management
212
+
213
+ Create and manage dashboards with DSL-based rendering:
214
+
215
+ ```typescript
216
+ const dashboardManager = sdk.getDashboardManager();
217
+
218
+ // Create a dashboard
219
+ const dashboard = {
220
+ id: 'dashboard-1',
221
+ title: 'Sales Dashboard',
222
+ description: 'Overview of sales metrics',
223
+ dsl: {
224
+ type: 'container',
225
+ children: [
226
+ { type: 'chart', props: { chartType: 'line', data: [...] } },
227
+ { type: 'table', props: { columns: [...], data: [...] } },
228
+ ],
229
+ },
230
+ };
231
+
232
+ await dashboardManager.createDashboard(dashboard);
233
+
234
+ // Get a dashboard
235
+ const retrieved = await dashboardManager.getDashboard('dashboard-1');
236
+
237
+ // Update a dashboard
238
+ await dashboardManager.updateDashboard('dashboard-1', {
239
+ title: 'Updated Sales Dashboard',
240
+ });
241
+
242
+ // Delete a dashboard
243
+ await dashboardManager.deleteDashboard('dashboard-1');
244
+
245
+ // Get all dashboards
246
+ const allDashboards = await dashboardManager.getAllDashboards();
247
+ ```
248
+
249
+ ### 5. Report Management
250
+
251
+ Similar to dashboards, but for reports:
252
+
253
+ ```typescript
254
+ const reportManager = sdk.getReportManager();
255
+
256
+ // Create a report
257
+ const report = {
258
+ id: 'report-1',
259
+ title: 'Monthly Report',
260
+ description: 'Monthly performance report',
261
+ dsl: {
262
+ type: 'report',
263
+ sections: [
264
+ { type: 'summary', content: '...' },
265
+ { type: 'charts', data: [...] },
266
+ ],
267
+ },
268
+ };
269
+
270
+ await reportManager.createReport(report);
271
+
272
+ // CRUD operations work the same as dashboards
273
+ const retrieved = await reportManager.getReport('report-1');
274
+ await reportManager.updateReport('report-1', { title: 'Q1 Report' });
275
+ await reportManager.deleteReport('report-1');
276
+ const allReports = await reportManager.getAllReports();
277
+ ```
278
+
279
+ ### 6. LLM Integration
280
+
281
+ Unified interface for multiple LLM providers with streaming support:
282
+
283
+ ```typescript
284
+ import { LLM } from '@superatomai/sdk-node';
285
+
286
+ // Text generation
287
+ const response = await LLM.text(
288
+ {
289
+ sys: 'You are a helpful assistant.',
290
+ user: 'What is the meaning of life?',
291
+ },
292
+ {
293
+ model: 'anthropic/claude-sonnet-4-5', // or 'groq/llama3-70b'
294
+ apiKey: 'your-api-key',
295
+ maxTokens: 1000,
296
+ temperature: 0.7,
297
+ }
298
+ );
299
+
300
+ // Streaming responses
301
+ const result = await LLM.stream(
302
+ {
303
+ sys: 'You are a storyteller.',
304
+ user: 'Tell me a short story.',
305
+ },
306
+ {
307
+ model: 'anthropic/claude-sonnet-4-5',
308
+ apiKey: 'your-api-key',
309
+ partial: (chunk) => {
310
+ // Called for each chunk
311
+ process.stdout.write(chunk);
312
+ },
313
+ }
314
+ );
315
+
316
+ // JSON output
317
+ const jsonResult = await LLM.stream(
318
+ {
319
+ sys: 'Return a JSON object with user data.',
320
+ user: 'Create a user profile for John Doe.',
321
+ },
322
+ {
323
+ model: 'groq/llama3-70b',
324
+ apiKey: 'your-api-key',
325
+ },
326
+ true // Enable JSON parsing
327
+ );
328
+ ```
329
+
330
+ **Supported Models:**
331
+ - **Anthropic:** `claude-sonnet-4-5`, `claude-opus-4`, etc.
332
+ - **Groq:** `llama3-70b`, `mixtral-8x7b`, etc.
333
+
334
+ **Model Format:**
335
+ - With provider: `anthropic/model-name` or `groq/model-name`
336
+ - Without provider: Defaults to Anthropic
337
+
338
+ ### 7. AI-Powered User Response System
339
+
340
+ The SDK includes a powerful AI system for generating intelligent responses to user questions with two modes: **component generation** and **text responses**.
341
+
342
+ #### Component Generation Mode
343
+
344
+ Automatically match and generate dashboard components based on user questions:
345
+
346
+ ```typescript
347
+ import { get_user_response } from '@superatomai/sdk-node/userResponse';
348
+
349
+ const components = [
350
+ { id: 'sales-chart', name: 'SalesChart', type: 'BarChart', /* ... */ },
351
+ { id: 'kpi-card', name: 'RevenueKPI', type: 'KPICard', /* ... */ },
352
+ // ... more components
353
+ ];
354
+
355
+ const result = await get_user_response(
356
+ 'Show me sales by region',
357
+ components,
358
+ anthropicApiKey,
359
+ groqApiKey,
360
+ ['anthropic', 'groq'], // Provider fallback order
361
+ logCollector,
362
+ conversationHistory,
363
+ 'component' // Component generation mode
364
+ );
365
+
366
+ if (result.success) {
367
+ console.log('Generated component:', result.data.component);
368
+ console.log('Reasoning:', result.data.reasoning);
369
+ }
370
+ ```
371
+
372
+ **Features:**
373
+ - **Question Classification** - Automatically determines question type (analytical, data_modification, general)
374
+ - **Visualization Type Detection** - Identifies required visualization types (charts, tables, KPIs)
375
+ - **Multi-Component Dashboards** - Generates multiple components for comprehensive analysis
376
+ - **Props Modification** - Intelligently modifies component props including SQL queries
377
+ - **SQL Query Validation** - Ensures queries have proper LIMIT clauses and fixes scalar subqueries
378
+
379
+ #### Text Response Mode
380
+
381
+ Generate conversational text responses with SQL query execution:
382
+
383
+ ```typescript
384
+ const result = await get_user_response(
385
+ 'What were the top 5 selling products last month?',
386
+ components,
387
+ anthropicApiKey,
388
+ groqApiKey,
389
+ ['anthropic', 'groq'],
390
+ logCollector,
391
+ conversationHistory,
392
+ 'text', // Text response mode
393
+ (chunk) => {
394
+ // Stream text chunks in real-time
395
+ process.stdout.write(chunk);
396
+ },
397
+ collections // Required for query execution
398
+ );
399
+
400
+ if (result.success) {
401
+ console.log('Text response:', result.data.text);
402
+ console.log('Matched components:', result.data.matchedComponents);
403
+ console.log('Container component:', result.data.component);
404
+ }
405
+ ```
406
+
407
+ **Features:**
408
+ - **SQL Query Execution** - Automatically generates and executes SQL queries via tool calling
409
+ - **Automatic Retry Logic** - Up to 6 retry attempts with query correction on errors
410
+ - **Streaming Responses** - Real-time text streaming with query execution status updates
411
+ - **Component Suggestions** - Parses component suggestions from text and matches with available components
412
+ - **Layout Discovery** - Automatically selects appropriate dashboard layouts based on component metadata
413
+ - **Performance Tracking** - Measures and logs total time taken for request processing
414
+
415
+ #### Using BaseLLM Classes Directly
416
+
417
+ For more control, use the BaseLLM implementations directly:
418
+
419
+ ```typescript
420
+ import { anthropicLLM, groqLLM } from '@superatomai/sdk-node/userResponse';
421
+
422
+ // Classify user question
423
+ const classification = await anthropicLLM.classifyUserQuestion(
424
+ 'Show me sales trends',
425
+ apiKey,
426
+ logCollector,
427
+ conversationHistory
428
+ );
429
+
430
+ console.log('Question type:', classification.questionType);
431
+ console.log('Visualizations needed:', classification.visualizations);
432
+
433
+ // Generate analytical component
434
+ const result = await anthropicLLM.generateAnalyticalComponent(
435
+ 'Show me sales by region',
436
+ components,
437
+ 'BarChart', // Preferred visualization type
438
+ apiKey,
439
+ logCollector,
440
+ conversationHistory
441
+ );
442
+
443
+ // Match existing component
444
+ const matchResult = await anthropicLLM.matchComponent(
445
+ 'Update the sales dashboard',
446
+ components,
447
+ apiKey,
448
+ logCollector,
449
+ conversationHistory
450
+ );
451
+
452
+ // Generate next questions
453
+ const nextQuestions = await anthropicLLM.generateNextQuestions(
454
+ originalPrompt,
455
+ generatedComponent,
456
+ componentData,
457
+ apiKey,
458
+ logCollector,
459
+ conversationHistory
460
+ );
461
+ ```
462
+
463
+ **BaseLLM Methods:**
464
+ - `handleUserRequest()` - Main orchestration method (supports both component and text modes)
465
+ - `classifyUserQuestion()` - Classify question type and identify visualizations
466
+ - `generateAnalyticalComponent()` - Generate single analytical component
467
+ - `generateMultipleAnalyticalComponents()` - Generate multiple components in parallel
468
+ - `matchComponent()` - Match and modify existing component
469
+ - `validateAndModifyProps()` - Validate and modify component props
470
+ - `generateTextResponse()` - Generate text with tool calling support
471
+ - `matchComponentsFromTextResponse()` - Match components from text suggestions
472
+ - `generateNextQuestions()` - Generate follow-up question suggestions
473
+
474
+ ### 8. Prompt Loader System
475
+
476
+ The SDK includes a sophisticated prompt loading system with caching and template variable support:
477
+
478
+ ```typescript
479
+ import { promptLoader } from '@superatomai/sdk-node/userResponse';
480
+
481
+ // Initialize with custom directory (default: .prompts)
482
+ const sdk = new SuperatomSDK({
483
+ apiKey: 'your-api-key',
484
+ projectId: 'your-project-id',
485
+ promptsDir: './my-custom-prompts',
486
+ });
487
+
488
+ // Prompts are automatically loaded and cached on initialization
489
+ // Access prompt cache size
490
+ const cacheSize = promptLoader.getCacheSize();
491
+ console.log(`Loaded ${cacheSize} prompts`);
492
+
493
+ // Load specific prompts with variables
494
+ const prompts = await promptLoader.loadPrompts('classify', {
495
+ USER_PROMPT: userQuestion,
496
+ CONVERSATION_HISTORY: history || 'No previous conversation'
497
+ });
498
+
499
+ console.log('System prompt:', prompts.system);
500
+ console.log('User prompt:', prompts.user);
501
+ ```
502
+
503
+ **Prompt Directory Structure:**
504
+ ```
505
+ .prompts/
506
+ ├── classify/
507
+ │ ├── system.md # System prompt for classification
508
+ │ └── user.md # User prompt template
509
+ ├── match-component/
510
+ │ ├── system.md
511
+ │ └── user.md
512
+ ├── modify-props/
513
+ │ ├── system.md
514
+ │ └── user.md
515
+ ├── text-response/
516
+ │ ├── system.md
517
+ │ └── user.md
518
+ └── match-text-components/
519
+ ├── system.md
520
+ └── user.md
521
+ ```
522
+
523
+ **Template Variables:**
524
+ Variables in prompts are replaced using the `{{VARIABLE_NAME}}` syntax:
525
+
526
+ ```markdown
527
+ # system.md
528
+ You are analyzing this question: {{USER_PROMPT}}
529
+
530
+ Previous conversation:
531
+ {{CONVERSATION_HISTORY}}
532
+
533
+ Available components:
534
+ {{AVAILABLE_COMPONENTS}}
535
+ ```
536
+
537
+ **Built-in Prompt Types:**
538
+ - `classify` - Question classification and visualization type detection
539
+ - `match-component` - Component matching and selection
540
+ - `modify-props` - Props validation and modification
541
+ - `single-component` - Single analytical component generation
542
+ - `text-response` - Text response with tool calling
543
+ - `match-text-components` - Component matching from text suggestions
544
+ - `container-metadata` - Container title and description generation
545
+ - `actions` - Next question generation
546
+
547
+ ### 9. Thread & UI Block Management
548
+
549
+ Organize conversations and UI components:
550
+
551
+ ```typescript
552
+ import { Thread, UIBlock, ThreadManager } from '@superatomai/sdk-node';
553
+
554
+ const threadManager = ThreadManager.getInstance();
555
+
556
+ // Create a thread
557
+ const thread = threadManager.createThread({
558
+ userId: 'user-123',
559
+ metadata: { source: 'chat' },
560
+ });
561
+
562
+ // Add UI blocks
563
+ const block1 = new UIBlock(
564
+ 'block-1',
565
+ 'text',
566
+ { content: 'Hello!' }
567
+ );
568
+ thread.addBlock(block1);
569
+
570
+ const block2 = new UIBlock(
571
+ 'block-2',
572
+ 'table',
573
+ {
574
+ columns: ['Name', 'Age'],
575
+ data: [['John', 30], ['Jane', 25]]
576
+ }
577
+ );
578
+ thread.addBlock(block2);
579
+
580
+ // Get thread
581
+ const retrieved = threadManager.getThread(thread.getId());
582
+
583
+ // Get all threads
584
+ const allThreads = threadManager.getAllThreads();
585
+
586
+ // Delete thread
587
+ threadManager.deleteThread(thread.getId());
588
+ ```
589
+
590
+ **UI Block Types:**
591
+ - `text` - Text content
592
+ - `table` - Tabular data
593
+ - `chart` - Charts and visualizations
594
+ - `form` - Interactive forms
595
+ - Custom types as needed
596
+
597
+ ### 10. Logging System
598
+
599
+ The SDK includes a comprehensive logging system with environment-based log levels for both terminal and UI log collection.
600
+
601
+ #### Log Levels
602
+
603
+ The SDK supports hierarchical log levels:
604
+
605
+ - **`errors`** - Only error logs are shown
606
+ - **`warnings`** - Warning and error logs are shown
607
+ - **`info`** - Info, warning, and error logs are shown (default)
608
+ - **`verbose`** - All logs including debug messages are shown
609
+
610
+ #### Configuring Log Level
611
+
612
+ You can set the log level in three ways:
613
+
614
+ **1. Via environment variable (recommended for deployment):**
615
+
616
+ ```bash
617
+ export SUPERATOM_LOG_LEVEL=verbose
618
+ node your-app.js
619
+ ```
620
+
621
+ **2. Via SDK configuration (overrides environment variable):**
622
+
623
+ ```typescript
624
+ import { SuperatomSDK } from '@superatomai/sdk-node';
625
+
626
+ const sdk = new SuperatomSDK({
627
+ apiKey: 'your-api-key',
628
+ projectId: 'your-project-id',
629
+ logLevel: 'verbose', // errors | warnings | info | verbose
630
+ });
631
+ ```
632
+
633
+ **3. Programmatically at runtime:**
634
+
635
+ ```typescript
636
+ import { logger } from '@superatomai/sdk-node';
637
+
638
+ // Change log level at runtime
639
+ logger.setLogLevel('verbose');
640
+
641
+ // Get current log level
642
+ const currentLevel = logger.getLogLevel(); // returns 'verbose'
643
+ ```
644
+
645
+ #### Using the Logger
646
+
647
+ ```typescript
648
+ import { logger } from '@superatomai/sdk-node';
649
+
650
+ // These will be filtered based on the configured log level
651
+ logger.error('Critical error occurred'); // Shown at all levels
652
+ logger.warn('Something might be wrong'); // Hidden when level is 'errors'
653
+ logger.info('Processing completed'); // Hidden when level is 'errors' or 'warnings'
654
+ logger.debug('Detailed debug information'); // Only shown when level is 'verbose'
655
+ ```
656
+
657
+ #### UI Log Collection
658
+
659
+ The `UILogCollector` also respects the log level configuration. Logs are sent to the frontend and displayed in the terminal based on the configured level.
660
+
661
+ ```typescript
662
+ import { UILogCollector } from '@superatomai/sdk-node';
663
+
664
+ const collector = new UILogCollector(
665
+ clientId,
666
+ (msg) => sdk.send(msg),
667
+ 'uiblock-123'
668
+ );
669
+
670
+ // These logs are filtered based on log level before being sent to UI
671
+ collector.error('Error message'); // Always sent
672
+ collector.warn('Warning message'); // Sent unless level is 'errors'
673
+ collector.info('Info message'); // Sent unless level is 'errors' or 'warnings'
674
+ collector.debug('Debug message'); // Only sent when level is 'verbose'
675
+
676
+ // Get all collected logs
677
+ const logs = collector.getLogs();
678
+ ```
679
+
680
+ **Note:** The log level affects both terminal output and UI log collection, ensuring consistent logging behavior across your application.
681
+
682
+ ### 11. Cleanup Service
683
+
684
+ Automatic memory management for threads and UI blocks:
685
+
686
+ ```typescript
687
+ import { CleanupService } from '@superatomai/sdk-node';
688
+
689
+ const cleanupService = CleanupService.getInstance();
690
+
691
+ // Start automatic cleanup (runs every 24 hours by default)
692
+ cleanupService.startAutoCleanup(24);
693
+
694
+ // Manual cleanup
695
+ const stats = cleanupService.runFullCleanup();
696
+ console.log('Cleanup stats:', stats);
697
+ // Output: { threadsDeleted: 5, uiblocksDeleted: {...}, dataCleared: 10 }
698
+
699
+ // Get memory statistics
700
+ const memStats = cleanupService.getMemoryStats();
701
+ console.log('Memory:', memStats);
702
+ // Output: { threadCount: 42, totalUIBlocks: 156, avgUIBlocksPerThread: 3.7 }
703
+
704
+ // Stop automatic cleanup
705
+ cleanupService.stopAutoCleanup();
706
+ ```
707
+
708
+ **Configuration:**
709
+
710
+ ```typescript
711
+ import { STORAGE_CONFIG } from '@superatomai/sdk-node';
712
+
713
+ // Thread retention (default: 30 days)
714
+ STORAGE_CONFIG.THREAD_RETENTION_DAYS = 60;
715
+
716
+ // UI block retention (default: 7 days)
717
+ STORAGE_CONFIG.UIBLOCK_RETENTION_DAYS = 14;
718
+
719
+ // Max component data size (default: 100KB)
720
+ STORAGE_CONFIG.MAX_COMPONENT_DATA_SIZE = 200 * 1024;
721
+ ```
722
+
723
+ ## API Reference
724
+
725
+ ### SuperatomSDK
726
+
727
+ #### Methods
728
+
729
+ - `connect(): Promise<void>` - Connect to WebSocket service
730
+ - `disconnect(): void` - Disconnect from WebSocket
731
+ - `destroy(): Promise<void>` - Cleanup and disconnect permanently
732
+ - `isConnected(): boolean` - Check connection status
733
+ - `send(message: Message): void` - Send a message
734
+ - `onMessage(handler): () => void` - Register message handler (returns unsubscribe function)
735
+ - `onMessageType(type, handler): () => void` - Register type-specific handler
736
+ - `addCollection(name, operation, handler): void` - Register collection handler
737
+ - `getUserManager(): UserManager` - Get user manager instance
738
+ - `getDashboardManager(): DashboardManager` - Get dashboard manager instance
739
+ - `getReportManager(): ReportManager` - Get report manager instance
740
+
741
+ ### UserManager
742
+
743
+ #### Methods
744
+
745
+ - `createUser(data): Promise<User>` - Create a new user
746
+ - `getUser(username): Promise<User | null>` - Get user by username
747
+ - `updateUser(username, data): Promise<User>` - Update user
748
+ - `deleteUser(username): Promise<boolean>` - Delete user
749
+ - `getAllUsers(): Promise<User[]>` - Get all users
750
+ - `verifyPassword(username, password): Promise<boolean>` - Verify password
751
+ - `generateToken(username): Promise<string>` - Generate auth token
752
+ - `verifyToken(token): Promise<User | null>` - Verify auth token
753
+
754
+ ### DashboardManager
755
+
756
+ #### Methods
757
+
758
+ - `createDashboard(dashboard): Promise<DSLRendererProps>` - Create dashboard
759
+ - `getDashboard(id): Promise<DSLRendererProps | null>` - Get dashboard
760
+ - `updateDashboard(id, updates): Promise<DSLRendererProps>` - Update dashboard
761
+ - `deleteDashboard(id): Promise<boolean>` - Delete dashboard
762
+ - `getAllDashboards(): Promise<DSLRendererProps[]>` - Get all dashboards
763
+
764
+ ### ReportManager
765
+
766
+ Same methods as DashboardManager but for reports.
767
+
768
+ ### LLM (Static Class)
769
+
770
+ #### Methods
771
+
772
+ - `text(messages, options): Promise<string>` - Generate text response
773
+ - `stream(messages, options, json?): Promise<string | object>` - Stream response
774
+
775
+ ### ThreadManager
776
+
777
+ #### Methods
778
+
779
+ - `getInstance(): ThreadManager` - Get singleton instance
780
+ - `createThread(options): Thread` - Create new thread
781
+ - `getThread(id): Thread | undefined` - Get thread by ID
782
+ - `getAllThreads(): Thread[]` - Get all threads
783
+ - `deleteThread(id): boolean` - Delete thread
784
+
785
+ ### CleanupService
786
+
787
+ #### Methods
788
+
789
+ - `getInstance(): CleanupService` - Get singleton instance
790
+ - `startAutoCleanup(intervalHours?): void` - Start automatic cleanup
791
+ - `stopAutoCleanup(): void` - Stop automatic cleanup
792
+ - `runFullCleanup(): CleanupStats` - Run manual cleanup
793
+ - `getMemoryStats(): MemoryStats` - Get current memory statistics
794
+
795
+ ### UILogCollector
796
+
797
+ #### Methods
798
+
799
+ - `start(): void` - Start collecting logs
800
+ - `stop(): void` - Stop collecting
801
+ - `clear(): void` - Clear collected logs
802
+ - `getLogs(): CapturedLog[]` - Get all logs
803
+ - `addLog(log): void` - Add custom log
804
+ - `createMessage(uiBlockId): UILogsMessage` - Create message for SDK
805
+
806
+ ## Advanced Usage
807
+
808
+ ### Custom Message Handlers
809
+
810
+ ```typescript
811
+ // Handle custom message types
812
+ sdk.onMessageType('CUSTOM_EVENT', async (message) => {
813
+ console.log('Custom event:', message.payload);
814
+
815
+ // Process and respond
816
+ sdk.send({
817
+ type: 'CUSTOM_RESPONSE',
818
+ from: { id: 'sdk', type: 'agent' },
819
+ payload: { result: 'processed' },
820
+ });
821
+ });
822
+ ```
823
+
824
+ ### Error Handling
825
+
826
+ ```typescript
827
+ try {
828
+ await sdk.connect();
829
+ } catch (error) {
830
+ console.error('Connection failed:', error);
831
+ }
832
+
833
+ // Handle WebSocket errors
834
+ sdk.onMessageType('error', (message) => {
835
+ console.error('Error message:', message.payload);
836
+ });
837
+ ```
838
+
839
+ ### Reconnection
840
+
841
+ The SDK automatically handles reconnection with exponential backoff:
842
+ - Max attempts: 5
843
+ - Delay: 1s, 2s, 4s, 8s, 10s (capped at 10s)
844
+
845
+ ### Bundle Requests
846
+
847
+ Serve static files via bundle requests:
848
+
849
+ ```typescript
850
+ const sdk = new SuperatomSDK({
851
+ apiKey: 'your-api-key',
852
+ projectId: 'your-project-id',
853
+ bundleDir: './public', // Directory to serve files from
854
+ });
855
+
856
+ // Files in ./public will be served when requested
857
+ ```
858
+
859
+ ## TypeScript Support
860
+
861
+ This SDK is written in TypeScript and includes full type definitions. All exports are fully typed for the best development experience.
862
+
863
+ ```typescript
864
+ import type {
865
+ Message,
866
+ IncomingMessage,
867
+ SuperatomSDKConfig,
868
+ CollectionHandler,
869
+ CollectionOperation,
870
+ User,
871
+ UsersData,
872
+ Component,
873
+ T_RESPONSE,
874
+ LLMProvider,
875
+ LogLevel,
876
+ CapturedLog,
877
+ Action,
878
+ } from '@superatomai/sdk-node';
879
+
880
+ // Import LLM and utility classes
881
+ import {
882
+ LLM,
883
+ UserManager,
884
+ UILogCollector,
885
+ Thread,
886
+ UIBlock,
887
+ ThreadManager,
888
+ CleanupService,
889
+ logger,
890
+ } from '@superatomai/sdk-node';
891
+
892
+ // Import user response utilities
893
+ import {
894
+ get_user_response,
895
+ anthropicLLM,
896
+ groqLLM,
897
+ } from '@superatomai/sdk-node/userResponse';
898
+ ```
899
+
900
+ ## Examples
901
+
902
+ Check out the [examples](./examples) directory for complete examples:
903
+ - Basic WebSocket communication
904
+ - Data collection handlers
905
+ - User authentication flow
906
+ - LLM integration with streaming
907
+ - AI-powered component generation
908
+ - Text response with query execution
909
+ - Component matching and classification
910
+ - Thread management
911
+ - Dashboard creation
912
+ - Prompt customization
913
+
914
+ ## Development
915
+
916
+ ```bash
917
+ # Install dependencies
918
+ pnpm install
919
+
920
+ # Build the SDK
921
+ pnpm run build
922
+
923
+ # Watch mode
924
+ pnpm run dev
925
+
926
+ # Run tests
927
+ pnpm test
928
+ ```
929
+
930
+ ## License
931
+
932
+ MIT
933
+
934
+ ## Support
935
+
936
+ For issues and questions:
937
+ - **GitHub Issues:** [Report an issue](https://github.com/superatomai/sdk-nodejs/issues)
938
+ - **Email:** ashish@superatom.ai
939
+
940
+ ## Contributing
941
+
942
+ Contributions are welcome! Please feel free to submit a Pull Request.