adaptive-memory-multi-model-router 2.2.5 → 2.2.6

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.
Files changed (63) hide show
  1. package/README.md +17 -22
  2. package/README.md.bak +836 -0
  3. package/dist/analytics/costAnalytics.d.ts +1 -0
  4. package/dist/cache/cacheKeyGenerator.d.ts +67 -0
  5. package/dist/cache/cacheKeyGenerator.d.ts.map +1 -0
  6. package/dist/cache/cacheKeyGenerator.js +211 -0
  7. package/dist/cache/cacheKeyGenerator.js.map +1 -0
  8. package/dist/cache/semanticCache.d.ts +41 -0
  9. package/dist/cache/semanticCache.d.ts.map +1 -1
  10. package/dist/cache/semanticCache.js +142 -0
  11. package/dist/cache/semanticCache.js.map +1 -1
  12. package/dist/cli.js +35 -478
  13. package/dist/cost/costTracker.js +0 -3
  14. package/dist/cost/preCallCostEstimator.d.ts +114 -0
  15. package/dist/cost/preCallCostEstimator.d.ts.map +1 -0
  16. package/dist/cost/preCallCostEstimator.js +256 -0
  17. package/dist/cost/preCallCostEstimator.js.map +1 -0
  18. package/dist/index.d.ts +16 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +264 -64
  21. package/dist/index.js.map +1 -1
  22. package/dist/inference/speculativeDecoding.d.ts +133 -0
  23. package/dist/inference/speculativeDecoding.d.ts.map +1 -0
  24. package/dist/inference/speculativeDecoding.js +276 -0
  25. package/dist/inference/speculativeDecoding.js.map +1 -0
  26. package/dist/integrations/langchainAdapter.d.ts +1 -0
  27. package/dist/integrations/oauth.d.ts +1 -0
  28. package/dist/memory/autoFetch.d.ts +1 -0
  29. package/dist/memory/memoryTree.d.ts +1 -0
  30. package/dist/memory/obsidianVault.d.ts +1 -0
  31. package/dist/providers/providerConfig.d.ts +1 -0
  32. package/dist/providers/providerConfig.js +2 -0
  33. package/dist/providers/providerHealth.d.ts +117 -0
  34. package/dist/providers/providerHealth.d.ts.map +1 -0
  35. package/dist/providers/providerHealth.js +309 -0
  36. package/dist/providers/providerHealth.js.map +1 -0
  37. package/dist/providers/registry.js +126 -128
  38. package/dist/routing/advancedRouter.js +310 -427
  39. package/dist/routing/difficultyClassifier.d.ts +79 -0
  40. package/dist/routing/difficultyClassifier.d.ts.map +1 -0
  41. package/dist/routing/difficultyClassifier.js +329 -0
  42. package/dist/routing/difficultyClassifier.js.map +1 -0
  43. package/dist/sdk.d.ts +125 -0
  44. package/dist/sdk.d.ts.map +1 -0
  45. package/dist/sdk.js +109 -100
  46. package/dist/sdk.js.map +1 -0
  47. package/dist/security/guardrails.d.ts +1 -0
  48. package/dist/server/dashboard.d.ts +1 -0
  49. package/dist/server/modelMapper.d.ts +1 -0
  50. package/dist/server/proxyServer.d.ts +1 -0
  51. package/package.json +4 -2
  52. package/src/cache/cacheKeyGenerator.ts +242 -0
  53. package/src/cache/semanticCache.ts +148 -0
  54. package/src/cost/preCallCostEstimator.ts +345 -0
  55. package/src/inference/speculativeDecoding.ts +373 -0
  56. package/src/providers/providerHealth.ts +397 -0
  57. package/src/routing/difficultyClassifier.ts +420 -0
  58. package/test/provider-test.js +2 -2
  59. package/test.js +7 -7
  60. package/test.js.bak +376 -0
  61. package/tsconfig.json +15 -5
  62. package/src/index.ts +0 -99
  63. package/src/skills/__tests__/skill_manager.test.ts +0 -328
