@superatomai/sdk-node 0.0.5 → 0.0.6-cp

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,724 +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
- - **Collection Handlers** - Register custom data operation handlers (CRUD, queries, mutations)
9
- - **User Management** - Built-in authentication and user storage with file-based persistence
10
- - **Dashboard & Report Management** - Create and manage dashboards and reports with DSL-based rendering
11
- - **LLM Integration** - Unified interface for Anthropic Claude and Groq models with streaming support
12
- - **Thread & UI Block Management** - Organize conversations and UI components with automatic cleanup
13
- - **Log Collection** - Capture and send runtime logs to the UI
14
- - **Prompt Loader** - Load custom prompts from the file system
15
- - **Cleanup Service** - Automatic memory management and old data removal
16
- - **TypeScript First** - Full type safety with comprehensive type definitions
17
-
18
- ## Installation
19
-
20
- ```bash
21
- npm install @superatomai/sdk-node
22
- ```
23
-
24
- Or with pnpm:
25
-
26
- ```bash
27
- pnpm add @superatomai/sdk-node
28
- ```
29
-
30
- ## Quick Start
31
-
32
- ```typescript
33
- import { SuperatomSDK } from '@superatomai/sdk-node';
34
-
35
- // Initialize the SDK
36
- const sdk = new SuperatomSDK({
37
- apiKey: 'your-api-key',
38
- projectId: 'your-project-id',
39
- userId: 'user-123', // optional, defaults to 'anonymous'
40
- type: 'data-agent', // optional, defaults to 'data-agent'
41
- });
42
-
43
- // The SDK automatically connects to the Superatom WebSocket service
44
- // Wait for connection before using
45
- await sdk.connect();
46
-
47
- // Register a collection handler for data operations
48
- sdk.addCollection('users', 'getMany', async (params) => {
49
- return {
50
- data: [
51
- { id: 1, name: 'John Doe', email: 'john@example.com' },
52
- { id: 2, name: 'Jane Smith', email: 'jane@example.com' },
53
- ],
54
- };
55
- });
56
-
57
- // Listen to messages
58
- sdk.onMessage((message) => {
59
- console.log('Received:', message.type);
60
- });
61
-
62
- // Cleanup when done
63
- await sdk.destroy();
64
- ```
65
-
66
- ## Configuration
67
-
68
- ### SuperatomSDKConfig
69
-
70
- ```typescript
71
- interface SuperatomSDKConfig {
72
- apiKey: string; // Required: Your Superatom API key
73
- projectId: string; // Required: Your project ID
74
- userId?: string; // Optional: User identifier (default: 'anonymous')
75
- type?: string; // Optional: Agent type (default: 'data-agent')
76
- url?: string; // Optional: Custom WebSocket URL
77
- bundleDir?: string; // Optional: Directory for bundle requests
78
- promptsDir?: string; // Optional: Custom prompts directory (default: .prompts)
79
- ANTHROPIC_API_KEY?: string; // Optional: Anthropic API key for LLM
80
- GROQ_API_KEY?: string; // Optional: Groq API key for LLM
81
- LLM_PROVIDERS?: LLMProvider[]; // Optional: Custom LLM providers
82
- logLevel?: LogLevel; // Optional: Log level (errors, warnings, info, verbose) (default: 'info')
83
- }
84
- ```
85
-
86
- ### Environment Variables
87
-
88
- - `SA_WEBSOCKET_URL` - WebSocket URL (default: `wss://ws.superatom.ai/websocket`)
89
- - `ANTHROPIC_API_KEY` - Anthropic API key for Claude models
90
- - `GROQ_API_KEY` - Groq API key for open-source models
91
- - `SUPERATOM_LOG_LEVEL` - Log level for SDK logging (errors, warnings, info, verbose) (default: 'info')
92
-
93
- ## Core Features
94
-
95
- ### 1. Collection Handlers
96
-
97
- Register custom handlers for data operations. Supports standard CRUD operations and custom operations.
98
-
99
- ```typescript
100
- // Register a getMany handler
101
- sdk.addCollection<ParamsType, ResultType>(
102
- 'products',
103
- 'getMany',
104
- async (params) => {
105
- // params includes filters, pagination, etc.
106
- const products = await database.products.find(params);
107
- return { data: products };
108
- }
109
- );
110
-
111
- // Register a createOne handler
112
- sdk.addCollection('products', 'createOne', async (params) => {
113
- const newProduct = await database.products.create(params);
114
- return { data: newProduct };
115
- });
116
-
117
- // Register a custom query handler
118
- sdk.addCollection('analytics', 'query', async (params) => {
119
- const results = await runAnalyticsQuery(params);
120
- return { data: results };
121
- });
122
- ```
123
-
124
- **Supported Operations:**
125
- - `getMany` - Fetch multiple records
126
- - `getOne` - Fetch single record
127
- - `createOne` - Create a record
128
- - `updateOne` - Update a record
129
- - `deleteOne` - Delete a record
130
- - `query` - Custom queries
131
- - `mutation` - Custom mutations
132
-
133
- ### 2. Message Handling
134
-
135
- Listen to all messages or specific message types:
136
-
137
- ```typescript
138
- // Listen to all messages
139
- const unsubscribe = sdk.onMessage((message) => {
140
- console.log('Message:', message.type, message.payload);
141
- });
142
-
143
- // Listen to specific message types
144
- sdk.onMessageType('DATA_REQ', (message) => {
145
- console.log('Data request received:', message.payload);
146
- });
147
-
148
- // Unsubscribe when needed
149
- unsubscribe();
150
-
151
- // Send messages
152
- sdk.send({
153
- type: 'CUSTOM_MESSAGE',
154
- from: { id: 'sdk', type: 'agent' },
155
- payload: { data: 'Hello' },
156
- });
157
- ```
158
-
159
- **Built-in Message Types:**
160
- - `DATA_REQ` - Data request from runtime
161
- - `BUNDLE_REQ` - Bundle/asset request
162
- - `AUTH_LOGIN_REQ` - Authentication login request
163
- - `AUTH_VERIFY_REQ` - Token verification request
164
- - `USER_PROMPT_REQ` - User prompt for LLM processing
165
- - `USER_PROMPT_SUGGESTIONS_REQ` - Request for prompt suggestions
166
- - `ACTIONS` - Component actions request
167
- - `COMPONENT_LIST_RES` - Available components list
168
- - `USERS` - User management operations
169
- - `DASHBOARDS` - Dashboard CRUD operations
170
- - `REPORTS` - Report CRUD operations
171
-
172
- ### 3. User Management
173
-
174
- Built-in user authentication and management with file-based storage:
175
-
176
- ```typescript
177
- const userManager = sdk.getUserManager();
178
-
179
- // Create a user
180
- await userManager.createUser({
181
- username: 'john_doe',
182
- password: 'secure_password',
183
- });
184
-
185
- // Get a user
186
- const user = await userManager.getUser('john_doe');
187
-
188
- // Update a user
189
- await userManager.updateUser('john_doe', {
190
- password: 'new_password',
191
- });
192
-
193
- // Delete a user
194
- await userManager.deleteUser('john_doe');
195
-
196
- // Get all users
197
- const users = await userManager.getAllUsers();
198
- ```
199
-
200
- **Features:**
201
- - Automatic password hashing with bcrypt
202
- - File-based storage (JSON)
203
- - Token-based authentication
204
- - Auto-save on changes
205
- - Memory management with configurable limits
206
-
207
- ### 4. Dashboard Management
208
-
209
- Create and manage dashboards with DSL-based rendering:
210
-
211
- ```typescript
212
- const dashboardManager = sdk.getDashboardManager();
213
-
214
- // Create a dashboard
215
- const dashboard = {
216
- id: 'dashboard-1',
217
- title: 'Sales Dashboard',
218
- description: 'Overview of sales metrics',
219
- dsl: {
220
- type: 'container',
221
- children: [
222
- { type: 'chart', props: { chartType: 'line', data: [...] } },
223
- { type: 'table', props: { columns: [...], data: [...] } },
224
- ],
225
- },
226
- };
227
-
228
- await dashboardManager.createDashboard(dashboard);
229
-
230
- // Get a dashboard
231
- const retrieved = await dashboardManager.getDashboard('dashboard-1');
232
-
233
- // Update a dashboard
234
- await dashboardManager.updateDashboard('dashboard-1', {
235
- title: 'Updated Sales Dashboard',
236
- });
237
-
238
- // Delete a dashboard
239
- await dashboardManager.deleteDashboard('dashboard-1');
240
-
241
- // Get all dashboards
242
- const allDashboards = await dashboardManager.getAllDashboards();
243
- ```
244
-
245
- ### 5. Report Management
246
-
247
- Similar to dashboards, but for reports:
248
-
249
- ```typescript
250
- const reportManager = sdk.getReportManager();
251
-
252
- // Create a report
253
- const report = {
254
- id: 'report-1',
255
- title: 'Monthly Report',
256
- description: 'Monthly performance report',
257
- dsl: {
258
- type: 'report',
259
- sections: [
260
- { type: 'summary', content: '...' },
261
- { type: 'charts', data: [...] },
262
- ],
263
- },
264
- };
265
-
266
- await reportManager.createReport(report);
267
-
268
- // CRUD operations work the same as dashboards
269
- const retrieved = await reportManager.getReport('report-1');
270
- await reportManager.updateReport('report-1', { title: 'Q1 Report' });
271
- await reportManager.deleteReport('report-1');
272
- const allReports = await reportManager.getAllReports();
273
- ```
274
-
275
- ### 6. LLM Integration
276
-
277
- Unified interface for multiple LLM providers with streaming support:
278
-
279
- ```typescript
280
- import { LLM } from '@superatomai/sdk-node';
281
-
282
- // Text generation
283
- const response = await LLM.text(
284
- {
285
- sys: 'You are a helpful assistant.',
286
- user: 'What is the meaning of life?',
287
- },
288
- {
289
- model: 'anthropic/claude-sonnet-4-5', // or 'groq/llama3-70b'
290
- apiKey: 'your-api-key',
291
- maxTokens: 1000,
292
- temperature: 0.7,
293
- }
294
- );
295
-
296
- // Streaming responses
297
- const result = await LLM.stream(
298
- {
299
- sys: 'You are a storyteller.',
300
- user: 'Tell me a short story.',
301
- },
302
- {
303
- model: 'anthropic/claude-sonnet-4-5',
304
- apiKey: 'your-api-key',
305
- partial: (chunk) => {
306
- // Called for each chunk
307
- process.stdout.write(chunk);
308
- },
309
- }
310
- );
311
-
312
- // JSON output
313
- const jsonResult = await LLM.stream(
314
- {
315
- sys: 'Return a JSON object with user data.',
316
- user: 'Create a user profile for John Doe.',
317
- },
318
- {
319
- model: 'groq/llama3-70b',
320
- apiKey: 'your-api-key',
321
- },
322
- true // Enable JSON parsing
323
- );
324
- ```
325
-
326
- **Supported Models:**
327
- - **Anthropic:** `claude-sonnet-4-5`, `claude-opus-4`, etc.
328
- - **Groq:** `llama3-70b`, `mixtral-8x7b`, etc.
329
-
330
- **Model Format:**
331
- - With provider: `anthropic/model-name` or `groq/model-name`
332
- - Without provider: Defaults to Anthropic
333
-
334
- ### 7. Thread & UI Block Management
335
-
336
- Organize conversations and UI components:
337
-
338
- ```typescript
339
- import { Thread, UIBlock, ThreadManager } from '@superatomai/sdk-node';
340
-
341
- const threadManager = ThreadManager.getInstance();
342
-
343
- // Create a thread
344
- const thread = threadManager.createThread({
345
- userId: 'user-123',
346
- metadata: { source: 'chat' },
347
- });
348
-
349
- // Add UI blocks
350
- const block1 = new UIBlock(
351
- 'block-1',
352
- 'text',
353
- { content: 'Hello!' }
354
- );
355
- thread.addBlock(block1);
356
-
357
- const block2 = new UIBlock(
358
- 'block-2',
359
- 'table',
360
- {
361
- columns: ['Name', 'Age'],
362
- data: [['John', 30], ['Jane', 25]]
363
- }
364
- );
365
- thread.addBlock(block2);
366
-
367
- // Get thread
368
- const retrieved = threadManager.getThread(thread.getId());
369
-
370
- // Get all threads
371
- const allThreads = threadManager.getAllThreads();
372
-
373
- // Delete thread
374
- threadManager.deleteThread(thread.getId());
375
- ```
376
-
377
- **UI Block Types:**
378
- - `text` - Text content
379
- - `table` - Tabular data
380
- - `chart` - Charts and visualizations
381
- - `form` - Interactive forms
382
- - Custom types as needed
383
-
384
- ### 8. Logging System
385
-
386
- The SDK includes a comprehensive logging system with environment-based log levels for both terminal and UI log collection.
387
-
388
- #### Log Levels
389
-
390
- The SDK supports hierarchical log levels:
391
-
392
- - **`errors`** - Only error logs are shown
393
- - **`warnings`** - Warning and error logs are shown
394
- - **`info`** - Info, warning, and error logs are shown (default)
395
- - **`verbose`** - All logs including debug messages are shown
396
-
397
- #### Configuring Log Level
398
-
399
- You can set the log level in three ways:
400
-
401
- **1. Via environment variable (recommended for deployment):**
402
-
403
- ```bash
404
- export SUPERATOM_LOG_LEVEL=verbose
405
- node your-app.js
406
- ```
407
-
408
- **2. Via SDK configuration (overrides environment variable):**
409
-
410
- ```typescript
411
- import { SuperatomSDK } from '@superatomai/sdk-node';
412
-
413
- const sdk = new SuperatomSDK({
414
- apiKey: 'your-api-key',
415
- projectId: 'your-project-id',
416
- logLevel: 'verbose', // errors | warnings | info | verbose
417
- });
418
- ```
419
-
420
- **3. Programmatically at runtime:**
421
-
422
- ```typescript
423
- import { logger } from '@superatomai/sdk-node';
424
-
425
- // Change log level at runtime
426
- logger.setLogLevel('verbose');
427
-
428
- // Get current log level
429
- const currentLevel = logger.getLogLevel(); // returns 'verbose'
430
- ```
431
-
432
- #### Using the Logger
433
-
434
- ```typescript
435
- import { logger } from '@superatomai/sdk-node';
436
-
437
- // These will be filtered based on the configured log level
438
- logger.error('Critical error occurred'); // Shown at all levels
439
- logger.warn('Something might be wrong'); // Hidden when level is 'errors'
440
- logger.info('Processing completed'); // Hidden when level is 'errors' or 'warnings'
441
- logger.debug('Detailed debug information'); // Only shown when level is 'verbose'
442
- ```
443
-
444
- #### UI Log Collection
445
-
446
- The `UILogCollector` also respects the log level configuration. Logs are sent to the frontend and displayed in the terminal based on the configured level.
447
-
448
- ```typescript
449
- import { UILogCollector } from '@superatomai/sdk-node';
450
-
451
- const collector = new UILogCollector(
452
- clientId,
453
- (msg) => sdk.send(msg),
454
- 'uiblock-123'
455
- );
456
-
457
- // These logs are filtered based on log level before being sent to UI
458
- collector.error('Error message'); // Always sent
459
- collector.warn('Warning message'); // Sent unless level is 'errors'
460
- collector.info('Info message'); // Sent unless level is 'errors' or 'warnings'
461
- collector.debug('Debug message'); // Only sent when level is 'verbose'
462
-
463
- // Get all collected logs
464
- const logs = collector.getLogs();
465
- ```
466
-
467
- **Note:** The log level affects both terminal output and UI log collection, ensuring consistent logging behavior across your application.
468
-
469
- ### 9. Cleanup Service
470
-
471
- Automatic memory management for threads and UI blocks:
472
-
473
- ```typescript
474
- import { CleanupService } from '@superatomai/sdk-node';
475
-
476
- const cleanupService = CleanupService.getInstance();
477
-
478
- // Start automatic cleanup (runs every 24 hours by default)
479
- cleanupService.startAutoCleanup(24);
480
-
481
- // Manual cleanup
482
- const stats = cleanupService.runFullCleanup();
483
- console.log('Cleanup stats:', stats);
484
- // Output: { threadsDeleted: 5, uiblocksDeleted: {...}, dataCleared: 10 }
485
-
486
- // Get memory statistics
487
- const memStats = cleanupService.getMemoryStats();
488
- console.log('Memory:', memStats);
489
- // Output: { threadCount: 42, totalUIBlocks: 156, avgUIBlocksPerThread: 3.7 }
490
-
491
- // Stop automatic cleanup
492
- cleanupService.stopAutoCleanup();
493
- ```
494
-
495
- **Configuration:**
496
-
497
- ```typescript
498
- import { STORAGE_CONFIG } from '@superatomai/sdk-node';
499
-
500
- // Thread retention (default: 30 days)
501
- STORAGE_CONFIG.THREAD_RETENTION_DAYS = 60;
502
-
503
- // UI block retention (default: 7 days)
504
- STORAGE_CONFIG.UIBLOCK_RETENTION_DAYS = 14;
505
-
506
- // Max component data size (default: 100KB)
507
- STORAGE_CONFIG.MAX_COMPONENT_DATA_SIZE = 200 * 1024;
508
- ```
509
-
510
- ### 10. Prompt Loader
511
-
512
- Load custom prompts from the file system:
513
-
514
- ```typescript
515
- // Prompts are automatically loaded from .prompts/ directory
516
- // Or specify custom directory in config:
517
- const sdk = new SuperatomSDK({
518
- apiKey: 'your-api-key',
519
- projectId: 'your-project-id',
520
- promptsDir: './my-prompts',
521
- });
522
-
523
- // Prompts are loaded and cached on initialization
524
- // They can be accessed by handlers internally
525
- ```
526
-
527
- **Prompt File Structure:**
528
- ```
529
- .prompts/
530
- ├── system.txt # System prompts
531
- ├── user-greeting.txt # User greeting prompts
532
- └── analysis.txt # Analysis prompts
533
- ```
534
-
535
- ## API Reference
536
-
537
- ### SuperatomSDK
538
-
539
- #### Methods
540
-
541
- - `connect(): Promise<void>` - Connect to WebSocket service
542
- - `disconnect(): void` - Disconnect from WebSocket
543
- - `destroy(): Promise<void>` - Cleanup and disconnect permanently
544
- - `isConnected(): boolean` - Check connection status
545
- - `send(message: Message): void` - Send a message
546
- - `onMessage(handler): () => void` - Register message handler (returns unsubscribe function)
547
- - `onMessageType(type, handler): () => void` - Register type-specific handler
548
- - `addCollection(name, operation, handler): void` - Register collection handler
549
- - `getUserManager(): UserManager` - Get user manager instance
550
- - `getDashboardManager(): DashboardManager` - Get dashboard manager instance
551
- - `getReportManager(): ReportManager` - Get report manager instance
552
-
553
- ### UserManager
554
-
555
- #### Methods
556
-
557
- - `createUser(data): Promise<User>` - Create a new user
558
- - `getUser(username): Promise<User | null>` - Get user by username
559
- - `updateUser(username, data): Promise<User>` - Update user
560
- - `deleteUser(username): Promise<boolean>` - Delete user
561
- - `getAllUsers(): Promise<User[]>` - Get all users
562
- - `verifyPassword(username, password): Promise<boolean>` - Verify password
563
- - `generateToken(username): Promise<string>` - Generate auth token
564
- - `verifyToken(token): Promise<User | null>` - Verify auth token
565
-
566
- ### DashboardManager
567
-
568
- #### Methods
569
-
570
- - `createDashboard(dashboard): Promise<DSLRendererProps>` - Create dashboard
571
- - `getDashboard(id): Promise<DSLRendererProps | null>` - Get dashboard
572
- - `updateDashboard(id, updates): Promise<DSLRendererProps>` - Update dashboard
573
- - `deleteDashboard(id): Promise<boolean>` - Delete dashboard
574
- - `getAllDashboards(): Promise<DSLRendererProps[]>` - Get all dashboards
575
-
576
- ### ReportManager
577
-
578
- Same methods as DashboardManager but for reports.
579
-
580
- ### LLM (Static Class)
581
-
582
- #### Methods
583
-
584
- - `text(messages, options): Promise<string>` - Generate text response
585
- - `stream(messages, options, json?): Promise<string | object>` - Stream response
586
-
587
- ### ThreadManager
588
-
589
- #### Methods
590
-
591
- - `getInstance(): ThreadManager` - Get singleton instance
592
- - `createThread(options): Thread` - Create new thread
593
- - `getThread(id): Thread | undefined` - Get thread by ID
594
- - `getAllThreads(): Thread[]` - Get all threads
595
- - `deleteThread(id): boolean` - Delete thread
596
-
597
- ### CleanupService
598
-
599
- #### Methods
600
-
601
- - `getInstance(): CleanupService` - Get singleton instance
602
- - `startAutoCleanup(intervalHours?): void` - Start automatic cleanup
603
- - `stopAutoCleanup(): void` - Stop automatic cleanup
604
- - `runFullCleanup(): CleanupStats` - Run manual cleanup
605
- - `getMemoryStats(): MemoryStats` - Get current memory statistics
606
-
607
- ### UILogCollector
608
-
609
- #### Methods
610
-
611
- - `start(): void` - Start collecting logs
612
- - `stop(): void` - Stop collecting
613
- - `clear(): void` - Clear collected logs
614
- - `getLogs(): CapturedLog[]` - Get all logs
615
- - `addLog(log): void` - Add custom log
616
- - `createMessage(uiBlockId): UILogsMessage` - Create message for SDK
617
-
618
- ## Advanced Usage
619
-
620
- ### Custom Message Handlers
621
-
622
- ```typescript
623
- // Handle custom message types
624
- sdk.onMessageType('CUSTOM_EVENT', async (message) => {
625
- console.log('Custom event:', message.payload);
626
-
627
- // Process and respond
628
- sdk.send({
629
- type: 'CUSTOM_RESPONSE',
630
- from: { id: 'sdk', type: 'agent' },
631
- payload: { result: 'processed' },
632
- });
633
- });
634
- ```
635
-
636
- ### Error Handling
637
-
638
- ```typescript
639
- try {
640
- await sdk.connect();
641
- } catch (error) {
642
- console.error('Connection failed:', error);
643
- }
644
-
645
- // Handle WebSocket errors
646
- sdk.onMessageType('error', (message) => {
647
- console.error('Error message:', message.payload);
648
- });
649
- ```
650
-
651
- ### Reconnection
652
-
653
- The SDK automatically handles reconnection with exponential backoff:
654
- - Max attempts: 5
655
- - Delay: 1s, 2s, 4s, 8s, 10s (capped at 10s)
656
-
657
- ### Bundle Requests
658
-
659
- Serve static files via bundle requests:
660
-
661
- ```typescript
662
- const sdk = new SuperatomSDK({
663
- apiKey: 'your-api-key',
664
- projectId: 'your-project-id',
665
- bundleDir: './public', // Directory to serve files from
666
- });
667
-
668
- // Files in ./public will be served when requested
669
- ```
670
-
671
- ## TypeScript Support
672
-
673
- This SDK is written in TypeScript and includes full type definitions. All exports are fully typed for the best development experience.
674
-
675
- ```typescript
676
- import type {
677
- Message,
678
- IncomingMessage,
679
- SuperatomSDKConfig,
680
- CollectionHandler,
681
- User,
682
- DSLRendererProps,
683
- } from '@superatomai/sdk-node';
684
- ```
685
-
686
- ## Examples
687
-
688
- Check out the [examples](./examples) directory for complete examples:
689
- - Basic WebSocket communication
690
- - Data collection handlers
691
- - User authentication flow
692
- - LLM integration
693
- - Thread management
694
- - Dashboard creation
695
-
696
- ## Development
697
-
698
- ```bash
699
- # Install dependencies
700
- pnpm install
701
-
702
- # Build the SDK
703
- pnpm run build
704
-
705
- # Watch mode
706
- pnpm run dev
707
-
708
- # Run tests
709
- pnpm test
710
- ```
711
-
712
- ## License
713
-
714
- MIT
715
-
716
- ## Support
717
-
718
- For issues and questions:
719
- - **GitHub Issues:** [Report an issue](https://github.com/superatomai/sdk-nodejs/issues)
720
- - **Email:** ashish@superatom.ai
721
-
722
- ## Contributing
723
-
724
- 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.