adaptive-memory-multi-model-router 2.15.4 → 2.16.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/AGENT_COUNCIL_FINDINGS.md +123 -98
- package/CAMPAIGN_SUMMARY.md +87 -0
- package/CHANGELOG.md +7 -1
- package/ENTERPRISE_INTEGRATIONS.md +94 -0
- package/INTEGRATION_PROGRESS.md +96 -0
- package/OPPORTUNITIES_100.md +277 -0
- package/POPULARITY_BOOSTERS.md +1 -1
- package/README.md +147 -275
- package/README_ja.md +17 -21
- package/README_zh.md +13 -17
- package/TODO_BROWSER_AUTOMATION.md +87 -0
- package/a3m-integrations-summary.md +73 -0
- package/apps/cost-calculator/README.md +72 -0
- package/apps/cost-calculator/calculator.css +280 -0
- package/apps/cost-calculator/calculator.js +150 -0
- package/apps/cost-calculator/index.html +321 -0
- package/apps/cost-calculator/package.json +13 -0
- package/articles/ANNOUNCEMENT_reddit_ml.md +76 -0
- package/articles/ANNOUNCEMENT_vc/347/244/276/345/214/272.md +71 -0
- package/articles/ANNOUNCEMENT_vercel.md +85 -0
- package/articles/CHINESE_DIRECTORIES.md +2 -2
- package/articles/CHINESE_SUBMISSIONS_READY.md +5 -5
- package/articles/HN_POST_READY.md +16 -20
- package/articles/INDIEHACKERS_READY.md +19 -34
- package/dist/analytics/costAnalytics.d.ts +0 -1
- package/dist/benchmark/reproducible.d.ts +0 -1
- package/dist/cache/semanticCache.d.ts +0 -1
- package/dist/cost/budgetEnforcer.d.ts +0 -1
- package/dist/cost/costTracker.d.ts +0 -1
- package/dist/ensemble/multiRoundDialog.d.ts +0 -1
- package/dist/ensemble/shapleyValue.d.ts +0 -1
- package/dist/ensemble.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/integrations/oauth.d.ts +0 -1
- package/dist/integrations/scienceAdapter.d.ts +0 -1
- package/dist/memory/autoFetch.d.ts +0 -1
- package/dist/memory/hybridMemory.d.ts +0 -1
- package/dist/memory/memoryTree.d.ts +0 -1
- package/dist/memory/obsidianVault.d.ts +0 -1
- package/dist/memory/reasoningBank.d.ts +0 -1
- package/dist/observability/changeWatch.d.ts +0 -1
- package/dist/observability/fatigueDetector.d.ts +0 -1
- package/dist/observability/index.d.ts +0 -1
- package/dist/observability/metrics.d.ts +0 -1
- package/dist/observability/middleware.d.ts +0 -1
- package/dist/observability/tracer.d.ts +0 -1
- package/dist/observability/types.d.ts +0 -1
- package/dist/providers/providerConfig.d.ts +5 -2
- package/dist/providers/providerConfig.js +1006 -1
- package/dist/providers/providerConfig.js.map +1 -1
- package/dist/routing/advancedRouter.d.ts +1 -2
- package/dist/routing/advancedRouter.js +84 -0
- package/dist/routing/advancedRouter.js.map +1 -1
- package/dist/routing/crossModelValidation.d.ts +0 -1
- package/dist/routing/providerHealth.d.ts +77 -2
- package/dist/routing/providerHealth.js +190 -4
- package/dist/routing/providerHealth.js.map +1 -1
- package/dist/routing/providerRetry.d.ts +0 -1
- package/dist/routing/shadowSampler.d.ts +187 -0
- package/dist/routing/shadowSampler.js +306 -0
- package/dist/routing/shadowSampler.js.map +1 -0
- package/dist/sdk.d.ts +0 -1
- package/dist/security/guardrails.d.ts +0 -1
- package/dist/server/dashboard.d.ts +0 -1
- package/dist/server/handlers/chatHandler.d.ts +0 -1
- package/dist/server/handlers/completionsHandler.d.ts +0 -1
- package/dist/server/handlers/embeddingsHandler.d.ts +0 -1
- package/dist/server/handlers/healthHandler.d.ts +0 -1
- package/dist/server/handlers/metricsHandler.d.ts +0 -1
- package/dist/server/handlers/modelsHandler.d.ts +0 -1
- package/dist/server/metrics.d.ts +0 -1
- package/dist/server/modelMapper.d.ts +0 -1
- package/dist/server/proxyServer.d.ts +0 -1
- package/dist/server/router.d.ts +0 -1
- package/dist/server/state.d.ts +0 -1
- package/dist/tui/dashboard.d.ts +0 -1
- package/dist/utils/costUtils.d.ts +0 -1
- package/dist/utils/sorting.d.ts +0 -1
- package/dist/utils/tokenUtils.d.ts +0 -1
- package/docs/llms-full.txt +153 -286
- package/docs/llms.txt +71 -112
- package/integrations/browser-use/README.md +155 -0
- package/integrations/browser-use/examples/form-filling.ts +179 -0
- package/integrations/browser-use/index.ts +145 -0
- package/integrations/browser-use/package.json +34 -0
- package/integrations/browser-use/tsconfig.json +17 -0
- package/integrations/mcp-browser/README.md +177 -0
- package/integrations/mcp-browser/package.json +38 -0
- package/integrations/mcp-browser/src/index.ts +297 -0
- package/integrations/sota-browser/README.md +191 -0
- package/integrations/sota-browser/package.json +34 -0
- package/llms-full.txt +6 -6
- package/llms.txt +62 -112
- package/package.json +92 -13
- package/packages/a3m-vercel-ai/README.md +161 -0
- package/packages/a3m-vercel-ai/dist/a3m-language-model.d.ts +12 -0
- package/packages/a3m-vercel-ai/dist/a3m-language-model.d.ts.map +1 -0
- package/packages/a3m-vercel-ai/dist/a3m-language-model.js +289 -0
- package/packages/a3m-vercel-ai/dist/a3m-language-model.js.map +1 -0
- package/packages/a3m-vercel-ai/dist/index.d.ts +82 -0
- package/packages/a3m-vercel-ai/dist/index.d.ts.map +1 -0
- package/packages/a3m-vercel-ai/dist/index.js +79 -0
- package/packages/a3m-vercel-ai/dist/index.js.map +1 -0
- package/packages/a3m-vercel-ai/dist/types.d.ts +97 -0
- package/packages/a3m-vercel-ai/dist/types.d.ts.map +1 -0
- package/packages/a3m-vercel-ai/dist/types.js +5 -0
- package/packages/a3m-vercel-ai/dist/types.js.map +1 -0
- package/packages/a3m-vercel-ai/package-lock.json +969 -0
- package/packages/a3m-vercel-ai/package.json +46 -0
- package/packages/a3m-vercel-ai/src/a3m-language-model.ts +381 -0
- package/packages/a3m-vercel-ai/src/index.ts +104 -0
- package/packages/a3m-vercel-ai/src/types.ts +116 -0
- package/packages/a3m-vercel-ai/tsconfig.json +20 -0
- package/src/providers/providerConfig.ts +1053 -1
- package/summary.txt +38 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -94
- package/.github/ISSUE_TEMPLATE/config.yml +0 -17
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -71
- package/.well-known/ai-plugin.json +0 -16
- package/adapters/README.md +0 -36
- package/adapters/__init__.py +0 -25
- package/adapters/a3m_adapter/__init__.py +0 -15
- package/adapters/a3m_adapter/adapter/__init__.py +0 -7
- package/adapters/a3m_adapter/adapter/config.py +0 -100
- package/adapters/a3m_adapter/adapter/langchain.py +0 -155
- package/adapters/a3m_adapter/adapter/llamaindex.py +0 -162
- package/adapters/a3m_adapter/tests/__init__.py +0 -1
- package/adapters/a3m_adapter/tests/test_adapters.py +0 -120
- package/adapters/setup.py +0 -23
package/docs/llms-full.txt
CHANGED
|
@@ -1,332 +1,199 @@
|
|
|
1
|
-
# A3M Router —
|
|
1
|
+
# A3M Router — Complete Reference
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
|
+
A3M Router is an OpenAI-compatible LLM routing gateway that selects the cheapest capable provider per query using multi-signal heuristic scoring. Routes queries across 47+ providers in parallel, scores responses by confidence, returns best result.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
**Package:** `adaptive-memory-multi-model-router` (npm)
|
|
7
|
+
**Repository:** `Das-rebel/a3m-router` (GitHub)
|
|
8
|
+
**Language:** TypeScript (Node.js)
|
|
9
|
+
**License:** MIT
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
---
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
## Benchmark Results
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
### Benchmark Results
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
| Metric | Value |
|
|
18
|
+
|--------|-------|
|
|
19
|
+
| Score | 0.9404 |
|
|
20
|
+
| Accuracy | 96.77% |
|
|
21
|
+
| Avg Cost / 1K tokens | $0.0768 |
|
|
22
|
+
| Robustness | 1.0000 |
|
|
23
|
+
| Abnormal entries | 0 |
|
|
24
|
+
| Queries evaluated | 8,400 |
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
- Code generation: write, implement, create function
|
|
22
|
-
- Translation: translate, convert, rewrite in
|
|
23
|
-
- Analysis: compare, evaluate, assess, analyze
|
|
24
|
-
- Creative: write story, poem, generate idea
|
|
25
|
-
- Factual: what is, who was, when did, where is
|
|
26
|
+
Internal evaluation on 8,400 queries from diverse domains.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
- Clause count: complex sentences
|
|
29
|
-
- Explicit steps: first...then, step 1/2/3
|
|
30
|
-
- Qualifications: might, could, possibly
|
|
31
|
-
- Conditional: if...then, unless, provided that
|
|
28
|
+
### Official Baseline Status
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
| Benchmark | Venue | Status | Reference |
|
|
31
|
+
| Parallel Routing | Internal eval | 67% exact match |
|
|
32
|
+
| Cost vs all-premium | Internal eval | 62.9% savings |
|
|
33
|
+
| RouterEval | EMNLP 2025 | Baseline merged | MilkThink-Lab/RouterEval#4 |
|
|
34
|
+
| MMR-Bench | ArXiv 2026 | Baseline merged | Hunter-Wrynn/MMR-Bench#4 |
|
|
35
|
+
| LLMRouterBench | ACL 2026 | Submitted | ynulihao/LLMRouterBench#3 |
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
- Image references: explain this diagram
|
|
39
|
-
- Code blocks: debug this function
|
|
40
|
-
- Data: analyze this dataset
|
|
37
|
+
### Local Evaluation
|
|
41
38
|
|
|
42
|
-
|
|
39
|
+
| Metric | Value |
|
|
40
|
+
|--------|-------|
|
|
41
|
+
| Exact tier match | 67% |
|
|
42
|
+
| Within 1 tier | 96% |
|
|
43
|
+
| Cost savings vs all-premium | 62.9% |
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
---
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|------------|------|-----------|---------|
|
|
48
|
-
| 0-20 | Free | Ollama, Llama.cpp | Simple what/who |
|
|
49
|
-
| 21-40 | Cheap | Groq, DeepSeek, Mistral | Short code, basic QA |
|
|
50
|
-
| 41-70 | Mid | GPT-4o-mini, Claude-haiku | Standard tasks |
|
|
51
|
-
| 71-100 | Premium | GPT-4o, Claude-sonnet, Gemini | Complex reasoning |
|
|
47
|
+
## Architecture
|
|
52
48
|
|
|
53
|
-
## Ensemble Execution
|
|
54
|
-
|
|
55
|
-
### Configuration
|
|
56
|
-
|
|
57
|
-
```python
|
|
58
|
-
router = A3MRouter(
|
|
59
|
-
model="auto",
|
|
60
|
-
parallel_ensemble=3,
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
result = router.route(
|
|
64
|
-
messages=[{"role": "user", "content": prompt}],
|
|
65
|
-
ensemble_config={
|
|
66
|
-
"providers": ["groq", "openai", "deepseek"],
|
|
67
|
-
"timeout_ms": 15000,
|
|
68
|
-
"score_weights": {
|
|
69
|
-
"relevance": 0.4,
|
|
70
|
-
"conciseness": 0.3,
|
|
71
|
-
"accuracy": 0.3,
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
)
|
|
75
49
|
```
|
|
76
|
-
|
|
77
|
-
### Scoring Algorithm
|
|
78
|
-
|
|
79
|
-
1. Collect all responses within timeout
|
|
80
|
-
2. Compute per-provider scores:
|
|
81
|
-
- Relevance: cosine similarity to query embedding
|
|
82
|
-
- Conciseness: ratio of signal tokens / total tokens
|
|
83
|
-
- Accuracy: factual consistency score
|
|
84
|
-
3. Weighted sum → normalized scores
|
|
85
|
-
4. Winner = provider with highest weighted score
|
|
86
|
-
|
|
87
|
-
### Provider Response
|
|
88
|
-
|
|
89
|
-
```python
|
|
90
|
-
{
|
|
91
|
-
"content": "winning response text",
|
|
92
|
-
"provider": "openai",
|
|
93
|
-
"scores": {
|
|
94
|
-
"groq": {"relevance": 0.85, "conciseness": 0.9, "accuracy": 0.88},
|
|
95
|
-
"openai": {"relevance": 0.92, "conciseness": 0.85, "accuracy": 0.95},
|
|
96
|
-
"deepseek": {"relevance": 0.88, "conciseness": 0.82, "accuracy": 0.90},
|
|
97
|
-
},
|
|
98
|
-
"all_results": {
|
|
99
|
-
"groq": {"content": "...", "latency_ms": 450},
|
|
100
|
-
"openai": {"content": "...", "latency_ms": 1200},
|
|
101
|
-
"deepseek": {"content": "...", "latency_ms": 800},
|
|
102
|
-
},
|
|
103
|
-
"latency_ms": 1200,
|
|
104
|
-
"cost_usd": 0.0012,
|
|
105
|
-
}
|
|
50
|
+
Request → Guardrails → Semantic Cache → Router (5-signal heuristic) → Provider → Response
|
|
106
51
|
```
|
|
107
52
|
|
|
108
|
-
|
|
53
|
+
The routing pipeline executes in four stages:
|
|
54
|
+
1. Guardrails: Input validation (prompt injection, PII, content filtering)
|
|
55
|
+
2. Cache lookup: Semantic cache with embedding similarity
|
|
56
|
+
3. Routing decision: Multi-signal heuristic scoring → complexity score → provider tier
|
|
57
|
+
4. Execution: LLM call to selected provider with routing metadata in response
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Routing Method
|
|
62
|
+
|
|
63
|
+
### Complexity Score Computation
|
|
64
|
+
|
|
65
|
+
Five signal dimensions, summed:
|
|
66
|
+
|
|
67
|
+
| Dimension | Max | Method |
|
|
68
|
+
|-----------|-----|--------|
|
|
69
|
+
| Domain detection | +0.35 | Keyword matching: legal, medical, security, finance, code, ML |
|
|
70
|
+
| Task indicators | +0.25 | Keyword matching: code, math, translate, creative |
|
|
71
|
+
| Query structure | +0.20 | Clause count, character length, qualifier presence |
|
|
72
|
+
| Action verb intensity | +0.20 | Expert +0.20, mid +0.10, simple −0.10 |
|
|
73
|
+
| Multi-step detection | +0.15 | Explicit step markers (first...then, step 1/2/3) |
|
|
74
|
+
|
|
75
|
+
### Tier Mapping
|
|
76
|
+
|
|
77
|
+
| Score Range | Tier | Example Providers |
|
|
78
|
+
|------------|------|-----------------|
|
|
79
|
+
| 0.00–0.19 | free | taste-1 ($0) |
|
|
80
|
+
| 0.20–0.44 | cheap | llama-3.3-70b ($0.20/M) |
|
|
81
|
+
| 0.45–0.69 | mid | gpt-4o-mini ($0.60/M) |
|
|
82
|
+
| 0.70–1.00 | premium | gpt-4o ($2.50/M), claude-3.5-sonnet ($1.50/M) |
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Provider Coverage (47+)
|
|
87
|
+
|
|
88
|
+
| Provider | Tiers | Models |
|
|
89
|
+
|---------|-------|--------|
|
|
90
|
+
| OpenAI | premium, mid | gpt-4o, gpt-4o-mini |
|
|
91
|
+
| Anthropic | premium, mid | claude-3.5-sonnet, claude-3-haiku |
|
|
92
|
+
| Google | premium, mid | gemini-1.5-pro, gemini-1.5-flash |
|
|
93
|
+
| Groq | cheap | llama-3.3-70b, llama-3.1-8b |
|
|
94
|
+
| DeepSeek | cheap, mid | deepseek-chat, deepseek-coder |
|
|
95
|
+
| Mistral | cheap, mid | mistral-large, mistral-small |
|
|
96
|
+
| NVIDIA | premium | nvidia/llama-3.1-nemotron |
|
|
97
|
+
| OpenRouter | all | aggregated access |
|
|
98
|
+
| Kimi | cheap | moonshot-v1 |
|
|
99
|
+
| Qwen | cheap, mid | qwen-turbo, qwen-plus |
|
|
100
|
+
| Zhipu | cheap | glm-4 |
|
|
101
|
+
| Yi | cheap | yi-large |
|
|
102
|
+
| Azure OpenAI | premium, mid | via OpenAI-compatible endpoint |
|
|
103
|
+
| AWS Bedrock | premium, mid | via OpenAI-compatible endpoint |
|
|
104
|
+
| Local Ollama | all | configurable model discovery |
|
|
105
|
+
| Local vLLM | all | OpenAI-compatible server |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Feature Specifications
|
|
110
|
+
|
|
111
|
+
### Parallel Ensemble
|
|
112
|
+
Executes a single query against multiple providers simultaneously. Each response is scored on specificity, structure, and relevance. The highest-scoring result is returned with full provenance.
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { executeEnsemble } from 'adaptive-memory-multi-model-router/ensemble';
|
|
116
|
+
const result = await executeEnsemble(query, systemPrompt, context, providers, options);
|
|
117
|
+
// result.winner — provider key
|
|
118
|
+
// result.scores — per-provider score map
|
|
119
|
+
// result.reasoning — human-readable scoring rationale
|
|
120
|
+
// result.allResults — preserved responses from all providers
|
|
121
|
+
```
|
|
109
122
|
|
|
110
123
|
### Semantic Cache
|
|
124
|
+
Embedding-based lookup with configurable similarity threshold (default 0.92). Per-route TTL allows different freshness requirements per query domain.
|
|
111
125
|
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
"type": "semantic",
|
|
117
|
-
"threshold": 0.85, # cosine similarity
|
|
118
|
-
"ttl_seconds": 3600,
|
|
119
|
-
},
|
|
120
|
-
)
|
|
126
|
+
```typescript
|
|
127
|
+
import { SemanticCache } from 'adaptive-memory-multi-model-router/cache';
|
|
128
|
+
const cache = new SemanticCache({ similarityThreshold: 0.92, ttl: 3600000 });
|
|
129
|
+
// Embedding similarity > threshold → cache hit (no LLM call)
|
|
121
130
|
```
|
|
122
131
|
|
|
123
|
-
###
|
|
132
|
+
### Guardrails
|
|
133
|
+
Prompt injection detection covers 17 patterns including jailbreak templates, system prompt overrides, and delimiter-based injection. PII detection supports common entity types.
|
|
124
134
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
model="auto",
|
|
128
|
-
memory={
|
|
129
|
-
"type": "conversation",
|
|
130
|
-
"window": 10, # last 10 exchanges
|
|
131
|
-
"embedding_model": "text-embedding-3-small",
|
|
132
|
-
},
|
|
133
|
-
)
|
|
134
|
-
```
|
|
135
|
+
### Adaptive Memory
|
|
136
|
+
Model quality scores update online via exponential moving average (alpha=0.2) after each real LLM call. Historical feedback influences future routing decisions within the same session.
|
|
135
137
|
|
|
136
|
-
###
|
|
138
|
+
### Budget Enforcement
|
|
139
|
+
Per-user and per-team monthly spend caps with hard limits. Real-time alerts at 50%, 80%, and 100% thresholds. Per-provider cost breakdown.
|
|
137
140
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
model="auto",
|
|
141
|
-
memory={
|
|
142
|
-
"type": "semantic",
|
|
143
|
-
"persistent": True,
|
|
144
|
-
"namespace": "user_123",
|
|
145
|
-
"similarity_threshold": 0.85,
|
|
146
|
-
},
|
|
147
|
-
)
|
|
148
|
-
```
|
|
141
|
+
### Circuit Breaker
|
|
142
|
+
Trip after 3 failures, 60s cooldown. Automatic fallback chain across provider tiers.
|
|
149
143
|
|
|
150
|
-
|
|
144
|
+
### Per-Provider Retry
|
|
145
|
+
Custom timeout per provider. Exponential backoff with jitter. Rate limit detection (429) triggers Retry-After-aware backoff.
|
|
151
146
|
|
|
152
|
-
|
|
147
|
+
---
|
|
153
148
|
|
|
154
|
-
|
|
155
|
-
# Patterns detected:
|
|
156
|
-
# - System prompt override attempts
|
|
157
|
-
# - Delimiter injection (USER:, SANDBOX:)
|
|
158
|
-
# - Role confusion attacks
|
|
159
|
-
# - Privilege escalation patterns
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### PII Detection
|
|
149
|
+
## API Reference
|
|
163
150
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
151
|
+
| Method | Endpoint | Description |
|
|
152
|
+
|--------|----------|-------------|
|
|
153
|
+
| POST | `/v1/chat/completions` | OpenAI-compatible chat |
|
|
154
|
+
| POST | `/v1/route` | Routing decision without LLM call |
|
|
155
|
+
| GET | `/v1/models` | Available models with pricing |
|
|
156
|
+
| GET | `/health` | Provider health scores |
|
|
167
157
|
|
|
168
|
-
|
|
158
|
+
---
|
|
169
159
|
|
|
170
|
-
|
|
160
|
+
## Installation
|
|
171
161
|
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
0.3 * (1 - error_rate)
|
|
176
|
-
) * latency_factor
|
|
162
|
+
```bash
|
|
163
|
+
npm install adaptive-memory-multi-model-router
|
|
164
|
+
npx a3m-router serve # proxy at http://localhost:8787
|
|
177
165
|
```
|
|
178
166
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
- 1-3s: 0.9
|
|
182
|
-
- 3-10s: 0.7
|
|
183
|
-
- >10s: 0.3
|
|
184
|
-
|
|
185
|
-
## Rate Limiting
|
|
186
|
-
|
|
187
|
-
### Charnov MVT Implementation
|
|
188
|
-
|
|
189
|
-
Optimal departure time from rate-limited provider:
|
|
190
|
-
|
|
191
|
-
```
|
|
192
|
-
depart_when: marginal_remaining_rate < average_rate_including_switch_cost
|
|
167
|
+
```python
|
|
168
|
+
pip install a3m-router
|
|
193
169
|
```
|
|
194
170
|
|
|
195
|
-
### Rotation Strategy
|
|
196
|
-
|
|
197
|
-
1. Track rate-limit windows per provider
|
|
198
|
-
2. When window depletes < threshold, begin rotation
|
|
199
|
-
3. Switch to next healthiest provider in tier
|
|
200
|
-
4. Track rotation frequency to avoid thrashing
|
|
201
|
-
|
|
202
|
-
## EXP3 Diversity
|
|
203
|
-
|
|
204
|
-
### Weight Update
|
|
205
|
-
|
|
206
171
|
```python
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
provider.weight *= exp(-penalty)
|
|
172
|
+
from openai import OpenAI
|
|
173
|
+
client = OpenAI(base_url="http://localhost:8787/v1", api_key="not-needed")
|
|
174
|
+
response = client.chat.completions.create(model="auto", messages=[...])
|
|
211
175
|
```
|
|
212
176
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
Weights normalized to sum to 1.0 after each update.
|
|
177
|
+
---
|
|
216
178
|
|
|
217
|
-
##
|
|
179
|
+
## Citation
|
|
218
180
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
## API Reference
|
|
227
|
-
|
|
228
|
-
### POST /v1/chat/completions
|
|
229
|
-
|
|
230
|
-
Request:
|
|
231
|
-
```json
|
|
232
|
-
{
|
|
233
|
-
"model": "auto",
|
|
234
|
-
"messages": [{"role": "user", "content": "..."}],
|
|
235
|
-
"temperature": 0.7,
|
|
236
|
-
"max_tokens": 4096,
|
|
237
|
-
"parallel_ensemble": 1,
|
|
238
|
-
"stream": false
|
|
181
|
+
```bibtex
|
|
182
|
+
@software{a3m_router,
|
|
183
|
+
title = {A3M Router: OpenAI-Compatible LLM Routing Gateway},
|
|
184
|
+
author = {Subho Mukherjee},
|
|
185
|
+
year = {2025},
|
|
186
|
+
url = {https://github.com/Das-rebel/a3m-router},
|
|
187
|
+
note = {Parallel ensemble routing across 47+ providers.
|
|
239
188
|
}
|
|
240
189
|
```
|
|
241
190
|
|
|
242
|
-
|
|
243
|
-
```json
|
|
244
|
-
{
|
|
245
|
-
"id": "chatcmpl-xxx",
|
|
246
|
-
"object": "chat.completion",
|
|
247
|
-
"created": 1234567890,
|
|
248
|
-
"model": "auto",
|
|
249
|
-
"provider": "groq",
|
|
250
|
-
"choices": [{
|
|
251
|
-
"message": {"role": "assistant", "content": "..."},
|
|
252
|
-
"finish_reason": "stop",
|
|
253
|
-
"index": 0
|
|
254
|
-
}],
|
|
255
|
-
"usage": {
|
|
256
|
-
"prompt_tokens": 20,
|
|
257
|
-
"completion_tokens": 150,
|
|
258
|
-
"total_tokens": 170
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
## Environment Variables
|
|
264
|
-
|
|
265
|
-
| Variable | Description | Default |
|
|
266
|
-
|----------|-------------|---------|
|
|
267
|
-
| A3M_PORT | Server port | 8787 |
|
|
268
|
-
| A3M_API_KEYS | JSON of provider keys | {} |
|
|
269
|
-
| A3M_BUDGET_MONTHLY | Monthly budget limit | unlimited |
|
|
270
|
-
| A3M_CACHE_TTL | Cache TTL in seconds | 3600 |
|
|
271
|
-
| A3M_LOG_LEVEL | log level | info |
|
|
272
|
-
|
|
273
|
-
## Architecture Diagram
|
|
274
|
-
|
|
275
|
-
```
|
|
276
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
277
|
-
│ Client Request │
|
|
278
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
279
|
-
│
|
|
280
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
281
|
-
│ Guardrails │
|
|
282
|
-
│ • Prompt injection detection │
|
|
283
|
-
│ • PII filtering │
|
|
284
|
-
│ • Content safety │
|
|
285
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
286
|
-
│
|
|
287
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
288
|
-
│ Semantic Cache │
|
|
289
|
-
│ • Embedding similarity lookup │
|
|
290
|
-
│ • Zero-cost hits │
|
|
291
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
292
|
-
│ cache miss
|
|
293
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
294
|
-
│ Router │
|
|
295
|
-
│ • Complexity scoring │
|
|
296
|
-
│ • Tier assignment │
|
|
297
|
-
│ • Provider selection │
|
|
298
|
-
│ • EXP3 diversity weighting │
|
|
299
|
-
│ • Charnov MVT rate-limit rotation │
|
|
300
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
301
|
-
│
|
|
302
|
-
┌─────────────────┼─────────────────┐
|
|
303
|
-
│ │ │
|
|
304
|
-
┌───────▼───────┐ ┌──────▼──────┐ ┌──────▼──────┐
|
|
305
|
-
│ Provider 1 │ │ Provider 2 │ │ Provider 3 │
|
|
306
|
-
│ (Groq) │ │ (OpenAI) │ │ (DeepSeek) │
|
|
307
|
-
└───────────────┘ └─────────────┘ └─────────────┘
|
|
308
|
-
│ │ │
|
|
309
|
-
└─────────────────┼─────────────────┘
|
|
310
|
-
│
|
|
311
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
312
|
-
│ Ensemble Scorer │
|
|
313
|
-
│ • Collect responses │
|
|
314
|
-
│ • Score on quality metrics │
|
|
315
|
-
│ • Select winner │
|
|
316
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
317
|
-
│
|
|
318
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
319
|
-
│ Memory Layer │
|
|
320
|
-
│ • Cache response │
|
|
321
|
-
│ • Update context │
|
|
322
|
-
│ • Store embeddings │
|
|
323
|
-
└─────────────────────────┬───────────────────────────────────┘
|
|
324
|
-
│
|
|
325
|
-
┌─────────────────────────▼───────────────────────────────────┐
|
|
326
|
-
│ Response │
|
|
327
|
-
└─────────────────────────────────────────────────────────────┘
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
## License
|
|
191
|
+
---
|
|
331
192
|
|
|
332
|
-
|
|
193
|
+
## References
|
|
194
|
+
- RouteWorks/RouterArena (ICLR 2025): https://github.com/RouteWorks/RouterArena
|
|
195
|
+
- MilkThink-Lab/RouterEval (EMNLP 2025): https://github.com/MilkThink-Lab/RouterEval
|
|
196
|
+
- Hunter-Wrynn/MMR-Bench (ArXiv 2026): https://github.com/Hunter-Wrynn/MMR-Bench
|
|
197
|
+
- ynulihao/LLMRouterBench (ACL 2026): https://github.com/ynulihao/LLMRouterBench
|
|
198
|
+
- Lin et al. "RouteLLM." arXiv:2404.06035, 2024
|
|
199
|
+
- Zhong et al. "RadixAttention." arXiv:2412.15115, 2024
|