@soulcraft/brainy 1.5.0 → 2.0.1
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/CHANGELOG.md +188 -0
- package/LICENSE +2 -2
- package/README.md +200 -595
- package/bin/brainy-interactive.js +564 -0
- package/bin/brainy-ts.js +18 -0
- package/bin/brainy.js +672 -81
- package/dist/augmentationPipeline.d.ts +48 -220
- package/dist/augmentationPipeline.js +60 -508
- package/dist/augmentationRegistry.d.ts +22 -31
- package/dist/augmentationRegistry.js +28 -79
- package/dist/augmentations/apiServerAugmentation.d.ts +108 -0
- package/dist/augmentations/apiServerAugmentation.js +502 -0
- package/dist/augmentations/batchProcessingAugmentation.d.ts +95 -0
- package/dist/augmentations/batchProcessingAugmentation.js +567 -0
- package/dist/augmentations/brainyAugmentation.d.ts +153 -0
- package/dist/augmentations/brainyAugmentation.js +145 -0
- package/dist/augmentations/cacheAugmentation.d.ts +105 -0
- package/dist/augmentations/cacheAugmentation.js +238 -0
- package/dist/augmentations/conduitAugmentations.d.ts +54 -156
- package/dist/augmentations/conduitAugmentations.js +156 -1082
- package/dist/augmentations/connectionPoolAugmentation.d.ts +62 -0
- package/dist/augmentations/connectionPoolAugmentation.js +316 -0
- package/dist/augmentations/defaultAugmentations.d.ts +53 -0
- package/dist/augmentations/defaultAugmentations.js +88 -0
- package/dist/augmentations/entityRegistryAugmentation.d.ts +126 -0
- package/dist/augmentations/entityRegistryAugmentation.js +386 -0
- package/dist/augmentations/indexAugmentation.d.ts +117 -0
- package/dist/augmentations/indexAugmentation.js +284 -0
- package/dist/augmentations/intelligentVerbScoringAugmentation.d.ts +152 -0
- package/dist/augmentations/intelligentVerbScoringAugmentation.js +554 -0
- package/dist/augmentations/metricsAugmentation.d.ts +202 -0
- package/dist/augmentations/metricsAugmentation.js +291 -0
- package/dist/augmentations/monitoringAugmentation.d.ts +94 -0
- package/dist/augmentations/monitoringAugmentation.js +227 -0
- package/dist/augmentations/neuralImport.d.ts +50 -117
- package/dist/augmentations/neuralImport.js +255 -629
- package/dist/augmentations/requestDeduplicatorAugmentation.d.ts +52 -0
- package/dist/augmentations/requestDeduplicatorAugmentation.js +162 -0
- package/dist/augmentations/serverSearchAugmentations.d.ts +43 -22
- package/dist/augmentations/serverSearchAugmentations.js +125 -72
- package/dist/augmentations/storageAugmentation.d.ts +54 -0
- package/dist/augmentations/storageAugmentation.js +93 -0
- package/dist/augmentations/storageAugmentations.d.ts +96 -0
- package/dist/augmentations/storageAugmentations.js +182 -0
- package/dist/augmentations/synapseAugmentation.d.ts +156 -0
- package/dist/augmentations/synapseAugmentation.js +312 -0
- package/dist/augmentations/walAugmentation.d.ts +108 -0
- package/dist/augmentations/walAugmentation.js +515 -0
- package/dist/brainyData.d.ts +404 -130
- package/dist/brainyData.js +1331 -853
- package/dist/chat/BrainyChat.d.ts +16 -8
- package/dist/chat/BrainyChat.js +60 -32
- package/dist/chat/ChatCLI.d.ts +1 -1
- package/dist/chat/ChatCLI.js +6 -6
- package/dist/cli/catalog.d.ts +3 -3
- package/dist/cli/catalog.js +116 -70
- package/dist/cli/commands/core.d.ts +61 -0
- package/dist/cli/commands/core.js +348 -0
- package/dist/cli/commands/neural.d.ts +25 -0
- package/dist/cli/commands/neural.js +508 -0
- package/dist/cli/commands/utility.d.ts +37 -0
- package/dist/cli/commands/utility.js +276 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +167 -0
- package/dist/cli/interactive.d.ts +164 -0
- package/dist/cli/interactive.js +542 -0
- package/dist/cortex/neuralImport.js +5 -5
- package/dist/critical/model-guardian.js +11 -4
- package/dist/embeddings/lightweight-embedder.d.ts +23 -0
- package/dist/embeddings/lightweight-embedder.js +136 -0
- package/dist/embeddings/universal-memory-manager.d.ts +38 -0
- package/dist/embeddings/universal-memory-manager.js +206 -0
- package/dist/embeddings/worker-embedding.d.ts +7 -0
- package/dist/embeddings/worker-embedding.js +77 -0
- package/dist/embeddings/worker-manager.d.ts +28 -0
- package/dist/embeddings/worker-manager.js +162 -0
- package/dist/examples/basicUsage.js +7 -7
- package/dist/graph/pathfinding.d.ts +78 -0
- package/dist/graph/pathfinding.js +393 -0
- package/dist/hnsw/hnswIndex.d.ts +13 -0
- package/dist/hnsw/hnswIndex.js +35 -0
- package/dist/hnsw/hnswIndexOptimized.d.ts +1 -0
- package/dist/hnsw/hnswIndexOptimized.js +3 -0
- package/dist/index.d.ts +9 -11
- package/dist/index.js +21 -11
- package/dist/indices/fieldIndex.d.ts +76 -0
- package/dist/indices/fieldIndex.js +357 -0
- package/dist/mcp/brainyMCPAdapter.js +3 -2
- package/dist/mcp/mcpAugmentationToolset.js +11 -17
- package/dist/neural/embeddedPatterns.d.ts +41 -0
- package/dist/neural/embeddedPatterns.js +4044 -0
- package/dist/neural/naturalLanguageProcessor.d.ts +94 -0
- package/dist/neural/naturalLanguageProcessor.js +317 -0
- package/dist/neural/naturalLanguageProcessorStatic.d.ts +64 -0
- package/dist/neural/naturalLanguageProcessorStatic.js +151 -0
- package/dist/neural/neuralAPI.d.ts +255 -0
- package/dist/neural/neuralAPI.js +612 -0
- package/dist/neural/patternLibrary.d.ts +101 -0
- package/dist/neural/patternLibrary.js +313 -0
- package/dist/neural/patterns.d.ts +27 -0
- package/dist/neural/patterns.js +68 -0
- package/dist/neural/staticPatternMatcher.d.ts +35 -0
- package/dist/neural/staticPatternMatcher.js +153 -0
- package/dist/scripts/precomputePatternEmbeddings.d.ts +19 -0
- package/dist/scripts/precomputePatternEmbeddings.js +100 -0
- package/dist/storage/adapters/fileSystemStorage.d.ts +5 -0
- package/dist/storage/adapters/fileSystemStorage.js +20 -0
- package/dist/storage/adapters/s3CompatibleStorage.d.ts +5 -0
- package/dist/storage/adapters/s3CompatibleStorage.js +16 -0
- package/dist/storage/enhancedClearOperations.d.ts +83 -0
- package/dist/storage/enhancedClearOperations.js +345 -0
- package/dist/storage/storageFactory.js +31 -27
- package/dist/triple/TripleIntelligence.d.ts +134 -0
- package/dist/triple/TripleIntelligence.js +548 -0
- package/dist/types/augmentations.d.ts +45 -344
- package/dist/types/augmentations.js +5 -2
- package/dist/types/brainyDataInterface.d.ts +20 -10
- package/dist/types/graphTypes.d.ts +46 -0
- package/dist/types/graphTypes.js +16 -2
- package/dist/utils/BoundedRegistry.d.ts +29 -0
- package/dist/utils/BoundedRegistry.js +54 -0
- package/dist/utils/embedding.js +20 -3
- package/dist/utils/hybridModelManager.js +10 -5
- package/dist/utils/metadataFilter.d.ts +33 -19
- package/dist/utils/metadataFilter.js +58 -23
- package/dist/utils/metadataIndex.d.ts +37 -6
- package/dist/utils/metadataIndex.js +427 -64
- package/dist/utils/requestDeduplicator.d.ts +10 -0
- package/dist/utils/requestDeduplicator.js +24 -0
- package/dist/utils/unifiedCache.d.ts +103 -0
- package/dist/utils/unifiedCache.js +311 -0
- package/package.json +40 -125
- package/scripts/ensure-models.js +108 -0
- package/scripts/prepare-models.js +387 -0
- package/OFFLINE_MODELS.md +0 -56
- package/dist/intelligence/neuralEngine.d.ts +0 -207
- package/dist/intelligence/neuralEngine.js +0 -706
- package/dist/utils/modelLoader.d.ts +0 -32
- package/dist/utils/modelLoader.js +0 -219
- package/dist/utils/modelManager.d.ts +0 -77
- package/dist/utils/modelManager.js +0 -219
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Server Augmentation - Universal API Exposure
|
|
3
|
+
*
|
|
4
|
+
* 🌐 Exposes Brainy through REST, WebSocket, and MCP
|
|
5
|
+
* 🔌 Works in Node.js, Deno, and Service Workers
|
|
6
|
+
* 🚀 Single augmentation for all API needs
|
|
7
|
+
*
|
|
8
|
+
* This unifies and replaces:
|
|
9
|
+
* - BrainyMCPBroadcast (Node-specific server)
|
|
10
|
+
* - WebSocketConduitAugmentation (client connections)
|
|
11
|
+
* - Future REST API implementations
|
|
12
|
+
*/
|
|
13
|
+
import { BaseAugmentation } from './brainyAugmentation.js';
|
|
14
|
+
import { BrainyMCPService } from '../mcp/brainyMCPService.js';
|
|
15
|
+
import { v4 as uuidv4 } from '../universal/uuid.js';
|
|
16
|
+
import { isNode, isBrowser } from '../utils/environment.js';
|
|
17
|
+
/**
|
|
18
|
+
* Unified API Server Augmentation
|
|
19
|
+
* Exposes Brainy through multiple protocols
|
|
20
|
+
*/
|
|
21
|
+
export class APIServerAugmentation extends BaseAugmentation {
|
|
22
|
+
constructor(config = {}) {
|
|
23
|
+
super();
|
|
24
|
+
this.name = 'api-server';
|
|
25
|
+
this.timing = 'after';
|
|
26
|
+
this.operations = ['all'];
|
|
27
|
+
this.priority = 5; // Low priority, runs after other augmentations
|
|
28
|
+
this.clients = new Map();
|
|
29
|
+
this.operationHistory = [];
|
|
30
|
+
this.maxHistorySize = 1000;
|
|
31
|
+
this.config = {
|
|
32
|
+
enabled: true,
|
|
33
|
+
port: 3000,
|
|
34
|
+
host: '0.0.0.0',
|
|
35
|
+
cors: { origin: '*', credentials: true },
|
|
36
|
+
auth: { required: false },
|
|
37
|
+
rateLimit: { windowMs: 60000, max: 100 },
|
|
38
|
+
...config
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async onInitialize() {
|
|
42
|
+
if (!this.config.enabled) {
|
|
43
|
+
this.log('API Server disabled in config');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// Initialize MCP service
|
|
47
|
+
this.mcpService = new BrainyMCPService(this.context.brain, {
|
|
48
|
+
enableAuth: this.config.auth?.required
|
|
49
|
+
});
|
|
50
|
+
// Start appropriate server based on environment
|
|
51
|
+
if (isNode()) {
|
|
52
|
+
await this.startNodeServer();
|
|
53
|
+
}
|
|
54
|
+
else if (typeof globalThis.Deno !== 'undefined') {
|
|
55
|
+
await this.startDenoServer();
|
|
56
|
+
}
|
|
57
|
+
else if (isBrowser() && 'serviceWorker' in navigator) {
|
|
58
|
+
await this.startServiceWorker();
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
this.log('No suitable server environment detected', 'warn');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Start Node.js server with Express
|
|
66
|
+
*/
|
|
67
|
+
async startNodeServer() {
|
|
68
|
+
try {
|
|
69
|
+
// Dynamic imports for Node.js dependencies
|
|
70
|
+
const express = await import('express').catch(() => null);
|
|
71
|
+
const cors = await import('cors').catch(() => null);
|
|
72
|
+
const ws = await import('ws').catch(() => null);
|
|
73
|
+
const { createServer } = await import('http');
|
|
74
|
+
if (!express || !cors || !ws) {
|
|
75
|
+
this.log('Express, cors, or ws not available. Install with: npm install express cors ws', 'error');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const WebSocketServer = ws?.WebSocketServer || ws?.default?.WebSocketServer || ws?.Server;
|
|
79
|
+
const app = express.default();
|
|
80
|
+
// Middleware
|
|
81
|
+
app.use(cors.default(this.config.cors));
|
|
82
|
+
app.use((express.default || express).json({ limit: '50mb' }));
|
|
83
|
+
app.use(this.authMiddleware.bind(this));
|
|
84
|
+
app.use(this.rateLimitMiddleware.bind(this));
|
|
85
|
+
// REST API Routes
|
|
86
|
+
this.setupRESTRoutes(app);
|
|
87
|
+
// Create HTTP server
|
|
88
|
+
this.httpServer = createServer(app);
|
|
89
|
+
// WebSocket server
|
|
90
|
+
this.wsServer = new WebSocketServer({
|
|
91
|
+
server: this.httpServer,
|
|
92
|
+
path: '/ws'
|
|
93
|
+
});
|
|
94
|
+
this.setupWebSocketServer();
|
|
95
|
+
// Start listening
|
|
96
|
+
await new Promise((resolve, reject) => {
|
|
97
|
+
this.httpServer.listen(this.config.port, this.config.host, () => {
|
|
98
|
+
this.log(`🌐 API Server listening on http://${this.config.host}:${this.config.port}`);
|
|
99
|
+
this.log(`🔌 WebSocket: ws://${this.config.host}:${this.config.port}/ws`);
|
|
100
|
+
this.log(`🧠 MCP endpoint: http://${this.config.host}:${this.config.port}/api/mcp`);
|
|
101
|
+
resolve();
|
|
102
|
+
}).on('error', reject);
|
|
103
|
+
});
|
|
104
|
+
// Heartbeat interval
|
|
105
|
+
setInterval(() => this.sendHeartbeats(), 30000);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
this.log(`Failed to start Node.js server: ${error}`, 'error');
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Setup REST API routes
|
|
114
|
+
*/
|
|
115
|
+
setupRESTRoutes(app) {
|
|
116
|
+
// Health check
|
|
117
|
+
app.get('/health', (_req, res) => {
|
|
118
|
+
res.json({
|
|
119
|
+
status: 'healthy',
|
|
120
|
+
version: '2.0.0',
|
|
121
|
+
clients: this.clients.size,
|
|
122
|
+
uptime: process.uptime ? process.uptime() : 0
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
// Search endpoint
|
|
126
|
+
app.post('/api/search', async (req, res) => {
|
|
127
|
+
try {
|
|
128
|
+
const { query, limit = 10, options = {} } = req.body;
|
|
129
|
+
const results = await this.context.brain.search(query, limit, options);
|
|
130
|
+
res.json({ success: true, results });
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
res.status(500).json({ success: false, error: error.message });
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
// Add data endpoint
|
|
137
|
+
app.post('/api/add', async (req, res) => {
|
|
138
|
+
try {
|
|
139
|
+
const { content, metadata } = req.body;
|
|
140
|
+
const id = await this.context.brain.add(content, metadata);
|
|
141
|
+
res.json({ success: true, id });
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
res.status(500).json({ success: false, error: error.message });
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
// Get by ID endpoint
|
|
148
|
+
app.get('/api/get/:id', async (req, res) => {
|
|
149
|
+
try {
|
|
150
|
+
const data = await this.context.brain.get(req.params.id);
|
|
151
|
+
if (data) {
|
|
152
|
+
res.json({ success: true, data });
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
res.status(404).json({ success: false, error: 'Not found' });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
res.status(500).json({ success: false, error: error.message });
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
// Delete endpoint
|
|
163
|
+
app.delete('/api/delete/:id', async (req, res) => {
|
|
164
|
+
try {
|
|
165
|
+
await this.context.brain.delete(req.params.id);
|
|
166
|
+
res.json({ success: true });
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
res.status(500).json({ success: false, error: error.message });
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
// Relate endpoint
|
|
173
|
+
app.post('/api/relate', async (req, res) => {
|
|
174
|
+
try {
|
|
175
|
+
const { source, target, verb, metadata } = req.body;
|
|
176
|
+
await this.context.brain.relate(source, target, verb, metadata);
|
|
177
|
+
res.json({ success: true });
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
res.status(500).json({ success: false, error: error.message });
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
// Find endpoint (complex queries)
|
|
184
|
+
app.post('/api/find', async (req, res) => {
|
|
185
|
+
try {
|
|
186
|
+
const results = await this.context.brain.find(req.body);
|
|
187
|
+
res.json({ success: true, results });
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
res.status(500).json({ success: false, error: error.message });
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
// Cluster endpoint
|
|
194
|
+
app.post('/api/cluster', async (req, res) => {
|
|
195
|
+
try {
|
|
196
|
+
const { algorithm = 'kmeans', options = {} } = req.body;
|
|
197
|
+
const clusters = await this.context.brain.cluster(algorithm, options);
|
|
198
|
+
res.json({ success: true, clusters });
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
res.status(500).json({ success: false, error: error.message });
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
// MCP endpoint
|
|
205
|
+
app.post('/api/mcp', async (req, res) => {
|
|
206
|
+
try {
|
|
207
|
+
const response = await this.mcpService.handleRequest(req.body);
|
|
208
|
+
res.json(response);
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
res.status(500).json({ success: false, error: error.message });
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
// Statistics endpoint
|
|
215
|
+
app.get('/api/stats', async (_req, res) => {
|
|
216
|
+
try {
|
|
217
|
+
const stats = await this.context.brain.getStatistics();
|
|
218
|
+
res.json({ success: true, stats });
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
res.status(500).json({ success: false, error: error.message });
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
// Operation history endpoint
|
|
225
|
+
app.get('/api/history', (_req, res) => {
|
|
226
|
+
res.json({
|
|
227
|
+
success: true,
|
|
228
|
+
history: this.operationHistory.slice(-100)
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Setup WebSocket server
|
|
234
|
+
*/
|
|
235
|
+
setupWebSocketServer() {
|
|
236
|
+
if (!this.wsServer)
|
|
237
|
+
return;
|
|
238
|
+
this.wsServer.on('connection', (socket, request) => {
|
|
239
|
+
const clientId = uuidv4();
|
|
240
|
+
const client = {
|
|
241
|
+
id: clientId,
|
|
242
|
+
type: 'websocket',
|
|
243
|
+
socket,
|
|
244
|
+
subscriptions: [],
|
|
245
|
+
lastSeen: Date.now()
|
|
246
|
+
};
|
|
247
|
+
this.clients.set(clientId, client);
|
|
248
|
+
// Send welcome message
|
|
249
|
+
socket.send(JSON.stringify({
|
|
250
|
+
type: 'welcome',
|
|
251
|
+
clientId,
|
|
252
|
+
message: 'Connected to Brainy API Server',
|
|
253
|
+
capabilities: ['search', 'add', 'delete', 'relate', 'subscribe', 'mcp']
|
|
254
|
+
}));
|
|
255
|
+
// Handle messages
|
|
256
|
+
socket.on('message', async (message) => {
|
|
257
|
+
try {
|
|
258
|
+
const msg = JSON.parse(message);
|
|
259
|
+
await this.handleWebSocketMessage(msg, client);
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
socket.send(JSON.stringify({
|
|
263
|
+
type: 'error',
|
|
264
|
+
error: error.message
|
|
265
|
+
}));
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
// Handle disconnect
|
|
269
|
+
socket.on('close', () => {
|
|
270
|
+
this.clients.delete(clientId);
|
|
271
|
+
this.log(`Client ${clientId} disconnected`);
|
|
272
|
+
});
|
|
273
|
+
// Handle errors
|
|
274
|
+
socket.on('error', (error) => {
|
|
275
|
+
this.log(`WebSocket error for client ${clientId}: ${error}`, 'error');
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Handle WebSocket message
|
|
281
|
+
*/
|
|
282
|
+
async handleWebSocketMessage(msg, client) {
|
|
283
|
+
const { socket } = client;
|
|
284
|
+
switch (msg.type) {
|
|
285
|
+
case 'subscribe':
|
|
286
|
+
// Subscribe to operation types
|
|
287
|
+
client.subscriptions = msg.operations || ['all'];
|
|
288
|
+
socket.send(JSON.stringify({
|
|
289
|
+
type: 'subscribed',
|
|
290
|
+
operations: client.subscriptions
|
|
291
|
+
}));
|
|
292
|
+
break;
|
|
293
|
+
case 'search':
|
|
294
|
+
const searchResults = await this.context.brain.search(msg.query, msg.limit || 10, msg.options || {});
|
|
295
|
+
socket.send(JSON.stringify({
|
|
296
|
+
type: 'searchResults',
|
|
297
|
+
requestId: msg.requestId,
|
|
298
|
+
results: searchResults
|
|
299
|
+
}));
|
|
300
|
+
break;
|
|
301
|
+
case 'add':
|
|
302
|
+
const id = await this.context.brain.add(msg.content, msg.metadata);
|
|
303
|
+
socket.send(JSON.stringify({
|
|
304
|
+
type: 'addResult',
|
|
305
|
+
requestId: msg.requestId,
|
|
306
|
+
id
|
|
307
|
+
}));
|
|
308
|
+
break;
|
|
309
|
+
case 'mcp':
|
|
310
|
+
const mcpResponse = await this.mcpService.handleRequest(msg.request);
|
|
311
|
+
socket.send(JSON.stringify({
|
|
312
|
+
type: 'mcpResponse',
|
|
313
|
+
requestId: msg.requestId,
|
|
314
|
+
response: mcpResponse
|
|
315
|
+
}));
|
|
316
|
+
break;
|
|
317
|
+
case 'heartbeat':
|
|
318
|
+
client.lastSeen = Date.now();
|
|
319
|
+
socket.send(JSON.stringify({
|
|
320
|
+
type: 'heartbeat',
|
|
321
|
+
timestamp: Date.now()
|
|
322
|
+
}));
|
|
323
|
+
break;
|
|
324
|
+
default:
|
|
325
|
+
socket.send(JSON.stringify({
|
|
326
|
+
type: 'error',
|
|
327
|
+
error: `Unknown message type: ${msg.type}`
|
|
328
|
+
}));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Execute augmentation - broadcast operations to clients
|
|
333
|
+
*/
|
|
334
|
+
async execute(operation, params, next) {
|
|
335
|
+
const startTime = Date.now();
|
|
336
|
+
const result = await next();
|
|
337
|
+
const duration = Date.now() - startTime;
|
|
338
|
+
// Record operation in history
|
|
339
|
+
const historyEntry = {
|
|
340
|
+
operation,
|
|
341
|
+
params: this.sanitizeParams(params),
|
|
342
|
+
timestamp: Date.now(),
|
|
343
|
+
duration
|
|
344
|
+
};
|
|
345
|
+
this.operationHistory.push(historyEntry);
|
|
346
|
+
if (this.operationHistory.length > this.maxHistorySize) {
|
|
347
|
+
this.operationHistory.shift();
|
|
348
|
+
}
|
|
349
|
+
// Broadcast to subscribed WebSocket clients
|
|
350
|
+
const message = JSON.stringify({
|
|
351
|
+
type: 'operation',
|
|
352
|
+
operation,
|
|
353
|
+
params: historyEntry.params,
|
|
354
|
+
timestamp: historyEntry.timestamp,
|
|
355
|
+
duration
|
|
356
|
+
});
|
|
357
|
+
for (const client of this.clients.values()) {
|
|
358
|
+
if (client.type === 'websocket' && client.socket) {
|
|
359
|
+
if (client.subscriptions?.includes('all') ||
|
|
360
|
+
client.subscriptions?.includes(operation)) {
|
|
361
|
+
try {
|
|
362
|
+
client.socket.send(message);
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
// Client might be disconnected
|
|
366
|
+
this.clients.delete(client.id);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return result;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Auth middleware for Express
|
|
375
|
+
*/
|
|
376
|
+
authMiddleware(req, res, next) {
|
|
377
|
+
if (!this.config.auth?.required) {
|
|
378
|
+
return next();
|
|
379
|
+
}
|
|
380
|
+
const apiKey = req.headers['x-api-key'];
|
|
381
|
+
const bearerToken = req.headers.authorization?.replace('Bearer ', '');
|
|
382
|
+
if (apiKey && this.config.auth.apiKeys?.includes(apiKey)) {
|
|
383
|
+
return next();
|
|
384
|
+
}
|
|
385
|
+
if (bearerToken && this.config.auth.bearerTokens?.includes(bearerToken)) {
|
|
386
|
+
return next();
|
|
387
|
+
}
|
|
388
|
+
res.status(401).json({ error: 'Unauthorized' });
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Rate limiting middleware
|
|
392
|
+
*/
|
|
393
|
+
rateLimitMiddleware(req, res, next) {
|
|
394
|
+
// Simple in-memory rate limiting
|
|
395
|
+
// In production, use redis or proper rate limiting library
|
|
396
|
+
const ip = req.ip || req.connection.remoteAddress;
|
|
397
|
+
const now = Date.now();
|
|
398
|
+
const windowMs = this.config.rateLimit?.windowMs || 60000;
|
|
399
|
+
const max = this.config.rateLimit?.max || 100;
|
|
400
|
+
// Clean old entries
|
|
401
|
+
for (const [key, client] of this.clients.entries()) {
|
|
402
|
+
if (now - client.lastSeen > windowMs) {
|
|
403
|
+
this.clients.delete(key);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
// For now, just pass through
|
|
407
|
+
// Real implementation would track requests per IP
|
|
408
|
+
next();
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Sanitize parameters before broadcasting
|
|
412
|
+
*/
|
|
413
|
+
sanitizeParams(params) {
|
|
414
|
+
if (!params)
|
|
415
|
+
return params;
|
|
416
|
+
const sanitized = { ...params };
|
|
417
|
+
// Remove sensitive fields
|
|
418
|
+
delete sanitized.password;
|
|
419
|
+
delete sanitized.apiKey;
|
|
420
|
+
delete sanitized.token;
|
|
421
|
+
delete sanitized.secret;
|
|
422
|
+
// Truncate large data
|
|
423
|
+
if (sanitized.content && sanitized.content.length > 1000) {
|
|
424
|
+
sanitized.content = sanitized.content.substring(0, 1000) + '...';
|
|
425
|
+
}
|
|
426
|
+
return sanitized;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Send heartbeats to all connected clients
|
|
430
|
+
*/
|
|
431
|
+
sendHeartbeats() {
|
|
432
|
+
const now = Date.now();
|
|
433
|
+
for (const [id, client] of this.clients.entries()) {
|
|
434
|
+
if (client.type === 'websocket' && client.socket) {
|
|
435
|
+
// Remove inactive clients
|
|
436
|
+
if (now - client.lastSeen > 60000) {
|
|
437
|
+
this.clients.delete(id);
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
// Send heartbeat
|
|
441
|
+
try {
|
|
442
|
+
client.socket.send(JSON.stringify({
|
|
443
|
+
type: 'heartbeat',
|
|
444
|
+
timestamp: now
|
|
445
|
+
}));
|
|
446
|
+
}
|
|
447
|
+
catch {
|
|
448
|
+
// Client disconnected
|
|
449
|
+
this.clients.delete(id);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Start Deno server
|
|
456
|
+
*/
|
|
457
|
+
async startDenoServer() {
|
|
458
|
+
// Deno implementation would go here
|
|
459
|
+
// Using Deno.serve() or oak framework
|
|
460
|
+
this.log('Deno server not yet implemented', 'warn');
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Start Service Worker (for browser)
|
|
464
|
+
*/
|
|
465
|
+
async startServiceWorker() {
|
|
466
|
+
// Service Worker implementation would go here
|
|
467
|
+
// Intercepts fetch() calls and handles them locally
|
|
468
|
+
this.log('Service Worker API not yet implemented', 'warn');
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Shutdown the server
|
|
472
|
+
*/
|
|
473
|
+
async onShutdown() {
|
|
474
|
+
// Close all WebSocket connections
|
|
475
|
+
for (const client of this.clients.values()) {
|
|
476
|
+
if (client.socket) {
|
|
477
|
+
try {
|
|
478
|
+
client.socket.close();
|
|
479
|
+
}
|
|
480
|
+
catch { }
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
this.clients.clear();
|
|
484
|
+
// Close servers
|
|
485
|
+
if (this.wsServer) {
|
|
486
|
+
this.wsServer.close();
|
|
487
|
+
}
|
|
488
|
+
if (this.httpServer) {
|
|
489
|
+
await new Promise(resolve => {
|
|
490
|
+
this.httpServer.close(() => resolve());
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
this.log('API Server shut down');
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Helper function to create and configure API server
|
|
498
|
+
*/
|
|
499
|
+
export function createAPIServer(config) {
|
|
500
|
+
return new APIServerAugmentation(config);
|
|
501
|
+
}
|
|
502
|
+
//# sourceMappingURL=apiServerAugmentation.js.map
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch Processing Augmentation
|
|
3
|
+
*
|
|
4
|
+
* Critical for enterprise-scale performance: 500,000+ operations/second
|
|
5
|
+
* Automatically batches operations for maximum throughput
|
|
6
|
+
* Handles streaming data, bulk imports, and high-frequency operations
|
|
7
|
+
*
|
|
8
|
+
* Performance Impact: 10-50x improvement for bulk operations
|
|
9
|
+
*/
|
|
10
|
+
import { BaseAugmentation } from './brainyAugmentation.js';
|
|
11
|
+
interface BatchConfig {
|
|
12
|
+
enabled?: boolean;
|
|
13
|
+
adaptiveMode?: boolean;
|
|
14
|
+
immediateThreshold?: number;
|
|
15
|
+
batchThreshold?: number;
|
|
16
|
+
maxBatchSize?: number;
|
|
17
|
+
maxWaitTime?: number;
|
|
18
|
+
adaptiveBatching?: boolean;
|
|
19
|
+
priorityLanes?: number;
|
|
20
|
+
memoryLimit?: number;
|
|
21
|
+
}
|
|
22
|
+
interface BatchMetrics {
|
|
23
|
+
totalOperations: number;
|
|
24
|
+
batchesProcessed: number;
|
|
25
|
+
averageBatchSize: number;
|
|
26
|
+
averageLatency: number;
|
|
27
|
+
throughputPerSecond: number;
|
|
28
|
+
memoryUsage: number;
|
|
29
|
+
adaptiveAdjustments: number;
|
|
30
|
+
}
|
|
31
|
+
export declare class BatchProcessingAugmentation extends BaseAugmentation {
|
|
32
|
+
name: string;
|
|
33
|
+
timing: "around";
|
|
34
|
+
operations: ("add" | "addNoun" | "addVerb" | "saveNoun" | "saveVerb" | "storage")[];
|
|
35
|
+
priority: number;
|
|
36
|
+
private config;
|
|
37
|
+
private batches;
|
|
38
|
+
private flushTimers;
|
|
39
|
+
private metrics;
|
|
40
|
+
private currentMemoryUsage;
|
|
41
|
+
private performanceHistory;
|
|
42
|
+
constructor(config?: BatchConfig);
|
|
43
|
+
protected onInitialize(): Promise<void>;
|
|
44
|
+
shouldExecute(operation: string, params: any): boolean;
|
|
45
|
+
execute<T = any>(operation: string, params: any, next: () => Promise<T>): Promise<T>;
|
|
46
|
+
private shouldBatch;
|
|
47
|
+
/**
|
|
48
|
+
* SMART WORKFLOW DETECTION METHODS
|
|
49
|
+
* These methods detect critical patterns that must not be batched
|
|
50
|
+
*/
|
|
51
|
+
private isEntityRegistryWorkflow;
|
|
52
|
+
private isDependencyChainStart;
|
|
53
|
+
private isWriteOnlyMode;
|
|
54
|
+
private hasEntityRegistryMetadata;
|
|
55
|
+
private getOperationContext;
|
|
56
|
+
private getCurrentLoad;
|
|
57
|
+
private addToBatch;
|
|
58
|
+
private getOperationPriority;
|
|
59
|
+
private getBatchKey;
|
|
60
|
+
private getOperationType;
|
|
61
|
+
private estimateOperationSize;
|
|
62
|
+
private shouldFlushBatch;
|
|
63
|
+
private extractPriorityFromKey;
|
|
64
|
+
private setFlushTimer;
|
|
65
|
+
private getAdaptiveWaitTime;
|
|
66
|
+
private getPerformanceMultiplier;
|
|
67
|
+
private flushBatch;
|
|
68
|
+
private processBatch;
|
|
69
|
+
private processBatchByType;
|
|
70
|
+
private processBatchSave;
|
|
71
|
+
private processBatchUpdate;
|
|
72
|
+
private processBatchDelete;
|
|
73
|
+
private processIndividually;
|
|
74
|
+
private processWithConcurrency;
|
|
75
|
+
private executeOperation;
|
|
76
|
+
private flushOldestBatch;
|
|
77
|
+
private updateMetrics;
|
|
78
|
+
private adjustBatchSize;
|
|
79
|
+
private startMetricsCollection;
|
|
80
|
+
/**
|
|
81
|
+
* Get batch processing statistics
|
|
82
|
+
*/
|
|
83
|
+
getStats(): BatchMetrics & {
|
|
84
|
+
pendingBatches: number;
|
|
85
|
+
pendingOperations: number;
|
|
86
|
+
currentBatchSize: number;
|
|
87
|
+
memoryUtilization: string;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Force flush all pending batches
|
|
91
|
+
*/
|
|
92
|
+
flushAll(): Promise<void>;
|
|
93
|
+
protected onShutdown(): Promise<void>;
|
|
94
|
+
}
|
|
95
|
+
export {};
|