adaptive-memory-multi-model-router 2.1.0 → 2.2.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 +48 -21
- package/dist/sdk.js +122 -0
- package/docs/API.md +637 -344
- package/package.json +65 -25
- 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/src/sdk.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A3M Router TypeScript SDK
|
|
3
|
+
*
|
|
4
|
+
* Clean wrapper class providing a better DX than raw exports.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { A3MRouter } from 'adaptive-memory-multi-model-router/sdk';
|
|
8
|
+
*
|
|
9
|
+
* const router = new A3MRouter();
|
|
10
|
+
*
|
|
11
|
+
* // Route a query (no execution, just model selection)
|
|
12
|
+
* const decision = router.route("What is 2+2?");
|
|
13
|
+
* console.log(decision.model, decision.tier, decision.cost);
|
|
14
|
+
*
|
|
15
|
+
* // Start the OpenAI-compatible proxy server
|
|
16
|
+
* const proxyURL = await router.serve(8787);
|
|
17
|
+
*
|
|
18
|
+
* // Use with any OpenAI SDK
|
|
19
|
+
* import OpenAI from 'openai';
|
|
20
|
+
* const client = new OpenAI({ baseURL: router.proxyURL });
|
|
21
|
+
* const response = await client.chat.completions.create({
|
|
22
|
+
* model: 'auto',
|
|
23
|
+
* messages: [{ role: 'user', content: 'Hello' }]
|
|
24
|
+
* });
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import {
|
|
28
|
+
routeQuery,
|
|
29
|
+
extractQueryFeatures,
|
|
30
|
+
routeBatch,
|
|
31
|
+
recommendForTask,
|
|
32
|
+
} from './routing/advancedRouter';
|
|
33
|
+
import { createProxyServer } from './server/proxyServer';
|
|
34
|
+
|
|
35
|
+
// ============================================================
|
|
36
|
+
// Types
|
|
37
|
+
// ============================================================
|
|
38
|
+
|
|
39
|
+
export interface RoutingResult {
|
|
40
|
+
/** Selected model identifier (e.g. "groq/llama-3.3-70b-versatile") */
|
|
41
|
+
model: string;
|
|
42
|
+
/** Cost tier classification */
|
|
43
|
+
tier: 'free' | 'cheap' | 'mid' | 'premium';
|
|
44
|
+
/** Estimated cost in USD */
|
|
45
|
+
cost: number;
|
|
46
|
+
/** Complexity score 0.0–1.0 */
|
|
47
|
+
complexity: number;
|
|
48
|
+
/** Human-readable reasoning for the selection */
|
|
49
|
+
reasoning: string;
|
|
50
|
+
/** Alternative models in priority order */
|
|
51
|
+
fallbackModels: string[];
|
|
52
|
+
/** Whether the selected model is free */
|
|
53
|
+
isFree: boolean;
|
|
54
|
+
/** Whether this is classified as an expert-level query */
|
|
55
|
+
isExpert: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface QueryFeatures {
|
|
59
|
+
complexity: number;
|
|
60
|
+
length: number;
|
|
61
|
+
has_code: boolean;
|
|
62
|
+
has_math: boolean;
|
|
63
|
+
is_multilingual: boolean;
|
|
64
|
+
is_translation: boolean;
|
|
65
|
+
is_creative: boolean;
|
|
66
|
+
requires_reasoning: boolean;
|
|
67
|
+
is_security: boolean;
|
|
68
|
+
is_devops: boolean;
|
|
69
|
+
is_data: boolean;
|
|
70
|
+
detected_domain: string;
|
|
71
|
+
domain_score: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface A3MRouterConfig {
|
|
75
|
+
/** Default model to use when routing is ambiguous */
|
|
76
|
+
defaultModel?: string;
|
|
77
|
+
/** Maximum cost per query in USD (routes to cheaper models if exceeded) */
|
|
78
|
+
maxCostPerQuery?: number;
|
|
79
|
+
/** Prefer fast responses over higher quality */
|
|
80
|
+
preferSpeedOverQuality?: boolean;
|
|
81
|
+
/** Restrict routing to these provider IDs */
|
|
82
|
+
providers?: string[];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ============================================================
|
|
86
|
+
// A3MRouter SDK Class
|
|
87
|
+
// ============================================================
|
|
88
|
+
|
|
89
|
+
export class A3MRouter {
|
|
90
|
+
private config: A3MRouterConfig;
|
|
91
|
+
private _proxyURL: string | null = null;
|
|
92
|
+
|
|
93
|
+
constructor(config: A3MRouterConfig = {}) {
|
|
94
|
+
this.config = config;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Route a query — returns model selection without executing it.
|
|
99
|
+
*
|
|
100
|
+
* @param query - The user prompt to route
|
|
101
|
+
* @returns Routing decision with model, tier, cost, complexity
|
|
102
|
+
*/
|
|
103
|
+
route(query: string): RoutingResult {
|
|
104
|
+
const features = extractQueryFeatures(query);
|
|
105
|
+
const result = routeQuery(query, this.config.providers);
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
model: result.primary_model || 'unknown',
|
|
109
|
+
tier: this.classifyTier(features.complexity),
|
|
110
|
+
cost: result.estimated_cost || 0,
|
|
111
|
+
complexity: features.complexity,
|
|
112
|
+
reasoning: result.reasoning || '',
|
|
113
|
+
fallbackModels: result.fallback_models || [],
|
|
114
|
+
isFree: (result.estimated_cost || 0) === 0,
|
|
115
|
+
isExpert: features.complexity >= 0.65,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Route multiple queries in batch.
|
|
121
|
+
*
|
|
122
|
+
* @param queries - Array of user prompts
|
|
123
|
+
* @returns Array of routing decisions
|
|
124
|
+
*/
|
|
125
|
+
routeBatch(queries: string[]): RoutingResult[] {
|
|
126
|
+
routeBatch(queries); // warm the internal cache
|
|
127
|
+
return queries.map((q) => this.route(q));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Get model recommendation for a task description.
|
|
132
|
+
*
|
|
133
|
+
* @param task - Task description (e.g. "code generation", "summarization")
|
|
134
|
+
* @returns Routing decision
|
|
135
|
+
*/
|
|
136
|
+
recommend(task: string): RoutingResult {
|
|
137
|
+
recommendForTask(task);
|
|
138
|
+
return this.route(task);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Start the OpenAI-compatible proxy server.
|
|
143
|
+
*
|
|
144
|
+
* @param port - Port to listen on (default: 8787)
|
|
145
|
+
* @returns The proxy base URL (e.g. "http://localhost:8787/v1")
|
|
146
|
+
*/
|
|
147
|
+
async serve(port: number = 8787): Promise<string> {
|
|
148
|
+
createProxyServer(port);
|
|
149
|
+
this._proxyURL = `http://localhost:${port}/v1`;
|
|
150
|
+
return this._proxyURL;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Get the proxy URL. Available after serve() is called,
|
|
155
|
+
* otherwise returns the default.
|
|
156
|
+
*/
|
|
157
|
+
get proxyURL(): string {
|
|
158
|
+
return this._proxyURL || 'http://localhost:8787/v1';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Extract features from a query for debugging or analysis.
|
|
163
|
+
*
|
|
164
|
+
* @param query - The user prompt to analyze
|
|
165
|
+
* @returns Detailed feature breakdown
|
|
166
|
+
*/
|
|
167
|
+
analyze(query: string): QueryFeatures {
|
|
168
|
+
return extractQueryFeatures(query);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Classify a complexity score into a named tier.
|
|
173
|
+
*/
|
|
174
|
+
private classifyTier(
|
|
175
|
+
complexity: number,
|
|
176
|
+
): 'free' | 'cheap' | 'mid' | 'premium' {
|
|
177
|
+
if (complexity < 0.20) return 'free';
|
|
178
|
+
if (complexity < 0.45) return 'cheap';
|
|
179
|
+
if (complexity < 0.65) return 'mid';
|
|
180
|
+
return 'premium';
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Convenience: create an A3MRouter instance.
|
|
186
|
+
*
|
|
187
|
+
* @param config - Optional configuration
|
|
188
|
+
* @returns Configured A3MRouter instance
|
|
189
|
+
*/
|
|
190
|
+
export function createSDK(config?: A3MRouterConfig): A3MRouter {
|
|
191
|
+
return new A3MRouter(config);
|
|
192
|
+
}
|