adaptive-memory-multi-model-router 2.14.16 → 2.14.18
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/.a3m-vault.json +23 -0
- package/.github/workflows/ci.yml +253 -5
- package/.publish-tick +1 -1
- package/AGENT_COUNCIL_FINDINGS.md +142 -0
- package/LAUNCH_CHECKLIST.md +141 -0
- package/README.md +15 -17
- package/README.md.bak +836 -0
- package/articles/CHINESE_SUBMISSIONS_READY.md +322 -0
- package/articles/DEVTO_READY.md +255 -0
- package/articles/HN_POST_READY.md +137 -0
- package/articles/INDIEHACKERS_READY.md +120 -0
- package/articles/NEWSLETTER_SEND_NOW.md +259 -0
- package/articles/PRODUCTHUNT_READY.md +106 -0
- package/articles/REDDIT_SUBMISSION_READY.md +348 -0
- package/articles/TWEET_STORM_READY.md +165 -0
- package/benchmark-results.json +45 -43
- package/council-votes/architecture-vote.md +121 -0
- package/council-votes/coverage-vote.md +93 -0
- package/dist/cost/costTracker.d.ts +109 -44
- package/dist/cost/costTracker.js +321 -98
- package/dist/cost/costTracker.js.map +1 -1
- package/dist/ensemble.d.ts +21 -0
- package/dist/ensemble.js +85 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.js +12 -4
- package/dist/routing/advancedRouter.d.ts +38 -43
- package/dist/routing/advancedRouter.js +394 -408
- package/dist/routing/advancedRouter.js.map +1 -1
- package/dist/routing/providers/providerConfig.d.ts +49 -0
- package/dist/routing/providers/providerConfig.js +883 -0
- package/dist/routing/routing/advancedRouter.d.ts +62 -0
- package/dist/routing/routing/advancedRouter.js +447 -0
- package/dist/routing/utils/tokenUtils.d.ts +52 -0
- package/dist/routing/utils/tokenUtils.js +129 -0
- package/dist/server/proxyServer.d.ts +1 -1
- package/dist/tui/dashboard.js +66 -2
- package/dist/tui/dashboard.js.map +1 -1
- package/dist/utils/tokenUtils.d.ts +48 -1
- package/dist/utils/tokenUtils.js +117 -4
- package/dist/utils/tokenUtils.js.map +1 -1
- package/docs/CITATIONS.md +2 -2
- package/docs/GEO_STATUS.md +43 -157
- package/docs/ai-plugin.json +4 -4
- package/docs/llms.txt +21 -27
- package/docs/sitemap.xml +14 -20
- package/package.json +2 -2
- package/research-log.md +49 -0
- package/sitemap.xml +57 -0
- package/src/cost/costTracker.ts +576 -0
- package/src/ensemble.ts +103 -0
- package/src/index.ts +13 -3
- package/src/routing/advancedRouter.ts +536 -0
- package/src/tui/dashboard.ts +76 -3
- package/src/utils/tokenUtils.ts +142 -4
- package/test-council/1-structure-tests.test.js +353 -0
- package/test-council/1-structure-tests.test.ts +353 -0
- package/test-council/2-edge-case-tests.test.ts +361 -0
- package/test-council/3-performance-tests.test.ts +669 -0
- package/test-council/4-integration-tests.test.ts +391 -0
- package/test-council/5-agent-council-eval.test.ts +413 -0
- package/test-council/AGENT_COUNCIL_ARCHITECTURE.md +349 -0
- package/test-council/TEST_COUNCIL_REPORT.md +201 -0
- package/test-council/agents/edge-case-agent.ts +363 -0
- package/test-council/agents/performance-agent.ts +426 -0
- package/test-council/agents/structure-agent.ts +227 -0
- package/test-council/council.md +183 -0
- package/tests/security/guardrailEngine.test.ts +700 -0
- package/docs/.well-known/ai-plugin.json +0 -16
- package/research/PUBLISH_LOG.md +0 -3
package/dist/ensemble.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EnsembleOrchestrator = void 0;
|
|
4
|
+
class EnsembleOrchestrator {
|
|
5
|
+
router;
|
|
6
|
+
constructor(router) {
|
|
7
|
+
this.router = router;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Executes a query across multiple providers in parallel and resolves the best answer.
|
|
11
|
+
*/
|
|
12
|
+
async executeEnsemble(query, providers, strategy = 'majority', weights = {}) {
|
|
13
|
+
// 1. Parallel Execution
|
|
14
|
+
const results = await Promise.all(providers.map(async (p) => {
|
|
15
|
+
try {
|
|
16
|
+
const res = await this.router.chat(query, { model: p });
|
|
17
|
+
return { provider: p, answer: res.choices[0].message.content, success: true };
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
return { provider: p, answer: '', success: false };
|
|
21
|
+
}
|
|
22
|
+
}));
|
|
23
|
+
const successful = results.filter(r => r.success);
|
|
24
|
+
const answers = successful.map(r => r.answer.trim());
|
|
25
|
+
if (answers.length === 0) {
|
|
26
|
+
throw new Error('All ensemble providers failed.');
|
|
27
|
+
}
|
|
28
|
+
// 2. Voting Logic
|
|
29
|
+
let winnerAnswer = '';
|
|
30
|
+
let winnerProvider = '';
|
|
31
|
+
let confidence = 0;
|
|
32
|
+
if (strategy === 'majority') {
|
|
33
|
+
const counts = {};
|
|
34
|
+
successful.forEach(r => counts[r.answer] = (counts[r.answer] || 0) + 1);
|
|
35
|
+
const sorted = Object.entries(counts).sort((a, b) => b[1] - a[1]);
|
|
36
|
+
winnerAnswer = sorted[0][0];
|
|
37
|
+
confidence = sorted[0][1] / successful.length;
|
|
38
|
+
winnerProvider = successful.find(r => r.answer === winnerAnswer)?.provider || 'unknown';
|
|
39
|
+
}
|
|
40
|
+
else if (strategy === 'weighted') {
|
|
41
|
+
const weightedCounts = {};
|
|
42
|
+
successful.forEach(r => {
|
|
43
|
+
const weight = weights[r.provider] || 1.0;
|
|
44
|
+
weightedCounts[r.answer] = (weightedCounts[r.answer] || 0) + weight;
|
|
45
|
+
});
|
|
46
|
+
const sorted = Object.entries(weightedCounts).sort((a, b) => b[1] - a[1]);
|
|
47
|
+
winnerAnswer = sorted[0][0];
|
|
48
|
+
confidence = sorted[0][1] / (successful.length || 1); // Simplified
|
|
49
|
+
winnerProvider = successful.find(r => r.answer === winnerAnswer)?.provider || 'unknown';
|
|
50
|
+
}
|
|
51
|
+
else if (strategy === 'conservative') {
|
|
52
|
+
const counts = {};
|
|
53
|
+
successful.forEach(r => counts[r.answer] = (counts[r.answer] || 0) + 1);
|
|
54
|
+
const best = Object.entries(counts).sort((a, b) => b[1] - a[1])[0];
|
|
55
|
+
if (best && best[1] >= 2) {
|
|
56
|
+
winnerAnswer = best[0];
|
|
57
|
+
confidence = best[1] / successful.length;
|
|
58
|
+
winnerProvider = successful.find(r => r.answer === winnerAnswer)?.provider || 'unknown';
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
winnerAnswer = 'UNCERTAIN';
|
|
62
|
+
confidence = 0;
|
|
63
|
+
winnerProvider = 'none';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// 3. Final Assembly
|
|
67
|
+
const allResults = {};
|
|
68
|
+
successful.forEach(r => {
|
|
69
|
+
allResults[r.provider] = {
|
|
70
|
+
answer: r.answer,
|
|
71
|
+
score: r.answer === winnerAnswer ? 1.0 : 0.0
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
finalAnswer: winnerAnswer,
|
|
76
|
+
confidence: confidence,
|
|
77
|
+
isUncertain: confidence < 0.6 || winnerAnswer === 'UNCERTAIN',
|
|
78
|
+
winner: winnerProvider,
|
|
79
|
+
allResults,
|
|
80
|
+
reasoning: `Ensemble of ${successful.length} models. ${Math.round(confidence * 100)}% agreement.`
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.EnsembleOrchestrator = EnsembleOrchestrator;
|
|
85
|
+
//# sourceMappingURL=ensemble.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -9,15 +9,18 @@ export type { BudgetConfig, SpendRecord, BudgetCheckResult } from './cost/budget
|
|
|
9
9
|
export { MemoryTree } from './memory/memoryTree';
|
|
10
10
|
export type { MemoryChunk, TreeNode } from './memory/memoryTree';
|
|
11
11
|
export { countTokens, estimateTokens } from './utils/tokenUtils';
|
|
12
|
-
export { MODEL_COSTS } from './utils/tokenUtils';
|
|
13
12
|
export { SemanticCache } from './cache/semanticCache';
|
|
14
13
|
export { GuardrailEngine } from './security/guardrails';
|
|
15
14
|
export { CostAnalytics } from './analytics/costAnalytics';
|
|
16
15
|
export { createProxyServer } from './server/proxyServer';
|
|
17
16
|
export { Tracer, getTracer, createTracer, MetricsCollector, getMetrics, createMetricsCollector, observabilityMiddleware, observabilityPlugin, budgetAlertMiddleware, } from './observability';
|
|
18
17
|
export type { Span, Metric, RouteTrace, ObservabilityEvent } from './observability';
|
|
18
|
+
export { EnsembleOrchestrator, EnsembleStrategy, EnsembleResponse } from './ensemble';
|
|
19
|
+
import { routeQuery, routeBatch, recommendForTask } from './routing/advancedRouter';
|
|
19
20
|
import { getAvailableProviders, healthCheck } from './providers/providerConfig';
|
|
21
|
+
import { CostTracker } from './cost/costTracker';
|
|
20
22
|
import { MemoryTree } from './memory/memoryTree';
|
|
23
|
+
import { EnsembleOrchestrator } from './ensemble';
|
|
21
24
|
export interface A3MRouterOptions {
|
|
22
25
|
defaultProvider?: string;
|
|
23
26
|
enableCache?: boolean;
|
|
@@ -25,13 +28,14 @@ export interface A3MRouterOptions {
|
|
|
25
28
|
costLimit?: number;
|
|
26
29
|
}
|
|
27
30
|
export declare function createA3MRouter(options?: A3MRouterOptions): {
|
|
28
|
-
route:
|
|
29
|
-
routeBatch:
|
|
30
|
-
recommendForTask:
|
|
31
|
+
route: typeof routeQuery;
|
|
32
|
+
routeBatch: typeof routeBatch;
|
|
33
|
+
recommendForTask: typeof recommendForTask;
|
|
31
34
|
getAvailableProviders: typeof getAvailableProviders;
|
|
32
35
|
healthCheck: typeof healthCheck;
|
|
33
|
-
costTracker:
|
|
36
|
+
costTracker: CostTracker;
|
|
34
37
|
memoryTree: MemoryTree;
|
|
38
|
+
ensemble: EnsembleOrchestrator;
|
|
35
39
|
options: A3MRouterOptions;
|
|
36
40
|
};
|
|
37
41
|
export default createA3MRouter;
|
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.budgetAlertMiddleware = exports.observabilityPlugin = exports.observabilityMiddleware = exports.createMetricsCollector = exports.getMetrics = exports.MetricsCollector = exports.createTracer = exports.getTracer = exports.Tracer = exports.createProxyServer = exports.CostAnalytics = exports.GuardrailEngine = exports.SemanticCache = exports.
|
|
5
|
+
exports.EnsembleOrchestrator = exports.budgetAlertMiddleware = exports.observabilityPlugin = exports.observabilityMiddleware = exports.createMetricsCollector = exports.getMetrics = exports.MetricsCollector = exports.createTracer = exports.getTracer = exports.Tracer = exports.createProxyServer = exports.CostAnalytics = exports.GuardrailEngine = exports.SemanticCache = 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
|
|
@@ -60,8 +60,6 @@ Object.defineProperty(exports, "MemoryTree", { enumerable: true, get: function (
|
|
|
60
60
|
var tokenUtils_1 = require("./utils/tokenUtils");
|
|
61
61
|
Object.defineProperty(exports, "countTokens", { enumerable: true, get: function () { return tokenUtils_1.countTokens; } });
|
|
62
62
|
Object.defineProperty(exports, "estimateTokens", { enumerable: true, get: function () { return tokenUtils_1.estimateTokens; } });
|
|
63
|
-
var tokenUtils_2 = require("./utils/tokenUtils");
|
|
64
|
-
Object.defineProperty(exports, "MODEL_COSTS", { enumerable: true, get: function () { return tokenUtils_2.MODEL_COSTS; } });
|
|
65
63
|
// ============================================================
|
|
66
64
|
// v2.0.0 FEATURES
|
|
67
65
|
// ============================================================
|
|
@@ -87,16 +85,22 @@ Object.defineProperty(exports, "observabilityMiddleware", { enumerable: true, ge
|
|
|
87
85
|
Object.defineProperty(exports, "observabilityPlugin", { enumerable: true, get: function () { return observability_1.observabilityPlugin; } });
|
|
88
86
|
Object.defineProperty(exports, "budgetAlertMiddleware", { enumerable: true, get: function () { return observability_1.budgetAlertMiddleware; } });
|
|
89
87
|
// ============================================================
|
|
88
|
+
// ENSEMBLE ORCHESTRATION
|
|
89
|
+
// ============================================================
|
|
90
|
+
var ensemble_1 = require("./ensemble");
|
|
91
|
+
Object.defineProperty(exports, "EnsembleOrchestrator", { enumerable: true, get: function () { return ensemble_1.EnsembleOrchestrator; } });
|
|
92
|
+
// ============================================================
|
|
90
93
|
// CONVENIENCE: Create a router instance
|
|
91
94
|
// ============================================================
|
|
92
95
|
const advancedRouter_2 = require("./routing/advancedRouter");
|
|
93
96
|
const providerConfig_2 = require("./providers/providerConfig");
|
|
94
97
|
const costTracker_2 = require("./cost/costTracker");
|
|
95
98
|
const memoryTree_2 = require("./memory/memoryTree");
|
|
99
|
+
const ensemble_2 = require("./ensemble");
|
|
96
100
|
function createA3MRouter(options) {
|
|
97
101
|
const costTracker = new costTracker_2.CostTracker();
|
|
98
102
|
const memoryTree = new memoryTree_2.MemoryTree();
|
|
99
|
-
|
|
103
|
+
const router = {
|
|
100
104
|
route: advancedRouter_2.routeQuery,
|
|
101
105
|
routeBatch: advancedRouter_2.routeBatch,
|
|
102
106
|
recommendForTask: advancedRouter_2.recommendForTask,
|
|
@@ -104,8 +108,12 @@ function createA3MRouter(options) {
|
|
|
104
108
|
healthCheck: providerConfig_2.healthCheck,
|
|
105
109
|
costTracker,
|
|
106
110
|
memoryTree,
|
|
111
|
+
ensemble: new ensemble_2.EnsembleOrchestrator(null), // Lazy initialization or pass router instance
|
|
107
112
|
options: options || {},
|
|
108
113
|
};
|
|
114
|
+
// Properly link the orchestrator back to the router methods
|
|
115
|
+
router.ensemble.router = router;
|
|
116
|
+
return router;
|
|
109
117
|
}
|
|
110
118
|
// Default export
|
|
111
119
|
exports.default = createA3MRouter;
|
|
@@ -1,68 +1,63 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* A3M Router - Generic Adaptive Routing (RouteLLM Style)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Routes queries to the best available LLM based on:
|
|
5
|
+
* - Query features (code, math, creative, etc.)
|
|
6
|
+
* - Provider availability (checks API keys)
|
|
7
|
+
* - Cost optimization
|
|
8
|
+
* - Quality vs speed tradeoff
|
|
9
|
+
*
|
|
10
|
+
* All provider references are dynamically loaded from providerConfig.
|
|
11
|
+
* Users can add/remove providers via environment variables or config files.
|
|
6
12
|
*/
|
|
7
|
-
|
|
8
|
-
complexity: number;
|
|
9
|
-
length: number;
|
|
10
|
-
has_code: boolean;
|
|
11
|
-
has_math: boolean;
|
|
12
|
-
is_multilingual: boolean;
|
|
13
|
-
is_creative: boolean;
|
|
14
|
-
requires_reasoning: boolean;
|
|
15
|
-
}
|
|
16
|
-
export interface ModelProfile {
|
|
13
|
+
interface ModelProfile {
|
|
17
14
|
name: string;
|
|
18
15
|
provider: string;
|
|
16
|
+
providerName: string;
|
|
19
17
|
cost_per_1k_input: number;
|
|
20
18
|
cost_per_1k_output: number;
|
|
21
19
|
latency_ms: number;
|
|
22
20
|
quality_score: number;
|
|
23
21
|
strengths: string[];
|
|
24
22
|
context_window: number;
|
|
23
|
+
type: string;
|
|
24
|
+
priority: number;
|
|
25
|
+
}
|
|
26
|
+
export declare let MODEL_PROFILES: Record<string, ModelProfile>;
|
|
27
|
+
export interface QueryFeatures {
|
|
28
|
+
length: number;
|
|
29
|
+
wordCount: number;
|
|
30
|
+
complexity: number;
|
|
31
|
+
has_code: boolean;
|
|
32
|
+
requires_reasoning: boolean;
|
|
33
|
+
is_multilingual: boolean;
|
|
34
|
+
is_translation: boolean;
|
|
35
|
+
domain: string | null;
|
|
36
|
+
intent: string;
|
|
37
|
+
detected_language: string | null;
|
|
25
38
|
}
|
|
39
|
+
export declare function extractQueryFeatures(prompt: string): QueryFeatures;
|
|
26
40
|
export interface RouteDecision {
|
|
27
|
-
primary_model: string;
|
|
41
|
+
primary_model: string | null;
|
|
28
42
|
fallback_models: string[];
|
|
29
43
|
confidence: number;
|
|
30
44
|
reasoning: string;
|
|
31
45
|
estimated_cost: number;
|
|
32
46
|
estimated_latency_ms: number;
|
|
47
|
+
features?: QueryFeatures;
|
|
48
|
+
provider_type?: string;
|
|
33
49
|
}
|
|
34
|
-
export declare const MODEL_PROFILES: Record<string, ModelProfile>;
|
|
35
|
-
/**
|
|
36
|
-
* Extract features from prompt for routing decision
|
|
37
|
-
*/
|
|
38
|
-
export declare function extractQueryFeatures(prompt: string): QueryFeatures;
|
|
39
|
-
/**
|
|
40
|
-
* RouteLLM-style learned routing decision
|
|
41
|
-
*/
|
|
42
50
|
export declare function routeQuery(prompt: string, available_models?: string[], budget_multiplier?: number): RouteDecision;
|
|
43
|
-
/**
|
|
44
|
-
* Batch routing for multiple prompts
|
|
45
|
-
*/
|
|
46
51
|
export declare function routeBatch(prompts: string[], options?: {
|
|
47
52
|
same_model?: boolean;
|
|
48
53
|
max_cost_per_prompt?: number;
|
|
49
|
-
balance_cost?: boolean;
|
|
50
54
|
}): RouteDecision[];
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
* Update model profile from execution feedback (online learning)
|
|
57
|
-
*/
|
|
58
|
-
export declare function updateModelProfile(model_name: string, actual_latency_ms: number, actual_cost: number, quality_rating: number): void;
|
|
59
|
-
declare const _default: {
|
|
60
|
-
extractQueryFeatures: typeof extractQueryFeatures;
|
|
61
|
-
routeQuery: typeof routeQuery;
|
|
62
|
-
routeBatch: typeof routeBatch;
|
|
63
|
-
recommendForTask: typeof recommendForTask;
|
|
64
|
-
updateModelProfile: typeof updateModelProfile;
|
|
65
|
-
MODEL_PROFILES: Record<string, ModelProfile>;
|
|
55
|
+
export declare function recommendForTask(task: string): {
|
|
56
|
+
primary: string;
|
|
57
|
+
fallbacks: string[];
|
|
58
|
+
reason: string;
|
|
59
|
+
features: QueryFeatures;
|
|
66
60
|
};
|
|
67
|
-
export
|
|
68
|
-
|
|
61
|
+
export declare function updateModelProfile(model_name: string, actual_latency_ms: number, actual_cost: number, quality_rating: number): void;
|
|
62
|
+
export declare function getProviderHealth(): Promise<any>;
|
|
63
|
+
export {};
|