@@ -0,0 +1,309 @@
1
+ "use strict";
2
+ /**
3
+ * A3M Router - Provider Health Score
4
+ *
5
+ * Probabilistic health scoring (not binary up/down).
6
+ * Uses latency history, error rate, partial failure patterns, queue depth estimates.
7
+ *
8
+ * Usage:
9
+ * const healthMonitor = new ProviderHealthMonitor();
10
+ * healthMonitor.recordLatency('groq', 250);
11
+ * healthMonitor.recordError('groq', 'rate_limit');
12
+ * const score = healthMonitor.getHealthScore('groq');
13
+ * console.log(score); // { score: 0.85, confidence: 0.7, status: 'healthy' }
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.ProviderHealthMonitor = void 0;
17
+ exports.createProviderHealthMonitor = createProviderHealthMonitor;
18
+ const DEFAULT_CONFIG = {
19
+ latencyAlpha: 0.3,
20
+ errorAlpha: 0.2,
21
+ anomalyWindow: 20,
22
+ anomalyThreshold: 2.0,
23
+ healthyThreshold: 0.75,
24
+ degradedThreshold: 0.4,
25
+ };
26
+ // ============================================================
27
+ // ProviderHealthMonitor
28
+ // ============================================================
29
+ class ProviderHealthMonitor {
30
+ records = new Map();
31
+ config;
32
+ ewmaLatency = new Map();
33
+ ewmaErrorRate = new Map();
34
+ anomalyScores = new Map();
35
+ constructor(config = {}) {
36
+ this.config = { ...DEFAULT_CONFIG, ...config };
37
+ }
38
+ /**
39
+ * Record a successful request with latency.
40
+ */
41
+ recordSuccess(providerId, latencyMs) {
42
+ this.addRecord(providerId, {
43
+ timestamp: Date.now(),
44
+ latency: latencyMs,
45
+ success: true,
46
+ });
47
+ this.updateEwmaLatency(providerId, latencyMs);
48
+ this.updateEwmaErrorRate(providerId, false);
49
+ this.updateAnomalyScore(providerId, latencyMs);
50
+ }
51
+ /**
52
+ * Record a failed request.
53
+ */
54
+ recordError(providerId, errorType = 'unknown') {
55
+ this.addRecord(providerId, {
56
+ timestamp: Date.now(),
57
+ success: false,
58
+ errorType,
59
+ });
60
+ this.updateEwmaErrorRate(providerId, true);
61
+ }
62
+ /**
63
+ * Record a partial failure (slow response, incomplete output, etc).
64
+ */
65
+ recordPartialFailure(providerId, latencyMs) {
66
+ this.addRecord(providerId, {
67
+ timestamp: Date.now(),
68
+ latency: latencyMs,
69
+ success: false,
70
+ partialFailure: true,
71
+ });
72
+ if (latencyMs !== undefined) {
73
+ this.updateEwmaLatency(providerId, latencyMs);
74
+ this.updateAnomalyScore(providerId, latencyMs);
75
+ }
76
+ // Partial failures count as half an error
77
+ this.updateEwmaErrorRate(providerId, false, 0.5);
78
+ }
79
+ /**
80
+ * Record queue depth estimate (when available from provider metadata).
81
+ */
82
+ recordQueueDepth(providerId, depth) {
83
+ // Queue depth affects latency estimation but doesn't directly
84
+ // impact the health score unless it's extremely high
85
+ const maxQueueDepth = 100;
86
+ const queueFactor = 1 + Math.min(depth / maxQueueDepth, 1.0) * 0.5;
87
+ const currentLatency = this.ewmaLatency.get(providerId) || 0;
88
+ if (currentLatency > 0) {
89
+ this.ewmaLatency.set(providerId, currentLatency * queueFactor);
90
+ }
91
+ }
92
+ /**
93
+ * Get the current health score for a provider.
94
+ */
95
+ getHealthScore(providerId) {
96
+ const records = this.getRecords(providerId);
97
+ const sampleSize = records.length;
98
+ const now = Date.now();
99
+ // Not enough data
100
+ if (sampleSize < 3) {
101
+ return {
102
+ score: sampleSize === 0 ? 1.0 : 0.8,
103
+ confidence: sampleSize / 10, // 0 at 0 samples, 0.3 at 3 samples
104
+ status: sampleSize === 0 ? 'healthy' : 'degraded',
105
+ components: { latency: 1.0, errorRate: 1.0, recentTrend: 1.0 },
106
+ lastUpdated: now,
107
+ metadata: { sampleSize, isAnomaly: false },
108
+ };
109
+ }
110
+ const latencyScore = this.calculateLatencyScore(providerId);
111
+ const errorScore = this.calculateErrorScore(providerId);
112
+ const trendScore = this.calculateTrendScore(providerId);
113
+ // Weighted combination
114
+ const score = latencyScore * 0.35 +
115
+ errorScore * 0.45 +
116
+ trendScore * 0.20;
117
+ // Determine status
118
+ let status;
119
+ if (score >= this.config.healthyThreshold) {
120
+ status = 'healthy';
121
+ }
122
+ else if (score >= this.config.degradedThreshold) {
123
+ status = 'degraded';
124
+ }
125
+ else {
126
+ status = 'critical';
127
+ }
128
+ // Anomaly detection
129
+ const anomalyScore = this.anomalyScores.get(providerId) || 0;
130
+ const isAnomaly = anomalyScore > this.config.anomalyThreshold;
131
+ const anomalyReason = isAnomaly
132
+ ? `Anomaly detected: score ${anomalyScore.toFixed(2)} > threshold ${this.config.anomalyThreshold}`
133
+ : undefined;
134
+ // Confidence based on sample size and anomaly status
135
+ const baseConfidence = Math.min(sampleSize / 30, 1.0);
136
+ const confidence = isAnomaly
137
+ ? Math.min(baseConfidence * 0.5, 0.5) // Lower confidence when anomalous
138
+ : baseConfidence;
139
+ return {
140
+ score: Math.round(score * 1000) / 1000,
141
+ confidence: Math.round(confidence * 1000) / 1000,
142
+ status,
143
+ components: {
144
+ latency: Math.round(latencyScore * 1000) / 1000,
145
+ errorRate: Math.round(errorScore * 1000) / 1000,
146
+ recentTrend: Math.round(trendScore * 1000) / 1000,
147
+ },
148
+ lastUpdated: now,
149
+ metadata: {
150
+ sampleSize,
151
+ isAnomaly,
152
+ anomalyReason,
153
+ },
154
+ };
155
+ }
156
+ /**
157
+ * Get health scores for all tracked providers.
158
+ */
159
+ getAllHealthScores() {
160
+ const result = {};
161
+ for (const providerId of this.records.keys()) {
162
+ result[providerId] = this.getHealthScore(providerId);
163
+ }
164
+ return result;
165
+ }
166
+ /**
167
+ * Get the recommended provider based on health scores.
168
+ * Excludes providers that are 'critical'.
169
+ */
170
+ getRecommendedProvider(providers) {
171
+ const candidates = providers.filter(p => {
172
+ const score = this.getHealthScore(p.id);
173
+ return score.status !== 'critical';
174
+ });
175
+ if (candidates.length === 0)
176
+ return null;
177
+ // Sort by health score, then by priority (if available)
178
+ candidates.sort((a, b) => {
179
+ const scoreA = this.getHealthScore(a.id).score;
180
+ const scoreB = this.getHealthScore(b.id).score;
181
+ if (Math.abs(scoreA - scoreB) > 0.1) {
182
+ return scoreB - scoreA; // Higher score first
183
+ }
184
+ return (a.priority || 50) - (b.priority || 50); // Lower priority first
185
+ });
186
+ return candidates[0].id;
187
+ }
188
+ /**
189
+ * Clear all records for a provider.
190
+ */
191
+ clearProvider(providerId) {
192
+ this.records.delete(providerId);
193
+ this.ewmaLatency.delete(providerId);
194
+ this.ewmaErrorRate.delete(providerId);
195
+ this.anomalyScores.delete(providerId);
196
+ }
197
+ /**
198
+ * Clear all records for all providers.
199
+ */
200
+ clearAll() {
201
+ this.records.clear();
202
+ this.ewmaLatency.clear();
203
+ this.ewmaErrorRate.clear();
204
+ this.anomalyScores.clear();
205
+ }
206
+ // ---- Private methods ----
207
+ addRecord(providerId, record) {
208
+ if (!this.records.has(providerId)) {
209
+ this.records.set(providerId, []);
210
+ }
211
+ const records = this.records.get(providerId);
212
+ records.push(record);
213
+ // Keep only recent records (last hour)
214
+ const oneHourAgo = Date.now() - 3600000;
215
+ const filtered = records.filter(r => r.timestamp >= oneHourAgo);
216
+ this.records.set(providerId, filtered);
217
+ }
218
+ getRecords(providerId) {
219
+ return this.records.get(providerId) || [];
220
+ }
221
+ updateEwmaLatency(providerId, latency) {
222
+ const current = this.ewmaLatency.get(providerId);
223
+ if (current === undefined) {
224
+ this.ewmaLatency.set(providerId, latency);
225
+ }
226
+ else {
227
+ this.ewmaLatency.set(providerId, this.config.latencyAlpha * latency + (1 - this.config.latencyAlpha) * current);
228
+ }
229
+ }
230
+ updateEwmaErrorRate(providerId, isError, weight = 1.0) {
231
+ const current = this.ewmaErrorRate.get(providerId) || 0;
232
+ const errorValue = isError ? 1.0 * weight : 0;
233
+ if (current === 0 && !isError) {
234
+ this.ewmaErrorRate.set(providerId, 0);
235
+ }
236
+ else {
237
+ this.ewmaErrorRate.set(providerId, this.config.errorAlpha * errorValue + (1 - this.config.errorAlpha) * current);
238
+ }
239
+ }
240
+ updateAnomalyScore(providerId, latency) {
241
+ const records = this.getRecords(providerId).filter(r => r.latency !== undefined);
242
+ if (records.length < 3)
243
+ return;
244
+ // Calculate standard deviation of recent latencies
245
+ const recentLatencies = records
246
+ .slice(-this.config.anomalyWindow)
247
+ .map(r => r.latency)
248
+ .filter(l => l !== undefined);
249
+ if (recentLatencies.length < 3)
250
+ return;
251
+ const mean = recentLatencies.reduce((a, b) => a + b, 0) / recentLatencies.length;
252
+ const variance = recentLatencies.reduce((sum, l) => sum + Math.pow(l - mean, 2), 0) /
253
+ recentLatencies.length;
254
+ const stdDev = Math.sqrt(variance);
255
+ // Z-score of current latency
256
+ const zScore = stdDev > 0 ? Math.abs(latency - mean) / stdDev : 0;
257
+ // Update anomaly score with decay
258
+ const currentScore = this.anomalyScores.get(providerId) || 0;
259
+ const newScore = currentScore * 0.9 + zScore * 0.1;
260
+ this.anomalyScores.set(providerId, newScore);
261
+ }
262
+ calculateLatencyScore(providerId) {
263
+ const latency = this.ewmaLatency.get(providerId);
264
+ if (latency === undefined)
265
+ return 1.0;
266
+ // Score based on latency brackets (ms)
267
+ // Tier-appropriate expectations
268
+ if (latency < 200)
269
+ return 1.0;
270
+ if (latency < 500)
271
+ return 0.95;
272
+ if (latency < 800)
273
+ return 0.85;
274
+ if (latency < 1500)
275
+ return 0.7;
276
+ if (latency < 3000)
277
+ return 0.5;
278
+ return Math.max(0.1, 1 - latency / 10000);
279
+ }
280
+ calculateErrorScore(providerId) {
281
+ const errorRate = this.ewmaErrorRate.get(providerId) || 0;
282
+ // Score: 1 - errorRate, but with floor
283
+ return Math.max(0.05, 1 - errorRate);
284
+ }
285
+ calculateTrendScore(providerId) {
286
+ const records = this.getRecords(providerId).filter(r => r.latency !== undefined);
287
+ if (records.length < 5)
288
+ return 1.0;
289
+ // Compare recent 5 vs previous 5
290
+ const recent = records.slice(-5);
291
+ const previous = records.slice(-10, -5);
292
+ if (previous.length === 0)
293
+ return 1.0;
294
+ const recentAvg = recent.reduce((sum, r) => sum + (r.latency || 0), 0) / recent.length;
295
+ const previousAvg = previous.reduce((sum, r) => sum + (r.latency || 0), 0) / previous.length;
296
+ // If improving (lower latency), score > 1
297
+ // If degrading, score < 1
298
+ const ratio = previousAvg / recentAvg;
299
+ return Math.min(1.2, Math.max(0.6, ratio));
300
+ }
301
+ }
302
+ exports.ProviderHealthMonitor = ProviderHealthMonitor;
303
+ // ============================================================
304
+ // Factory
305
+ // ============================================================
306
+ function createProviderHealthMonitor(config) {
307
+ return new ProviderHealthMonitor(config);
308
+ }
309
+ //# sourceMappingURL=providerHealth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerHealth.js","sourceRoot":"","sources":["../../src/providers/providerHealth.ts"],"names":[],"mappings":"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"}
@@ -1,140 +1,138 @@
1
1
  "use strict";
