adaptive-memory-multi-model-router 2.7.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/dist/index.d.ts +2 -0
- package/dist/index.js +11 -1
- package/dist/routing/providerRetry.d.ts +110 -0
- package/dist/routing/providerRetry.js +460 -0
- package/dist/routing/providerRetry.js.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +18 -0
- package/src/routing/providerRetry.ts +578 -0
- package/test/test_providerRetry.ts +348 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { routeQuery, routeBatch, recommendForTask, extractQueryFeatures, MODEL_PROFILES, updateModelProfile, getProviderHealth, } from './routing/advancedRouter';
|
|
2
|
+
export { ProviderRetryHandler, createRetryHandler, getDefaultRetryHandler, DEFAULT_RETRY_CONFIG, DEFAULT_PROVIDER_CONFIG, PROVIDER_CONTEXT_LIMITS, } from './routing/providerRetry';
|
|
3
|
+
export type { RetryConfig, ProviderRetryConfig, RetryStats, ContextWindowValidation, } from './routing/providerRetry';
|
|
2
4
|
export { DEFAULT_PROVIDERS, getAvailableProviders, registerProvider, deregisterProvider, updateProvider, healthCheck, checkAllProviders, findCheapestAvailableProvider, findFastestAvailableProvider, loadConfig, saveConfig, } from './providers/providerConfig';
|
|
3
5
|
export type { ProviderTier, ProviderFormat, ProviderType, ProviderCost, ProviderDefinition, } from './providers/providerConfig';
|
|
4
6
|
export { CostTracker } from './cost/costTracker';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// A3M Router - Main Entry Point
|
|
3
3
|
// Version: 2.0.0
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.createProxyServer = exports.CostAnalytics = exports.GuardrailEngine = exports.SemanticCache = exports.MODEL_COSTS = exports.estimateTokens = exports.countTokens = exports.MemoryTree = exports.createBudgetEnforcer = exports.BudgetExceededError = exports.BudgetEnforcer = exports.CostTracker = exports.saveConfig = exports.loadConfig = exports.findFastestAvailableProvider = exports.findCheapestAvailableProvider = exports.checkAllProviders = exports.healthCheck = exports.updateProvider = exports.deregisterProvider = exports.registerProvider = exports.getAvailableProviders = exports.DEFAULT_PROVIDERS = exports.getProviderHealth = exports.updateModelProfile = exports.MODEL_PROFILES = exports.extractQueryFeatures = exports.recommendForTask = exports.routeBatch = exports.routeQuery = void 0;
|
|
5
|
+
exports.createProxyServer = exports.CostAnalytics = exports.GuardrailEngine = exports.SemanticCache = exports.MODEL_COSTS = exports.estimateTokens = exports.countTokens = exports.MemoryTree = exports.createBudgetEnforcer = exports.BudgetExceededError = exports.BudgetEnforcer = exports.CostTracker = exports.saveConfig = exports.loadConfig = exports.findFastestAvailableProvider = exports.findCheapestAvailableProvider = exports.checkAllProviders = exports.healthCheck = exports.updateProvider = exports.deregisterProvider = exports.registerProvider = exports.getAvailableProviders = exports.DEFAULT_PROVIDERS = exports.PROVIDER_CONTEXT_LIMITS = exports.DEFAULT_PROVIDER_CONFIG = exports.DEFAULT_RETRY_CONFIG = exports.getDefaultRetryHandler = exports.createRetryHandler = exports.ProviderRetryHandler = exports.getProviderHealth = exports.updateModelProfile = exports.MODEL_PROFILES = exports.extractQueryFeatures = exports.recommendForTask = exports.routeBatch = exports.routeQuery = void 0;
|
|
6
6
|
exports.createA3MRouter = createA3MRouter;
|
|
7
7
|
// ============================================================
|
|
8
8
|
// ROUTING ENGINE
|
|
@@ -16,6 +16,16 @@ Object.defineProperty(exports, "MODEL_PROFILES", { enumerable: true, get: functi
|
|
|
16
16
|
Object.defineProperty(exports, "updateModelProfile", { enumerable: true, get: function () { return advancedRouter_1.updateModelProfile; } });
|
|
17
17
|
Object.defineProperty(exports, "getProviderHealth", { enumerable: true, get: function () { return advancedRouter_1.getProviderHealth; } });
|
|
18
18
|
// ============================================================
|
|
19
|
+
// ROUTING
|
|
20
|
+
// ============================================================
|
|
21
|
+
var providerRetry_1 = require("./routing/providerRetry");
|
|
22
|
+
Object.defineProperty(exports, "ProviderRetryHandler", { enumerable: true, get: function () { return providerRetry_1.ProviderRetryHandler; } });
|
|
23
|
+
Object.defineProperty(exports, "createRetryHandler", { enumerable: true, get: function () { return providerRetry_1.createRetryHandler; } });
|
|
24
|
+
Object.defineProperty(exports, "getDefaultRetryHandler", { enumerable: true, get: function () { return providerRetry_1.getDefaultRetryHandler; } });
|
|
25
|
+
Object.defineProperty(exports, "DEFAULT_RETRY_CONFIG", { enumerable: true, get: function () { return providerRetry_1.DEFAULT_RETRY_CONFIG; } });
|
|
26
|
+
Object.defineProperty(exports, "DEFAULT_PROVIDER_CONFIG", { enumerable: true, get: function () { return providerRetry_1.DEFAULT_PROVIDER_CONFIG; } });
|
|
27
|
+
Object.defineProperty(exports, "PROVIDER_CONTEXT_LIMITS", { enumerable: true, get: function () { return providerRetry_1.PROVIDER_CONTEXT_LIMITS; } });
|
|
28
|
+
// ============================================================
|
|
19
29
|
// PROVIDERS
|
|
20
30
|
// ============================================================
|
|
21
31
|
var providerConfig_1 = require("./providers/providerConfig");
|
|
@@ -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, };
|
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A3M Router - Per-Provider Retry Logic
|
|
4
|
+
*
|
|
5
|
+
* Implements exponential backoff with jitter for transient errors,
|
|
6
|
+
* rate limit (429) handling with Retry-After header support,
|
|
7
|
+
* and context window validation before sending requests.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.PROVIDER_CONTEXT_LIMITS = exports.DEFAULT_RETRY_CONFIG = exports.ProviderRetryHandler = exports.DEFAULT_PROVIDER_CONFIG = void 0;
|
|
11
|
+
exports.createRetryHandler = createRetryHandler;
|
|
12
|
+
exports.getDefaultRetryHandler = getDefaultRetryHandler;
|
|
13
|
+
const tokenUtils_1 = require("../utils/tokenUtils");
|
|
14
|
+
// ============================================================
|
|
15
|
+
// DEFAULT CONFIGURATION
|
|
16
|
+
// ============================================================
|
|
17
|
+
const DEFAULT_RETRY_CONFIG = {
|
|
18
|
+
maxRetries: 3,
|
|
19
|
+
initialDelayMs: 1000,
|
|
20
|
+
maxDelayMs: 30000,
|
|
21
|
+
backoffMultiplier: 2,
|
|
22
|
+
retryableErrors: [
|
|
23
|
+
'ECONNRESET',
|
|
24
|
+
'ETIMEDOUT',
|
|
25
|
+
'ECONNREFUSED',
|
|
26
|
+
'503',
|
|
27
|
+
'429',
|
|
28
|
+
'500',
|
|
29
|
+
'502',
|
|
30
|
+
'504',
|
|
31
|
+
'NETWORK_ERROR',
|
|
32
|
+
'TIMEOUT',
|
|
33
|
+
'SOCKET_HANG_UP',
|
|
34
|
+
'EAI_AGAIN',
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
exports.DEFAULT_RETRY_CONFIG = DEFAULT_RETRY_CONFIG;
|
|
38
|
+
exports.DEFAULT_PROVIDER_CONFIG = {
|
|
39
|
+
// Chinese providers need longer timeouts and more retries
|
|
40
|
+
'deepseek': {
|
|
41
|
+
timeout: 30000,
|
|
42
|
+
retry: {
|
|
43
|
+
...DEFAULT_RETRY_CONFIG,
|
|
44
|
+
maxRetries: 5,
|
|
45
|
+
initialDelayMs: 2000,
|
|
46
|
+
},
|
|
47
|
+
rateLimitRetries: 3,
|
|
48
|
+
},
|
|
49
|
+
'zhipu': {
|
|
50
|
+
timeout: 25000,
|
|
51
|
+
retry: {
|
|
52
|
+
...DEFAULT_RETRY_CONFIG,
|
|
53
|
+
maxRetries: 4,
|
|
54
|
+
initialDelayMs: 1500,
|
|
55
|
+
},
|
|
56
|
+
rateLimitRetries: 3,
|
|
57
|
+
},
|
|
58
|
+
'qwen': {
|
|
59
|
+
timeout: 25000,
|
|
60
|
+
retry: {
|
|
61
|
+
...DEFAULT_RETRY_CONFIG,
|
|
62
|
+
maxRetries: 4,
|
|
63
|
+
},
|
|
64
|
+
rateLimitRetries: 3,
|
|
65
|
+
},
|
|
66
|
+
'moonshot': {
|
|
67
|
+
timeout: 25000,
|
|
68
|
+
retry: {
|
|
69
|
+
...DEFAULT_RETRY_CONFIG,
|
|
70
|
+
maxRetries: 4,
|
|
71
|
+
},
|
|
72
|
+
rateLimitRetries: 3,
|
|
73
|
+
},
|
|
74
|
+
'minimax': {
|
|
75
|
+
timeout: 20000,
|
|
76
|
+
retry: {
|
|
77
|
+
...DEFAULT_RETRY_CONFIG,
|
|
78
|
+
maxRetries: 3,
|
|
79
|
+
},
|
|
80
|
+
rateLimitRetries: 2,
|
|
81
|
+
},
|
|
82
|
+
'yi': {
|
|
83
|
+
timeout: 20000,
|
|
84
|
+
retry: {
|
|
85
|
+
...DEFAULT_RETRY_CONFIG,
|
|
86
|
+
maxRetries: 3,
|
|
87
|
+
},
|
|
88
|
+
rateLimitRetries: 2,
|
|
89
|
+
},
|
|
90
|
+
// US providers are faster
|
|
91
|
+
'openai': {
|
|
92
|
+
timeout: 15000,
|
|
93
|
+
retry: {
|
|
94
|
+
...DEFAULT_RETRY_CONFIG,
|
|
95
|
+
maxRetries: 3,
|
|
96
|
+
},
|
|
97
|
+
rateLimitRetries: 2,
|
|
98
|
+
},
|
|
99
|
+
'anthropic': {
|
|
100
|
+
timeout: 15000,
|
|
101
|
+
retry: {
|
|
102
|
+
...DEFAULT_RETRY_CONFIG,
|
|
103
|
+
maxRetries: 3,
|
|
104
|
+
},
|
|
105
|
+
rateLimitRetries: 2,
|
|
106
|
+
},
|
|
107
|
+
'groq': {
|
|
108
|
+
timeout: 10000,
|
|
109
|
+
retry: {
|
|
110
|
+
...DEFAULT_RETRY_CONFIG,
|
|
111
|
+
maxRetries: 2,
|
|
112
|
+
},
|
|
113
|
+
rateLimitRetries: 1,
|
|
114
|
+
},
|
|
115
|
+
'cerebras': {
|
|
116
|
+
timeout: 10000,
|
|
117
|
+
retry: {
|
|
118
|
+
...DEFAULT_RETRY_CONFIG,
|
|
119
|
+
maxRetries: 2,
|
|
120
|
+
},
|
|
121
|
+
rateLimitRetries: 1,
|
|
122
|
+
},
|
|
123
|
+
// Default fallback for unknown providers
|
|
124
|
+
'default': {
|
|
125
|
+
timeout: 15000,
|
|
126
|
+
retry: { ...DEFAULT_RETRY_CONFIG },
|
|
127
|
+
rateLimitRetries: 2,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
// Provider context window limits (approximate)
|
|
131
|
+
const PROVIDER_CONTEXT_LIMITS = {
|
|
132
|
+
'openai': 128000,
|
|
133
|
+
'anthropic': 200000,
|
|
134
|
+
'deepseek': 64000,
|
|
135
|
+
'qwen': 32000,
|
|
136
|
+
'zhipu': 128000,
|
|
137
|
+
'moonshot': 128000,
|
|
138
|
+
'minimax': 1000000,
|
|
139
|
+
'yi': 16000,
|
|
140
|
+
'groq': 32000,
|
|
141
|
+
'cerebras': 8000,
|
|
142
|
+
'default': 8192,
|
|
143
|
+
};
|
|
144
|
+
exports.PROVIDER_CONTEXT_LIMITS = PROVIDER_CONTEXT_LIMITS;
|
|
145
|
+
// ============================================================
|
|
146
|
+
// PROVIDER RETRY HANDLER
|
|
147
|
+
// ============================================================
|
|
148
|
+
class ProviderRetryHandler {
|
|
149
|
+
configs;
|
|
150
|
+
stats;
|
|
151
|
+
customProviders;
|
|
152
|
+
constructor(customConfigs) {
|
|
153
|
+
this.configs = new Map();
|
|
154
|
+
this.stats = new Map();
|
|
155
|
+
this.customProviders = new Set();
|
|
156
|
+
// Initialize with defaults
|
|
157
|
+
for (const [provider, config] of Object.entries(exports.DEFAULT_PROVIDER_CONFIG)) {
|
|
158
|
+
this.configs.set(provider, {
|
|
159
|
+
timeout: config.timeout,
|
|
160
|
+
retry: { ...config.retry },
|
|
161
|
+
rateLimitRetries: config.rateLimitRetries ?? 2,
|
|
162
|
+
});
|
|
163
|
+
this.initStats(provider);
|
|
164
|
+
}
|
|
165
|
+
// Apply custom configs
|
|
166
|
+
if (customConfigs) {
|
|
167
|
+
for (const [provider, config] of Object.entries(customConfigs)) {
|
|
168
|
+
this.configureProvider(provider, config);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
initStats(provider) {
|
|
173
|
+
this.stats.set(provider, {
|
|
174
|
+
totalRequests: 0,
|
|
175
|
+
successfulRequests: 0,
|
|
176
|
+
failedRequests: 0,
|
|
177
|
+
totalRetries: 0,
|
|
178
|
+
rateLimitRetries: 0,
|
|
179
|
+
averageLatencyMs: 0,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Configure or update a provider's retry settings
|
|
184
|
+
*/
|
|
185
|
+
configureProvider(provider, config) {
|
|
186
|
+
const existing = this.configs.get(provider) || {
|
|
187
|
+
timeout: 15000,
|
|
188
|
+
retry: { ...DEFAULT_RETRY_CONFIG },
|
|
189
|
+
rateLimitRetries: 2,
|
|
190
|
+
};
|
|
191
|
+
this.configs.set(provider, {
|
|
192
|
+
timeout: config.timeout ?? existing.timeout,
|
|
193
|
+
retry: {
|
|
194
|
+
...existing.retry,
|
|
195
|
+
...config.retry,
|
|
196
|
+
retryableErrors: config.retry?.retryableErrors ?? existing.retry.retryableErrors,
|
|
197
|
+
},
|
|
198
|
+
rateLimitRetries: config.rateLimitRetries ?? existing.rateLimitRetries,
|
|
199
|
+
});
|
|
200
|
+
if (!this.stats.has(provider)) {
|
|
201
|
+
this.initStats(provider);
|
|
202
|
+
}
|
|
203
|
+
this.customProviders.add(provider);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get current config for a provider
|
|
207
|
+
*/
|
|
208
|
+
getConfig(provider) {
|
|
209
|
+
return (this.configs.get(provider) ||
|
|
210
|
+
this.configs.get('default'));
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Execute a function with retry logic
|
|
214
|
+
*/
|
|
215
|
+
async executeWithRetry(provider, fn, options) {
|
|
216
|
+
const config = this.getConfig(provider);
|
|
217
|
+
const timeout = options?.timeout ?? config.timeout;
|
|
218
|
+
let lastError;
|
|
219
|
+
let attempts = 0;
|
|
220
|
+
for (let retryAttempt = 0; retryAttempt <= config.retry.maxRetries; retryAttempt++) {
|
|
221
|
+
attempts++;
|
|
222
|
+
try {
|
|
223
|
+
const result = await this.executeWithTimeout(fn, timeout);
|
|
224
|
+
// Success - update stats
|
|
225
|
+
this.recordSuccess(provider, 0);
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
lastError = error;
|
|
230
|
+
// Check if we've exhausted retries
|
|
231
|
+
if (retryAttempt >= config.retry.maxRetries) {
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
// Check if error is retryable
|
|
235
|
+
if (!this.isRetryableError(error)) {
|
|
236
|
+
this.recordFailure(provider, attempts - 1);
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
239
|
+
// Handle rate limiting (429)
|
|
240
|
+
const isRateLimit = this.isRateLimitError(error);
|
|
241
|
+
const rateLimitRetries = isRateLimit ? config.rateLimitRetries : 0;
|
|
242
|
+
if (isRateLimit && retryAttempt >= rateLimitRetries) {
|
|
243
|
+
// Exceeded rate limit retries
|
|
244
|
+
this.recordFailure(provider, attempts - 1);
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
// Calculate delay
|
|
248
|
+
const delayMs = this.calculateBackoffDelay(retryAttempt, config.retry, error);
|
|
249
|
+
// Notify callback if provided
|
|
250
|
+
if (options?.onRetry) {
|
|
251
|
+
options.onRetry(retryAttempt + 1, error, delayMs);
|
|
252
|
+
}
|
|
253
|
+
// Wait before retry
|
|
254
|
+
await this.sleep(delayMs);
|
|
255
|
+
this.recordRetry(provider, isRateLimit);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
this.recordFailure(provider, attempts - 1);
|
|
259
|
+
throw lastError;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Execute with custom timeout wrapper
|
|
263
|
+
*/
|
|
264
|
+
async executeWithTimeout(fn, timeoutMs) {
|
|
265
|
+
return new Promise((resolve, reject) => {
|
|
266
|
+
const timer = setTimeout(() => {
|
|
267
|
+
reject(this.createTimeoutError(timeoutMs));
|
|
268
|
+
}, timeoutMs);
|
|
269
|
+
fn()
|
|
270
|
+
.then((result) => {
|
|
271
|
+
clearTimeout(timer);
|
|
272
|
+
resolve(result);
|
|
273
|
+
})
|
|
274
|
+
.catch((error) => {
|
|
275
|
+
clearTimeout(timer);
|
|
276
|
+
reject(error);
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Check if an error should trigger a retry
|
|
282
|
+
*/
|
|
283
|
+
isRetryableError(error) {
|
|
284
|
+
if (!error)
|
|
285
|
+
return false;
|
|
286
|
+
const config = this.configs.get('default').retry;
|
|
287
|
+
const retryableErrors = config.retryableErrors || DEFAULT_RETRY_CONFIG.retryableErrors;
|
|
288
|
+
// Check error code/message
|
|
289
|
+
const errorCode = error.code || error.status || error.statusCode || '';
|
|
290
|
+
const errorMessage = error.message || '';
|
|
291
|
+
const errorString = String(errorCode).toUpperCase();
|
|
292
|
+
for (const retryable of retryableErrors) {
|
|
293
|
+
if (errorString.includes(retryable) ||
|
|
294
|
+
errorMessage.includes(retryable)) {
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Check for specific error patterns
|
|
299
|
+
if (error.status === 429)
|
|
300
|
+
return true;
|
|
301
|
+
if (error.status >= 500 && error.status < 600)
|
|
302
|
+
return true;
|
|
303
|
+
if (error.errno === 'ETIMEDOUT' || error.errno === 'ECONNRESET')
|
|
304
|
+
return true;
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Check if error is a rate limit (429)
|
|
309
|
+
*/
|
|
310
|
+
isRateLimitError(error) {
|
|
311
|
+
return error?.status === 429 || error?.statusCode === 429;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Calculate backoff delay with exponential increase and jitter
|
|
315
|
+
*/
|
|
316
|
+
calculateBackoffDelay(attempt, config, error) {
|
|
317
|
+
// Check for Retry-After header on 429
|
|
318
|
+
if (error && this.isRateLimitError(error)) {
|
|
319
|
+
const retryAfter = error.headers?.['retry-after'] || error.headers?.['Retry-After'];
|
|
320
|
+
if (retryAfter) {
|
|
321
|
+
const retryAfterMs = parseInt(String(retryAfter), 10) * 1000;
|
|
322
|
+
if (!isNaN(retryAfterMs) && retryAfterMs > 0) {
|
|
323
|
+
return Math.min(retryAfterMs, config.maxDelayMs);
|
|
324
|
+
}
|
|
325
|
+
// Could also be a date string - handle that case too
|
|
326
|
+
const retryAfterDate = new Date(retryAfter);
|
|
327
|
+
if (!isNaN(retryAfterDate.getTime())) {
|
|
328
|
+
const diffMs = retryAfterDate.getTime() - Date.now();
|
|
329
|
+
if (diffMs > 0) {
|
|
330
|
+
return Math.min(diffMs, config.maxDelayMs);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// Exponential backoff: initialDelay * (multiplier ^ attempt)
|
|
336
|
+
const baseDelay = config.initialDelayMs * Math.pow(config.backoffMultiplier, attempt);
|
|
337
|
+
// Cap at max delay
|
|
338
|
+
const cappedDelay = Math.min(baseDelay, config.maxDelayMs);
|
|
339
|
+
// Add jitter: delay *= (0.5 + random * 0.5) = delay * [0.5, 1.0]
|
|
340
|
+
const jitter = 0.5 + Math.random() * 0.5;
|
|
341
|
+
return Math.floor(cappedDelay * jitter);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Validate context window size before sending request
|
|
345
|
+
*/
|
|
346
|
+
validateContextWindow(provider, prompt, expectedTokens) {
|
|
347
|
+
// Use actual token count or estimate
|
|
348
|
+
const actualTokens = expectedTokens || (0, tokenUtils_1.estimateTokens)(prompt);
|
|
349
|
+
// Get provider's context limit
|
|
350
|
+
const contextLimit = PROVIDER_CONTEXT_LIMITS[provider] || PROVIDER_CONTEXT_LIMITS['default'];
|
|
351
|
+
// Estimate output tokens (rough guess: 25% of input for responses)
|
|
352
|
+
const estimatedOutputTokens = Math.floor(actualTokens * 0.25);
|
|
353
|
+
const totalTokens = actualTokens + estimatedOutputTokens;
|
|
354
|
+
if (totalTokens > contextLimit) {
|
|
355
|
+
// Find alternative providers with larger context
|
|
356
|
+
const largerProviders = Object.entries(PROVIDER_CONTEXT_LIMITS)
|
|
357
|
+
.filter(([name, limit]) => name !== provider && limit > contextLimit)
|
|
358
|
+
.sort(([, a], [, b]) => b - a);
|
|
359
|
+
const suggested = largerProviders.length > 0 ? largerProviders[0][0] : undefined;
|
|
360
|
+
return {
|
|
361
|
+
valid: false,
|
|
362
|
+
reason: `Context window exceeded: ${totalTokens} tokens (estimated) > ${contextLimit} limit for ${provider}`,
|
|
363
|
+
suggestedProvider: suggested,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
return { valid: true };
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Get retry statistics for a provider
|
|
370
|
+
*/
|
|
371
|
+
getStats(provider) {
|
|
372
|
+
return this.stats.get(provider) || this.initStats(provider);
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Get all provider stats
|
|
376
|
+
*/
|
|
377
|
+
getAllStats() {
|
|
378
|
+
const result = {};
|
|
379
|
+
for (const [provider, stats] of this.stats.entries()) {
|
|
380
|
+
result[provider] = stats;
|
|
381
|
+
}
|
|
382
|
+
return result;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Reset stats for a provider
|
|
386
|
+
*/
|
|
387
|
+
resetStats(provider) {
|
|
388
|
+
if (provider) {
|
|
389
|
+
this.initStats(provider);
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
for (const provider of this.configs.keys()) {
|
|
393
|
+
this.initStats(provider);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
// ============================================================
|
|
398
|
+
// PRIVATE HELPERS
|
|
399
|
+
// ============================================================
|
|
400
|
+
createTimeoutError(timeoutMs) {
|
|
401
|
+
const error = new Error(`Request timed out after ${timeoutMs}ms`);
|
|
402
|
+
error.code = 'ETIMEDOUT';
|
|
403
|
+
error.status = 408;
|
|
404
|
+
error.statusCode = 408;
|
|
405
|
+
return error;
|
|
406
|
+
}
|
|
407
|
+
sleep(ms) {
|
|
408
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
409
|
+
}
|
|
410
|
+
recordSuccess(provider, latencyMs) {
|
|
411
|
+
const stats = this.stats.get(provider);
|
|
412
|
+
if (!stats)
|
|
413
|
+
return;
|
|
414
|
+
stats.totalRequests++;
|
|
415
|
+
stats.successfulRequests++;
|
|
416
|
+
// Running average for latency
|
|
417
|
+
if (latencyMs > 0) {
|
|
418
|
+
const totalLatency = stats.averageLatencyMs * (stats.totalRequests - 1) + latencyMs;
|
|
419
|
+
stats.averageLatencyMs = totalLatency / stats.totalRequests;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
recordFailure(provider, retryCount) {
|
|
423
|
+
const stats = this.stats.get(provider);
|
|
424
|
+
if (!stats)
|
|
425
|
+
return;
|
|
426
|
+
stats.totalRequests++;
|
|
427
|
+
stats.failedRequests++;
|
|
428
|
+
stats.totalRetries += retryCount;
|
|
429
|
+
}
|
|
430
|
+
recordRetry(provider, isRateLimit) {
|
|
431
|
+
const stats = this.stats.get(provider);
|
|
432
|
+
if (!stats)
|
|
433
|
+
return;
|
|
434
|
+
stats.totalRetries++;
|
|
435
|
+
if (isRateLimit) {
|
|
436
|
+
stats.rateLimitRetries++;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
exports.ProviderRetryHandler = ProviderRetryHandler;
|
|
441
|
+
// ============================================================
|
|
442
|
+
// CONVENIENCE FUNCTIONS
|
|
443
|
+
// ============================================================
|
|
444
|
+
/**
|
|
445
|
+
* Create a retry handler with optional custom configs
|
|
446
|
+
*/
|
|
447
|
+
function createRetryHandler(customConfigs) {
|
|
448
|
+
return new ProviderRetryHandler(customConfigs);
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Default retry handler instance (singleton)
|
|
452
|
+
*/
|
|
453
|
+
let defaultHandler = null;
|
|
454
|
+
function getDefaultRetryHandler() {
|
|
455
|
+
if (!defaultHandler) {
|
|
456
|
+
defaultHandler = new ProviderRetryHandler();
|
|
457
|
+
}
|
|
458
|
+
return defaultHandler;
|
|
459
|
+
}
|
|
460
|
+
//# sourceMappingURL=providerRetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerRetry.js","sourceRoot":"","sources":["../../src/routing/providerRetry.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adaptive-memory-multi-model-router",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"shortName": "A3M Router",
|
|
5
5
|
"displayName": "A3M Router - Adaptive Memory Multi-Model Router",
|
|
6
6
|
"description": "LLM router & AI gateway — 99.5% routing accuracy, 47 providers (DeepSeek, Kimi/Moonshot, Qwen, Zhipu GLM, Yi + more). Semantic cache, guardrails, cost analytics. Built on 30+ arXiv papers (SGLang, Medusa, MemoRAG). Zero ML, 19.5KB. TypeScript + Python SDK. MIT.",
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,24 @@ export {
|
|
|
14
14
|
getProviderHealth,
|
|
15
15
|
} from './routing/advancedRouter';
|
|
16
16
|
|
|
17
|
+
// ============================================================
|
|
18
|
+
// ROUTING
|
|
19
|
+
// ============================================================
|
|
20
|
+
export {
|
|
21
|
+
ProviderRetryHandler,
|
|
22
|
+
createRetryHandler,
|
|
23
|
+
getDefaultRetryHandler,
|
|
24
|
+
DEFAULT_RETRY_CONFIG,
|
|
25
|
+
DEFAULT_PROVIDER_CONFIG,
|
|
26
|
+
PROVIDER_CONTEXT_LIMITS,
|
|
27
|
+
} from './routing/providerRetry';
|
|
28
|
+
export type {
|
|
29
|
+
RetryConfig,
|
|
30
|
+
ProviderRetryConfig,
|
|
31
|
+
RetryStats,
|
|
32
|
+
ContextWindowValidation,
|
|
33
|
+
} from './routing/providerRetry';
|
|
34
|
+
|
|
17
35
|
// ============================================================
|
|
18
36
|
// PROVIDERS
|
|
19
37
|
// ============================================================
|