@sudocode-ai/local-server 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +6 -104
- package/dist/cli.js.map +1 -7
- package/dist/execution/engine/engine.js +10 -0
- package/dist/execution/engine/engine.js.map +1 -0
- package/dist/execution/engine/simple-engine.js +611 -0
- package/dist/execution/engine/simple-engine.js.map +1 -0
- package/dist/execution/engine/types.js +10 -0
- package/dist/execution/engine/types.js.map +1 -0
- package/dist/execution/output/ag-ui-adapter.js +438 -0
- package/dist/execution/output/ag-ui-adapter.js.map +1 -0
- package/dist/execution/output/ag-ui-integration.js +96 -0
- package/dist/execution/output/ag-ui-integration.js.map +1 -0
- package/dist/execution/output/claude-code-output-processor.js +769 -0
- package/dist/execution/output/claude-code-output-processor.js.map +1 -0
- package/dist/execution/output/index.js +15 -0
- package/dist/execution/output/index.js.map +1 -0
- package/dist/execution/output/types.js +22 -0
- package/dist/execution/output/types.js.map +1 -0
- package/dist/execution/process/builders/claude.js +59 -0
- package/dist/execution/process/builders/claude.js.map +1 -0
- package/dist/execution/process/index.js +15 -0
- package/dist/execution/process/index.js.map +1 -0
- package/dist/execution/process/manager.js +10 -0
- package/dist/execution/process/manager.js.map +1 -0
- package/dist/execution/process/simple-manager.js +336 -0
- package/dist/execution/process/simple-manager.js.map +1 -0
- package/dist/execution/process/types.js +10 -0
- package/dist/execution/process/types.js.map +1 -0
- package/dist/execution/process/utils.js +97 -0
- package/dist/execution/process/utils.js.map +1 -0
- package/dist/execution/resilience/circuit-breaker.js +291 -0
- package/dist/execution/resilience/circuit-breaker.js.map +1 -0
- package/dist/execution/resilience/executor.js +10 -0
- package/dist/execution/resilience/executor.js.map +1 -0
- package/dist/execution/resilience/index.js +15 -0
- package/dist/execution/resilience/index.js.map +1 -0
- package/dist/execution/resilience/resilient-executor.js +261 -0
- package/dist/execution/resilience/resilient-executor.js.map +1 -0
- package/dist/execution/resilience/retry.js +234 -0
- package/dist/execution/resilience/retry.js.map +1 -0
- package/dist/execution/resilience/types.js +30 -0
- package/dist/execution/resilience/types.js.map +1 -0
- package/dist/execution/transport/event-buffer.js +208 -0
- package/dist/execution/transport/event-buffer.js.map +1 -0
- package/dist/execution/transport/index.js +10 -0
- package/dist/execution/transport/index.js.map +1 -0
- package/dist/execution/transport/sse-transport.js +282 -0
- package/dist/execution/transport/sse-transport.js.map +1 -0
- package/dist/execution/transport/transport-manager.js +231 -0
- package/dist/execution/transport/transport-manager.js.map +1 -0
- package/dist/execution/workflow/index.js +13 -0
- package/dist/execution/workflow/index.js.map +1 -0
- package/dist/execution/workflow/linear-orchestrator.js +683 -0
- package/dist/execution/workflow/linear-orchestrator.js.map +1 -0
- package/dist/execution/workflow/memory-storage.js +68 -0
- package/dist/execution/workflow/memory-storage.js.map +1 -0
- package/dist/execution/workflow/orchestrator.js +9 -0
- package/dist/execution/workflow/orchestrator.js.map +1 -0
- package/dist/execution/workflow/types.js +9 -0
- package/dist/execution/workflow/types.js.map +1 -0
- package/dist/execution/workflow/utils.js +152 -0
- package/dist/execution/workflow/utils.js.map +1 -0
- package/dist/execution/worktree/config.js +280 -0
- package/dist/execution/worktree/config.js.map +1 -0
- package/dist/execution/worktree/git-cli.js +189 -0
- package/dist/execution/worktree/git-cli.js.map +1 -0
- package/dist/execution/worktree/index.js +15 -0
- package/dist/execution/worktree/index.js.map +1 -0
- package/dist/execution/worktree/manager.js +452 -0
- package/dist/execution/worktree/manager.js.map +1 -0
- package/dist/execution/worktree/types.js +42 -0
- package/dist/execution/worktree/types.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +357 -104
- package/dist/index.js.map +1 -7
- package/dist/routes/executions-stream.js +55 -0
- package/dist/routes/executions-stream.js.map +1 -0
- package/dist/routes/executions.js +267 -0
- package/dist/routes/executions.js.map +1 -0
- package/dist/routes/feedback.js +329 -0
- package/dist/routes/feedback.js.map +1 -0
- package/dist/routes/issues.js +280 -0
- package/dist/routes/issues.js.map +1 -0
- package/dist/routes/relationships.js +308 -0
- package/dist/routes/relationships.js.map +1 -0
- package/dist/routes/specs.js +270 -0
- package/dist/routes/specs.js.map +1 -0
- package/dist/services/db.js +85 -0
- package/dist/services/db.js.map +1 -0
- package/dist/services/execution-lifecycle.d.ts.map +1 -1
- package/dist/services/execution-lifecycle.js +291 -0
- package/dist/services/execution-lifecycle.js.map +1 -0
- package/dist/services/execution-service.js +676 -0
- package/dist/services/execution-service.js.map +1 -0
- package/dist/services/executions.js +164 -0
- package/dist/services/executions.js.map +1 -0
- package/dist/services/export.js +106 -0
- package/dist/services/export.js.map +1 -0
- package/dist/services/feedback.js +54 -0
- package/dist/services/feedback.js.map +1 -0
- package/dist/services/issues.js +35 -0
- package/dist/services/issues.js.map +1 -0
- package/dist/services/prompt-template-engine.js +212 -0
- package/dist/services/prompt-template-engine.js.map +1 -0
- package/dist/services/prompt-templates.js +236 -0
- package/dist/services/prompt-templates.js.map +1 -0
- package/dist/services/relationships.js +42 -0
- package/dist/services/relationships.js.map +1 -0
- package/dist/services/specs.js +35 -0
- package/dist/services/specs.js.map +1 -0
- package/dist/services/watcher.js +69 -0
- package/dist/services/watcher.js.map +1 -0
- package/dist/services/websocket.js +389 -0
- package/dist/services/websocket.js.map +1 -0
- package/dist/utils/sudocode-dir.js +9 -0
- package/dist/utils/sudocode-dir.js.map +1 -0
- package/package.json +4 -6
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circuit Breaker Implementation
|
|
3
|
+
*
|
|
4
|
+
* Implements the circuit breaker pattern for preventing cascading failures.
|
|
5
|
+
* Tracks failures and successes, automatically opening when thresholds are
|
|
6
|
+
* exceeded and recovering through half-open state.
|
|
7
|
+
*
|
|
8
|
+
* @module execution/resilience/circuit-breaker
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* CircuitBreakerManager - Manages multiple circuit breakers
|
|
12
|
+
*
|
|
13
|
+
* Maintains a collection of circuit breakers, typically one per task type
|
|
14
|
+
* or service. Provides methods for checking state, recording outcomes,
|
|
15
|
+
* and managing circuit lifecycle.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const manager = new CircuitBreakerManager();
|
|
20
|
+
* const breaker = manager.getOrCreate('issue-executor', {
|
|
21
|
+
* failureThreshold: 5,
|
|
22
|
+
* successThreshold: 2,
|
|
23
|
+
* timeout: 60000,
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* if (manager.canExecute('issue-executor')) {
|
|
27
|
+
* // Execute task
|
|
28
|
+
* const success = await executeTask();
|
|
29
|
+
* if (success) {
|
|
30
|
+
* manager.recordSuccess('issue-executor');
|
|
31
|
+
* } else {
|
|
32
|
+
* manager.recordFailure('issue-executor', new Error('Task failed'));
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export class CircuitBreakerManager {
|
|
38
|
+
breakers = new Map();
|
|
39
|
+
/**
|
|
40
|
+
* Get an existing circuit breaker by name
|
|
41
|
+
*
|
|
42
|
+
* @param name - Circuit breaker name
|
|
43
|
+
* @returns Circuit breaker or null if not found
|
|
44
|
+
*/
|
|
45
|
+
get(name) {
|
|
46
|
+
return this.breakers.get(name) || null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get or create a circuit breaker
|
|
50
|
+
*
|
|
51
|
+
* If a circuit breaker with the given name exists, returns it.
|
|
52
|
+
* Otherwise creates a new one with the provided configuration.
|
|
53
|
+
*
|
|
54
|
+
* @param name - Circuit breaker name (typically task type)
|
|
55
|
+
* @param config - Configuration for new circuit breaker
|
|
56
|
+
* @returns Circuit breaker instance
|
|
57
|
+
*/
|
|
58
|
+
getOrCreate(name, config = {
|
|
59
|
+
failureThreshold: 5,
|
|
60
|
+
successThreshold: 2,
|
|
61
|
+
timeout: 60000,
|
|
62
|
+
}) {
|
|
63
|
+
let breaker = this.breakers.get(name);
|
|
64
|
+
if (!breaker) {
|
|
65
|
+
breaker = {
|
|
66
|
+
name,
|
|
67
|
+
state: 'closed',
|
|
68
|
+
config,
|
|
69
|
+
metrics: {
|
|
70
|
+
totalRequests: 0,
|
|
71
|
+
failedRequests: 0,
|
|
72
|
+
successfulRequests: 0,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
this.breakers.set(name, breaker);
|
|
76
|
+
}
|
|
77
|
+
return breaker;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if a circuit breaker allows execution
|
|
81
|
+
*
|
|
82
|
+
* Returns false if circuit is open and timeout hasn't elapsed yet.
|
|
83
|
+
* Returns true for closed and half-open states.
|
|
84
|
+
*
|
|
85
|
+
* @param name - Circuit breaker name
|
|
86
|
+
* @returns True if execution is allowed
|
|
87
|
+
*/
|
|
88
|
+
canExecute(name) {
|
|
89
|
+
const breaker = this.breakers.get(name);
|
|
90
|
+
if (!breaker) {
|
|
91
|
+
return true; // No breaker means no restriction
|
|
92
|
+
}
|
|
93
|
+
if (breaker.state === 'open') {
|
|
94
|
+
// Check if timeout has elapsed to transition to half-open
|
|
95
|
+
if (this.shouldTransitionToHalfOpen(breaker)) {
|
|
96
|
+
breaker.state = 'half-open';
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
return true; // closed or half-open allows execution
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Record a successful execution
|
|
105
|
+
*
|
|
106
|
+
* Updates metrics and may transition circuit from half-open to closed
|
|
107
|
+
* if success threshold is met.
|
|
108
|
+
*
|
|
109
|
+
* @param name - Circuit breaker name
|
|
110
|
+
*/
|
|
111
|
+
recordSuccess(name) {
|
|
112
|
+
const breaker = this.breakers.get(name);
|
|
113
|
+
if (!breaker) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
breaker.metrics.totalRequests++;
|
|
117
|
+
breaker.metrics.successfulRequests++;
|
|
118
|
+
breaker.metrics.lastSuccessTime = new Date();
|
|
119
|
+
// If in half-open state, check if we should close
|
|
120
|
+
if (breaker.state === 'half-open') {
|
|
121
|
+
// Count recent successes (simplified: use total for now)
|
|
122
|
+
// In production, you'd track a sliding window of recent attempts
|
|
123
|
+
const recentSuccesses = this.getConsecutiveSuccesses(breaker);
|
|
124
|
+
if (recentSuccesses >= breaker.config.successThreshold) {
|
|
125
|
+
breaker.state = 'closed';
|
|
126
|
+
breaker.metrics.failedRequests = 0; // Reset failure count
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Record a failed execution
|
|
132
|
+
*
|
|
133
|
+
* Updates metrics and may transition circuit from closed/half-open to open
|
|
134
|
+
* if failure threshold is met.
|
|
135
|
+
*
|
|
136
|
+
* @param name - Circuit breaker name
|
|
137
|
+
* @param error - Error that occurred
|
|
138
|
+
*/
|
|
139
|
+
recordFailure(name, error) {
|
|
140
|
+
const breaker = this.breakers.get(name);
|
|
141
|
+
if (!breaker) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
void error; // Error logged but not used in current implementation
|
|
145
|
+
breaker.metrics.totalRequests++;
|
|
146
|
+
breaker.metrics.failedRequests++;
|
|
147
|
+
breaker.metrics.lastFailureTime = new Date();
|
|
148
|
+
// Check if we should open the circuit
|
|
149
|
+
if (breaker.state === 'closed') {
|
|
150
|
+
if (breaker.metrics.failedRequests >= breaker.config.failureThreshold) {
|
|
151
|
+
breaker.state = 'open';
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else if (breaker.state === 'half-open') {
|
|
155
|
+
// Any failure in half-open state reopens the circuit
|
|
156
|
+
breaker.state = 'open';
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Reset a circuit breaker to closed state
|
|
161
|
+
*
|
|
162
|
+
* Clears all failure counts and returns circuit to closed state.
|
|
163
|
+
* Useful for manual recovery or after fixing underlying issues.
|
|
164
|
+
*
|
|
165
|
+
* @param name - Circuit breaker name
|
|
166
|
+
*/
|
|
167
|
+
reset(name) {
|
|
168
|
+
const breaker = this.breakers.get(name);
|
|
169
|
+
if (!breaker) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
breaker.state = 'closed';
|
|
173
|
+
breaker.metrics.failedRequests = 0;
|
|
174
|
+
breaker.metrics.successfulRequests = 0;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Get all circuit breakers
|
|
178
|
+
*
|
|
179
|
+
* @returns Map of circuit breaker name to breaker instance
|
|
180
|
+
*/
|
|
181
|
+
getAll() {
|
|
182
|
+
return new Map(this.breakers);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Check if enough time has passed to transition from open to half-open
|
|
186
|
+
*
|
|
187
|
+
* @param breaker - Circuit breaker to check
|
|
188
|
+
* @returns True if timeout has elapsed
|
|
189
|
+
* @private
|
|
190
|
+
*/
|
|
191
|
+
shouldTransitionToHalfOpen(breaker) {
|
|
192
|
+
if (!breaker.metrics.lastFailureTime) {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
const timeSinceFailure = Date.now() - breaker.metrics.lastFailureTime.getTime();
|
|
196
|
+
return timeSinceFailure >= breaker.config.timeout;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Get count of consecutive successes
|
|
200
|
+
*
|
|
201
|
+
* In a production implementation, this would track a sliding window
|
|
202
|
+
* of recent attempts. For simplicity, we use total successful requests.
|
|
203
|
+
*
|
|
204
|
+
* @param breaker - Circuit breaker to check
|
|
205
|
+
* @returns Number of consecutive successes
|
|
206
|
+
* @private
|
|
207
|
+
*/
|
|
208
|
+
getConsecutiveSuccesses(breaker) {
|
|
209
|
+
// Simplified: In production, track recent attempts in a circular buffer
|
|
210
|
+
// For now, use successful requests as a proxy
|
|
211
|
+
return breaker.metrics.successfulRequests;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Create a new circuit breaker instance
|
|
216
|
+
*
|
|
217
|
+
* Helper function to create a properly configured circuit breaker.
|
|
218
|
+
*
|
|
219
|
+
* @param name - Circuit breaker name
|
|
220
|
+
* @param config - Circuit breaker configuration
|
|
221
|
+
* @returns New circuit breaker instance
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* const breaker = createCircuitBreaker('api-calls', {
|
|
226
|
+
* failureThreshold: 10,
|
|
227
|
+
* successThreshold: 3,
|
|
228
|
+
* timeout: 30000,
|
|
229
|
+
* });
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
export function createCircuitBreaker(name, config = {
|
|
233
|
+
failureThreshold: 5,
|
|
234
|
+
successThreshold: 2,
|
|
235
|
+
timeout: 60000,
|
|
236
|
+
}) {
|
|
237
|
+
return {
|
|
238
|
+
name,
|
|
239
|
+
state: 'closed',
|
|
240
|
+
config,
|
|
241
|
+
metrics: {
|
|
242
|
+
totalRequests: 0,
|
|
243
|
+
failedRequests: 0,
|
|
244
|
+
successfulRequests: 0,
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Check if a circuit breaker is in a specific state
|
|
250
|
+
*
|
|
251
|
+
* @param breaker - Circuit breaker to check
|
|
252
|
+
* @param state - State to check for
|
|
253
|
+
* @returns True if breaker is in the specified state
|
|
254
|
+
*/
|
|
255
|
+
export function isInState(breaker, state) {
|
|
256
|
+
return breaker.state === state;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get the current state of a circuit breaker
|
|
260
|
+
*
|
|
261
|
+
* @param breaker - Circuit breaker to check
|
|
262
|
+
* @returns Current state
|
|
263
|
+
*/
|
|
264
|
+
export function getState(breaker) {
|
|
265
|
+
return breaker.state;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Calculate failure rate for a circuit breaker
|
|
269
|
+
*
|
|
270
|
+
* @param breaker - Circuit breaker to analyze
|
|
271
|
+
* @returns Failure rate (0-1) or 0 if no requests
|
|
272
|
+
*/
|
|
273
|
+
export function getFailureRate(breaker) {
|
|
274
|
+
if (breaker.metrics.totalRequests === 0) {
|
|
275
|
+
return 0;
|
|
276
|
+
}
|
|
277
|
+
return breaker.metrics.failedRequests / breaker.metrics.totalRequests;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Calculate success rate for a circuit breaker
|
|
281
|
+
*
|
|
282
|
+
* @param breaker - Circuit breaker to analyze
|
|
283
|
+
* @returns Success rate (0-1) or 0 if no requests
|
|
284
|
+
*/
|
|
285
|
+
export function getSuccessRate(breaker) {
|
|
286
|
+
if (breaker.metrics.totalRequests === 0) {
|
|
287
|
+
return 0;
|
|
288
|
+
}
|
|
289
|
+
return breaker.metrics.successfulRequests / breaker.metrics.totalRequests;
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../../src/execution/resilience/circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,OAAO,qBAAqB;IACxB,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;IAErD;;;;;OAKG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IACzC,CAAC;IAED;;;;;;;;;OASG;IACH,WAAW,CACT,IAAY,EACZ,SAAmC;QACjC,gBAAgB,EAAE,CAAC;QACnB,gBAAgB,EAAE,CAAC;QACnB,OAAO,EAAE,KAAK;KACf;QAED,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEtC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG;gBACR,IAAI;gBACJ,KAAK,EAAE,QAAQ;gBACf,MAAM;gBACN,OAAO,EAAE;oBACP,aAAa,EAAE,CAAC;oBAChB,cAAc,EAAE,CAAC;oBACjB,kBAAkB,EAAE,CAAC;iBACtB;aACF,CAAC;YAEF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;;;OAQG;IACH,UAAU,CAAC,IAAY;QACrB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,CAAC,kCAAkC;QACjD,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC7B,0DAA0D;YAC1D,IAAI,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7C,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC;gBAC5B,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC,CAAC,uCAAuC;IACtD,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,IAAY;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QAED,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAChC,OAAO,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;QACrC,OAAO,CAAC,OAAO,CAAC,eAAe,GAAG,IAAI,IAAI,EAAE,CAAC;QAE7C,kDAAkD;QAClD,IAAI,OAAO,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAClC,yDAAyD;YACzD,iEAAiE;YACjE,MAAM,eAAe,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;YAE9D,IAAI,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;gBACvD,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;gBACzB,OAAO,CAAC,OAAO,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,sBAAsB;YAC5D,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,aAAa,CAAC,IAAY,EAAE,KAAY;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QAED,KAAK,KAAK,CAAC,CAAC,sDAAsD;QAElE,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAChC,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QACjC,OAAO,CAAC,OAAO,CAAC,eAAe,GAAG,IAAI,IAAI,EAAE,CAAC;QAE7C,sCAAsC;QACtC,IAAI,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC/B,IAAI,OAAO,CAAC,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;gBACtE,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;YACzB,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YACzC,qDAAqD;YACrD,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;QACzB,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAY;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QAED,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;QACzB,OAAO,CAAC,OAAO,CAAC,cAAc,GAAG,CAAC,CAAC;QACnC,OAAO,CAAC,OAAO,CAAC,kBAAkB,GAAG,CAAC,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACH,MAAM;QACJ,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED;;;;;;OAMG;IACK,0BAA0B,CAAC,OAAuB;QACxD,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,gBAAgB,GACpB,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;QAEzD,OAAO,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;IACpD,CAAC;IAED;;;;;;;;;OASG;IACK,uBAAuB,CAAC,OAAuB;QACrD,wEAAwE;QACxE,8CAA8C;QAC9C,OAAO,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC;IAC5C,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,SAAmC;IACjC,gBAAgB,EAAE,CAAC;IACnB,gBAAgB,EAAE,CAAC;IACnB,OAAO,EAAE,KAAK;CACf;IAED,OAAO;QACL,IAAI;QACJ,KAAK,EAAE,QAAQ;QACf,MAAM;QACN,OAAO,EAAE;YACP,aAAa,EAAE,CAAC;YAChB,cAAc,EAAE,CAAC;YACjB,kBAAkB,EAAE,CAAC;SACtB;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,OAAuB,EACvB,KAAmB;IAEnB,OAAO,OAAO,CAAC,KAAK,KAAK,KAAK,CAAC;AACjC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAuB;IAC9C,OAAO,OAAO,CAAC,KAAK,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,OAAuB;IACpD,IAAI,OAAO,CAAC,OAAO,CAAC,aAAa,KAAK,CAAC,EAAE,CAAC;QACxC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;AACxE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,OAAuB;IACpD,IAAI,OAAO,CAAC,OAAO,CAAC,aAAa,KAAK,CAAC,EAAE,CAAC;QACxC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resilient Executor Interface
|
|
3
|
+
*
|
|
4
|
+
* Core abstraction for resilient task execution. Provides methods for
|
|
5
|
+
* executing tasks with retry logic, circuit breakers, and fault tolerance.
|
|
6
|
+
*
|
|
7
|
+
* @module execution/resilience/executor
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/execution/resilience/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resilience Layer Exports
|
|
3
|
+
*
|
|
4
|
+
* Layer 3: Task Execution Layer - Resilience & Retry
|
|
5
|
+
*
|
|
6
|
+
* @module execution/resilience
|
|
7
|
+
*/
|
|
8
|
+
export { DEFAULT_RETRY_POLICY } from './types.js';
|
|
9
|
+
// Implementation
|
|
10
|
+
export { ResilientExecutor } from './resilient-executor.js';
|
|
11
|
+
// Retry utilities
|
|
12
|
+
export { calculateBackoff, isRetryableError, isRetryableExitCode, isRetryableResult, sleep, createAttempt, calculateTotalRetryDelay, } from './retry.js';
|
|
13
|
+
// Circuit breaker
|
|
14
|
+
export { CircuitBreakerManager, createCircuitBreaker, isInState, getState, getFailureRate, getSuccessRate, } from './circuit-breaker.js';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/execution/resilience/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAcH,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAKlD,iBAAiB;AACjB,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,kBAAkB;AAClB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,EACL,aAAa,EACb,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAEpB,kBAAkB;AAClB,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,SAAS,EACT,QAAQ,EACR,cAAc,EACd,cAAc,GACf,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resilient Executor Implementation
|
|
3
|
+
*
|
|
4
|
+
* Implements resilient task execution with retry logic and circuit breakers.
|
|
5
|
+
* Wraps the Engine Layer with fault tolerance mechanisms.
|
|
6
|
+
*
|
|
7
|
+
* @module execution/resilience/resilient-executor
|
|
8
|
+
*/
|
|
9
|
+
import { CircuitBreakerManager } from "./circuit-breaker.js";
|
|
10
|
+
import { calculateBackoff, isRetryableResult, sleep, createAttempt, } from "./retry.js";
|
|
11
|
+
import { DEFAULT_RETRY_POLICY } from "./types.js";
|
|
12
|
+
/**
|
|
13
|
+
* ResilientExecutor - Main implementation of resilient task execution
|
|
14
|
+
*
|
|
15
|
+
* Provides retry logic and circuit breaker protection for task execution.
|
|
16
|
+
* Wraps an IExecutionEngine with fault tolerance mechanisms.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const engine = new SimpleExecutionEngine(processManager);
|
|
21
|
+
* const executor = new ResilientExecutor(engine);
|
|
22
|
+
*
|
|
23
|
+
* const task: ExecutionTask = {
|
|
24
|
+
* id: 'task-1',
|
|
25
|
+
* type: 'issue',
|
|
26
|
+
* prompt: 'Fix the bug in authentication',
|
|
27
|
+
* workDir: '/path/to/project',
|
|
28
|
+
* priority: 0,
|
|
29
|
+
* dependencies: [],
|
|
30
|
+
* createdAt: new Date(),
|
|
31
|
+
* config: {},
|
|
32
|
+
* };
|
|
33
|
+
*
|
|
34
|
+
* const result = await executor.executeTask(task);
|
|
35
|
+
* console.log(`Completed after ${result.totalAttempts} attempts`);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export class ResilientExecutor {
|
|
39
|
+
_engine;
|
|
40
|
+
_circuitManager;
|
|
41
|
+
_defaultPolicy;
|
|
42
|
+
_metrics;
|
|
43
|
+
// Event handlers
|
|
44
|
+
_retryHandlers = [];
|
|
45
|
+
_circuitOpenHandlers = [];
|
|
46
|
+
constructor(engine, defaultPolicy = DEFAULT_RETRY_POLICY) {
|
|
47
|
+
this._engine = engine;
|
|
48
|
+
this._circuitManager = new CircuitBreakerManager();
|
|
49
|
+
this._defaultPolicy = defaultPolicy;
|
|
50
|
+
this._metrics = {
|
|
51
|
+
totalRetries: 0,
|
|
52
|
+
successfulRetries: 0,
|
|
53
|
+
failedRetries: 0,
|
|
54
|
+
averageAttemptsToSuccess: 0,
|
|
55
|
+
circuitBreakers: new Map(),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Execute a single task with retry and circuit breaker protection
|
|
60
|
+
*/
|
|
61
|
+
async executeTask(task, policy) {
|
|
62
|
+
const retryPolicy = policy || this._defaultPolicy;
|
|
63
|
+
const circuitBreakerName = task.type; // Use task type as circuit breaker name
|
|
64
|
+
const attempts = [];
|
|
65
|
+
// Get or create circuit breaker for this task type
|
|
66
|
+
const breaker = this._circuitManager.getOrCreate(circuitBreakerName, {
|
|
67
|
+
failureThreshold: 5,
|
|
68
|
+
successThreshold: 2,
|
|
69
|
+
timeout: 60000,
|
|
70
|
+
});
|
|
71
|
+
// Attempt execution with retries
|
|
72
|
+
for (let attemptNumber = 1; attemptNumber <= retryPolicy.maxAttempts; attemptNumber++) {
|
|
73
|
+
// Check circuit breaker before execution
|
|
74
|
+
if (!this._circuitManager.canExecute(circuitBreakerName)) {
|
|
75
|
+
// Call circuit open handlers
|
|
76
|
+
this._circuitOpenHandlers.forEach((handler) => {
|
|
77
|
+
handler(circuitBreakerName, breaker);
|
|
78
|
+
});
|
|
79
|
+
// Return result indicating circuit breaker triggered
|
|
80
|
+
const circuitOpenResult = {
|
|
81
|
+
taskId: task.id,
|
|
82
|
+
executionId: "circuit-breaker-open",
|
|
83
|
+
success: false,
|
|
84
|
+
exitCode: -1,
|
|
85
|
+
output: "",
|
|
86
|
+
error: `Circuit breaker is open for ${circuitBreakerName}`,
|
|
87
|
+
startedAt: new Date(),
|
|
88
|
+
completedAt: new Date(),
|
|
89
|
+
duration: 0,
|
|
90
|
+
attempts: [],
|
|
91
|
+
totalAttempts: 0,
|
|
92
|
+
finalAttempt: createAttempt(0, false, {
|
|
93
|
+
error: new Error(`Circuit breaker is open for ${circuitBreakerName}`),
|
|
94
|
+
}),
|
|
95
|
+
circuitBreakerTriggered: true,
|
|
96
|
+
};
|
|
97
|
+
return circuitOpenResult;
|
|
98
|
+
}
|
|
99
|
+
const attemptStart = new Date();
|
|
100
|
+
try {
|
|
101
|
+
// Submit task to engine and wait for result
|
|
102
|
+
const taskId = await this._engine.submitTask(task);
|
|
103
|
+
const result = await this._engine.waitForTask(taskId);
|
|
104
|
+
const attemptDuration = Date.now() - attemptStart.getTime();
|
|
105
|
+
// Check if execution was successful
|
|
106
|
+
if (result.success) {
|
|
107
|
+
// Success! Record in circuit breaker and return
|
|
108
|
+
this._circuitManager.recordSuccess(circuitBreakerName);
|
|
109
|
+
const successAttempt = createAttempt(attemptNumber, true, {
|
|
110
|
+
exitCode: result.exitCode,
|
|
111
|
+
duration: attemptDuration,
|
|
112
|
+
});
|
|
113
|
+
attempts.push(successAttempt);
|
|
114
|
+
// Update metrics for successful retry
|
|
115
|
+
if (attemptNumber > 1) {
|
|
116
|
+
this._metrics.successfulRetries++;
|
|
117
|
+
this._updateAverageAttempts(attemptNumber);
|
|
118
|
+
}
|
|
119
|
+
return this._createResilientResult(result, attempts);
|
|
120
|
+
}
|
|
121
|
+
// Execution completed but failed - check if retryable
|
|
122
|
+
const isRetryable = isRetryableResult(result, retryPolicy);
|
|
123
|
+
const willRetry = isRetryable && attemptNumber < retryPolicy.maxAttempts;
|
|
124
|
+
const failureAttempt = createAttempt(attemptNumber, false, {
|
|
125
|
+
error: new Error(result.error || "Task failed"),
|
|
126
|
+
exitCode: result.exitCode,
|
|
127
|
+
duration: attemptDuration,
|
|
128
|
+
willRetry,
|
|
129
|
+
});
|
|
130
|
+
if (willRetry) {
|
|
131
|
+
const backoffDelay = calculateBackoff(attemptNumber + 1, retryPolicy.backoff);
|
|
132
|
+
failureAttempt.nextRetryAt = new Date(Date.now() + backoffDelay);
|
|
133
|
+
// Call retry attempt handlers
|
|
134
|
+
this._retryHandlers.forEach((handler) => {
|
|
135
|
+
handler(task.id, failureAttempt);
|
|
136
|
+
});
|
|
137
|
+
this._metrics.totalRetries++;
|
|
138
|
+
attempts.push(failureAttempt);
|
|
139
|
+
// Wait before retry
|
|
140
|
+
await sleep(backoffDelay);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
// Not retryable or max attempts reached - record failure
|
|
144
|
+
attempts.push(failureAttempt);
|
|
145
|
+
this._circuitManager.recordFailure(circuitBreakerName, new Error(result.error || "Task failed"));
|
|
146
|
+
// Update metrics for failed retries
|
|
147
|
+
// Count all retry attempts in this failed task
|
|
148
|
+
if (attemptNumber > 1) {
|
|
149
|
+
this._metrics.failedRetries += attemptNumber - 1;
|
|
150
|
+
}
|
|
151
|
+
return this._createResilientResult(result, attempts);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
// Engine execution error (not a task failure)
|
|
155
|
+
const attemptDuration = Date.now() - attemptStart.getTime();
|
|
156
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
157
|
+
const isRetryable = retryPolicy.retryableErrors.some((pattern) => err.message.includes(pattern));
|
|
158
|
+
const willRetry = isRetryable && attemptNumber < retryPolicy.maxAttempts;
|
|
159
|
+
const errorAttempt = createAttempt(attemptNumber, false, {
|
|
160
|
+
error: err,
|
|
161
|
+
duration: attemptDuration,
|
|
162
|
+
willRetry,
|
|
163
|
+
});
|
|
164
|
+
if (willRetry) {
|
|
165
|
+
const backoffDelay = calculateBackoff(attemptNumber + 1, retryPolicy.backoff);
|
|
166
|
+
errorAttempt.nextRetryAt = new Date(Date.now() + backoffDelay);
|
|
167
|
+
// Call retry attempt handlers
|
|
168
|
+
this._retryHandlers.forEach((handler) => {
|
|
169
|
+
handler(task.id, errorAttempt);
|
|
170
|
+
});
|
|
171
|
+
this._metrics.totalRetries++;
|
|
172
|
+
attempts.push(errorAttempt);
|
|
173
|
+
// Wait before retry
|
|
174
|
+
await sleep(backoffDelay);
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
// Not retryable or max attempts reached
|
|
178
|
+
attempts.push(errorAttempt);
|
|
179
|
+
this._circuitManager.recordFailure(circuitBreakerName, err);
|
|
180
|
+
// Update metrics for failed retries
|
|
181
|
+
// Count all retry attempts in this failed task
|
|
182
|
+
if (attemptNumber > 1) {
|
|
183
|
+
this._metrics.failedRetries += attemptNumber - 1;
|
|
184
|
+
}
|
|
185
|
+
throw err;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Should never reach here, but TypeScript needs it
|
|
189
|
+
throw new Error("Unexpected state: exceeded max attempts without return");
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Execute multiple tasks with retry and circuit breaker protection
|
|
193
|
+
*/
|
|
194
|
+
async executeTasks(tasks, policy) {
|
|
195
|
+
// Execute all tasks in parallel
|
|
196
|
+
const promises = tasks.map((task) => this.executeTask(task, policy));
|
|
197
|
+
return Promise.all(promises);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get circuit breaker by name
|
|
201
|
+
*/
|
|
202
|
+
getCircuitBreaker(name) {
|
|
203
|
+
return this._circuitManager.get(name);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Reset a circuit breaker to closed state
|
|
207
|
+
*/
|
|
208
|
+
resetCircuitBreaker(name) {
|
|
209
|
+
this._circuitManager.reset(name);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Get aggregate retry metrics
|
|
213
|
+
*/
|
|
214
|
+
getRetryMetrics() {
|
|
215
|
+
// Update circuit breakers in metrics
|
|
216
|
+
this._metrics.circuitBreakers = this._circuitManager.getAll();
|
|
217
|
+
// Return defensive copy
|
|
218
|
+
return {
|
|
219
|
+
...this._metrics,
|
|
220
|
+
circuitBreakers: new Map(this._metrics.circuitBreakers),
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Register handler for retry attempt events
|
|
225
|
+
*/
|
|
226
|
+
onRetryAttempt(handler) {
|
|
227
|
+
this._retryHandlers.push(handler);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Register handler for circuit breaker open events
|
|
231
|
+
*/
|
|
232
|
+
onCircuitOpen(handler) {
|
|
233
|
+
this._circuitOpenHandlers.push(handler);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Helper to create ResilientExecutionResult from engine result
|
|
237
|
+
* @private
|
|
238
|
+
*/
|
|
239
|
+
_createResilientResult(result, attempts) {
|
|
240
|
+
const finalAttempt = attempts[attempts.length - 1];
|
|
241
|
+
return {
|
|
242
|
+
...result,
|
|
243
|
+
attempts,
|
|
244
|
+
totalAttempts: attempts.length,
|
|
245
|
+
finalAttempt,
|
|
246
|
+
failureReason: result.success ? undefined : result.error,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Helper to update average attempts to success metric
|
|
251
|
+
* @private
|
|
252
|
+
*/
|
|
253
|
+
_updateAverageAttempts(attemptCount) {
|
|
254
|
+
const totalSuccessful = this._metrics.successfulRetries;
|
|
255
|
+
const previousAverage = this._metrics.averageAttemptsToSuccess;
|
|
256
|
+
const previousTotal = previousAverage * (totalSuccessful - 1);
|
|
257
|
+
this._metrics.averageAttemptsToSuccess =
|
|
258
|
+
(previousTotal + attemptCount) / totalSuccessful;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=resilient-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resilient-executor.js","sourceRoot":"","sources":["../../../src/execution/resilience/resilient-executor.ts"],"names":[],"mappings":"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"}
|