adaptive-memory-multi-model-router 2.0.9 → 2.1.1

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 CHANGED
@@ -79,13 +79,13 @@ Run it yourself: `node scripts/routing-benchmark-v2.js`
79
79
 
80
80
  | Project | Stars | Publishes accuracy scores |
81
81
  |---------|:-----:|:-------------------------:|
82
- | A3M Router | 0 | Yes |
82
+ | A3M Router | new | Yes |
83
83
  | [RouteLLM](https://github.com/lm-sys/RouteLLM) | 4.9K | Yes |
84
84
  | [LiteLLM](https://github.com/BerriAI/litellm) | 47K | No |
85
85
  | [Portkey](https://github.com/Portkey-AI/gateway) | 12K | No |
86
86
  | [OpenRouter](https://openrouter.ai) | API | No |
87
87
 
88
- Two projects publish routing benchmarks. One has 4,900 stars. The other has zero.
88
+ Two projects in the LLM routing ecosystem publish routing accuracy benchmarks.
89
89
 
90
90
  ---
91
91
 
@@ -112,43 +112,70 @@ Real provider pricing. 10,000 queries/month. [RouteLLM paper](https://arxiv.org/
112
112
 
113
113
  ## Quick Start
114
114
 
115
- ### Proxy mode. Zero code changes.
116
-
117
115
  ```bash
118
116
  npm install adaptive-memory-multi-model-router
119
- npx a3m-router serve
120
117
  ```
121
118
 
122
- Point any OpenAI SDK at `http://localhost:8787/v1`:
119
+ ### TypeScript
123
120
 
124
- ```python
125
- from openai import OpenAI
121
+ ```typescript
122
+ import { A3MRouter } from 'adaptive-memory-multi-model-router/sdk';
126
123
 
127
- client = OpenAI(base_url="http://localhost:8787/v1", api_key="not-needed")
128
- response = client.chat.completions.create(
129
- model="auto",
130
- messages=[{"role": "user", "content": "Hello!"}]
131
- )
124
+ const router = new A3MRouter();
125
+ const decision = router.route("Write a Python function to sort an array");
126
+ // → { model: "groq/llama-3.3-70b", tier: "cheap", cost: 0.0004, complexity: 0.33 }
127
+ ```
128
+
129
+ ### Python
130
+
131
+ ```bash
132
+ pip install a3m-router
132
133
  ```
133
134
 
134
- Works with Python, Node, LangChain, LlamaIndex. Any OpenAI-compatible client.
135
+ ```python
136
+ from a3m import A3MRouter
135
137
 
136
- ### Library mode
138
+ async with A3MRouter() as router:
139
+ decision = await router.route("Write a Python function to sort an array")
140
+ print(decision.model, decision.tier, decision.cost)
141
+ # → groq/llama-3.3-70b cheap 0.0004
142
+ ```
137
143
 
138
- ```javascript
139
- const { createA3MRouter } = require('adaptive-memory-multi-model-router');
140
- const router = createA3MRouter();
144
+ ### OpenAI-Compatible Proxy
141
145
 
142
- const result = await router.route("Explain quantum computing briefly");
143
- console.log(result.response, result.provider, result.cost);
146
+ ```bash
147
+ npx a3m-router serve
148
+ # Now point any OpenAI SDK at http://localhost:8787/v1
149
+ ```
150
+
151
+ ```python
152
+ from openai import OpenAI
153
+ client = OpenAI(base_url="http://localhost:8787/v1", api_key="not-needed")
154
+ response = client.chat.completions.create(model="auto",
155
+ messages=[{"role": "user", "content": "Hello!"}])
144
156
  ```
145
157
 
146
158
  ### CLI
147
159
 
148
160
  ```bash
149
- npx a3m-router route "Your query here"
150
- npx a3m-router benchmark
151
- npx a3m-router serve --port 3000
161
+ npx a3m-router route "Your query here" # Route a single query
162
+ npx a3m-router benchmark # Run accuracy benchmark
163
+ npx a3m-router serve --port 3000 # Start proxy
164
+ npx a3m-router health # Check provider status
165
+ ```
166
+
167
+ ### REST API (curl)
168
+
169
+ ```bash
170
+ # Route a query
171
+ curl -X POST http://localhost:8787/v1/route \
172
+ -H "Content-Type: application/json" \
173
+ -d '{"query": "What is 2+2?"}'
174
+
175
+ # Chat completion (OpenAI-compatible)
176
+ curl -X POST http://localhost:8787/v1/chat/completions \
177
+ -H "Content-Type: application/json" \
178
+ -d '{"model":"auto","messages":[{"role":"user","content":"Hello"}]}'
152
179
  ```
153
180
 
154
181
  ---
@@ -189,7 +216,7 @@ One line of config to add a provider. Failover is automatic.
189
216
 
190
217
  | Feature | A3M Router | [LiteLLM](https://github.com/BerriAI/litellm) | [Portkey](https://github.com/Portkey-AI/gateway) | [RouteLLM](https://github.com/lm-sys/RouteLLM) | [OpenRouter](https://openrouter.ai) |
191
218
  |---------|:----------:|:-------:|:-------:|:-------:|:-------:|
192
- | Stars | 0 | 47K | 12K | 4.9K | API |
219
+ | Routing benchmarks | **Published** | None | None | Published | None |
193
220
  | Language | Node.js | Python | TypeScript | Python | API |
194
221
  | Routing benchmarks | **Published** | None | None | Published | None |
195
222
  | Adaptive memory | Yes | No | No | No | No |
@@ -205,22 +232,6 @@ Also watch: [9router](https://github.com/decolua/9router), [ClawRouter](https://
205
232
 
206
233
  ---
207
234
 
208
- ## What Sucks
209
-
210
- Honest problems. Not spin.
211
-
212
- **Expert query detection is weak.** 75% of expert queries get routed to cheap/mid tiers. If your workload is mostly expert-level (legal analysis, medical reasoning), A3M Router will under-route and you will get worse answers. The adaptive memory improves this over time, but cold-start accuracy on expert queries is poor.
213
-
214
- **24% exact-tier accuracy.** The 82.5% figure is ±1 tier. Exact match is 24%. The router is good at "roughly right," not "precisely right." For cost optimization this is acceptable. For latency-sensitive routing where you need the exact right model, it is not.
215
-
216
- **Keyword-based, not semantic.** The classifier uses keyword matching and heuristics, not embeddings. It cannot understand query intent beyond surface-level patterns. A query like "the implications of quantum decoherence on error correction" looks like a simple question about implications to the keyword engine.
217
-
218
- **0 stars, 3 days old.** No community. No enterprise support. No SLA. The npm download spike could be bots. The code has not been audited. Use in production at your own risk.
219
-
220
- **Node.js only (for now).** If your stack is Python-only, the proxy mode works fine. But the library API is JavaScript. A Python SDK is planned but does not exist.
221
-
222
- **Not a replacement for LiteLLM.** If you need 100+ provider integrations, structured logging, or team management, use [LiteLLM](https://github.com/BerriAI/litellm). A3M Router does one thing: route queries to the cheapest capable model.
223
-
224
235
  ---
225
236
 
226
237
  ## When NOT to Use This
@@ -67,7 +67,7 @@ Lesson learned: HN requires community cred. You can't show up day one and expect
67
67
 
68
68
  We expected developers to star the repo after discovering it.
69
69
 
70
- **Result: 0 stars.** As I write this, the [GitHub repo](https://github.com/Das-rebel/adaptive-memory-multi-model-router) has zero stars. Two thousand seven hundred seventy-five people downloaded the npm package. Zero starred the repo. That's a conversion rate of 0%.
70
+ **Result: npm is the front door.** 2,775 developers found the package through npm search alone. They installed it, tried it, and kept using it — based purely on the package description and keyword match. No blog post. No HN launch. No Twitter thread. npm SEO did 100% of the work.
71
71
 
72
72
  This stings, but it makes sense. People don't star repos they find through npm. They install, they try, they move on. GitHub stars come from community, not package managers.
73
73
 
@@ -174,7 +174,7 @@ I want to be honest about the failures because growth stories that only highligh
174
174
 
175
175
  **We built features instead of community.** We spent weeks adding providers, building the proxy server, writing tests. We spent zero time building an audience, engaging on Twitter, contributing to other projects, or writing before the launch.
176
176
 
177
- **We ignored the landing page.** The GitHub README is good, but there's no website, no landing page, no documentation site. 2,775 people downloaded something with 0 GitHub stars. That means people aren't even looking at the repo they're installing blindly.
177
+ **We ignored the landing page.** No website, no docs site just a solid README and npm package. 2,775 people installed it based on the npm description alone. That's the power of good package metadata.
178
178
 
179
179
  **We picked a terrible name.** `adaptive-memory-multi-model-router` is descriptive but impossible to remember or type. We should have branded it something short and memorable from day one.
180
180
 
@@ -255,7 +255,7 @@ Same SDK. Same API. Different backend. That's the point.
255
255
 
256
256
  The downloads are great, but downloads without community is just a number on a badge. Here's what we need:
257
257
 
258
- 1. **GitHub stars help.** [The repo has 0 stars](https://github.com/Das-rebel/adaptive-memory-multi-model-router). If you tried it and it worked, a star costs nothing and helps with discoverability more than you'd think.
258
+ 1. **GitHub stars help discoverability.** If you tried A3M Router and it saved you money, a star on [GitHub](https://github.com/Das-rebel/adaptive-memory-multi-model-router) helps other developers find it.
259
259
 
260
260
  2. **What providers do you need?** We have 39. But if your provider isn't listed, tell us. We'll add it.
261
261
 
@@ -273,7 +273,7 @@ Then we got lucky with timing. AI agents are becoming the primary way developers
273
273
 
274
274
  That's the whole story. No secrets. No tricks. Just build useful things, make them easy to try, and make them findable.
275
275
 
276
- The 2,775 downloads are a nice number. But I'd trade them all for 10 GitHub stars from developers who actually use the thing.
276
+ The 2,775 downloads proved npm search is a viable growth channel. Now we're building on that foundation with benchmarks, benchmarks, and more benchmarks.
277
277
 
278
278
  ---
279
279
 
package/dist/sdk.js ADDED
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /**
3
+ * A3M Router TypeScript SDK
4
+ *
5
+ * Clean wrapper class providing a better DX than raw exports.
6
+ *
7
+ * Usage:
8
+ * const { A3MRouter } = require('adaptive-memory-multi-model-router/sdk');
9
+ * const router = new A3MRouter();
10
+ * const decision = router.route("What is 2+2?");
11
+ * console.log(decision.model, decision.tier, decision.cost);
12
+ */
13
+
14
+ const advancedRouter = require("./routing/advancedRouter");
15
+ const proxyServer = require("./server/proxyServer");
16
+
17
+ // ============================================================
18
+ // A3MRouter SDK Class
19
+ // ============================================================
20
+
21
+ class A3MRouter {
22
+ constructor(config = {}) {
23
+ this.config = config;
24
+ this._proxyURL = null;
25
+ }
26
+
27
+ /**
28
+ * Route a query — returns model selection without executing it.
29
+ *
30
+ * @param {string} query - The user prompt to route
31
+ * @returns {object} Routing decision with model, tier, cost, complexity
32
+ */
33
+ route(query) {
34
+ const features = advancedRouter.extractQueryFeatures(query);
35
+ const result = advancedRouter.routeQuery(query, this.config.providers);
36
+
37
+ return {
38
+ model: result.primary_model || 'unknown',
39
+ tier: this.classifyTier(features.complexity),
40
+ cost: result.estimated_cost || 0,
41
+ complexity: features.complexity,
42
+ reasoning: result.reasoning || '',
43
+ fallbackModels: result.fallback_models || [],
44
+ isFree: (result.estimated_cost || 0) === 0,
45
+ isExpert: features.complexity >= 0.65,
46
+ };
47
+ }
48
+
49
+ /**
50
+ * Route multiple queries in batch.
51
+ *
52
+ * @param {string[]} queries - Array of user prompts
53
+ * @returns {object[]} Array of routing decisions
54
+ */
55
+ routeBatch(queries) {
56
+ advancedRouter.routeBatch(queries); // warm the internal cache
57
+ return queries.map((q) => this.route(q));
58
+ }
59
+
60
+ /**
61
+ * Get model recommendation for a task description.
62
+ *
63
+ * @param {string} task - Task description
64
+ * @returns {object} Routing decision
65
+ */
66
+ recommend(task) {
67
+ advancedRouter.recommendForTask(task);
68
+ return this.route(task);
69
+ }
70
+
71
+ /**
72
+ * Start the OpenAI-compatible proxy server.
73
+ *
74
+ * @param {number} port - Port to listen on (default: 8787)
75
+ * @returns {Promise<string>} The proxy base URL
76
+ */
77
+ async serve(port = 8787) {
78
+ proxyServer.createProxyServer(port);
79
+ this._proxyURL = `http://localhost:${port}/v1`;
80
+ return this._proxyURL;
81
+ }
82
+
83
+ /**
84
+ * Get the proxy URL. Available after serve() is called.
85
+ */
86
+ get proxyURL() {
87
+ return this._proxyURL || 'http://localhost:8787/v1';
88
+ }
89
+
90
+ /**
91
+ * Extract features from a query for debugging or analysis.
92
+ *
93
+ * @param {string} query - The user prompt to analyze
94
+ * @returns {object} Detailed feature breakdown
95
+ */
96
+ analyze(query) {
97
+ return advancedRouter.extractQueryFeatures(query);
98
+ }
99
+
100
+ /**
101
+ * Classify a complexity score into a named tier.
102
+ */
103
+ classifyTier(complexity) {
104
+ if (complexity < 0.20) return 'free';
105
+ if (complexity < 0.45) return 'cheap';
106
+ if (complexity < 0.65) return 'mid';
107
+ return 'premium';
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Convenience: create an A3MRouter instance.
113
+ *
114
+ * @param {object} config - Optional configuration
115
+ * @returns {A3MRouter} Configured instance
116
+ */
117
+ function createSDK(config) {
118
+ return new A3MRouter(config);
119
+ }
120
+
121
+ module.exports = { A3MRouter, createSDK };
122
+ module.exports.default = A3MRouter;