adaptive-memory-multi-model-router 1.6.0 → 1.7.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 +278 -23
- package/dist/index.js +91 -2
- package/docs/API.md +562 -0
- package/docs/INTEGRATIONS.md +420 -0
- package/docs/QUICKSTART.md +271 -0
- package/package.json +132 -55
package/docs/API.md
ADDED
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
# A3M Router API Documentation
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Core Functions](#core-functions)
|
|
6
|
+
- [Memory Module](#memory-module)
|
|
7
|
+
- [Compression Module](#compression-module)
|
|
8
|
+
- [Auto-Fetch Module](#auto-fetch-module)
|
|
9
|
+
- [OAuth Module](#oauth-module)
|
|
10
|
+
- [Provider Registry](#provider-registry)
|
|
11
|
+
- [Cost Tracker](#cost-tracker)
|
|
12
|
+
- [Circuit Breaker](#circuit-breaker)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Core Functions
|
|
17
|
+
|
|
18
|
+
### createA3MRouter
|
|
19
|
+
|
|
20
|
+
Creates an A3M Router instance with specified configuration.
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
import { createA3MRouter } from 'adaptive-memory-multi-model-router';
|
|
24
|
+
|
|
25
|
+
const router = createA3MRouter({
|
|
26
|
+
memory: true, // Enable memory tree
|
|
27
|
+
costBudget: 0.05, // Max cost per request in USD
|
|
28
|
+
providers: ['openai', 'groq', 'anthropic'], // Enabled providers
|
|
29
|
+
maxLatency: 2000, // Max latency in ms
|
|
30
|
+
cacheEnabled: true // Enable caching
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Parameters:**
|
|
35
|
+
|
|
36
|
+
| Name | Type | Default | Description |
|
|
37
|
+
|------|------|---------|-------------|
|
|
38
|
+
| `memory` | boolean | `false` | Enable memory tree |
|
|
39
|
+
| `costBudget` | number | `0.10` | Max cost per request |
|
|
40
|
+
| `providers` | string[] | `['openai']` | Enabled providers |
|
|
41
|
+
| `maxLatency` | number | `5000` | Max latency in ms |
|
|
42
|
+
| `cacheEnabled` | boolean | `true` | Enable response cache |
|
|
43
|
+
|
|
44
|
+
**Returns:** `A3MRouter` instance
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### router.route()
|
|
49
|
+
|
|
50
|
+
Routes a request to the optimal provider.
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
const result = await router.route({
|
|
54
|
+
prompt: 'Your prompt here',
|
|
55
|
+
context: {
|
|
56
|
+
type: 'coding', // 'coding', 'analysis', 'creative'
|
|
57
|
+
language: 'python', // Optional language hint
|
|
58
|
+
domain: 'tech' // Optional domain hint
|
|
59
|
+
},
|
|
60
|
+
options: {
|
|
61
|
+
maxCost: 0.02,
|
|
62
|
+
maxLatency: 2000
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Parameters:**
|
|
68
|
+
|
|
69
|
+
| Name | Type | Description |
|
|
70
|
+
|------|------|-------------|
|
|
71
|
+
| `prompt` | string | The input prompt |
|
|
72
|
+
| `context` | object | Routing context |
|
|
73
|
+
| `options.maxCost` | number | Max cost for this request |
|
|
74
|
+
| `options.maxLatency` | number | Max latency in ms |
|
|
75
|
+
|
|
76
|
+
**Returns:**
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
{
|
|
80
|
+
output: 'Response text',
|
|
81
|
+
provider: 'openai',
|
|
82
|
+
model: 'gpt-4o',
|
|
83
|
+
cost: 0.0015,
|
|
84
|
+
latency: 850,
|
|
85
|
+
tokens: { prompt: 150, completion: 200 }
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Memory Module
|
|
92
|
+
|
|
93
|
+
### MemoryTree
|
|
94
|
+
|
|
95
|
+
Hierarchical memory with LRU cache and fast index.
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
import { MemoryTree } from 'adaptive-memory-multi-model-router/memory';
|
|
99
|
+
|
|
100
|
+
const tree = new MemoryTree(maxChunkSize = 3000);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### tree.add(data)
|
|
104
|
+
|
|
105
|
+
Adds data to memory tree.
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
await tree.add('Your context content here');
|
|
109
|
+
await tree.add('More content for the tree');
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### tree.search(query)
|
|
113
|
+
|
|
114
|
+
Fast indexed search.
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
const results = tree.search('keyword');
|
|
118
|
+
// Returns: [{ id, content, score, accessCount, ... }]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### tree.getContext(maxTokens)
|
|
122
|
+
|
|
123
|
+
Gets context for routing.
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
const context = tree.getContext(3000);
|
|
127
|
+
// Returns: concatenated context string
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### tree.toMarkdown()
|
|
131
|
+
|
|
132
|
+
Exports memory as Obsidian-compatible markdown.
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
const md = tree.toMarkdown();
|
|
136
|
+
fs.writeFileSync('./memory.md', md);
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### tree.getStats()
|
|
140
|
+
|
|
141
|
+
Returns tree statistics.
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
const stats = tree.getStats();
|
|
145
|
+
// { totalChunks, maxDepth, indexSize, lruSize }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
### EpisodicMemoryStore
|
|
151
|
+
|
|
152
|
+
Episodic memory for routing decisions.
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
import { EpisodicMemoryStore } from 'adaptive-memory-multi-model-router';
|
|
156
|
+
|
|
157
|
+
const memory = new EpisodicMemoryStore();
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### memory.record(request, response, routing)
|
|
161
|
+
|
|
162
|
+
Records a routing decision.
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
await memory.record(request, response, {
|
|
166
|
+
provider: 'openai',
|
|
167
|
+
model: 'gpt-4o',
|
|
168
|
+
reasoning: 'Simple query, fast model sufficient'
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### memory.getSimilar(request)
|
|
173
|
+
|
|
174
|
+
Gets similar past requests.
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
const similar = await memory.getSimilar({ prompt: 'Debug Python' });
|
|
178
|
+
// Returns routing decisions for similar prompts
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### ObsidianVault
|
|
184
|
+
|
|
185
|
+
Exports routing decisions as markdown files.
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
import { ObsidianVault } from 'adaptive-memory-multi-model-router/vault';
|
|
189
|
+
|
|
190
|
+
const vault = new ObsidianVault({ path: './vault' });
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### vault.saveDecision(decision)
|
|
194
|
+
|
|
195
|
+
Saves a routing decision as markdown.
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
await vault.saveDecision({
|
|
199
|
+
id: 'decision-001',
|
|
200
|
+
timestamp: Date.now(),
|
|
201
|
+
prompt: 'Explain quantum',
|
|
202
|
+
selectedProvider: 'openai',
|
|
203
|
+
selectedModel: 'gpt-4o',
|
|
204
|
+
reasoning: 'Complex topic, use best model',
|
|
205
|
+
cost: 0.003,
|
|
206
|
+
latency: 1200
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### vault.getRecentDecisions(count)
|
|
211
|
+
|
|
212
|
+
Gets recent decisions.
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
const recent = vault.getRecentDecisions(10);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Compression Module
|
|
221
|
+
|
|
222
|
+
### EnhancedCompression
|
|
223
|
+
|
|
224
|
+
TokenJuice-style compression with caching.
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
import { EnhancedCompression } from 'adaptive-memory-multi-model-router/compression';
|
|
228
|
+
|
|
229
|
+
const compressor = new EnhancedCompression();
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
#### compressor.compress(text)
|
|
233
|
+
|
|
234
|
+
Compresses text (HTML→Markdown, URL shortening, etc).
|
|
235
|
+
|
|
236
|
+
```javascript
|
|
237
|
+
const compressed = compressor.compress('<h1>Hello</h1><p>URL: https://very-long-url.com</p>');
|
|
238
|
+
// Returns: '# Hello\n\nURL: very-long-url.com/...'
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
#### compressor.getStats(original, compressed)
|
|
242
|
+
|
|
243
|
+
Gets compression statistics.
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
const stats = compressor.getStats(original, compressed);
|
|
247
|
+
// { original: 200, compressed: 80, reduction: '60.0%', ratio: '0.40' }
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### isonEncode / isonDecode
|
|
253
|
+
|
|
254
|
+
ISON format compression.
|
|
255
|
+
|
|
256
|
+
```javascript
|
|
257
|
+
import { isonEncode, isonDecode } from 'adaptive-memory-multi-model-router/utils/compression';
|
|
258
|
+
|
|
259
|
+
const encoded = isonEncode(messages);
|
|
260
|
+
const decoded = isonDecode(encoded);
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Auto-Fetch Module
|
|
266
|
+
|
|
267
|
+
### AutoFetch
|
|
268
|
+
|
|
269
|
+
Periodically syncs data from connected tools.
|
|
270
|
+
|
|
271
|
+
```javascript
|
|
272
|
+
import { AutoFetch } from 'adaptive-memory-multi-model-router/autofetch';
|
|
273
|
+
|
|
274
|
+
const fetcher = new AutoFetch({
|
|
275
|
+
intervalMs: 20 * 60 * 1000, // 20 minutes
|
|
276
|
+
targets: ['github', 'notion', 'slack', 'gmail', 'calendar']
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
#### fetcher.start()
|
|
281
|
+
|
|
282
|
+
Starts the sync loop.
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
fetcher.start();
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
#### fetcher.syncAll()
|
|
289
|
+
|
|
290
|
+
Triggers immediate sync.
|
|
291
|
+
|
|
292
|
+
```javascript
|
|
293
|
+
const results = await fetcher.syncAll();
|
|
294
|
+
// Returns: Map<target, SyncResult>
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### fetcher.stop()
|
|
298
|
+
|
|
299
|
+
Stops the sync loop.
|
|
300
|
+
|
|
301
|
+
```javascript
|
|
302
|
+
fetcher.stop();
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
#### fetcher.getStats()
|
|
306
|
+
|
|
307
|
+
Gets sync statistics.
|
|
308
|
+
|
|
309
|
+
```javascript
|
|
310
|
+
const stats = fetcher.getStats();
|
|
311
|
+
// { totalTargets: 5, failedTargets: 0 }
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## OAuth Module
|
|
317
|
+
|
|
318
|
+
### OAuthManager
|
|
319
|
+
|
|
320
|
+
One-click OAuth for integrations.
|
|
321
|
+
|
|
322
|
+
```javascript
|
|
323
|
+
import { OAuthManager } from 'adaptive-memory-multi-model-router/oauth';
|
|
324
|
+
|
|
325
|
+
const oauth = new OAuthManager();
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
#### oauth.configure(provider, config)
|
|
329
|
+
|
|
330
|
+
Configures an OAuth provider.
|
|
331
|
+
|
|
332
|
+
```javascript
|
|
333
|
+
oauth.configure('github', {
|
|
334
|
+
clientId: 'your-client-id',
|
|
335
|
+
clientSecret: 'your-secret',
|
|
336
|
+
redirectUri: 'http://localhost:3000/callback'
|
|
337
|
+
});
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### oauth.getAuthUrl(provider)
|
|
341
|
+
|
|
342
|
+
Gets authorization URL.
|
|
343
|
+
|
|
344
|
+
```javascript
|
|
345
|
+
const url = oauth.getAuthUrl('github');
|
|
346
|
+
// Opens OAuth flow
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
#### oauth.handleCallback(provider, code, state)
|
|
350
|
+
|
|
351
|
+
Handles OAuth callback.
|
|
352
|
+
|
|
353
|
+
```javascript
|
|
354
|
+
const tokens = await oauth.handleCallback('github', code, state);
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### oauth.isConnected(provider)
|
|
358
|
+
|
|
359
|
+
Checks if provider is connected.
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
const connected = oauth.isConnected('github');
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
#### oauth.getAccessToken(provider)
|
|
366
|
+
|
|
367
|
+
Gets valid access token (auto-refreshes).
|
|
368
|
+
|
|
369
|
+
```javascript
|
|
370
|
+
const token = await oauth.getAccessToken('github');
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## Provider Registry
|
|
376
|
+
|
|
377
|
+
### ProviderRegistry
|
|
378
|
+
|
|
379
|
+
Manages 14 LLM providers.
|
|
380
|
+
|
|
381
|
+
```javascript
|
|
382
|
+
import { ProviderRegistry } from 'adaptive-memory-multi-model-router/providers';
|
|
383
|
+
|
|
384
|
+
const registry = new ProviderRegistry();
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
#### registry.getReadyProviders()
|
|
388
|
+
|
|
389
|
+
Gets currently available providers.
|
|
390
|
+
|
|
391
|
+
```javascript
|
|
392
|
+
const ready = registry.getReadyProviders();
|
|
393
|
+
// ['openai', 'groq', 'anthropic']
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
#### registry.selectModel()
|
|
397
|
+
|
|
398
|
+
Selects optimal model based on cost-latency tradeoff.
|
|
399
|
+
|
|
400
|
+
```javascript
|
|
401
|
+
const model = registry.selectModel();
|
|
402
|
+
// 'openai/gpt-4o'
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
#### registry.recordSuccess(provider)
|
|
406
|
+
|
|
407
|
+
Records successful request.
|
|
408
|
+
|
|
409
|
+
```javascript
|
|
410
|
+
registry.recordSuccess('openai');
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
#### registry.recordFailure(provider)
|
|
414
|
+
|
|
415
|
+
Records failed request.
|
|
416
|
+
|
|
417
|
+
```javascript
|
|
418
|
+
registry.recordFailure('openai');
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
## Cost Tracker
|
|
424
|
+
|
|
425
|
+
### CostTracker
|
|
426
|
+
|
|
427
|
+
Tracks request costs and budgets.
|
|
428
|
+
|
|
429
|
+
```javascript
|
|
430
|
+
import { CostTracker } from 'adaptive-memory-multi-model-router/cost';
|
|
431
|
+
|
|
432
|
+
const tracker = new CostTracker();
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
#### tracker.record(requestInfo)
|
|
436
|
+
|
|
437
|
+
Records a request.
|
|
438
|
+
|
|
439
|
+
```javascript
|
|
440
|
+
tracker.record({
|
|
441
|
+
provider: 'openai',
|
|
442
|
+
model: 'gpt-4o',
|
|
443
|
+
promptTokens: 150,
|
|
444
|
+
completionTokens: 200,
|
|
445
|
+
cost: 0.003
|
|
446
|
+
});
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
#### tracker.getSummary()
|
|
450
|
+
|
|
451
|
+
Gets cost summary.
|
|
452
|
+
|
|
453
|
+
```javascript
|
|
454
|
+
const summary = tracker.getSummary();
|
|
455
|
+
// { totalRequests, totalCost, byProvider, byModel }
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
#### tracker.getRemainingBudget(provider)
|
|
459
|
+
|
|
460
|
+
Gets remaining budget.
|
|
461
|
+
|
|
462
|
+
```javascript
|
|
463
|
+
const remaining = tracker.getRemainingBudget('openai');
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
## Circuit Breaker
|
|
469
|
+
|
|
470
|
+
### CircuitBreaker
|
|
471
|
+
|
|
472
|
+
Prevents cascading failures.
|
|
473
|
+
|
|
474
|
+
```javascript
|
|
475
|
+
import { CircuitBreaker } from 'adaptive-memory-multi-model-router/utils/reliability';
|
|
476
|
+
|
|
477
|
+
const breaker = new CircuitBreaker({
|
|
478
|
+
name: 'openai',
|
|
479
|
+
failureThreshold: 3,
|
|
480
|
+
resetTimeout: 60000
|
|
481
|
+
});
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
#### breaker.canExecute()
|
|
485
|
+
|
|
486
|
+
Checks if request can proceed.
|
|
487
|
+
|
|
488
|
+
```javascript
|
|
489
|
+
if (breaker.canExecute()) {
|
|
490
|
+
// Proceed with request
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
#### breaker.recordSuccess()
|
|
495
|
+
|
|
496
|
+
Records success.
|
|
497
|
+
|
|
498
|
+
```javascript
|
|
499
|
+
breaker.recordSuccess();
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
#### breaker.recordFailure()
|
|
503
|
+
|
|
504
|
+
Records failure.
|
|
505
|
+
|
|
506
|
+
```javascript
|
|
507
|
+
breaker.recordFailure();
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## CLI Commands
|
|
513
|
+
|
|
514
|
+
| Command | Description |
|
|
515
|
+
|---------|-------------|
|
|
516
|
+
| `a3m-router route "prompt"` | Route to optimal model |
|
|
517
|
+
| `a3m-router parallel "t1" "t2" "t3"` | Parallel execution |
|
|
518
|
+
| `a3m-router compare "prompt"` | Compare models |
|
|
519
|
+
| `a3m-router cost` | Show cost summary |
|
|
520
|
+
| `a3m-router count "text"` | Count tokens |
|
|
521
|
+
| `a3m-router compress "text"` | Compress text |
|
|
522
|
+
| `a3m-router local "prompt"` | Local Ollama |
|
|
523
|
+
| `a3m-router providers` | List providers |
|
|
524
|
+
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## Error Handling
|
|
528
|
+
|
|
529
|
+
```javascript
|
|
530
|
+
import { CircuitBreaker, withRetry } from 'adaptive-memory-multi-model-router';
|
|
531
|
+
|
|
532
|
+
const breaker = new CircuitBreaker({ name: 'test' });
|
|
533
|
+
|
|
534
|
+
try {
|
|
535
|
+
const result = await withRetry(
|
|
536
|
+
() => router.route({ prompt: 'test' }),
|
|
537
|
+
{ maxRetries: 3, retryDelay: 1000 }
|
|
538
|
+
);
|
|
539
|
+
} catch (error) {
|
|
540
|
+
if (breaker.getState().status === 'open') {
|
|
541
|
+
console.log('Circuit open - using fallback');
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
## TypeScript Support
|
|
549
|
+
|
|
550
|
+
A3M Router is written in TypeScript with full type definitions.
|
|
551
|
+
|
|
552
|
+
```typescript
|
|
553
|
+
import { createA3MRouter, type A3MRouterConfig } from 'adaptive-memory-multi-model-router';
|
|
554
|
+
|
|
555
|
+
const config: A3MRouterConfig = {
|
|
556
|
+
memory: true,
|
|
557
|
+
costBudget: 0.05,
|
|
558
|
+
providers: ['openai', 'groq']
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
const router = createA3MRouter(config);
|
|
562
|
+
```
|