@azumag/opencode-rate-limit-fallback 1.39.0 → 1.40.0
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.
|
@@ -19,6 +19,7 @@ export class FallbackHandler {
|
|
|
19
19
|
retryState;
|
|
20
20
|
fallbackInProgress;
|
|
21
21
|
fallbackMessages;
|
|
22
|
+
sessionLock;
|
|
22
23
|
// Metrics manager reference
|
|
23
24
|
metricsManager;
|
|
24
25
|
// Subagent tracker reference
|
|
@@ -46,6 +47,7 @@ export class FallbackHandler {
|
|
|
46
47
|
this.retryState = new Map();
|
|
47
48
|
this.fallbackInProgress = new Map();
|
|
48
49
|
this.fallbackMessages = new Map();
|
|
50
|
+
this.sessionLock = new Set();
|
|
49
51
|
// Initialize retry manager
|
|
50
52
|
this.retryManager = new RetryManager(config.retryPolicy || {}, logger);
|
|
51
53
|
}
|
|
@@ -147,10 +149,16 @@ export class FallbackHandler {
|
|
|
147
149
|
* Handle the rate limit fallback process
|
|
148
150
|
*/
|
|
149
151
|
async handleRateLimitFallback(sessionID, currentProviderID, currentModelID) {
|
|
152
|
+
// Resolve target session before acquiring lock
|
|
153
|
+
const rootSessionID = this.subagentTracker.getRootSession(sessionID);
|
|
154
|
+
const targetSessionID = rootSessionID || sessionID;
|
|
155
|
+
// Session-level lock: prevent concurrent fallback processing
|
|
156
|
+
if (this.sessionLock.has(targetSessionID)) {
|
|
157
|
+
this.logger.debug(`Fallback already in progress for session ${targetSessionID}, skipping`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
this.sessionLock.add(targetSessionID);
|
|
150
161
|
try {
|
|
151
|
-
// Get root session and hierarchy using subagent tracker
|
|
152
|
-
const rootSessionID = this.subagentTracker.getRootSession(sessionID);
|
|
153
|
-
const targetSessionID = rootSessionID || sessionID;
|
|
154
162
|
const hierarchy = this.subagentTracker.getHierarchy(sessionID);
|
|
155
163
|
// If no model info provided, try to get from tracked session model
|
|
156
164
|
if (!currentProviderID || !currentModelID) {
|
|
@@ -309,10 +317,11 @@ export class FallbackHandler {
|
|
|
309
317
|
name: errorName,
|
|
310
318
|
});
|
|
311
319
|
// Record retry failure on error
|
|
312
|
-
const rootSessionID = this.subagentTracker.getRootSession(sessionID);
|
|
313
|
-
const targetSessionID = rootSessionID || sessionID;
|
|
314
320
|
this.retryManager.recordFailure(targetSessionID);
|
|
315
321
|
}
|
|
322
|
+
finally {
|
|
323
|
+
this.sessionLock.delete(targetSessionID);
|
|
324
|
+
}
|
|
316
325
|
}
|
|
317
326
|
/**
|
|
318
327
|
* Handle message updated events for metrics recording
|
|
@@ -419,6 +428,7 @@ export class FallbackHandler {
|
|
|
419
428
|
this.retryState.clear();
|
|
420
429
|
this.fallbackInProgress.clear();
|
|
421
430
|
this.fallbackMessages.clear();
|
|
431
|
+
this.sessionLock.clear();
|
|
422
432
|
this.retryManager.destroy();
|
|
423
433
|
// Destroy circuit breaker
|
|
424
434
|
if (this.circuitBreaker) {
|
package/package.json
CHANGED