adaptive-memory-multi-model-router 2.1.0 → 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 +48 -21
- package/dist/sdk.js +122 -0
- package/docs/API.md +637 -344
- package/package.json +5 -1
- package/python/README.md +102 -0
- package/python/a3m/__init__.py +6 -0
- package/python/a3m/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/a3m/__pycache__/client.cpython-312.pyc +0 -0
- package/python/a3m/__pycache__/models.cpython-312.pyc +0 -0
- package/python/a3m/__pycache__/sync_client.cpython-312.pyc +0 -0
- package/python/a3m/client.py +190 -0
- package/python/a3m/models.py +40 -0
- package/python/a3m/sync_client.py +61 -0
- package/python/pyproject.toml +23 -0
- package/src/sdk.ts +192 -0
package/README.md
CHANGED
|
@@ -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
|
-
|
|
119
|
+
### TypeScript
|
|
123
120
|
|
|
124
|
-
```
|
|
125
|
-
|
|
121
|
+
```typescript
|
|
122
|
+
import { A3MRouter } from 'adaptive-memory-multi-model-router/sdk';
|
|
126
123
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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 }
|
|
132
127
|
```
|
|
133
128
|
|
|
134
|
-
|
|
129
|
+
### Python
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
pip install a3m-router
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from a3m import A3MRouter
|
|
137
|
+
|
|
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
|
+
```
|
|
135
143
|
|
|
136
|
-
###
|
|
144
|
+
### OpenAI-Compatible Proxy
|
|
137
145
|
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
|
|
146
|
+
```bash
|
|
147
|
+
npx a3m-router serve
|
|
148
|
+
# Now point any OpenAI SDK at http://localhost:8787/v1
|
|
149
|
+
```
|
|
141
150
|
|
|
142
|
-
|
|
143
|
-
|
|
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
|
---
|
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;
|