adaptive-memory-multi-model-router 2.2.7 → 2.2.8
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 +15 -12
- package/package.json +95 -66
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/sdk.d.ts.map +0 -1
- package/dist/sdk.js.map +0 -1
- package/test.js.bak +0 -376
package/README.md
CHANGED
|
@@ -254,7 +254,7 @@ LiteLLM ████████████████ ~500ms
|
|
|
254
254
|
|
|
255
255
|
See full benchmark methodology at [`scripts/routing-benchmark-v2.js`](scripts/routing-benchmark-v2.js) or run it with `node scripts/routing-benchmark-v2.js`.
|
|
256
256
|
|
|
257
|
-
| Metric | A3M Router | LiteLLM |
|
|
257
|
+
| Metric | A3M Router | [LiteLLM](https://github.com/BerriAI/litellm) |
|
|
258
258
|
|--------|:----------:|:---------------:|
|
|
259
259
|
| **±1 tier accuracy** | **99.5%** | N/A (manual) |
|
|
260
260
|
| Exact tier match | 64.5% | N/A |
|
|
@@ -310,7 +310,7 @@ We ran **MMLU-style questions** and **quality tests** against each provider via
|
|
|
310
310
|
|
|
311
311
|
> **May 2026** — 15 MMLU questions + 8 quality questions per provider via real API. Run `node scripts/run-mmlu-benchmark.js` to replicate. Results in [`benchmark-results.json`](benchmark-results.json).
|
|
312
312
|
|
|
313
|
-
| Metric | A3M Router | LiteLLM |
|
|
313
|
+
| Metric | A3M Router | [LiteLLM](https://github.com/BerriAI/litellm) |
|
|
314
314
|
|--------|:----------:|:--------:|
|
|
315
315
|
| ±1 tier accuracy | **99.5%** | N/A |
|
|
316
316
|
| Package size | **19.5 KB** | ~50 MB |
|
|
@@ -784,20 +784,22 @@ const modelWithTools = model.bindTools([searchTool, calculatorTool]);
|
|
|
784
784
|
|
|
785
785
|
## Comparison
|
|
786
786
|
|
|
787
|
-
| Feature | A3M Router | [LiteLLM](https://github.com/BerriAI/litellm) | [Portkey](https://github.com/Portkey-AI/gateway) | [
|
|
787
|
+
| Feature | A3M Router | [LiteLLM](https://github.com/BerriAI/litellm) | [Portkey](https://github.com/Portkey-AI/gateway) | [RouteLLM](https://github.com/Surfsol/RouteLLM) |
|
|
788
788
|
|---------|:----------:|:-------:|:-------:|:-------:|
|
|
789
789
|
| **Routing accuracy published** | **Yes** (99.5% ±1) | No (manual) | No | No |
|
|
790
790
|
| **Intelligent routing** | Multi-signal per-query | Manual selection | Manual | Manual |
|
|
791
791
|
| **Zero ML / Zero GPU** | **Yes** | Yes | Yes | Yes |
|
|
792
|
-
| **Package size** | 19.5 KB | ~50 MB | ~30 MB |
|
|
793
|
-
| **OpenAI-compatible proxy** | **Yes** | No | Yes | Yes |
|
|
794
|
-
| **Adaptive memory** | **Yes** | No | No | No |
|
|
795
|
-
| **Semantic cache** | **Yes** (trigram) | No | No |
|
|
796
|
-
| **Prompt injection detection** | **Yes** (17 patterns) | No | No |
|
|
797
|
-
| **PII redaction** | **Yes** | No | No |
|
|
798
|
-
| **Hallucination checks** | **Yes** | No | No | No |
|
|
799
|
-
| **Cost analytics** | **Yes** | No | Yes |
|
|
800
|
-
| **Budget alerts** | **Yes** | No | No |
|
|
792
|
+
| **Package size** | 19.5 KB | ~50 MB | ~30 MB | ~15 MB |
|
|
793
|
+
| **OpenAI-compatible proxy** | **Yes** | No | Yes | Yes |
|
|
794
|
+
| **Adaptive memory** | **Yes** | No | No | No |
|
|
795
|
+
| **Semantic cache** | **Yes** (trigram) | No | No | No |
|
|
796
|
+
| **Prompt injection detection** | **Yes** (17 patterns) | No | No | No |
|
|
797
|
+
| **PII redaction** | **Yes** | No | No | No |
|
|
798
|
+
| **Hallucination checks** | **Yes** | No | No | No |
|
|
799
|
+
| **Cost analytics** | **Yes** | No | Yes | No |
|
|
800
|
+
| **Budget alerts** | **Yes** | No | No | No |
|
|
801
|
+
| **Circuit breaker** | **Yes** | No | No | No |
|
|
802
|
+
| **Multi-provider (36+)** | **Yes** | Yes | Yes | Yes |
|
|
801
803
|
| **Circuit breaker** | **Yes** | No | No | Yes | No |
|
|
802
804
|
| **LangChain adapter** | **Yes** | No | Yes | Yes | No |
|
|
803
805
|
| **Python SDK** | **Yes** | Yes | Yes | Yes | Yes |
|
|
@@ -852,6 +854,7 @@ import { createProxyServer } from 'adaptive-memory-multi-model-router/server';
|
|
|
852
854
|
- You only use one LLM provider
|
|
853
855
|
- Your workload is >80% expert-level queries (just use GPT-4o directly)
|
|
854
856
|
- You need 250+ provider integrations (use [Portkey](https://github.com/Portkey-AI/gateway))
|
|
857
|
+
- You need ML-based routing with BERT classifiers (use [RouteLLM](https://github.com/Surfsol/RouteLLM))
|
|
855
858
|
- You need enterprise SLAs or managed hosting
|
|
856
859
|
|
|
857
860
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adaptive-memory-multi-model-router",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.8",
|
|
4
4
|
"shortName": "A3M Router",
|
|
5
5
|
"displayName": "A3M Router - Adaptive Memory Multi-Model Router",
|
|
6
6
|
"description": "LLM router & AI gateway with 99.5% routing accuracy — supports 47 providers including DeepSeek, Kimi (Moonshot), Qwen, Zhipu GLM, Yi, Baichuan, MiniMax, StepFun. Zero ML, 19.5KB. Multi-signal routing, semantic cache, guardrails, cost analytics. MIT. TypeScript SDK + Python SDK + OpenAI proxy.",
|
|
@@ -53,89 +53,118 @@
|
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
"keywords": [
|
|
56
|
-
"
|
|
56
|
+
"ai-guardrails",
|
|
57
|
+
"moonshot",
|
|
58
|
+
"adaptive-routing",
|
|
59
|
+
"llm-manager",
|
|
57
60
|
"claude",
|
|
58
|
-
"
|
|
59
|
-
"openai-compatible",
|
|
60
|
-
"no-gpu",
|
|
61
|
-
"openai",
|
|
62
|
-
"routing-accuracy",
|
|
63
|
-
"minimax",
|
|
64
|
-
"portkey-alternative",
|
|
65
|
-
"中文llm",
|
|
66
|
-
"provider-fallback",
|
|
67
|
-
"nlp",
|
|
68
|
-
"ollama",
|
|
69
|
-
"cerebras",
|
|
70
|
-
"openai-sdk",
|
|
61
|
+
"guardrails",
|
|
71
62
|
"ai-sdk",
|
|
63
|
+
"qwen",
|
|
64
|
+
"groq",
|
|
65
|
+
"high-availability",
|
|
72
66
|
"openai-proxy",
|
|
73
|
-
"
|
|
74
|
-
"深度求索",
|
|
75
|
-
"anthropic",
|
|
76
|
-
"ai-cost-optimization",
|
|
67
|
+
"multi-provider",
|
|
77
68
|
"model-router",
|
|
78
|
-
"
|
|
79
|
-
"chinese-ai",
|
|
80
|
-
"vercel-ai",
|
|
81
|
-
"ai-load-balancer",
|
|
82
|
-
"deepseek",
|
|
69
|
+
"rate-limiter",
|
|
83
70
|
"llm-routing",
|
|
71
|
+
"semantic-routing",
|
|
72
|
+
"circuit-breaker",
|
|
73
|
+
"openrouter",
|
|
74
|
+
"litellm-alternative",
|
|
75
|
+
"zhipu",
|
|
76
|
+
"llm-management",
|
|
77
|
+
"ai-agent",
|
|
78
|
+
"vercel-ai",
|
|
79
|
+
"deepseek-proxy",
|
|
80
|
+
"groq-proxy",
|
|
84
81
|
"mistral",
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
82
|
+
"llm-gateway",
|
|
83
|
+
"cost-based-routing",
|
|
84
|
+
"ollama",
|
|
88
85
|
"cost-optimization",
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"llm-
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
86
|
+
"chatgpt",
|
|
87
|
+
"nlp",
|
|
88
|
+
"smart-llm-router",
|
|
89
|
+
"openai-sdk",
|
|
90
|
+
"distributed-llm",
|
|
91
|
+
"llm-proxy",
|
|
92
|
+
"chatbot",
|
|
93
|
+
"ai-cost-optimization",
|
|
94
|
+
"stepfun",
|
|
95
|
+
"reverse-proxy",
|
|
96
|
+
"llm-orchestration",
|
|
97
|
+
"llm-caching",
|
|
98
|
+
"intelligent-load-balancer",
|
|
98
99
|
"llm-load-balancer",
|
|
99
|
-
"
|
|
100
|
+
"ai-gateway",
|
|
101
|
+
"helicone",
|
|
102
|
+
"failover",
|
|
103
|
+
"ai",
|
|
104
|
+
"intent-routing",
|
|
105
|
+
"api-gateway",
|
|
106
|
+
"retry-proxy",
|
|
107
|
+
"glms",
|
|
100
108
|
"claude-proxy",
|
|
109
|
+
"content-routing",
|
|
110
|
+
"chinese-llm",
|
|
101
111
|
"lightweight",
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
112
|
+
"dynamic-routing",
|
|
113
|
+
"provider-selector",
|
|
114
|
+
"ai-orchestration",
|
|
115
|
+
"provider-fallback",
|
|
105
116
|
"zh-llm",
|
|
117
|
+
"load-balancer",
|
|
118
|
+
"request-routing",
|
|
119
|
+
"model-routing",
|
|
120
|
+
"anthropic",
|
|
121
|
+
"阿里qwen",
|
|
122
|
+
"multi-llm",
|
|
123
|
+
"深度求索",
|
|
124
|
+
"intelligent-router",
|
|
125
|
+
"domain-routing",
|
|
106
126
|
"中文ai",
|
|
127
|
+
"aleph-alpha",
|
|
128
|
+
"llm-router",
|
|
129
|
+
"minimax",
|
|
107
130
|
"benchmark",
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
"guardrails",
|
|
115
|
-
"ai-agent",
|
|
131
|
+
"cerebras",
|
|
132
|
+
"keyword-routing",
|
|
133
|
+
"traffic-routing",
|
|
134
|
+
"中文llm",
|
|
135
|
+
"ai-proxy",
|
|
136
|
+
"llm-cluster",
|
|
116
137
|
"baichuan",
|
|
117
|
-
"
|
|
138
|
+
"portkey-alternative",
|
|
139
|
+
"openai",
|
|
140
|
+
"language-model",
|
|
141
|
+
"ai-router",
|
|
142
|
+
"yi-llm",
|
|
118
143
|
"anthropic-proxy",
|
|
119
|
-
"
|
|
120
|
-
"deepseek-proxy",
|
|
121
|
-
"llm-gateway",
|
|
122
|
-
"multi-llm",
|
|
123
|
-
"ai-gateway",
|
|
124
|
-
"groq",
|
|
125
|
-
"litellm-alternative",
|
|
126
|
-
"ai-proxy",
|
|
127
|
-
"llm-router",
|
|
128
|
-
"domain-routing",
|
|
129
|
-
"groq-proxy",
|
|
130
|
-
"qwen",
|
|
144
|
+
"query-routing",
|
|
131
145
|
"gpt",
|
|
146
|
+
"chinese-ai",
|
|
147
|
+
"moonshot-kimi",
|
|
148
|
+
"routing-accuracy",
|
|
149
|
+
"cerebras-proxy",
|
|
132
150
|
"openai-api",
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"
|
|
151
|
+
"kimi",
|
|
152
|
+
"model-selection",
|
|
153
|
+
"no-gpu",
|
|
154
|
+
"ai-load-balancer",
|
|
155
|
+
"routellm-alternative",
|
|
156
|
+
"token-counter",
|
|
157
|
+
"smart-routing",
|
|
158
|
+
"model-management",
|
|
159
|
+
"deepseek",
|
|
160
|
+
"task-routing",
|
|
161
|
+
"ollama-proxy",
|
|
136
162
|
"langchain",
|
|
137
|
-
"
|
|
138
|
-
"
|
|
163
|
+
"llm-failover",
|
|
164
|
+
"mistral-proxy",
|
|
165
|
+
"openai-compatible",
|
|
166
|
+
"semantic-cache",
|
|
167
|
+
"llm"
|
|
139
168
|
],
|
|
140
169
|
"author": "Das-rebel <subho@example.com>",
|
|
141
170
|
"license": "MIT",
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,gCAAgC;AAChC,iBAAiB;;;AAgFjB,0CAcC;AA5FD,+DAA+D;AAC/D,iBAAiB;AACjB,+DAA+D;AAC/D,2DAQkC;AAPhC,4GAAA,UAAU,OAAA;AACV,4GAAA,UAAU,OAAA;AACV,kHAAA,gBAAgB,OAAA;AAChB,sHAAA,oBAAoB,OAAA;AACpB,gHAAA,cAAc,OAAA;AACd,oHAAA,kBAAkB,OAAA;AAClB,mHAAA,iBAAiB,OAAA;AAGnB,+DAA+D;AAC/D,YAAY;AACZ,+DAA+D;AAC/D,6DAYoC;AAXlC,mHAAA,iBAAiB,OAAA;AACjB,uHAAA,qBAAqB,OAAA;AACrB,kHAAA,gBAAgB,OAAA;AAChB,oHAAA,kBAAkB,OAAA;AAClB,gHAAA,cAAc,OAAA;AACd,6GAAA,WAAW,OAAA;AACX,mHAAA,iBAAiB,OAAA;AACjB,+HAAA,6BAA6B,OAAA;AAC7B,8HAAA,4BAA4B,OAAA;AAC5B,4GAAA,UAAU,OAAA;AACV,4GAAA,UAAU,OAAA;AAWZ,+DAA+D;AAC/D,gBAAgB;AAChB,+DAA+D;AAC/D,kDAAiD;AAAxC,0GAAA,WAAW,OAAA;AAEpB,+DAA+D;AAC/D,SAAS;AACT,+DAA+D;AAC/D,kDAAiD;AAAxC,wGAAA,UAAU,OAAA;AAGnB,+DAA+D;AAC/D,YAAY;AACZ,+DAA+D;AAC/D,iDAAiE;AAAxD,yGAAA,WAAW,OAAA;AAAE,4GAAA,cAAc,OAAA;AACpC,iDAAiD;AAAxC,yGAAA,WAAW,OAAA;AAEpB,+DAA+D;AAC/D,kBAAkB;AAClB,+DAA+D;AAC/D,uDAAsD;AAA7C,8GAAA,aAAa,OAAA;AACtB,oDAAwD;AAA/C,6GAAA,eAAe,OAAA;AACxB,2DAA0D;AAAjD,8GAAA,aAAa,OAAA;AACtB,oDAAyD;AAAhD,gHAAA,iBAAiB,OAAA;AAE1B,+DAA+D;AAC/D,wCAAwC;AACxC,+DAA+D;AAC/D,6DAAoF;AACpF,+DAAgF;AAChF,oDAAiD;AACjD,oDAAiD;AASjD,SAAgB,eAAe,CAAC,OAA0B;IACxD,MAAM,WAAW,GAAG,IAAI,yBAAW,EAAE,CAAC;IACtC,MAAM,UAAU,GAAG,IAAI,uBAAU,EAAE,CAAC;IAEpC,OAAO;QACL,KAAK,EAAE,2BAAU;QACjB,UAAU,EAAV,2BAAU;QACV,gBAAgB,EAAhB,iCAAgB;QAChB,qBAAqB,EAArB,sCAAqB;QACrB,WAAW,EAAX,4BAAW;QACX,WAAW;QACX,UAAU;QACV,OAAO,EAAE,OAAO,IAAI,EAAE;KACvB,CAAC;AACJ,CAAC;AAED,iBAAiB;AACjB,kBAAe,eAAe,CAAC"}
|
package/dist/sdk.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAcH,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC;IAC3C,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,yCAAyC;IACzC,MAAM,EAAE,OAAO,CAAC;IAChB,0DAA0D;IAC1D,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAMD,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,SAAS,CAAuB;gBAE5B,MAAM,GAAE,eAAoB;IAIxC;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa;IAgBnC;;;;;OAKG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE;IAK9C;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IAKtC;;;;;OAKG;IACG,KAAK,CAAC,IAAI,GAAE,MAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAMjD;;;OAGG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;;;;OAKG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa;IAIrC;;OAEG;IACH,OAAO,CAAC,YAAY;CAQrB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS,CAE7D"}
|
package/dist/sdk.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;;;AAqKH,8BAEC;AArKD,6DAKkC;AAClC,sDAAyD;AAoDzD,+DAA+D;AAC/D,sBAAsB;AACtB,+DAA+D;AAE/D,MAAa,SAAS;IACZ,MAAM,CAAkB;IACxB,SAAS,GAAkB,IAAI,CAAC;IAExC,YAAY,SAA0B,EAAE;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAa;QACjB,MAAM,QAAQ,GAAG,IAAA,qCAAoB,EAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAA,2BAAU,EAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAExD,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,aAAa,IAAI,SAAS;YACxC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC5C,IAAI,EAAE,MAAM,CAAC,cAAc,IAAI,CAAC;YAChC,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;YACjC,cAAc,EAAE,MAAM,CAAC,eAAe,IAAI,EAAE;YAC5C,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,IAAI,CAAC,CAAC,KAAK,CAAC;YAC1C,QAAQ,EAAE,QAAQ,CAAC,UAAU,IAAI,IAAI;SACtC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,OAAiB;QAC1B,IAAA,2BAAU,EAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B;QAC/C,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,IAAY;QACpB,IAAA,iCAAgB,EAAC,IAAI,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,OAAe,IAAI;QAC7B,IAAA,+BAAiB,EAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,oBAAoB,IAAI,KAAK,CAAC;QAC/C,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,SAAS,IAAI,0BAA0B,CAAC;IACtD,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,KAAa;QACnB,OAAO,IAAA,qCAAoB,EAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACK,YAAY,CAClB,UAAkB;QAElB,IAAI,UAAU,GAAG,IAAI;YAAE,OAAO,MAAM,CAAC;QACrC,IAAI,UAAU,GAAG,IAAI;YAAE,OAAO,OAAO,CAAC;QACtC,IAAI,UAAU,GAAG,IAAI;YAAE,OAAO,KAAK,CAAC;QACpC,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AA7FD,8BA6FC;AAED;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,MAAwB;IAChD,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|
package/test.js.bak
DELETED
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* A3M Router Test Suite v1.9.0
|
|
4
|
-
* Comprehensive tests for generic provider system
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const assert = require('assert');
|
|
8
|
-
const {
|
|
9
|
-
createA3MRouter,
|
|
10
|
-
getAvailableProviders,
|
|
11
|
-
registerProvider,
|
|
12
|
-
deregisterProvider,
|
|
13
|
-
DEFAULT_PROVIDERS,
|
|
14
|
-
providerConfig,
|
|
15
|
-
routeQuery,
|
|
16
|
-
routeBatch,
|
|
17
|
-
recommendForTask,
|
|
18
|
-
extractQueryFeatures,
|
|
19
|
-
MODEL_PROFILES,
|
|
20
|
-
countTokens,
|
|
21
|
-
estimateCost,
|
|
22
|
-
MemoryTree,
|
|
23
|
-
CostTracker,
|
|
24
|
-
ResponseCache,
|
|
25
|
-
ProviderRegistry,
|
|
26
|
-
} = require('./dist/index.js');
|
|
27
|
-
|
|
28
|
-
let passed = 0;
|
|
29
|
-
let failed = 0;
|
|
30
|
-
|
|
31
|
-
function test(name, fn) {
|
|
32
|
-
try {
|
|
33
|
-
fn();
|
|
34
|
-
console.log(' ✅ ' + name);
|
|
35
|
-
passed++;
|
|
36
|
-
} catch (e) {
|
|
37
|
-
console.log(' ❌ ' + name + ': ' + e.message);
|
|
38
|
-
failed++;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function asyncTest(name, fn) {
|
|
43
|
-
return fn()
|
|
44
|
-
.then(() => {
|
|
45
|
-
console.log(' ✅ ' + name);
|
|
46
|
-
passed++;
|
|
47
|
-
})
|
|
48
|
-
.catch(e => {
|
|
49
|
-
console.log(' ❌ ' + name + ': ' + e.message);
|
|
50
|
-
failed++;
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
console.log('\n═══════════════════════════════════════════════════════════════');
|
|
55
|
-
console.log('🧪 A3M Router Test Suite v1.9.0');
|
|
56
|
-
console.log('═══════════════════════════════════════════════════════════════\n');
|
|
57
|
-
|
|
58
|
-
// ============================================================
|
|
59
|
-
// TEST 1: Provider Configuration
|
|
60
|
-
// ============================================================
|
|
61
|
-
console.log('📦 Provider Configuration Tests');
|
|
62
|
-
console.log('─────────────────────────────────────────────────────────────');
|
|
63
|
-
|
|
64
|
-
test('providerConfig module loads', () => {
|
|
65
|
-
assert(providerConfig, 'providerConfig should be defined');
|
|
66
|
-
assert(typeof providerConfig.loadConfig === 'function', 'loadConfig should be a function');
|
|
67
|
-
assert(typeof providerConfig.getAvailableProviders === 'function', 'getAvailableProviders should be a function');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test('DEFAULT_PROVIDERS has expected providers', () => {
|
|
71
|
-
assert(DEFAULT_PROVIDERS, 'DEFAULT_PROVIDERS should be defined');
|
|
72
|
-
assert(DEFAULT_PROVIDERS.groq, 'should have groq');
|
|
73
|
-
assert(DEFAULT_PROVIDERS.mistral, 'should have mistral');
|
|
74
|
-
assert(DEFAULT_PROVIDERS.cerebras, 'should have cerebras');
|
|
75
|
-
assert(DEFAULT_PROVIDERS.commandcode, 'should have commandcode');
|
|
76
|
-
assert(DEFAULT_PROVIDERS.opencode, 'should have opencode');
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
test('getAvailableProviders returns configured providers', () => {
|
|
80
|
-
const available = getAvailableProviders();
|
|
81
|
-
assert(available, 'should return available providers');
|
|
82
|
-
assert(Object.keys(available).length > 0, 'should have at least one provider');
|
|
83
|
-
|
|
84
|
-
// Check that available providers have required fields
|
|
85
|
-
for (const [id, p] of Object.entries(available)) {
|
|
86
|
-
assert(p.id, 'provider should have id');
|
|
87
|
-
assert(p.name, 'provider should have name');
|
|
88
|
-
assert(p.type, 'provider should have type');
|
|
89
|
-
assert(p.models, 'provider should have models');
|
|
90
|
-
assert(Array.isArray(p.models), 'models should be an array');
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test('Provider types are correct', () => {
|
|
95
|
-
const available = getAvailableProviders();
|
|
96
|
-
|
|
97
|
-
if (available.groq) {
|
|
98
|
-
assert.strictEqual(available.groq.type, 'api', 'groq should be api type');
|
|
99
|
-
}
|
|
100
|
-
if (available.commandcode) {
|
|
101
|
-
assert.strictEqual(available.commandcode.type, 'cli', 'commandcode should be cli type');
|
|
102
|
-
}
|
|
103
|
-
if (available.opencode) {
|
|
104
|
-
assert.strictEqual(available.opencode.type, 'cli', 'opencode should be cli type');
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// ============================================================
|
|
109
|
-
// TEST 2: Routing
|
|
110
|
-
// ============================================================
|
|
111
|
-
console.log('\n🔀 Routing Tests');
|
|
112
|
-
console.log('─────────────────────────────────────────────────────────────');
|
|
113
|
-
|
|
114
|
-
test('routeQuery returns valid result', () => {
|
|
115
|
-
const result = routeQuery('What is 2+2?');
|
|
116
|
-
assert(result, 'should return a result');
|
|
117
|
-
assert(result.primary_model, 'should have primary_model');
|
|
118
|
-
assert(Array.isArray(result.fallback_models), 'should have fallback_models array');
|
|
119
|
-
assert(typeof result.estimated_cost === 'number', 'should have estimated_cost');
|
|
120
|
-
assert(typeof result.confidence === 'number', 'should have confidence');
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test('routeQuery selects free providers for simple queries', () => {
|
|
124
|
-
const result = routeQuery('Hello');
|
|
125
|
-
assert(result.primary_model, 'should have primary_model');
|
|
126
|
-
// Should prefer free/cheap providers for simple queries
|
|
127
|
-
assert(result.estimated_cost < 0.5, 'should have low cost for simple query');
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
test('routeQuery selects appropriate provider for code', () => {
|
|
131
|
-
const result = routeQuery('Write a Python function to sort an array');
|
|
132
|
-
assert(result.primary_model, 'should have primary_model');
|
|
133
|
-
assert(result.reasoning, 'should have reasoning');
|
|
134
|
-
// Should mention code in reasoning
|
|
135
|
-
assert(result.reasoning.toLowerCase().includes('code') ||
|
|
136
|
-
result.features.has_code, 'should detect code');
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
test('routeBatch returns array of results', () => {
|
|
140
|
-
const queries = ['Hello', 'What is 2+2?', 'Write Python code'];
|
|
141
|
-
const results = routeBatch(queries);
|
|
142
|
-
assert(Array.isArray(results), 'should return array');
|
|
143
|
-
assert.strictEqual(results.length, queries.length, 'should have same length as queries');
|
|
144
|
-
|
|
145
|
-
results.forEach((r, i) => {
|
|
146
|
-
assert(r.primary_model, 'result ' + i + ' should have primary_model');
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
test('recommendForTask returns recommendation', () => {
|
|
151
|
-
const rec = recommendForTask('coding');
|
|
152
|
-
assert(rec, 'should return recommendation');
|
|
153
|
-
assert(rec.primary, 'should have primary');
|
|
154
|
-
assert(Array.isArray(rec.fallbacks), 'should have fallbacks array');
|
|
155
|
-
assert(rec.reason, 'should have reason');
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
test('extractQueryFeatures detects code', () => {
|
|
159
|
-
const features = extractQueryFeatures('function test() { return 1; }');
|
|
160
|
-
assert(features.has_code, 'should detect code');
|
|
161
|
-
assert(features.complexity > 0.3, 'should have elevated complexity');
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
test('extractQueryFeatures detects math', () => {
|
|
165
|
-
const features = extractQueryFeatures('Calculate the integral of x^2');
|
|
166
|
-
assert(features.has_math, 'should detect math');
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
test('extractQueryFeatures detects translation', () => {
|
|
170
|
-
const features = extractQueryFeatures('Translate hello to French');
|
|
171
|
-
assert(features.is_translation, 'should detect translation');
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
// ============================================================
|
|
175
|
-
// TEST 3: Model Profiles
|
|
176
|
-
// ============================================================
|
|
177
|
-
console.log('\n📊 Model Profile Tests');
|
|
178
|
-
console.log('─────────────────────────────────────────────────────────────');
|
|
179
|
-
|
|
180
|
-
test('MODEL_PROFILES is populated', () => {
|
|
181
|
-
assert(MODEL_PROFILES, 'MODEL_PROFILES should be defined');
|
|
182
|
-
assert(Object.keys(MODEL_PROFILES).length > 0, 'should have model profiles');
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test('Model profiles have required fields', () => {
|
|
186
|
-
for (const [name, profile] of Object.entries(MODEL_PROFILES)) {
|
|
187
|
-
assert(profile.name, name + ' should have name');
|
|
188
|
-
assert(profile.provider, name + ' should have provider');
|
|
189
|
-
assert(typeof profile.cost_per_1k_input === 'number', name + ' should have cost_per_1k_input');
|
|
190
|
-
assert(typeof profile.cost_per_1k_output === 'number', name + ' should have cost_per_1k_output');
|
|
191
|
-
assert(typeof profile.quality_score === 'number', name + ' should have quality_score');
|
|
192
|
-
assert(Array.isArray(profile.strengths), name + ' should have strengths array');
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// ============================================================
|
|
197
|
-
// TEST 4: Token Utilities
|
|
198
|
-
// ============================================================
|
|
199
|
-
console.log('\n🔢 Token Utility Tests');
|
|
200
|
-
console.log('─────────────────────────────────────────────────────────────');
|
|
201
|
-
|
|
202
|
-
test('countTokens returns number', () => {
|
|
203
|
-
const tokens = countTokens('Hello world');
|
|
204
|
-
assert(typeof tokens === 'number', 'should return number');
|
|
205
|
-
assert(tokens > 0, 'should return positive number');
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
test('countTokens counts correctly', () => {
|
|
209
|
-
const tokens = countTokens('Hello world');
|
|
210
|
-
assert(tokens >= 2, 'should count at least 2 tokens for 2 words');
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
test('estimateCost returns number', () => {
|
|
214
|
-
const cost = estimateCost(100, 50, 'gpt-4o');
|
|
215
|
-
assert(typeof cost === 'number', 'should return number');
|
|
216
|
-
assert(cost >= 0, 'should return non-negative');
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
// ============================================================
|
|
220
|
-
// TEST 5: A3M Router Factory
|
|
221
|
-
// ============================================================
|
|
222
|
-
console.log('\n🏭 A3M Router Factory Tests');
|
|
223
|
-
console.log('─────────────────────────────────────────────────────────────');
|
|
224
|
-
|
|
225
|
-
test('createA3MRouter returns router object', () => {
|
|
226
|
-
const router = createA3MRouter({});
|
|
227
|
-
assert(router, 'should return router');
|
|
228
|
-
assert(typeof router.route === 'function', 'should have route function');
|
|
229
|
-
assert(typeof router.routeBatch === 'function', 'should have routeBatch function');
|
|
230
|
-
assert(typeof router.recommend === 'function', 'should have recommend function');
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
test('createA3MRouter has memory', () => {
|
|
234
|
-
const router = createA3MRouter({});
|
|
235
|
-
assert(router.memory, 'should have memory');
|
|
236
|
-
assert(typeof router.memory.add === 'function', 'memory should have add');
|
|
237
|
-
assert(typeof router.memory.search === 'function', 'memory should have search');
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
test('createA3MRouter has cache', () => {
|
|
241
|
-
const router = createA3MRouter({});
|
|
242
|
-
assert(router.cache, 'should have cache');
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
test('createA3MRouter has costTracker', () => {
|
|
246
|
-
const router = createA3MRouter({});
|
|
247
|
-
assert(router.costTracker, 'should have costTracker');
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
test('createA3MRouter has providers registry', () => {
|
|
251
|
-
const router = createA3MRouter({});
|
|
252
|
-
assert(router.providers, 'should have providers');
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
test('createA3MRouter has compression', () => {
|
|
256
|
-
const router = createA3MRouter({});
|
|
257
|
-
assert(router.compression, 'should have compression');
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
test('createA3MRouter has vault', () => {
|
|
261
|
-
const router = createA3MRouter({});
|
|
262
|
-
assert(router.vault, 'should have vault');
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
test('createA3MRouter has autoFetch', () => {
|
|
266
|
-
const router = createA3MRouter({});
|
|
267
|
-
assert(router.autoFetch, 'should have autoFetch');
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
test('createA3MRouter has oauth', () => {
|
|
271
|
-
const router = createA3MRouter({});
|
|
272
|
-
assert(router.oauth, 'should have oauth');
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
// ============================================================
|
|
276
|
-
// TEST 6: Memory Tree
|
|
277
|
-
// ============================================================
|
|
278
|
-
console.log('\n🧠 Memory Tree Tests');
|
|
279
|
-
console.log('─────────────────────────────────────────────────────────────');
|
|
280
|
-
|
|
281
|
-
test('MemoryTree can add and search', () => {
|
|
282
|
-
const memory = new MemoryTree({ maxSize: 100 });
|
|
283
|
-
memory.add('Python is great for data science', { tags: ['python', 'data'] });
|
|
284
|
-
memory.add('JavaScript is great for web', { tags: ['js', 'web'] });
|
|
285
|
-
|
|
286
|
-
const results = memory.search('python data');
|
|
287
|
-
assert(Array.isArray(results), 'should return array');
|
|
288
|
-
assert(results.length > 0, 'should find results');
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
test('MemoryTree getStats returns stats', () => {
|
|
292
|
-
const memory = new MemoryTree({ maxSize: 100 });
|
|
293
|
-
memory.add('Test entry', { tags: ['test'] });
|
|
294
|
-
|
|
295
|
-
const stats = memory.getStats();
|
|
296
|
-
assert(stats, 'should return stats');
|
|
297
|
-
assert(typeof stats.totalChunks === 'number', 'should have totalChunks');
|
|
298
|
-
assert(typeof stats.indexSize === 'number', 'should have indexSize');
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
// ============================================================
|
|
302
|
-
// TEST 7: Provider Registry
|
|
303
|
-
// ============================================================
|
|
304
|
-
console.log('\n📋 Provider Registry Tests');
|
|
305
|
-
console.log('─────────────────────────────────────────────────────────────');
|
|
306
|
-
|
|
307
|
-
test('ProviderRegistry can be instantiated', () => {
|
|
308
|
-
const registry = new ProviderRegistry();
|
|
309
|
-
assert(registry, 'should create registry');
|
|
310
|
-
assert(typeof registry.getReadyProviders === 'function', 'should have getReadyProviders');
|
|
311
|
-
assert(typeof registry.selectModel === 'function', 'should have selectModel');
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
test('ProviderRegistry getStatus returns status', () => {
|
|
315
|
-
const registry = new ProviderRegistry();
|
|
316
|
-
const status = registry.getStatus();
|
|
317
|
-
assert(status, 'should return status');
|
|
318
|
-
assert(Array.isArray(status.providers), 'should have providers array');
|
|
319
|
-
assert(Array.isArray(status.available), 'should have available array');
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
// ============================================================
|
|
323
|
-
// TEST 8: Dynamic Provider Registration
|
|
324
|
-
// ============================================================
|
|
325
|
-
console.log('\n🔧 Dynamic Provider Registration Tests');
|
|
326
|
-
console.log('─────────────────────────────────────────────────────────────');
|
|
327
|
-
|
|
328
|
-
test('registerProvider adds new provider', () => {
|
|
329
|
-
const testProvider = {
|
|
330
|
-
name: 'TestProvider',
|
|
331
|
-
type: 'api',
|
|
332
|
-
baseUrl: 'https://test.example.com',
|
|
333
|
-
models: ['test-model'],
|
|
334
|
-
priority: 99,
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
registerProvider('test-provider', testProvider);
|
|
338
|
-
|
|
339
|
-
// Check it was added to runtime providers
|
|
340
|
-
const available = getAvailableProviders();
|
|
341
|
-
// Note: won't show up without API key, but should be in _providers
|
|
342
|
-
assert(providerConfig._providers['test-provider'], 'should be in _providers');
|
|
343
|
-
assert.strictEqual(providerConfig._providers['test-provider'].name, 'TestProvider');
|
|
344
|
-
|
|
345
|
-
// Clean up
|
|
346
|
-
deregisterProvider('test-provider');
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
test('deregisterProvider removes provider', () => {
|
|
350
|
-
// First add
|
|
351
|
-
registerProvider('temp-provider', { name: 'Temp', type: 'api', models: [] });
|
|
352
|
-
assert(providerConfig._providers['temp-provider'], 'should exist in _providers');
|
|
353
|
-
|
|
354
|
-
// Then remove
|
|
355
|
-
deregisterProvider('temp-provider');
|
|
356
|
-
assert(!providerConfig._providers['temp-provider'], 'should be removed from _providers');
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
// ============================================================
|
|
360
|
-
// SUMMARY
|
|
361
|
-
// ============================================================
|
|
362
|
-
console.log('\n═══════════════════════════════════════════════════════════════');
|
|
363
|
-
console.log('📊 Test Summary');
|
|
364
|
-
console.log('═══════════════════════════════════════════════════════════════');
|
|
365
|
-
console.log(' Total: ' + (passed + failed));
|
|
366
|
-
console.log(' Passed: ' + passed + ' ✅');
|
|
367
|
-
console.log(' Failed: ' + failed + (failed > 0 ? ' ❌' : ''));
|
|
368
|
-
console.log('');
|
|
369
|
-
|
|
370
|
-
if (failed > 0) {
|
|
371
|
-
console.log('❌ Some tests failed');
|
|
372
|
-
process.exit(1);
|
|
373
|
-
} else {
|
|
374
|
-
console.log('✅ All tests passed!');
|
|
375
|
-
process.exit(0);
|
|
376
|
-
}
|