adaptive-memory-multi-model-router 2.6.0 → 2.8.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.
- package/README.md +149 -22
- package/dist/cache/semanticCache.d.ts +54 -22
- package/dist/cache/semanticCache.js +230 -86
- package/dist/cache/semanticCache.js.map +1 -1
- package/dist/cost/budgetEnforcer.d.ts +108 -0
- package/dist/cost/budgetEnforcer.js +295 -0
- package/dist/cost/budgetEnforcer.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +15 -1
- package/dist/routing/providerHealth.d.ts +154 -0
- package/dist/routing/providerHealth.js +371 -0
- package/dist/routing/providerHealth.js.map +1 -0
- package/dist/routing/providerRetry.d.ts +110 -0
- package/dist/routing/providerRetry.js +460 -0
- package/dist/routing/providerRetry.js.map +1 -0
- package/dist/sdk.d.ts +124 -0
- package/dist/sdk.js +109 -100
- package/package.json +3 -2
- package/src/cache/semanticCache.ts +293 -103
- package/src/cost/budgetEnforcer.ts +358 -0
- package/src/index.ts +20 -0
- package/src/routing/providerHealth.ts +483 -0
- package/src/routing/providerRetry.ts +578 -0
- package/test/test_budgetEnforcer.ts +310 -0
- package/test/test_providerHealth.ts +523 -0
- package/test/test_providerRetry.ts +348 -0
- package/test/test_semanticCache.ts +507 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Provider Health Manager with Circuit Breaker
|
|
4
|
+
*
|
|
5
|
+
* Intelligent failover system for A3M Router providing:
|
|
6
|
+
* - Rolling window metrics tracking (latency, error rate)
|
|
7
|
+
* - Health scoring based on latency percentile + error rate
|
|
8
|
+
* - Circuit breaker: 3 consecutive errors → 60s cooldown
|
|
9
|
+
* - Probe mode after cooldown for recovery
|
|
10
|
+
* - Sorted fallback chain based on health scores
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* import { ProviderHealthManager, ProviderHealth } from './routing/providerHealth';
|
|
14
|
+
*
|
|
15
|
+
* const healthManager = new ProviderHealthManager();
|
|
16
|
+
*
|
|
17
|
+
* // Record outcomes
|
|
18
|
+
* healthManager.recordSuccess('openai/gpt-4o', 150);
|
|
19
|
+
* healthManager.recordFailure('anthropic/claude-3-5-sonnet', 'rate_limit');
|
|
20
|
+
*
|
|
21
|
+
* // Get health status
|
|
22
|
+
* const health = healthManager.getHealth('openai/gpt-4o');
|
|
23
|
+
*
|
|
24
|
+
* // Get sorted fallback chain
|
|
25
|
+
* const chain = healthManager.getFallbackChain(['openai/gpt-4o', 'anthropic/claude-3-5-sonnet']);
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.ProviderHealthManager = exports.HealthEvent = void 0;
|
|
29
|
+
const events_1 = require("events");
|
|
30
|
+
// ============================================================
|
|
31
|
+
// Events
|
|
32
|
+
// ============================================================
|
|
33
|
+
var HealthEvent;
|
|
34
|
+
(function (HealthEvent) {
|
|
35
|
+
HealthEvent["HEALTH_CHANGED"] = "healthChanged";
|
|
36
|
+
HealthEvent["CIRCUIT_OPENED"] = "circuitOpened";
|
|
37
|
+
HealthEvent["CIRCUIT_CLOSED"] = "circuitClosed";
|
|
38
|
+
HealthEvent["COOLDOWN_STARTED"] = "cooldownStarted";
|
|
39
|
+
HealthEvent["COOLDOWN_ENDED"] = "cooldownEnded";
|
|
40
|
+
HealthEvent["PROVIDER_DISABLED"] = "providerDisabled";
|
|
41
|
+
HealthEvent["PROVIDER_ENABLED"] = "providerEnabled";
|
|
42
|
+
HealthEvent["PROBE_ALLOWED"] = "probeAllowed";
|
|
43
|
+
})(HealthEvent || (exports.HealthEvent = HealthEvent = {}));
|
|
44
|
+
// ============================================================
|
|
45
|
+
// ProviderHealthManager
|
|
46
|
+
// ============================================================
|
|
47
|
+
class ProviderHealthManager extends events_1.EventEmitter {
|
|
48
|
+
// Rolling window metrics per provider
|
|
49
|
+
metrics = new Map();
|
|
50
|
+
// Current health state per provider
|
|
51
|
+
health = new Map();
|
|
52
|
+
// Disabled providers (manual disable)
|
|
53
|
+
disabled = new Map();
|
|
54
|
+
// Config
|
|
55
|
+
config;
|
|
56
|
+
constructor(config = {}) {
|
|
57
|
+
super();
|
|
58
|
+
this.config = {
|
|
59
|
+
windowSize: config.windowSize ?? 100,
|
|
60
|
+
circuitBreakerThreshold: config.circuitBreakerThreshold ?? 3,
|
|
61
|
+
cooldownMs: config.cooldownMs ?? 60000,
|
|
62
|
+
latencyPercentile: config.latencyPercentile ?? 95,
|
|
63
|
+
weights: {
|
|
64
|
+
latency: config.weights?.latency ?? 0.3,
|
|
65
|
+
errorRate: config.weights?.errorRate ?? 0.5,
|
|
66
|
+
consecutiveErrors: config.weights?.consecutiveErrors ?? 0.2,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Record a successful request
|
|
72
|
+
*/
|
|
73
|
+
recordSuccess(provider, latencyMs) {
|
|
74
|
+
this.ensureProviderExists(provider);
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
const window = this.getMetricsWindow(provider);
|
|
77
|
+
window.push({
|
|
78
|
+
name: provider,
|
|
79
|
+
totalRequests: 1,
|
|
80
|
+
successfulRequests: 1,
|
|
81
|
+
failedRequests: 0,
|
|
82
|
+
totalLatency: latencyMs,
|
|
83
|
+
lastLatency: latencyMs,
|
|
84
|
+
});
|
|
85
|
+
// Trim to window size
|
|
86
|
+
while (window.length > this.config.windowSize) {
|
|
87
|
+
window.shift();
|
|
88
|
+
}
|
|
89
|
+
// Update health state
|
|
90
|
+
const health = this.health.get(provider);
|
|
91
|
+
health.lastSuccess = now;
|
|
92
|
+
health.consecutiveErrors = 0;
|
|
93
|
+
health.cooldownUntil = 0;
|
|
94
|
+
health.isHealthy = true;
|
|
95
|
+
// Recalculate health score
|
|
96
|
+
this.recalculateHealthScore(provider);
|
|
97
|
+
this.emit(HealthEvent.HEALTH_CHANGED, health);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Record a failed request
|
|
101
|
+
*/
|
|
102
|
+
recordFailure(provider, error) {
|
|
103
|
+
this.ensureProviderExists(provider);
|
|
104
|
+
const now = Date.now();
|
|
105
|
+
const window = this.getMetricsWindow(provider);
|
|
106
|
+
window.push({
|
|
107
|
+
name: provider,
|
|
108
|
+
totalRequests: 1,
|
|
109
|
+
successfulRequests: 0,
|
|
110
|
+
failedRequests: 1,
|
|
111
|
+
totalLatency: 0,
|
|
112
|
+
lastLatency: 0,
|
|
113
|
+
});
|
|
114
|
+
// Trim to window size
|
|
115
|
+
while (window.length > this.config.windowSize) {
|
|
116
|
+
window.shift();
|
|
117
|
+
}
|
|
118
|
+
// Update health state
|
|
119
|
+
const health = this.health.get(provider);
|
|
120
|
+
health.lastError = now;
|
|
121
|
+
health.consecutiveErrors++;
|
|
122
|
+
// Check circuit breaker
|
|
123
|
+
if (health.consecutiveErrors >= this.config.circuitBreakerThreshold) {
|
|
124
|
+
health.cooldownUntil = now + this.config.cooldownMs;
|
|
125
|
+
health.isHealthy = false;
|
|
126
|
+
this.emit(HealthEvent.CIRCUIT_OPENED, {
|
|
127
|
+
provider,
|
|
128
|
+
consecutiveErrors: health.consecutiveErrors,
|
|
129
|
+
cooldownUntil: health.cooldownUntil,
|
|
130
|
+
reason: error,
|
|
131
|
+
});
|
|
132
|
+
this.emit(HealthEvent.COOLDOWN_STARTED, {
|
|
133
|
+
provider,
|
|
134
|
+
duration: this.config.cooldownMs,
|
|
135
|
+
reason: error,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
this.recalculateHealthScore(provider);
|
|
139
|
+
this.emit(HealthEvent.HEALTH_CHANGED, health);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get current health for a provider
|
|
143
|
+
*/
|
|
144
|
+
getHealth(provider) {
|
|
145
|
+
this.ensureProviderExists(provider);
|
|
146
|
+
return { ...this.health.get(provider) };
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Get all provider health statuses
|
|
150
|
+
*/
|
|
151
|
+
getAllHealth() {
|
|
152
|
+
const result = new Map();
|
|
153
|
+
for (const [name, health] of this.health.entries()) {
|
|
154
|
+
result.set(name, { ...health });
|
|
155
|
+
}
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Check if a provider is available (healthy and not in cooldown/manual disable)
|
|
160
|
+
*/
|
|
161
|
+
isAvailable(provider) {
|
|
162
|
+
const health = this.health.get(provider);
|
|
163
|
+
if (!health)
|
|
164
|
+
return false;
|
|
165
|
+
// Check manual disable
|
|
166
|
+
const disabled = this.disabled.get(provider);
|
|
167
|
+
if (disabled && disabled.until > Date.now()) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
// Check cooldown
|
|
171
|
+
if (health.cooldownUntil > Date.now()) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
return health.isHealthy;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Check if cooldown has expired and probe is allowed
|
|
178
|
+
*/
|
|
179
|
+
isProbeAllowed(provider) {
|
|
180
|
+
const health = this.health.get(provider);
|
|
181
|
+
if (!health)
|
|
182
|
+
return false;
|
|
183
|
+
// If not in cooldown, no probe needed
|
|
184
|
+
if (health.cooldownUntil === 0)
|
|
185
|
+
return true;
|
|
186
|
+
// If cooldown has expired
|
|
187
|
+
if (health.cooldownUntil <= Date.now()) {
|
|
188
|
+
// Only allow one probe request per cooldown period
|
|
189
|
+
// After probe (marked by consecutiveErrors reset), normal requests allowed
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Get the best provider from a list based on health scores
|
|
196
|
+
*/
|
|
197
|
+
getBestProvider(providers) {
|
|
198
|
+
const available = providers.filter(p => this.isAvailable(p));
|
|
199
|
+
if (available.length === 0)
|
|
200
|
+
return null;
|
|
201
|
+
return available.reduce((best, current) => {
|
|
202
|
+
const health = this.health.get(current);
|
|
203
|
+
const bestHealth = this.health.get(best);
|
|
204
|
+
if (!health || !bestHealth)
|
|
205
|
+
return current;
|
|
206
|
+
return health.healthScore >= bestHealth.healthScore ? current : best;
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get sorted fallback chain based on health scores
|
|
211
|
+
* Returns providers sorted by health score (descending)
|
|
212
|
+
*/
|
|
213
|
+
getFallbackChain(providers) {
|
|
214
|
+
// Score each provider
|
|
215
|
+
const scored = providers.map(p => ({
|
|
216
|
+
provider: p,
|
|
217
|
+
score: this.isAvailable(p) ? (this.health.get(p)?.healthScore ?? 0) : -1,
|
|
218
|
+
}));
|
|
219
|
+
// Sort by health score (descending), unavailable at end
|
|
220
|
+
scored.sort((a, b) => {
|
|
221
|
+
if (a.score === -1 && b.score === -1)
|
|
222
|
+
return 0;
|
|
223
|
+
if (a.score === -1)
|
|
224
|
+
return 1;
|
|
225
|
+
if (b.score === -1)
|
|
226
|
+
return -1;
|
|
227
|
+
return b.score - a.score;
|
|
228
|
+
});
|
|
229
|
+
return scored.map(s => s.provider);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Mark provider as disabled (manual circuit breaker)
|
|
233
|
+
*/
|
|
234
|
+
disableProvider(provider, reason) {
|
|
235
|
+
const until = Number.MAX_SAFE_INTEGER; // Manual disable until explicitly enabled
|
|
236
|
+
this.disabled.set(provider, { reason, until });
|
|
237
|
+
const health = this.health.get(provider);
|
|
238
|
+
if (health) {
|
|
239
|
+
health.isHealthy = false;
|
|
240
|
+
}
|
|
241
|
+
this.emit(HealthEvent.PROVIDER_DISABLED, { provider, reason });
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Enable a previously disabled provider
|
|
245
|
+
*/
|
|
246
|
+
enableProvider(provider) {
|
|
247
|
+
this.disabled.delete(provider);
|
|
248
|
+
const health = this.health.get(provider);
|
|
249
|
+
if (health) {
|
|
250
|
+
health.isHealthy = true;
|
|
251
|
+
health.consecutiveErrors = 0;
|
|
252
|
+
health.cooldownUntil = 0;
|
|
253
|
+
}
|
|
254
|
+
this.emit(HealthEvent.PROVIDER_ENABLED, { provider });
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Clear cooldown and reset circuit breaker for a provider
|
|
258
|
+
*/
|
|
259
|
+
resetCircuitBreaker(provider) {
|
|
260
|
+
const health = this.health.get(provider);
|
|
261
|
+
if (health) {
|
|
262
|
+
health.consecutiveErrors = 0;
|
|
263
|
+
health.cooldownUntil = 0;
|
|
264
|
+
health.isHealthy = true;
|
|
265
|
+
this.emit(HealthEvent.CIRCUIT_CLOSED, { provider });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Get health stats for monitoring
|
|
270
|
+
*/
|
|
271
|
+
getStats() {
|
|
272
|
+
let healthyCount = 0;
|
|
273
|
+
let cooldownCount = 0;
|
|
274
|
+
let disabledCount = 0;
|
|
275
|
+
let totalScore = 0;
|
|
276
|
+
for (const [name, health] of this.health.entries()) {
|
|
277
|
+
totalScore += health.healthScore;
|
|
278
|
+
if (!health.isHealthy && health.cooldownUntil > Date.now()) {
|
|
279
|
+
cooldownCount++;
|
|
280
|
+
}
|
|
281
|
+
else if (health.isHealthy) {
|
|
282
|
+
healthyCount++;
|
|
283
|
+
}
|
|
284
|
+
if (this.disabled.has(name)) {
|
|
285
|
+
disabledCount++;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const total = this.health.size;
|
|
289
|
+
return {
|
|
290
|
+
totalProviders: total,
|
|
291
|
+
healthyProviders: healthyCount,
|
|
292
|
+
cooldownProviders: cooldownCount,
|
|
293
|
+
disabledProviders: disabledCount,
|
|
294
|
+
avgHealthScore: total > 0 ? totalScore / total : 0,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
// ============================================================
|
|
298
|
+
// Private Methods
|
|
299
|
+
// ============================================================
|
|
300
|
+
ensureProviderExists(provider) {
|
|
301
|
+
if (!this.health.has(provider)) {
|
|
302
|
+
const now = Date.now();
|
|
303
|
+
this.health.set(provider, {
|
|
304
|
+
name: provider,
|
|
305
|
+
latency: 0,
|
|
306
|
+
errorRate: 0,
|
|
307
|
+
lastSuccess: 0,
|
|
308
|
+
lastError: 0,
|
|
309
|
+
consecutiveErrors: 0,
|
|
310
|
+
isHealthy: true,
|
|
311
|
+
cooldownUntil: 0,
|
|
312
|
+
healthScore: 1.0,
|
|
313
|
+
});
|
|
314
|
+
this.metrics.set(provider, []);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
getMetricsWindow(provider) {
|
|
318
|
+
return this.metrics.get(provider) ?? [];
|
|
319
|
+
}
|
|
320
|
+
recalculateHealthScore(provider) {
|
|
321
|
+
const window = this.getMetricsWindow(provider);
|
|
322
|
+
const health = this.health.get(provider);
|
|
323
|
+
if (!health || window.length === 0)
|
|
324
|
+
return;
|
|
325
|
+
// Calculate error rate
|
|
326
|
+
const totalRequests = window.reduce((sum, m) => sum + m.totalRequests, 0);
|
|
327
|
+
const failedRequests = window.reduce((sum, m) => sum + m.failedRequests, 0);
|
|
328
|
+
const errorRate = totalRequests > 0 ? failedRequests / totalRequests : 0;
|
|
329
|
+
health.errorRate = errorRate;
|
|
330
|
+
// Calculate latency metrics
|
|
331
|
+
const latencies = window.filter(m => m.totalLatency > 0).map(m => m.lastLatency);
|
|
332
|
+
const avgLatency = latencies.length > 0
|
|
333
|
+
? latencies.reduce((a, b) => a + b, 0) / latencies.length
|
|
334
|
+
: 0;
|
|
335
|
+
health.latency = avgLatency;
|
|
336
|
+
// Percentile latency (simplified: use avg latency as proxy)
|
|
337
|
+
// For true percentile, we'd need raw data points
|
|
338
|
+
const latencyScore = this.calculateLatencyScore(avgLatency);
|
|
339
|
+
// Health score: weighted combination
|
|
340
|
+
// Higher error rate = lower score, higher latency = lower score
|
|
341
|
+
const errorScore = 1 - errorRate;
|
|
342
|
+
const consecutiveScore = Math.max(0, 1 - (health.consecutiveErrors / this.config.circuitBreakerThreshold));
|
|
343
|
+
const score = this.config.weights.latency * latencyScore +
|
|
344
|
+
this.config.weights.errorRate * errorScore +
|
|
345
|
+
this.config.weights.consecutiveErrors * consecutiveScore;
|
|
346
|
+
health.healthScore = Math.max(0, Math.min(1, score));
|
|
347
|
+
}
|
|
348
|
+
calculateLatencyScore(avgLatency) {
|
|
349
|
+
// Latency score: 1 at 0ms, 0 at 10000ms+, with exponential decay
|
|
350
|
+
// Configurable thresholds could be passed in
|
|
351
|
+
const latencyThresholds = {
|
|
352
|
+
excellent: 100, // 100ms - score 1.0
|
|
353
|
+
good: 500, // 500ms - score 0.8
|
|
354
|
+
acceptable: 1000, // 1s - score 0.6
|
|
355
|
+
poor: 3000, // 3s - score 0.3
|
|
356
|
+
terrible: 10000, // 10s+ - score 0.0
|
|
357
|
+
};
|
|
358
|
+
if (avgLatency <= 0)
|
|
359
|
+
return 1.0;
|
|
360
|
+
if (avgLatency <= latencyThresholds.excellent)
|
|
361
|
+
return 1.0;
|
|
362
|
+
if (avgLatency >= latencyThresholds.terrible)
|
|
363
|
+
return 0.0;
|
|
364
|
+
// Exponential interpolation
|
|
365
|
+
const k = 0.003; // decay constant
|
|
366
|
+
return Math.exp(-k * avgLatency);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
exports.ProviderHealthManager = ProviderHealthManager;
|
|
370
|
+
exports.default = ProviderHealthManager;
|
|
371
|
+
//# sourceMappingURL=providerHealth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerHealth.js","sourceRoot":"","sources":["../../src/routing/providerHealth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A3M Router - Per-Provider Retry Logic
|
|
3
|
+
*
|
|
4
|
+
* Implements exponential backoff with jitter for transient errors,
|
|
5
|
+
* rate limit (429) handling with Retry-After header support,
|
|
6
|
+
* and context window validation before sending requests.
|
|
7
|
+
*/
|
|
8
|
+
export interface RetryConfig {
|
|
9
|
+
maxRetries: number;
|
|
10
|
+
initialDelayMs: number;
|
|
11
|
+
maxDelayMs: number;
|
|
12
|
+
backoffMultiplier: number;
|
|
13
|
+
retryableErrors?: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface ProviderRetryConfig {
|
|
16
|
+
[providerName: string]: {
|
|
17
|
+
timeout: number;
|
|
18
|
+
retry: RetryConfig;
|
|
19
|
+
rateLimitRetries?: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface RetryStats {
|
|
23
|
+
totalRequests: number;
|
|
24
|
+
successfulRequests: number;
|
|
25
|
+
failedRequests: number;
|
|
26
|
+
totalRetries: number;
|
|
27
|
+
rateLimitRetries: number;
|
|
28
|
+
averageLatencyMs: number;
|
|
29
|
+
}
|
|
30
|
+
export interface ContextWindowValidation {
|
|
31
|
+
valid: boolean;
|
|
32
|
+
reason?: string;
|
|
33
|
+
suggestedProvider?: string;
|
|
34
|
+
}
|
|
35
|
+
declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
36
|
+
export declare const DEFAULT_PROVIDER_CONFIG: ProviderRetryConfig;
|
|
37
|
+
declare const PROVIDER_CONTEXT_LIMITS: Record<string, number>;
|
|
38
|
+
export declare class ProviderRetryHandler {
|
|
39
|
+
private configs;
|
|
40
|
+
private stats;
|
|
41
|
+
private customProviders;
|
|
42
|
+
constructor(customConfigs?: ProviderRetryConfig);
|
|
43
|
+
private initStats;
|
|
44
|
+
/**
|
|
45
|
+
* Configure or update a provider's retry settings
|
|
46
|
+
*/
|
|
47
|
+
configureProvider(provider: string, config: Partial<{
|
|
48
|
+
timeout: number;
|
|
49
|
+
retry: Partial<RetryConfig>;
|
|
50
|
+
rateLimitRetries: number;
|
|
51
|
+
}>): void;
|
|
52
|
+
/**
|
|
53
|
+
* Get current config for a provider
|
|
54
|
+
*/
|
|
55
|
+
getConfig(provider: string): {
|
|
56
|
+
timeout: number;
|
|
57
|
+
retry: RetryConfig;
|
|
58
|
+
rateLimitRetries: number;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Execute a function with retry logic
|
|
62
|
+
*/
|
|
63
|
+
executeWithRetry<T>(provider: string, fn: () => Promise<T>, options?: {
|
|
64
|
+
timeout?: number;
|
|
65
|
+
onRetry?: (attempt: number, error: any, delayMs: number) => void;
|
|
66
|
+
}): Promise<T>;
|
|
67
|
+
/**
|
|
68
|
+
* Execute with custom timeout wrapper
|
|
69
|
+
*/
|
|
70
|
+
private executeWithTimeout;
|
|
71
|
+
/**
|
|
72
|
+
* Check if an error should trigger a retry
|
|
73
|
+
*/
|
|
74
|
+
isRetryableError(error: any): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Check if error is a rate limit (429)
|
|
77
|
+
*/
|
|
78
|
+
isRateLimitError(error: any): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Calculate backoff delay with exponential increase and jitter
|
|
81
|
+
*/
|
|
82
|
+
calculateBackoffDelay(attempt: number, config: RetryConfig, error?: any): number;
|
|
83
|
+
/**
|
|
84
|
+
* Validate context window size before sending request
|
|
85
|
+
*/
|
|
86
|
+
validateContextWindow(provider: string, prompt: string, expectedTokens?: number): ContextWindowValidation;
|
|
87
|
+
/**
|
|
88
|
+
* Get retry statistics for a provider
|
|
89
|
+
*/
|
|
90
|
+
getStats(provider: string): RetryStats;
|
|
91
|
+
/**
|
|
92
|
+
* Get all provider stats
|
|
93
|
+
*/
|
|
94
|
+
getAllStats(): Record<string, RetryStats>;
|
|
95
|
+
/**
|
|
96
|
+
* Reset stats for a provider
|
|
97
|
+
*/
|
|
98
|
+
resetStats(provider?: string): void;
|
|
99
|
+
private createTimeoutError;
|
|
100
|
+
private sleep;
|
|
101
|
+
private recordSuccess;
|
|
102
|
+
private recordFailure;
|
|
103
|
+
private recordRetry;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Create a retry handler with optional custom configs
|
|
107
|
+
*/
|
|
108
|
+
export declare function createRetryHandler(customConfigs?: ProviderRetryConfig): ProviderRetryHandler;
|
|
109
|
+
export declare function getDefaultRetryHandler(): ProviderRetryHandler;
|
|
110
|
+
export { DEFAULT_RETRY_CONFIG, PROVIDER_CONTEXT_LIMITS, };
|