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.
Files changed (69) hide show
  1. package/.a3m-vault.json +23 -0
  2. package/.github/workflows/ci.yml +253 -5
  3. package/.publish-tick +1 -1
  4. package/AGENT_COUNCIL_FINDINGS.md +142 -0
  5. package/LAUNCH_CHECKLIST.md +141 -0
  6. package/README.md +15 -17
  7. package/README.md.bak +836 -0
  8. package/articles/CHINESE_SUBMISSIONS_READY.md +322 -0
  9. package/articles/DEVTO_READY.md +255 -0
  10. package/articles/HN_POST_READY.md +137 -0
  11. package/articles/INDIEHACKERS_READY.md +120 -0
  12. package/articles/NEWSLETTER_SEND_NOW.md +259 -0
  13. package/articles/PRODUCTHUNT_READY.md +106 -0
  14. package/articles/REDDIT_SUBMISSION_READY.md +348 -0
  15. package/articles/TWEET_STORM_READY.md +165 -0
  16. package/benchmark-results.json +45 -43
  17. package/council-votes/architecture-vote.md +121 -0
  18. package/council-votes/coverage-vote.md +93 -0
  19. package/dist/cost/costTracker.d.ts +109 -44
  20. package/dist/cost/costTracker.js +321 -98
  21. package/dist/cost/costTracker.js.map +1 -1
  22. package/dist/ensemble.d.ts +21 -0
  23. package/dist/ensemble.js +85 -0
  24. package/dist/index.d.ts +9 -5
  25. package/dist/index.js +12 -4
  26. package/dist/routing/advancedRouter.d.ts +38 -43
  27. package/dist/routing/advancedRouter.js +394 -408
  28. package/dist/routing/advancedRouter.js.map +1 -1
  29. package/dist/routing/providers/providerConfig.d.ts +49 -0
  30. package/dist/routing/providers/providerConfig.js +883 -0
  31. package/dist/routing/routing/advancedRouter.d.ts +62 -0
  32. package/dist/routing/routing/advancedRouter.js +447 -0
  33. package/dist/routing/utils/tokenUtils.d.ts +52 -0
  34. package/dist/routing/utils/tokenUtils.js +129 -0
  35. package/dist/server/proxyServer.d.ts +1 -1
  36. package/dist/tui/dashboard.js +66 -2
  37. package/dist/tui/dashboard.js.map +1 -1
  38. package/dist/utils/tokenUtils.d.ts +48 -1
  39. package/dist/utils/tokenUtils.js +117 -4
  40. package/dist/utils/tokenUtils.js.map +1 -1
  41. package/docs/CITATIONS.md +2 -2
  42. package/docs/GEO_STATUS.md +43 -157
  43. package/docs/ai-plugin.json +4 -4
  44. package/docs/llms.txt +21 -27
  45. package/docs/sitemap.xml +14 -20
  46. package/package.json +2 -2
  47. package/research-log.md +49 -0
  48. package/sitemap.xml +57 -0
  49. package/src/cost/costTracker.ts +576 -0
  50. package/src/ensemble.ts +103 -0
  51. package/src/index.ts +13 -3
  52. package/src/routing/advancedRouter.ts +536 -0
  53. package/src/tui/dashboard.ts +76 -3
  54. package/src/utils/tokenUtils.ts +142 -4
  55. package/test-council/1-structure-tests.test.js +353 -0
  56. package/test-council/1-structure-tests.test.ts +353 -0
  57. package/test-council/2-edge-case-tests.test.ts +361 -0
  58. package/test-council/3-performance-tests.test.ts +669 -0
  59. package/test-council/4-integration-tests.test.ts +391 -0
  60. package/test-council/5-agent-council-eval.test.ts +413 -0
  61. package/test-council/AGENT_COUNCIL_ARCHITECTURE.md +349 -0
  62. package/test-council/TEST_COUNCIL_REPORT.md +201 -0
  63. package/test-council/agents/edge-case-agent.ts +363 -0
  64. package/test-council/agents/performance-agent.ts +426 -0
  65. package/test-council/agents/structure-agent.ts +227 -0
  66. package/test-council/council.md +183 -0
  67. package/tests/security/guardrailEngine.test.ts +700 -0
  68. package/docs/.well-known/ai-plugin.json +0 -16
  69. package/research/PUBLISH_LOG.md +0 -3
@@ -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: any;
29
- routeBatch: any;
30
- recommendForTask: any;
31
+ route: typeof routeQuery;
32
+ routeBatch: typeof routeBatch;
33
+ recommendForTask: typeof recommendForTask;
31
34
  getAvailableProviders: typeof getAvailableProviders;
32
35
  healthCheck: typeof healthCheck;
33
- costTracker: any;
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.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;
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
- return {
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
- * TMLPD Advanced Routing - RouteLLM Style
2
+ * A3M Router - Generic Adaptive Routing (RouteLLM Style)
3
3
  *
4
- * Learned routing based on arXiv:2404.06035 (RouteLLM)
5
- * Balances cost-quality tradeoff with confidence-based model selection
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
- export interface QueryFeatures {
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
- * Get model recommendation for task type
53
- */
54
- export declare function recommendForTask(task: string): string[];
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 default _default;
68
- //# sourceMappingURL=advancedRouter.d.ts.map
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 {};