adaptive-memory-multi-model-router 2.5.5 → 2.7.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 +165 -24
- 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 +2 -0
- package/dist/index.js +5 -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/sdk.d.ts +124 -0
- package/dist/sdk.js +109 -100
- package/docs/UPDATE_TOPICS.md +15 -0
- package/package.json +164 -3
- package/src/cache/semanticCache.ts +293 -103
- package/src/cost/budgetEnforcer.ts +358 -0
- package/src/index.ts +2 -0
- package/src/routing/providerHealth.ts +483 -0
- package/test/test_budgetEnforcer.ts +310 -0
- package/test/test_providerHealth.ts +523 -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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"}
|
package/dist/sdk.d.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A3M Router TypeScript SDK
|
|
3
|
+
*
|
|
4
|
+
* Clean wrapper class providing a better DX than raw exports.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { A3MRouter } from 'adaptive-memory-multi-model-router/sdk';
|
|
8
|
+
*
|
|
9
|
+
* const router = new A3MRouter();
|
|
10
|
+
*
|
|
11
|
+
* // Route a query (no execution, just model selection)
|
|
12
|
+
* const decision = router.route("What is 2+2?");
|
|
13
|
+
* console.log(decision.model, decision.tier, decision.cost);
|
|
14
|
+
*
|
|
15
|
+
* // Start the OpenAI-compatible proxy server
|
|
16
|
+
* const proxyURL = await router.serve(8787);
|
|
17
|
+
*
|
|
18
|
+
* // Use with any OpenAI SDK
|
|
19
|
+
* import OpenAI from 'openai';
|
|
20
|
+
* const client = new OpenAI({ baseURL: router.proxyURL });
|
|
21
|
+
* const response = await client.chat.completions.create({
|
|
22
|
+
* model: 'auto',
|
|
23
|
+
* messages: [{ role: 'user', content: 'Hello' }]
|
|
24
|
+
* });
|
|
25
|
+
*/
|
|
26
|
+
export interface RoutingResult {
|
|
27
|
+
/** Selected model identifier (e.g. "groq/llama-3.3-70b-versatile") */
|
|
28
|
+
model: string;
|
|
29
|
+
/** Cost tier classification */
|
|
30
|
+
tier: 'free' | 'cheap' | 'mid' | 'premium';
|
|
31
|
+
/** Estimated cost in USD */
|
|
32
|
+
cost: number;
|
|
33
|
+
/** Complexity score 0.0–1.0 */
|
|
34
|
+
complexity: number;
|
|
35
|
+
/** Human-readable reasoning for the selection */
|
|
36
|
+
reasoning: string;
|
|
37
|
+
/** Alternative models in priority order */
|
|
38
|
+
fallbackModels: string[];
|
|
39
|
+
/** Whether the selected model is free */
|
|
40
|
+
isFree: boolean;
|
|
41
|
+
/** Whether this is classified as an expert-level query */
|
|
42
|
+
isExpert: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface QueryFeatures {
|
|
45
|
+
complexity: number;
|
|
46
|
+
length: number;
|
|
47
|
+
has_code: boolean;
|
|
48
|
+
has_math: boolean;
|
|
49
|
+
is_multilingual: boolean;
|
|
50
|
+
is_translation: boolean;
|
|
51
|
+
is_creative: boolean;
|
|
52
|
+
requires_reasoning: boolean;
|
|
53
|
+
is_security: boolean;
|
|
54
|
+
is_devops: boolean;
|
|
55
|
+
is_data: boolean;
|
|
56
|
+
detected_domain: string;
|
|
57
|
+
domain_score: number;
|
|
58
|
+
}
|
|
59
|
+
export interface A3MRouterConfig {
|
|
60
|
+
/** Default model to use when routing is ambiguous */
|
|
61
|
+
defaultModel?: string;
|
|
62
|
+
/** Maximum cost per query in USD (routes to cheaper models if exceeded) */
|
|
63
|
+
maxCostPerQuery?: number;
|
|
64
|
+
/** Prefer fast responses over higher quality */
|
|
65
|
+
preferSpeedOverQuality?: boolean;
|
|
66
|
+
/** Restrict routing to these provider IDs */
|
|
67
|
+
providers?: string[];
|
|
68
|
+
}
|
|
69
|
+
export declare class A3MRouter {
|
|
70
|
+
private config;
|
|
71
|
+
private _proxyURL;
|
|
72
|
+
constructor(config?: A3MRouterConfig);
|
|
73
|
+
/**
|
|
74
|
+
* Route a query — returns model selection without executing it.
|
|
75
|
+
*
|
|
76
|
+
* @param query - The user prompt to route
|
|
77
|
+
* @returns Routing decision with model, tier, cost, complexity
|
|
78
|
+
*/
|
|
79
|
+
route(query: string): RoutingResult;
|
|
80
|
+
/**
|
|
81
|
+
* Route multiple queries in batch.
|
|
82
|
+
*
|
|
83
|
+
* @param queries - Array of user prompts
|
|
84
|
+
* @returns Array of routing decisions
|
|
85
|
+
*/
|
|
86
|
+
routeBatch(queries: string[]): RoutingResult[];
|
|
87
|
+
/**
|
|
88
|
+
* Get model recommendation for a task description.
|
|
89
|
+
*
|
|
90
|
+
* @param task - Task description (e.g. "code generation", "summarization")
|
|
91
|
+
* @returns Routing decision
|
|
92
|
+
*/
|
|
93
|
+
recommend(task: string): RoutingResult;
|
|
94
|
+
/**
|
|
95
|
+
* Start the OpenAI-compatible proxy server.
|
|
96
|
+
*
|
|
97
|
+
* @param port - Port to listen on (default: 8787)
|
|
98
|
+
* @returns The proxy base URL (e.g. "http://localhost:8787/v1")
|
|
99
|
+
*/
|
|
100
|
+
serve(port?: number): Promise<string>;
|
|
101
|
+
/**
|
|
102
|
+
* Get the proxy URL. Available after serve() is called,
|
|
103
|
+
* otherwise returns the default.
|
|
104
|
+
*/
|
|
105
|
+
get proxyURL(): string;
|
|
106
|
+
/**
|
|
107
|
+
* Extract features from a query for debugging or analysis.
|
|
108
|
+
*
|
|
109
|
+
* @param query - The user prompt to analyze
|
|
110
|
+
* @returns Detailed feature breakdown
|
|
111
|
+
*/
|
|
112
|
+
analyze(query: string): QueryFeatures;
|
|
113
|
+
/**
|
|
114
|
+
* Classify a complexity score into a named tier.
|
|
115
|
+
*/
|
|
116
|
+
private classifyTier;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Convenience: create an A3MRouter instance.
|
|
120
|
+
*
|
|
121
|
+
* @param config - Optional configuration
|
|
122
|
+
* @returns Configured A3MRouter instance
|
|
123
|
+
*/
|
|
124
|
+
export declare function createSDK(config?: A3MRouterConfig): A3MRouter;
|