@brutalist/mcp 0.5.1 → 0.6.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/README.md +65 -63
- package/dist/brutalist-server.d.ts +15 -0
- package/dist/brutalist-server.d.ts.map +1 -1
- package/dist/brutalist-server.js +405 -357
- package/dist/brutalist-server.js.map +1 -1
- package/dist/cli-agents.d.ts +8 -3
- package/dist/cli-agents.d.ts.map +1 -1
- package/dist/cli-agents.js +352 -50
- package/dist/cli-agents.js.map +1 -1
- package/dist/streaming/circuit-breaker.d.ts +186 -0
- package/dist/streaming/circuit-breaker.d.ts.map +1 -0
- package/dist/streaming/circuit-breaker.js +463 -0
- package/dist/streaming/circuit-breaker.js.map +1 -0
- package/dist/streaming/intelligent-buffer.d.ts +141 -0
- package/dist/streaming/intelligent-buffer.d.ts.map +1 -0
- package/dist/streaming/intelligent-buffer.js +555 -0
- package/dist/streaming/intelligent-buffer.js.map +1 -0
- package/dist/streaming/output-parser.d.ts +89 -0
- package/dist/streaming/output-parser.d.ts.map +1 -0
- package/dist/streaming/output-parser.js +349 -0
- package/dist/streaming/output-parser.js.map +1 -0
- package/dist/streaming/progress-tracker.d.ts +149 -0
- package/dist/streaming/progress-tracker.d.ts.map +1 -0
- package/dist/streaming/progress-tracker.js +519 -0
- package/dist/streaming/progress-tracker.js.map +1 -0
- package/dist/streaming/session-manager.d.ts +238 -0
- package/dist/streaming/session-manager.d.ts.map +1 -0
- package/dist/streaming/session-manager.js +546 -0
- package/dist/streaming/session-manager.js.map +1 -0
- package/dist/streaming/sse-transport.d.ts +95 -0
- package/dist/streaming/sse-transport.d.ts.map +1 -0
- package/dist/streaming/sse-transport.js +319 -0
- package/dist/streaming/sse-transport.js.map +1 -0
- package/dist/streaming/streaming-orchestrator.d.ts +153 -0
- package/dist/streaming/streaming-orchestrator.d.ts.map +1 -0
- package/dist/streaming/streaming-orchestrator.js +436 -0
- package/dist/streaming/streaming-orchestrator.js.map +1 -0
- package/dist/test-utils/process-manager.d.ts +61 -0
- package/dist/test-utils/process-manager.d.ts.map +1 -0
- package/dist/test-utils/process-manager.js +262 -0
- package/dist/test-utils/process-manager.js.map +1 -0
- package/dist/test-utils/server-harness.d.ts +73 -0
- package/dist/test-utils/server-harness.d.ts.map +1 -0
- package/dist/test-utils/server-harness.js +296 -0
- package/dist/test-utils/server-harness.js.map +1 -0
- package/dist/test-utils/streaming-fuzz.d.ts +57 -0
- package/dist/test-utils/streaming-fuzz.d.ts.map +1 -0
- package/dist/test-utils/streaming-fuzz.js +287 -0
- package/dist/test-utils/streaming-fuzz.js.map +1 -0
- package/dist/test-utils/test-isolation.d.ts +70 -0
- package/dist/test-utils/test-isolation.d.ts.map +1 -0
- package/dist/test-utils/test-isolation.js +193 -0
- package/dist/test-utils/test-isolation.js.map +1 -0
- package/dist/tool-definitions.d.ts +6 -0
- package/dist/tool-definitions.d.ts.map +1 -0
- package/dist/tool-definitions.js +217 -0
- package/dist/tool-definitions.js.map +1 -0
- package/dist/types/brutalist.d.ts +3 -19
- package/dist/types/brutalist.d.ts.map +1 -1
- package/dist/types/tool-config.d.ts +51 -0
- package/dist/types/tool-config.d.ts.map +1 -0
- package/dist/types/tool-config.js +24 -0
- package/dist/types/tool-config.js.map +1 -0
- package/dist/utils/pagination.d.ts +2 -2
- package/dist/utils/pagination.d.ts.map +1 -1
- package/dist/utils/pagination.js +1 -1
- package/dist/utils/pagination.js.map +1 -1
- package/dist/utils/response-cache.d.ts +96 -0
- package/dist/utils/response-cache.d.ts.map +1 -0
- package/dist/utils/response-cache.js +371 -0
- package/dist/utils/response-cache.js.map +1 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +22 -3
- package/dist/utils.js.map +1 -1
- package/package.json +14 -4
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
3
|
+
/**
|
|
4
|
+
* Circuit breaker states
|
|
5
|
+
*/
|
|
6
|
+
export var CircuitState;
|
|
7
|
+
(function (CircuitState) {
|
|
8
|
+
CircuitState["CLOSED"] = "closed";
|
|
9
|
+
CircuitState["OPEN"] = "open";
|
|
10
|
+
CircuitState["HALF_OPEN"] = "half_open"; // Testing if service has recovered
|
|
11
|
+
})(CircuitState || (CircuitState = {}));
|
|
12
|
+
/**
|
|
13
|
+
* Circuit breaker with intelligent fallback handling
|
|
14
|
+
*
|
|
15
|
+
* Features:
|
|
16
|
+
* - Automatic failure detection and recovery
|
|
17
|
+
* - Configurable thresholds and timeouts
|
|
18
|
+
* - Multiple fallback strategies with priority
|
|
19
|
+
* - Real-time statistics and monitoring
|
|
20
|
+
* - Graceful degradation patterns
|
|
21
|
+
* - Request queuing during recovery
|
|
22
|
+
*/
|
|
23
|
+
export class CircuitBreaker extends EventEmitter {
|
|
24
|
+
config;
|
|
25
|
+
name;
|
|
26
|
+
state = CircuitState.CLOSED;
|
|
27
|
+
failures = 0;
|
|
28
|
+
successes = 0;
|
|
29
|
+
totalRequests = 0;
|
|
30
|
+
lastFailureTime;
|
|
31
|
+
lastSuccessTime;
|
|
32
|
+
recoveryTimer;
|
|
33
|
+
pendingRequests = new Map();
|
|
34
|
+
fallbackStrategies = [];
|
|
35
|
+
responseTimesWindow = [];
|
|
36
|
+
requestTimesWindow = [];
|
|
37
|
+
constructor(config, name = 'CircuitBreaker') {
|
|
38
|
+
super();
|
|
39
|
+
this.config = config;
|
|
40
|
+
this.name = name;
|
|
41
|
+
logger.info(`🔌 Circuit breaker '${this.name}' initialized`, {
|
|
42
|
+
failureThreshold: config.failureThreshold,
|
|
43
|
+
recoveryTimeout: config.recoveryTimeout,
|
|
44
|
+
timeout: config.timeout
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Execute function with circuit breaker protection
|
|
49
|
+
*/
|
|
50
|
+
async execute(fn, context) {
|
|
51
|
+
const requestId = context?.id || `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
52
|
+
const startTime = Date.now();
|
|
53
|
+
this.totalRequests++;
|
|
54
|
+
// Check circuit state
|
|
55
|
+
if (this.state === CircuitState.OPEN) {
|
|
56
|
+
const error = new Error(`Circuit breaker '${this.name}' is OPEN`);
|
|
57
|
+
this.emit('requestBlocked', { requestId, reason: 'circuit_open' });
|
|
58
|
+
return this.handleFallback(requestId, startTime, error);
|
|
59
|
+
}
|
|
60
|
+
// Create request context
|
|
61
|
+
const requestContext = {
|
|
62
|
+
id: requestId,
|
|
63
|
+
startTime,
|
|
64
|
+
timeout: setTimeout(() => {
|
|
65
|
+
this.handleTimeout(requestContext);
|
|
66
|
+
}, this.config.timeout),
|
|
67
|
+
resolve: () => { },
|
|
68
|
+
reject: () => { }
|
|
69
|
+
};
|
|
70
|
+
this.pendingRequests.set(requestId, requestContext);
|
|
71
|
+
try {
|
|
72
|
+
logger.debug(`🔌 Circuit breaker executing request ${requestId}`);
|
|
73
|
+
const result = await Promise.race([
|
|
74
|
+
fn(),
|
|
75
|
+
new Promise((_, reject) => {
|
|
76
|
+
requestContext.reject = reject;
|
|
77
|
+
})
|
|
78
|
+
]);
|
|
79
|
+
this.handleSuccess(requestContext);
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
return this.handleFailure(requestContext, error);
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
clearTimeout(requestContext.timeout);
|
|
87
|
+
this.pendingRequests.delete(requestId);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Handle successful request
|
|
92
|
+
*/
|
|
93
|
+
handleSuccess(context) {
|
|
94
|
+
const responseTime = Date.now() - context.startTime;
|
|
95
|
+
this.successes++;
|
|
96
|
+
this.lastSuccessTime = Date.now();
|
|
97
|
+
// Track response time
|
|
98
|
+
this.responseTimesWindow.push(responseTime);
|
|
99
|
+
if (this.responseTimesWindow.length > 100) {
|
|
100
|
+
this.responseTimesWindow.shift();
|
|
101
|
+
}
|
|
102
|
+
// Track request in monitoring window
|
|
103
|
+
this.trackRequest(true);
|
|
104
|
+
logger.debug(`✅ Circuit breaker success: ${context.id} (${responseTime}ms)`);
|
|
105
|
+
// Handle state transitions
|
|
106
|
+
if (this.state === CircuitState.HALF_OPEN) {
|
|
107
|
+
if (this.successes >= this.config.successThreshold) {
|
|
108
|
+
this.transitionToClosed();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
this.emit('requestSuccess', {
|
|
112
|
+
requestId: context.id,
|
|
113
|
+
responseTime,
|
|
114
|
+
state: this.state
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Handle failed request
|
|
119
|
+
*/
|
|
120
|
+
async handleFailure(context, error) {
|
|
121
|
+
const responseTime = Date.now() - context.startTime;
|
|
122
|
+
this.failures++;
|
|
123
|
+
this.lastFailureTime = Date.now();
|
|
124
|
+
// Track request in monitoring window
|
|
125
|
+
this.trackRequest(false);
|
|
126
|
+
logger.warn(`❌ Circuit breaker failure: ${context.id} (${responseTime}ms) - ${error.message}`);
|
|
127
|
+
// Check if we should open the circuit
|
|
128
|
+
if (this.shouldOpenCircuit()) {
|
|
129
|
+
this.transitionToOpen();
|
|
130
|
+
}
|
|
131
|
+
this.emit('requestFailure', {
|
|
132
|
+
requestId: context.id,
|
|
133
|
+
error: error.message,
|
|
134
|
+
responseTime,
|
|
135
|
+
state: this.state
|
|
136
|
+
});
|
|
137
|
+
// Try fallback strategies
|
|
138
|
+
return this.handleFallback(context.id, context.startTime, error);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Handle request timeout
|
|
142
|
+
*/
|
|
143
|
+
handleTimeout(context) {
|
|
144
|
+
const error = new Error(`Request ${context.id} timed out after ${this.config.timeout}ms`);
|
|
145
|
+
context.reject(error);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Handle fallback execution
|
|
149
|
+
*/
|
|
150
|
+
async handleFallback(requestId, startTime, error) {
|
|
151
|
+
// Sort strategies by priority
|
|
152
|
+
const sortedStrategies = [...this.fallbackStrategies].sort((a, b) => a.priority - b.priority);
|
|
153
|
+
for (const strategy of sortedStrategies) {
|
|
154
|
+
if (strategy.canHandle(error)) {
|
|
155
|
+
try {
|
|
156
|
+
logger.info(`🔄 Executing fallback strategy for ${requestId}: ${strategy.constructor.name}`);
|
|
157
|
+
const result = await strategy.execute({
|
|
158
|
+
id: requestId,
|
|
159
|
+
startTime,
|
|
160
|
+
timeout: setTimeout(() => { }, 0), // Dummy timeout
|
|
161
|
+
resolve: () => { },
|
|
162
|
+
reject: () => { }
|
|
163
|
+
}, error);
|
|
164
|
+
this.emit('fallbackSuccess', {
|
|
165
|
+
requestId,
|
|
166
|
+
strategy: strategy.constructor.name,
|
|
167
|
+
originalError: error.message
|
|
168
|
+
});
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
catch (fallbackError) {
|
|
172
|
+
logger.warn(`Fallback strategy failed for ${requestId}:`, fallbackError);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// No fallback worked, throw original error
|
|
178
|
+
this.emit('fallbackExhausted', {
|
|
179
|
+
requestId,
|
|
180
|
+
originalError: error.message,
|
|
181
|
+
triedStrategies: sortedStrategies.length
|
|
182
|
+
});
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Check if circuit should be opened
|
|
187
|
+
*/
|
|
188
|
+
shouldOpenCircuit() {
|
|
189
|
+
if (this.state === CircuitState.OPEN) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
// Check failure threshold
|
|
193
|
+
if (this.failures >= this.config.failureThreshold) {
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
// Check failure rate within monitoring window
|
|
197
|
+
const recentRequests = this.getRecentRequests();
|
|
198
|
+
if (recentRequests.length >= this.config.minimumRequests) {
|
|
199
|
+
const recentFailures = recentRequests.filter(r => !r.success).length;
|
|
200
|
+
const failureRate = recentFailures / recentRequests.length;
|
|
201
|
+
// Open if failure rate > 50%
|
|
202
|
+
if (failureRate > 0.5) {
|
|
203
|
+
logger.warn(`📊 High failure rate detected: ${Math.round(failureRate * 100)}%`);
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get recent requests within monitoring window
|
|
211
|
+
*/
|
|
212
|
+
getRecentRequests() {
|
|
213
|
+
const cutoff = Date.now() - this.config.monitoringWindow;
|
|
214
|
+
return this.requestTimesWindow.filter(r => r.timestamp > cutoff);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Track request in monitoring window
|
|
218
|
+
*/
|
|
219
|
+
trackRequest(success) {
|
|
220
|
+
this.requestTimesWindow.push({
|
|
221
|
+
timestamp: Date.now(),
|
|
222
|
+
success
|
|
223
|
+
});
|
|
224
|
+
// Keep window size manageable
|
|
225
|
+
if (this.requestTimesWindow.length > 1000) {
|
|
226
|
+
this.requestTimesWindow.shift();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Transition to OPEN state
|
|
231
|
+
*/
|
|
232
|
+
transitionToOpen() {
|
|
233
|
+
if (this.state === CircuitState.OPEN) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
logger.warn(`🔴 Circuit breaker '${this.name}' opened (failures: ${this.failures})`);
|
|
237
|
+
this.state = CircuitState.OPEN;
|
|
238
|
+
this.successes = 0; // Reset success counter
|
|
239
|
+
// Set recovery timer
|
|
240
|
+
this.recoveryTimer = setTimeout(() => {
|
|
241
|
+
this.transitionToHalfOpen();
|
|
242
|
+
}, this.config.recoveryTimeout);
|
|
243
|
+
this.emit('stateChanged', {
|
|
244
|
+
state: this.state,
|
|
245
|
+
reason: 'failure_threshold_exceeded',
|
|
246
|
+
failures: this.failures
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Transition to HALF_OPEN state
|
|
251
|
+
*/
|
|
252
|
+
transitionToHalfOpen() {
|
|
253
|
+
logger.info(`🟡 Circuit breaker '${this.name}' half-open (testing recovery)`);
|
|
254
|
+
this.state = CircuitState.HALF_OPEN;
|
|
255
|
+
this.successes = 0; // Reset for testing
|
|
256
|
+
this.emit('stateChanged', {
|
|
257
|
+
state: this.state,
|
|
258
|
+
reason: 'recovery_timeout_reached'
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Transition to CLOSED state
|
|
263
|
+
*/
|
|
264
|
+
transitionToClosed() {
|
|
265
|
+
logger.info(`🟢 Circuit breaker '${this.name}' closed (recovered)`);
|
|
266
|
+
this.state = CircuitState.CLOSED;
|
|
267
|
+
this.failures = 0; // Reset failure counter
|
|
268
|
+
if (this.recoveryTimer) {
|
|
269
|
+
clearTimeout(this.recoveryTimer);
|
|
270
|
+
this.recoveryTimer = undefined;
|
|
271
|
+
}
|
|
272
|
+
this.emit('stateChanged', {
|
|
273
|
+
state: this.state,
|
|
274
|
+
reason: 'recovery_successful',
|
|
275
|
+
successes: this.successes
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Add fallback strategy
|
|
280
|
+
*/
|
|
281
|
+
addFallbackStrategy(strategy) {
|
|
282
|
+
this.fallbackStrategies.push(strategy);
|
|
283
|
+
this.fallbackStrategies.sort((a, b) => a.priority - b.priority);
|
|
284
|
+
logger.info(`📋 Added fallback strategy: ${strategy.constructor.name} (priority: ${strategy.priority})`);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Remove fallback strategy
|
|
288
|
+
*/
|
|
289
|
+
removeFallbackStrategy(strategyClass) {
|
|
290
|
+
const index = this.fallbackStrategies.findIndex(s => s instanceof strategyClass);
|
|
291
|
+
if (index >= 0) {
|
|
292
|
+
const removed = this.fallbackStrategies.splice(index, 1)[0];
|
|
293
|
+
logger.info(`🗑️ Removed fallback strategy: ${removed.constructor.name}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get current circuit breaker statistics
|
|
298
|
+
*/
|
|
299
|
+
getStats() {
|
|
300
|
+
const recentRequests = this.getRecentRequests();
|
|
301
|
+
const recentFailures = recentRequests.filter(r => !r.success).length;
|
|
302
|
+
const failureRate = recentRequests.length > 0
|
|
303
|
+
? recentFailures / recentRequests.length
|
|
304
|
+
: 0;
|
|
305
|
+
const averageResponseTime = this.responseTimesWindow.length > 0
|
|
306
|
+
? this.responseTimesWindow.reduce((sum, time) => sum + time, 0) / this.responseTimesWindow.length
|
|
307
|
+
: 0;
|
|
308
|
+
return {
|
|
309
|
+
state: this.state,
|
|
310
|
+
failures: this.failures,
|
|
311
|
+
successes: this.successes,
|
|
312
|
+
totalRequests: this.totalRequests,
|
|
313
|
+
lastFailureTime: this.lastFailureTime,
|
|
314
|
+
lastSuccessTime: this.lastSuccessTime,
|
|
315
|
+
uptime: this.lastSuccessTime ? Date.now() - this.lastSuccessTime : 0,
|
|
316
|
+
failureRate,
|
|
317
|
+
averageResponseTime
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Force circuit state change (for testing)
|
|
322
|
+
*/
|
|
323
|
+
forceState(state) {
|
|
324
|
+
logger.warn(`⚠️ Forcing circuit breaker '${this.name}' to ${state}`);
|
|
325
|
+
if (this.recoveryTimer) {
|
|
326
|
+
clearTimeout(this.recoveryTimer);
|
|
327
|
+
this.recoveryTimer = undefined;
|
|
328
|
+
}
|
|
329
|
+
this.state = state;
|
|
330
|
+
if (state === CircuitState.OPEN) {
|
|
331
|
+
this.recoveryTimer = setTimeout(() => {
|
|
332
|
+
this.transitionToHalfOpen();
|
|
333
|
+
}, this.config.recoveryTimeout);
|
|
334
|
+
}
|
|
335
|
+
this.emit('stateChanged', {
|
|
336
|
+
state: this.state,
|
|
337
|
+
reason: 'forced_state_change'
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Reset circuit breaker to initial state
|
|
342
|
+
*/
|
|
343
|
+
reset() {
|
|
344
|
+
logger.info(`🔄 Resetting circuit breaker '${this.name}'`);
|
|
345
|
+
if (this.recoveryTimer) {
|
|
346
|
+
clearTimeout(this.recoveryTimer);
|
|
347
|
+
this.recoveryTimer = undefined;
|
|
348
|
+
}
|
|
349
|
+
this.state = CircuitState.CLOSED;
|
|
350
|
+
this.failures = 0;
|
|
351
|
+
this.successes = 0;
|
|
352
|
+
this.totalRequests = 0;
|
|
353
|
+
this.lastFailureTime = undefined;
|
|
354
|
+
this.lastSuccessTime = undefined;
|
|
355
|
+
this.responseTimesWindow = [];
|
|
356
|
+
this.requestTimesWindow = [];
|
|
357
|
+
// Cancel pending requests
|
|
358
|
+
for (const [requestId, context] of this.pendingRequests) {
|
|
359
|
+
clearTimeout(context.timeout);
|
|
360
|
+
context.reject(new Error('Circuit breaker reset'));
|
|
361
|
+
}
|
|
362
|
+
this.pendingRequests.clear();
|
|
363
|
+
this.emit('reset');
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Cleanup and shutdown
|
|
367
|
+
*/
|
|
368
|
+
shutdown() {
|
|
369
|
+
logger.info(`🛑 Shutting down circuit breaker '${this.name}'`);
|
|
370
|
+
if (this.recoveryTimer) {
|
|
371
|
+
clearTimeout(this.recoveryTimer);
|
|
372
|
+
}
|
|
373
|
+
// Cancel all pending requests
|
|
374
|
+
for (const [requestId, context] of this.pendingRequests) {
|
|
375
|
+
clearTimeout(context.timeout);
|
|
376
|
+
context.reject(new Error('Circuit breaker shutdown'));
|
|
377
|
+
}
|
|
378
|
+
this.removeAllListeners();
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Default fallback strategies
|
|
383
|
+
*/
|
|
384
|
+
/**
|
|
385
|
+
* Cache fallback - return cached response if available
|
|
386
|
+
*/
|
|
387
|
+
export class CachedResponseFallback {
|
|
388
|
+
cache;
|
|
389
|
+
priority = 1;
|
|
390
|
+
constructor(cache) {
|
|
391
|
+
this.cache = cache;
|
|
392
|
+
}
|
|
393
|
+
canHandle(_error) {
|
|
394
|
+
return true; // Can handle any error if cache is available
|
|
395
|
+
}
|
|
396
|
+
async execute(context, _error) {
|
|
397
|
+
const cached = this.cache.get(context.id);
|
|
398
|
+
if (cached) {
|
|
399
|
+
logger.info(`📋 Using cached response for ${context.id}`);
|
|
400
|
+
return cached;
|
|
401
|
+
}
|
|
402
|
+
throw new Error('No cached response available');
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Degraded service fallback - return simplified response
|
|
407
|
+
*/
|
|
408
|
+
export class DegradedServiceFallback {
|
|
409
|
+
degradedResponse;
|
|
410
|
+
priority = 2;
|
|
411
|
+
constructor(degradedResponse) {
|
|
412
|
+
this.degradedResponse = degradedResponse;
|
|
413
|
+
}
|
|
414
|
+
canHandle(_error) {
|
|
415
|
+
return true;
|
|
416
|
+
}
|
|
417
|
+
async execute(context, error) {
|
|
418
|
+
logger.info(`🔻 Using degraded service response for ${context.id}`);
|
|
419
|
+
return {
|
|
420
|
+
...this.degradedResponse,
|
|
421
|
+
metadata: {
|
|
422
|
+
fallback: true,
|
|
423
|
+
originalError: error.message,
|
|
424
|
+
timestamp: Date.now()
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Retry with delay fallback
|
|
431
|
+
*/
|
|
432
|
+
export class RetryFallback {
|
|
433
|
+
retryFn;
|
|
434
|
+
maxRetries;
|
|
435
|
+
delay;
|
|
436
|
+
priority = 3;
|
|
437
|
+
constructor(retryFn, maxRetries = 3, delay = 1000) {
|
|
438
|
+
this.retryFn = retryFn;
|
|
439
|
+
this.maxRetries = maxRetries;
|
|
440
|
+
this.delay = delay;
|
|
441
|
+
}
|
|
442
|
+
canHandle(error) {
|
|
443
|
+
// Only retry on certain error types
|
|
444
|
+
return !error.message.includes('timeout') &&
|
|
445
|
+
!error.message.includes('validation');
|
|
446
|
+
}
|
|
447
|
+
async execute(context, _error) {
|
|
448
|
+
for (let i = 0; i < this.maxRetries; i++) {
|
|
449
|
+
try {
|
|
450
|
+
logger.info(`🔄 Retry attempt ${i + 1}/${this.maxRetries} for ${context.id}`);
|
|
451
|
+
await new Promise(resolve => setTimeout(resolve, this.delay * (i + 1)));
|
|
452
|
+
return await this.retryFn();
|
|
453
|
+
}
|
|
454
|
+
catch (retryError) {
|
|
455
|
+
if (i === this.maxRetries - 1) {
|
|
456
|
+
throw retryError;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
throw new Error('All retry attempts failed');
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/streaming/circuit-breaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { StreamingEvent } from '../cli-agents.js';
|
|
2
|
+
/**
|
|
3
|
+
* Priority level for events
|
|
4
|
+
*/
|
|
5
|
+
export type EventPriority = 'immediate' | 'high' | 'normal' | 'low';
|
|
6
|
+
/**
|
|
7
|
+
* Buffer state for monitoring and metrics
|
|
8
|
+
*/
|
|
9
|
+
interface BufferState {
|
|
10
|
+
sessionId: string;
|
|
11
|
+
totalEvents: number;
|
|
12
|
+
pendingEvents: number;
|
|
13
|
+
lastFlush: number;
|
|
14
|
+
flushCount: number;
|
|
15
|
+
backpressure: boolean;
|
|
16
|
+
memoryUsage: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Event batch for delivery
|
|
20
|
+
*/
|
|
21
|
+
export interface EventBatch {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
events: StreamingEvent[];
|
|
24
|
+
priority: EventPriority;
|
|
25
|
+
batchId: string;
|
|
26
|
+
createdAt: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Intelligent buffering system with adaptive throttling and content-aware batching
|
|
30
|
+
*
|
|
31
|
+
* Features:
|
|
32
|
+
* - Priority-based queuing with immediate delivery for critical events
|
|
33
|
+
* - Adaptive throttling based on content type and system load
|
|
34
|
+
* - Content coalescence to reduce noise
|
|
35
|
+
* - Memory-bounded circular buffers
|
|
36
|
+
* - Backpressure handling
|
|
37
|
+
* - Real-time metrics and monitoring
|
|
38
|
+
*/
|
|
39
|
+
export declare class IntelligentBuffer {
|
|
40
|
+
private buffers;
|
|
41
|
+
private flushTimers;
|
|
42
|
+
private states;
|
|
43
|
+
private backlog;
|
|
44
|
+
private readonly BUFFERING_RULES;
|
|
45
|
+
private readonly DEFAULT_RULE;
|
|
46
|
+
private readonly MAX_BUFFER_SIZE;
|
|
47
|
+
private readonly MAX_MEMORY_MB;
|
|
48
|
+
private readonly BACKLOG_SIZE;
|
|
49
|
+
constructor();
|
|
50
|
+
/**
|
|
51
|
+
* Add event to buffer with intelligent routing
|
|
52
|
+
*/
|
|
53
|
+
add(event: StreamingEvent): void;
|
|
54
|
+
/**
|
|
55
|
+
* Force flush of all pending events for a session
|
|
56
|
+
*/
|
|
57
|
+
flush(sessionId: string, priority?: EventPriority): EventBatch | null;
|
|
58
|
+
/**
|
|
59
|
+
* Get backlog events for late subscribers
|
|
60
|
+
*/
|
|
61
|
+
getBacklog(sessionId: string, limit?: number): StreamingEvent[];
|
|
62
|
+
/**
|
|
63
|
+
* Get buffer state for monitoring
|
|
64
|
+
*/
|
|
65
|
+
getState(sessionId: string): BufferState | null;
|
|
66
|
+
/**
|
|
67
|
+
* Get all active sessions
|
|
68
|
+
*/
|
|
69
|
+
getActiveSessions(): string[];
|
|
70
|
+
/**
|
|
71
|
+
* Cleanup session resources
|
|
72
|
+
*/
|
|
73
|
+
cleanup(sessionId: string): void;
|
|
74
|
+
/**
|
|
75
|
+
* Get total memory usage across all sessions
|
|
76
|
+
*/
|
|
77
|
+
getTotalMemoryUsage(): number;
|
|
78
|
+
/**
|
|
79
|
+
* Get system-wide metrics
|
|
80
|
+
*/
|
|
81
|
+
getMetrics(): {
|
|
82
|
+
activeSessions: number;
|
|
83
|
+
totalEvents: number;
|
|
84
|
+
totalMemoryMB: number;
|
|
85
|
+
backpressureSessions: number;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Classify event for buffering rules
|
|
89
|
+
*/
|
|
90
|
+
private classifyEvent;
|
|
91
|
+
/**
|
|
92
|
+
* Get event priority for backpressure handling
|
|
93
|
+
*/
|
|
94
|
+
private getEventPriority;
|
|
95
|
+
/**
|
|
96
|
+
* Schedule flush based on buffering rule
|
|
97
|
+
*/
|
|
98
|
+
private scheduleFlush;
|
|
99
|
+
/**
|
|
100
|
+
* Apply content coalescence to reduce noise
|
|
101
|
+
*/
|
|
102
|
+
private applyCoalescence;
|
|
103
|
+
/**
|
|
104
|
+
* Generate coalescence key for grouping similar events
|
|
105
|
+
*/
|
|
106
|
+
private getCoalescenceKey;
|
|
107
|
+
/**
|
|
108
|
+
* Merge similar events into single event
|
|
109
|
+
*/
|
|
110
|
+
private mergeEvents;
|
|
111
|
+
/**
|
|
112
|
+
* Get or create buffer for session
|
|
113
|
+
*/
|
|
114
|
+
private getOrCreateBuffer;
|
|
115
|
+
/**
|
|
116
|
+
* Get or create buffer state
|
|
117
|
+
*/
|
|
118
|
+
private getOrCreateState;
|
|
119
|
+
/**
|
|
120
|
+
* Add event to backlog for late subscribers
|
|
121
|
+
*/
|
|
122
|
+
private addToBacklog;
|
|
123
|
+
/**
|
|
124
|
+
* Estimate memory usage for session
|
|
125
|
+
*/
|
|
126
|
+
private estimateMemoryUsage;
|
|
127
|
+
/**
|
|
128
|
+
* Handle memory pressure by dropping low priority events
|
|
129
|
+
*/
|
|
130
|
+
private handleMemoryPressure;
|
|
131
|
+
/**
|
|
132
|
+
* Clean up stale sessions (no activity for > 1 hour)
|
|
133
|
+
*/
|
|
134
|
+
private cleanupStaleSessions;
|
|
135
|
+
/**
|
|
136
|
+
* Deliver batch to subscribers (to be implemented by transport layer)
|
|
137
|
+
*/
|
|
138
|
+
private deliverBatch;
|
|
139
|
+
}
|
|
140
|
+
export {};
|
|
141
|
+
//# sourceMappingURL=intelligent-buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intelligent-buffer.d.ts","sourceRoot":"","sources":["../../src/streaming/intelligent-buffer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAyIpE;;GAEG;AACH,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAoD;IACnE,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,OAAO,CAAqD;IAGpE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAgE9B;IAEF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAK3B;IAGF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAM;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAO;;IAOpC;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IA8ChC;;OAEG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,aAAa,GAAG,UAAU,GAAG,IAAI;IAyCrE;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE;IAS/D;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAI/C;;OAEG;IACH,iBAAiB,IAAI,MAAM,EAAE;IAI7B;;OAEG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAmBhC;;OAEG;IACH,mBAAmB,IAAI,MAAM;IAK7B;;OAEG;IACH,UAAU,IAAI;QACZ,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,oBAAoB,EAAE,MAAM,CAAC;KAC9B;IAWD;;OAEG;IACH,OAAO,CAAC,aAAa;IAwCrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoCrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA8BxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAkBnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAexB;;OAEG;IACH,OAAO,CAAC,YAAY;IAUpB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAkB5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;OAEG;IACH,OAAO,CAAC,YAAY;CAMrB"}
|