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
package/dist/sdk.js
CHANGED
|
@@ -5,118 +5,127 @@
|
|
|
5
5
|
* Clean wrapper class providing a better DX than raw exports.
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
|
-
*
|
|
8
|
+
* import { A3MRouter } from 'adaptive-memory-multi-model-router/sdk';
|
|
9
|
+
*
|
|
9
10
|
* const router = new A3MRouter();
|
|
11
|
+
*
|
|
12
|
+
* // Route a query (no execution, just model selection)
|
|
10
13
|
* const decision = router.route("What is 2+2?");
|
|
11
14
|
* console.log(decision.model, decision.tier, decision.cost);
|
|
15
|
+
*
|
|
16
|
+
* // Start the OpenAI-compatible proxy server
|
|
17
|
+
* const proxyURL = await router.serve(8787);
|
|
18
|
+
*
|
|
19
|
+
* // Use with any OpenAI SDK
|
|
20
|
+
* import OpenAI from 'openai';
|
|
21
|
+
* const client = new OpenAI({ baseURL: router.proxyURL });
|
|
22
|
+
* const response = await client.chat.completions.create({
|
|
23
|
+
* model: 'auto',
|
|
24
|
+
* messages: [{ role: 'user', content: 'Hello' }]
|
|
25
|
+
* });
|
|
12
26
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.A3MRouter = void 0;
|
|
29
|
+
exports.createSDK = createSDK;
|
|
30
|
+
const advancedRouter_1 = require("./routing/advancedRouter");
|
|
31
|
+
const proxyServer_1 = require("./server/proxyServer");
|
|
17
32
|
// ============================================================
|
|
18
33
|
// A3MRouter SDK Class
|
|
19
34
|
// ============================================================
|
|
20
|
-
|
|
21
35
|
class A3MRouter {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (complexity < 0.65) return 'mid';
|
|
107
|
-
return 'premium';
|
|
108
|
-
}
|
|
36
|
+
config;
|
|
37
|
+
_proxyURL = null;
|
|
38
|
+
constructor(config = {}) {
|
|
39
|
+
this.config = config;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Route a query — returns model selection without executing it.
|
|
43
|
+
*
|
|
44
|
+
* @param query - The user prompt to route
|
|
45
|
+
* @returns Routing decision with model, tier, cost, complexity
|
|
46
|
+
*/
|
|
47
|
+
route(query) {
|
|
48
|
+
const features = (0, advancedRouter_1.extractQueryFeatures)(query);
|
|
49
|
+
const result = (0, advancedRouter_1.routeQuery)(query, this.config.providers);
|
|
50
|
+
return {
|
|
51
|
+
model: result.primary_model || 'unknown',
|
|
52
|
+
tier: this.classifyTier(features.complexity),
|
|
53
|
+
cost: result.estimated_cost || 0,
|
|
54
|
+
complexity: features.complexity,
|
|
55
|
+
reasoning: result.reasoning || '',
|
|
56
|
+
fallbackModels: result.fallback_models || [],
|
|
57
|
+
isFree: (result.estimated_cost || 0) === 0,
|
|
58
|
+
isExpert: features.complexity >= 0.65,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Route multiple queries in batch.
|
|
63
|
+
*
|
|
64
|
+
* @param queries - Array of user prompts
|
|
65
|
+
* @returns Array of routing decisions
|
|
66
|
+
*/
|
|
67
|
+
routeBatch(queries) {
|
|
68
|
+
(0, advancedRouter_1.routeBatch)(queries); // warm the internal cache
|
|
69
|
+
return queries.map((q) => this.route(q));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get model recommendation for a task description.
|
|
73
|
+
*
|
|
74
|
+
* @param task - Task description (e.g. "code generation", "summarization")
|
|
75
|
+
* @returns Routing decision
|
|
76
|
+
*/
|
|
77
|
+
recommend(task) {
|
|
78
|
+
(0, advancedRouter_1.recommendForTask)(task);
|
|
79
|
+
return this.route(task);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Start the OpenAI-compatible proxy server.
|
|
83
|
+
*
|
|
84
|
+
* @param port - Port to listen on (default: 8787)
|
|
85
|
+
* @returns The proxy base URL (e.g. "http://localhost:8787/v1")
|
|
86
|
+
*/
|
|
87
|
+
async serve(port = 8787) {
|
|
88
|
+
(0, proxyServer_1.createProxyServer)(port);
|
|
89
|
+
this._proxyURL = `http://localhost:${port}/v1`;
|
|
90
|
+
return this._proxyURL;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get the proxy URL. Available after serve() is called,
|
|
94
|
+
* otherwise returns the default.
|
|
95
|
+
*/
|
|
96
|
+
get proxyURL() {
|
|
97
|
+
return this._proxyURL || 'http://localhost:8787/v1';
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Extract features from a query for debugging or analysis.
|
|
101
|
+
*
|
|
102
|
+
* @param query - The user prompt to analyze
|
|
103
|
+
* @returns Detailed feature breakdown
|
|
104
|
+
*/
|
|
105
|
+
analyze(query) {
|
|
106
|
+
return (0, advancedRouter_1.extractQueryFeatures)(query);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Classify a complexity score into a named tier.
|
|
110
|
+
*/
|
|
111
|
+
classifyTier(complexity) {
|
|
112
|
+
if (complexity < 0.20)
|
|
113
|
+
return 'free';
|
|
114
|
+
if (complexity < 0.45)
|
|
115
|
+
return 'cheap';
|
|
116
|
+
if (complexity < 0.65)
|
|
117
|
+
return 'mid';
|
|
118
|
+
return 'premium';
|
|
119
|
+
}
|
|
109
120
|
}
|
|
110
|
-
|
|
121
|
+
exports.A3MRouter = A3MRouter;
|
|
111
122
|
/**
|
|
112
123
|
* Convenience: create an A3MRouter instance.
|
|
113
124
|
*
|
|
114
|
-
* @param
|
|
115
|
-
* @returns
|
|
125
|
+
* @param config - Optional configuration
|
|
126
|
+
* @returns Configured A3MRouter instance
|
|
116
127
|
*/
|
|
117
128
|
function createSDK(config) {
|
|
118
|
-
|
|
129
|
+
return new A3MRouter(config);
|
|
119
130
|
}
|
|
120
|
-
|
|
121
|
-
module.exports = { A3MRouter, createSDK };
|
|
122
|
-
module.exports.default = A3MRouter;
|
|
131
|
+
//# sourceMappingURL=sdk.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# GitHub Topics Update Script
|
|
2
|
+
|
|
3
|
+
Run this to update GitHub repository topics:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
curl -X PATCH "https://api.github.com/repos/Das-rebel/adaptive-memory-multi-model-router" \
|
|
7
|
+
-H "Authorization: token YOUR_GITHUB_TOKEN" \
|
|
8
|
+
-H "Content-Type: application/json" \
|
|
9
|
+
-d '{
|
|
10
|
+
"topics": ["ai-agents", "ai-gateway", "ai-routing", "baichuan", "chinese-llm", "cost-optimization", "deepseek", "langchain", "llamaindex", "llm-gateway", "llm-router", "mcp", "minimax", "moonshot", "multi-llm", "openai-proxy", "proxy-server", "python", "qwen", "semantic-cache"],
|
|
11
|
+
"description": "🔀 Open-source LLM router with 99.5% routing accuracy — auto-routes to cheapest capable model (Groq, DeepSeek, Kimi, Qwen + 36+ providers). Semantic cache, guardrails, 62% cost savings. 19.5KB, zero ML. TypeScript + Python SDK. MIT license."
|
|
12
|
+
}'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Note: The topics and description are now properly optimized for discoverability.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adaptive-memory-multi-model-router",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.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.",
|
|
@@ -480,7 +480,167 @@
|
|
|
480
480
|
"semantic-routing",
|
|
481
481
|
"smart-llm-router",
|
|
482
482
|
"task-routing",
|
|
483
|
-
"traffic-routing"
|
|
483
|
+
"traffic-routing",
|
|
484
|
+
"smart-router",
|
|
485
|
+
"quality-routing",
|
|
486
|
+
"cross-provider-routing",
|
|
487
|
+
"provider-fallback-routing",
|
|
488
|
+
"http-proxy",
|
|
489
|
+
"network-proxy",
|
|
490
|
+
"gateway-proxy",
|
|
491
|
+
"cluster-llm",
|
|
492
|
+
"multi-region",
|
|
493
|
+
"health-check",
|
|
494
|
+
"automatic-failover",
|
|
495
|
+
"smart-failover",
|
|
496
|
+
"provider-failover",
|
|
497
|
+
"low-cost-llm",
|
|
498
|
+
"cost-saving",
|
|
499
|
+
"cost-reduction",
|
|
500
|
+
"budget-friendly",
|
|
501
|
+
"affordable-ai",
|
|
502
|
+
"cheaper-llm",
|
|
503
|
+
"llm-pricing",
|
|
504
|
+
"token-optimization",
|
|
505
|
+
"token-saving",
|
|
506
|
+
"api-cost",
|
|
507
|
+
"inference-cost",
|
|
508
|
+
"llm-cost",
|
|
509
|
+
"cost-effective-llm",
|
|
510
|
+
"pay-less-llm",
|
|
511
|
+
"llm-expense-management",
|
|
512
|
+
"api-budget",
|
|
513
|
+
"cost-control",
|
|
514
|
+
"spend-tracking",
|
|
515
|
+
"azure-openai",
|
|
516
|
+
"deepseek-v3",
|
|
517
|
+
"qwen2.5",
|
|
518
|
+
"qwen2.5-coder",
|
|
519
|
+
"moonshot-api",
|
|
520
|
+
"zhipu-api",
|
|
521
|
+
"glm-4v",
|
|
522
|
+
"glm-api",
|
|
523
|
+
"智谱ai",
|
|
524
|
+
"yi",
|
|
525
|
+
"yi-api",
|
|
526
|
+
"yi-34b",
|
|
527
|
+
"零一ai",
|
|
528
|
+
"minimax-abab",
|
|
529
|
+
"baichuan-api",
|
|
530
|
+
"baichuan4",
|
|
531
|
+
"stepfun-api",
|
|
532
|
+
"groq-api",
|
|
533
|
+
"groq-llama",
|
|
534
|
+
"groq-mixtral",
|
|
535
|
+
"cerebras-api",
|
|
536
|
+
"cerebras-qwen",
|
|
537
|
+
"mistral-api",
|
|
538
|
+
"mistral-7b",
|
|
539
|
+
"llama-api",
|
|
540
|
+
"llama-proxy",
|
|
541
|
+
"llama-3",
|
|
542
|
+
"llama-3.1",
|
|
543
|
+
"llama-3.3",
|
|
544
|
+
"openrouter-api",
|
|
545
|
+
"together-api",
|
|
546
|
+
"fireworks-api",
|
|
547
|
+
"perplexity-api",
|
|
548
|
+
"cohere-api",
|
|
549
|
+
"ai21",
|
|
550
|
+
"ai21-api",
|
|
551
|
+
"replicate",
|
|
552
|
+
"replicate-api",
|
|
553
|
+
"chinese-api",
|
|
554
|
+
"chinese-gateway",
|
|
555
|
+
"chinese-model",
|
|
556
|
+
"字节跳动",
|
|
557
|
+
"中文api",
|
|
558
|
+
"国产llm",
|
|
559
|
+
"中国llm",
|
|
560
|
+
"openai-gateway",
|
|
561
|
+
"openai-endpoint",
|
|
562
|
+
"openai-format",
|
|
563
|
+
"langchain-gateway",
|
|
564
|
+
"llamaindex-gateway",
|
|
565
|
+
"mcp-gateway",
|
|
566
|
+
"anthropic-mcp",
|
|
567
|
+
"vercel-ai-sdk",
|
|
568
|
+
"nextjs-ai",
|
|
569
|
+
"conversational-ai",
|
|
570
|
+
"pii-redaction",
|
|
571
|
+
"prompt-security",
|
|
572
|
+
"data-security",
|
|
573
|
+
"gdpr-llm",
|
|
574
|
+
"soc2",
|
|
575
|
+
"hipaa",
|
|
576
|
+
"fast-llm",
|
|
577
|
+
"low-latency",
|
|
578
|
+
"high-throughput",
|
|
579
|
+
"streaming-llm",
|
|
580
|
+
"batching",
|
|
581
|
+
"context-caching",
|
|
582
|
+
"flash-attention",
|
|
583
|
+
"smart-fallback",
|
|
584
|
+
"memory",
|
|
585
|
+
"routing-quality",
|
|
586
|
+
"routing-benchmark",
|
|
587
|
+
"node",
|
|
588
|
+
"npm-package",
|
|
589
|
+
"pypi-package",
|
|
590
|
+
"pip",
|
|
591
|
+
"json-api",
|
|
592
|
+
"client",
|
|
593
|
+
"server",
|
|
594
|
+
"microservices",
|
|
595
|
+
"api-management",
|
|
596
|
+
"workflow-automation",
|
|
597
|
+
"tree-search",
|
|
598
|
+
"monte-carlo",
|
|
599
|
+
"uct",
|
|
600
|
+
"performance-testing",
|
|
601
|
+
"llm-comparison",
|
|
602
|
+
"model-comparison",
|
|
603
|
+
"llm-evaluation",
|
|
604
|
+
"quality-metrics",
|
|
605
|
+
"latency-benchmark",
|
|
606
|
+
"throughput-testing",
|
|
607
|
+
"router-proxy",
|
|
608
|
+
"api-proxy",
|
|
609
|
+
"provider-management",
|
|
610
|
+
"provider-selection",
|
|
611
|
+
"automatic-selection",
|
|
612
|
+
"retrieval-augmented",
|
|
613
|
+
"text-generation",
|
|
614
|
+
"summarization",
|
|
615
|
+
"translation",
|
|
616
|
+
"sentiment-analysis",
|
|
617
|
+
"classification",
|
|
618
|
+
"extraction",
|
|
619
|
+
"named-entity-recognition",
|
|
620
|
+
"reliability",
|
|
621
|
+
"uptime",
|
|
622
|
+
"sla",
|
|
623
|
+
"metrics",
|
|
624
|
+
"alerting",
|
|
625
|
+
"docker",
|
|
626
|
+
"kubernetes",
|
|
627
|
+
"helm",
|
|
628
|
+
"aws",
|
|
629
|
+
"gcp",
|
|
630
|
+
"azure",
|
|
631
|
+
"self-hosted",
|
|
632
|
+
"self-host",
|
|
633
|
+
"on-premise",
|
|
634
|
+
"cloud-native",
|
|
635
|
+
"openai-relay",
|
|
636
|
+
"anthropic-relay",
|
|
637
|
+
"llm-relay",
|
|
638
|
+
"relay-server",
|
|
639
|
+
"api-relay",
|
|
640
|
+
"api-forwarder",
|
|
641
|
+
"api-aggregator",
|
|
642
|
+
"llm-middleware",
|
|
643
|
+
"api-middleware"
|
|
484
644
|
],
|
|
485
645
|
"author": "Das-rebel <subho@example.com>",
|
|
486
646
|
"license": "MIT",
|
|
@@ -496,7 +656,8 @@
|
|
|
496
656
|
"test": "node test.js && node test/provider-test.js",
|
|
497
657
|
"test:providers": "node test/provider-test.js",
|
|
498
658
|
"benchmark": "node test/benchmark.js",
|
|
499
|
-
"benchmark:verbose": "node test/benchmark.js --verbose"
|
|
659
|
+
"benchmark:verbose": "node test/benchmark.js --verbose",
|
|
660
|
+
"build": "npx tsc -p tsconfig.build.json"
|
|
500
661
|
},
|
|
501
662
|
"engines": {
|
|
502
663
|
"node": ">=18.0.0"
|