2
2
  /**
3
- * A3M Router - Generic Provider Registry
4
- *
5
- * Dynamically discovers and manages available LLM providers.
6
- * Users configure providers via:
7
- * - Environment variables (*_API_KEY patterns)
8
- * - ~/.config/a3m-router/providers.json
9
- * - Runtime registration via registerProvider()
10
- *
11
- * No hardcoded provider references - all loaded from providerConfig.
3
+ * TMLPD Provider Registry
4
+ *
5
+ * Manages provider configurations, API keys, and base URLs.
12
6
  */
13
-
14
- const { getAvailableProviders, loadConfig, healthCheck, registerProvider, deregisterProvider } = require("./providerConfig");
15
- const { routeQuery, routeBatch, recommendForTask, extractQueryFeatures, MODEL_PROFILES } = require("../routing/advancedRouter");
16
-
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.ProviderRegistry = void 0;
9
+ const DEFAULT_PROVIDER_CONFIG = {
10
+ providers: ["openai", "openrouter", "groq", "cerebras", "mistral", "xai", "zai", "anthropic", "google"],
11
+ modelPriority: ["openai/gpt-4o", "groq/llama-3.3-70b-versatile", "cerebras/llama-3.3-70b"],
12
+ useOpenclawFallback: false,
13
+ maxTokens: 4096,
14
+ };
17
15
  class ProviderRegistry {
18
- constructor(config = {}) {
19
- this.config = config;
20
- this.providers = new Map();
21
- this.readyCache = [];
22
- this.cacheTime = 0;
23
- this.cacheDuration = 60000; // 1 minute
24
-
25
- // Load configuration from env vars and config files
26
- loadConfig();
27
- this.initializeProviders();
28
- }
29
-
30
- initializeProviders() {
31
- const available = getAvailableProviders();
32
-
33
- for (const [name, provider] of Object.entries(available)) {
34
- this.providers.set(name, {
35
- name,
36
- apiKey: provider.apiKey || null,
37
- baseUrl: provider.baseUrl || null,
38
- models: provider.models,
39
- type: provider.type,
40
- priority: provider.priority,
41
- enabled: true,
42
- cooldownUntil: 0,
43
- failureCount: 0,
44
- });
16
+ providers = new Map();
17
+ config;
18
+ modelPriority;
19
+ constructor(config = {}) {
20
+ this.config = { ...DEFAULT_PROVIDER_CONFIG, ...config };
21
+ this.modelPriority = this.config.modelPriority;
22
+ this.initializeProviders();
23
+ }
24
+ initializeProviders() {
25
+ // Initialize from environment
26
+ const envVars = {
27
+ openai: { key: "OPENAI_API_KEY", url: "OPENAI_OPENAI_BASE_URL", mode: "openai" },
28
+ openrouter: { key: "OPENROUTER_API_KEY", url: "OPENROUTER_OPENAI_BASE_URL", mode: "openai" },
29
+ groq: { key: "GROQ_API_KEY", url: "GROQ_OPENAI_BASE_URL", mode: "openai" },
30
+ cerebras: { key: "CEREBRAS_API_KEY", url: "CEREBRAS_OPENAI_BASE_URL", mode: "openai" },
31
+ mistral: { key: "MISTRAL_API_KEY", url: "MISTRAL_OPENAI_BASE_URL", mode: "openai" },
32
+ xai: { key: "XAI_API_KEY", url: "XAI_OPENAI_BASE_URL", mode: "openai" },
33
+ zai: { key: "ZAI_API_KEY", url: "ZAI_OPENAI_BASE_URL", mode: "anthropic" },
34
+ anthropic: { key: "ANTHROPIC_API_KEY", url: "ANTHROPIC_BASE_URL", mode: "anthropic" },
35
+ google: { key: "GOOGLE_API_KEY", url: "GOOGLE_GEMINI_BASE_URL", mode: "gemini" },
36
+ };
37
+ for (const [name, env] of Object.entries(envVars)) {
38
+ const apiKey = process.env[env.key] || "";
39
+ const baseUrl = process.env[env.url] || "";
40
+ this.providers.set(name, {
41
+ name,
42
+ apiKey,
43
+ baseUrl,
44
+ mode: env.mode,
45
+ priority: this.modelPriority.findIndex((m) => m.startsWith(name + "/")),
46
+ enabled: Boolean(apiKey),
47
+ cooldownUntil: 0,
48
+ failureCount: 0,
49
+ lastError: null,
50
+ lastStatus: null,
51
+ });
52
+ }
45
53
  }
46
- }
47
-
48
- isProviderReady(name) {
49
- const provider = this.providers.get(name);
50
- if (!provider || !provider.enabled) return false;
51
- if (Date.now() < provider.cooldownUntil) return false;
52
- return true;
53
- }
54
-
55
- getReadyProviders() {
56
- const now = Date.now();
57
- if (now - this.cacheTime < this.cacheDuration && this.readyCache.length > 0) {
58
- return this.readyCache;
54
+ /**
55
+ * Check if provider is ready (has API key, not in cooldown)
56
+ */
57
+ isProviderReady(name) {
58
+ const provider = this.providers.get(name);
59
+ if (!provider || !provider.enabled)
60
+ return false;
61
+ if (Date.now() < provider.cooldownUntil)
62
+ return false;
63
+ return true;
59
64
  }
60
-
61
- this.readyCache = Array.from(this.providers.entries())
62
- .filter(([_, p]) => this.isProviderReady(p.name))
63
- .map(([name]) => name);
64
- this.cacheTime = now;
65
- return this.readyCache;
66
- }
67
-
68
- selectModel() {
69
- const available = getAvailableProviders();
70
- const sorted = Object.entries(available).sort(([, a], [, b]) => a.priority - b.priority);
71
-
72
- for (const [name, provider] of sorted) {
73
- for (const model of provider.models) {
74
- const modelKey = model.includes('/') ? model : name + '/' + model;
75
- if (this.isProviderReady(name)) {
76
- return modelKey;
65
+ /**
66
+ * Get best available model from priority list
67
+ */
68
+ selectModel() {
69
+ for (const model of this.modelPriority) {
70
+ const providerName = model.split("/")[0];
71
+ if (this.isProviderReady(providerName)) {
72
+ return model;
73
+ }
77
74
  }
78
- }
75
+ return null;
79
76
  }
80
- return null;
81
- }
82
-
83
- recordSuccess(name) {
84
- const provider = this.providers.get(name);
85
- if (provider) {
86
- provider.failureCount = 0;
87
- provider.cooldownUntil = 0;
77
+ /**
78
+ * Get all providers sorted by priority
79
+ */
80
+ getReadyProviders() {
81
+ return Array.from(this.providers.entries())
82
+ .filter(([_, p]) => this.isProviderReady(p.name))
83
+ .sort((a, b) => a[1].priority - b[1].priority)
84
+ .map(([name]) => name);
88
85
  }
89
- }
90
-
91
- recordFailure(name) {
92
- const provider = this.providers.get(name);
93
- if (provider) {
94
- provider.failureCount++;
95
- if (provider.failureCount >= 3) {
96
- provider.cooldownUntil = Date.now() + 60000;
97
- }
86
+ /**
87
+ * Record provider success
88
+ */
89
+ recordSuccess(name) {
90
+ const provider = this.providers.get(name);
91
+ if (provider) {
92
+ provider.cooldownUntil = 0;
93
+ provider.failureCount = 0;
94
+ provider.lastError = null;
95
+ provider.lastStatus = null;
96
+ }
98
97
  }
99
- }
100
-
101
- getStatus() {
102
- const available = getAvailableProviders();
103
- return {
104
- providers: Array.from(this.providers.keys()),
105
- available: Object.keys(available),
106
- ready: this.getReadyProviders(),
107
- modelPriority: this.selectModel(),
108
- };
109
- }
110
-
111
- // Dynamic provider management
112
- addProvider(id, config) {
113
- registerProvider(id, config);
114
- this.initializeProviders();
115
- }
116
-
117
- removeProvider(id) {
118
- deregisterProvider(id);
119
- this.initializeProviders();
120
- }
121
-
122
- async checkHealth() {
123
- const results = {};
124
- for (const [name] of this.providers) {
125
- results[name] = await healthCheck(name);
98
+ /**
99
+ * Record provider failure
100
+ */
101
+ recordFailure(name, statusCode, error) {
102
+ const provider = this.providers.get(name);
103
+ if (!provider)
104
+ return;
105
+ provider.failureCount++;
106
+ provider.lastError = error;
107
+ provider.lastStatus = statusCode;
108
+ // Apply exponential backoff cooldown
109
+ const baseDelay = statusCode === 429 ? 60000 : statusCode === 403 ? 300000 : 30000;
110
+ const multiplier = Math.min(4, Math.pow(2, Math.max(0, provider.failureCount - 1)));
111
+ provider.cooldownUntil = Date.now() + baseDelay * multiplier;
112
+ }
113
+ /**
114
+ * Get provider status summary
115
+ */
116
+ getStatus() {
117
+ const status = {};
118
+ for (const [name, provider] of this.providers.entries()) {
119
+ status[name] = {
120
+ enabled: provider.enabled,
121
+ mode: provider.mode,
122
+ ready: this.isProviderReady(name),
123
+ cooldownUntil: provider.cooldownUntil ? new Date(provider.cooldownUntil).toISOString() : null,
124
+ lastError: provider.lastError,
125
+ lastStatus: provider.lastStatus,
126
+ failureCount: provider.failureCount,
127
+ };
128
+ }
129
+ return {
130
+ modelPriority: this.modelPriority,
131
+ readyProviders: this.getReadyProviders(),
132
+ providers: status,
133
+ timestamp: new Date().toISOString(),
134
+ };
126
135
  }
127
- return results;
128
- }
129
136
  }
130
-
131
- const _routing = require("../routing/advancedRouter");
132
-
133
- module.exports = {
134
- ProviderRegistry,
135
- routeQuery: _routing.routeQuery,
136
- routeBatch: _routing.routeBatch,
137
- recommendForTask: _routing.recommendForTask,
138
- extractQueryFeatures: _routing.extractQueryFeatures,
139
- MODEL_PROFILES: _routing.MODEL_PROFILES,
140
- };
137
+ exports.ProviderRegistry = ProviderRegistry;
138
+ //# sourceMappingURL=registry.js.map