Skip to content

Commit b9788c4

Browse files
committed
docs: add ARCHITECTURE.md and CHANGELOG.md
1 parent f8a80d9 commit b9788c4

2 files changed

Lines changed: 732 additions & 22 deletions

File tree

‎ARCHITECTURE.md‎

Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
# Architecture
2+
3+
## A3M Router — Adaptive Memory Multi-Model Router
4+
5+
A multi-provider LLM routing and orchestration engine. Routes prompts across 47+ providers, executes them in parallel with ensemble voting, and adapts model selection based on learned quality profiles, cost constraints, and task complexity.
6+
7+
## High-Level Overview
8+
9+
The system has three layers:
10+
11+
```
12+
User / API / CLI / TUI
13+
|
14+
[Proxy Server / LangChain Adapter]
15+
|
16+
[Routing Engine] ←── [Memory System] ←── [Semantic Cache]
17+
|
18+
[Provider Layer] ←── [Retry Handler] ←── [Guardrails]
19+
|
20+
[47+ LLM APIs]
21+
```
22+
23+
- **TypeScript Core** — routing, provider config, cost tracking, observability, cache, guardrails, proxy server, TUI
24+
- **Python Layer** — Universal Model Router (learned routing), HALO orchestration (hierarchical planning), MCTS workflow search
25+
- **Integrations** — LangChain adapter, MCP server, OpenAI-compatible proxy, CLI/TUI
26+
27+
## Directory Structure
28+
29+
```
30+
src/
31+
index.ts # Main entry point — exports all public APIs, createA3MRouter()
32+
sdk.ts # A3MRouter SDK class — route(), routeBatch(), recommend(), serve(), analyze()
33+
routing/
34+
providerRetry.ts # Per-provider retry with exponential backoff + jitter, context window validation
35+
providerHealth.ts # Provider health monitoring
36+
universal_router.py # UniversalModelRouter — learned routing with online adaptation (Python)
37+
providers/
38+
providerConfig.ts # 47+ provider definitions, config loading, health checks, runtime registration
39+
registry.py # Python provider registry with health monitoring
40+
base.py # Python base provider classes
41+
anthropic.py # Anthropic provider implementation (Python)
42+
cerebras.py # Cerebras provider implementation (Python)
43+
memory/
44+
memoryTree.ts # MemoryTree — hierarchical chunk storage with search
45+
autoFetch.ts # Automatic memory fetching
46+
obsidianVault.ts # Obsidian vault integration
47+
agentic_memory.py # Agentic memory (Python)
48+
semantic_memory.py # Semantic memory (Python)
49+
simple_memory.py # Simple memory (Python)
50+
working_memory.py # Working memory (Python)
51+
cost/
52+
costTracker.ts # Per-request cost tracking
53+
budgetEnforcer.ts # Budget limits, spend records, alerts
54+
analytics/
55+
costAnalytics.ts # Advanced cost analytics, savings reports, projections
56+
cache/
57+
semanticCache.ts # Embedding-based semantic cache with cosine similarity
58+
research/ # Cache research files
59+
security/
60+
guardrails.ts # Prompt injection, PII detection, content filtering, output validation
61+
observability/
62+
index.ts # Observable exports
63+
types.ts # Span, Metric, RouteTrace types
64+
tracer.ts # Distributed tracing
65+
metrics.ts # Metrics collector
66+
middleware.ts # Express-style observability middleware
67+
server/
68+
proxyServer.ts # OpenAI-compatible HTTP proxy — POST /v1/chat/completions, GET /v1/models
69+
modelMapper.ts # Model name resolution
70+
dashboard.ts # Server dashboard
71+
integrations/
72+
langchainAdapter.ts # Drop-in ChatOpenAI replacement for LangChain
73+
oauth.ts # OAuth integration
74+
cli/
75+
setupWizard.ts # Interactive setup wizard
76+
tui/
77+
index.ts # TUI launch wrapper
78+
dashboard.ts # Blessed-based terminal dashboard
79+
orchestration/ # (Python) HALO hierarchical orchestration
80+
halo_orchestrator.py # HALO orchestrator — 3-tier planning
81+
task_planner.py # Task decomposition into subtasks
82+
role_assigner.py # Agent role assignment
83+
execution_engine.py # Parallel execution with verification
84+
mcts_workflow.py # MCTS-based workflow search
85+
workflows/ # (Python) Workflow executors
86+
router.py # Workflow router
87+
orchestrator.py # Workflow orchestrator
88+
chaining_executor.py # Sequential chain execution
89+
parallelization_executor.py # Parallel task execution
90+
difficulty_integration.py # Difficulty-aware routing
91+
agents/
92+
skill_enhanced_agent.py # Skill-enhanced agent (Python)
93+
state/
94+
simple_checkpoint.py # State checkpointing (Python)
95+
types/
96+
langchain.d.ts # LangChain type declarations
97+
utils/ # (referenced from index.ts exports)
98+
tokenUtils.ts # Token counting and estimation
99+
100+
python/
101+
a3m/ # Python SDK for A3M Router
102+
tmlpd.py # TMLPD Python client
103+
examples.py # Usage examples
104+
integrations.py # Python integration helpers
105+
106+
mcp-server/ # MCP (Model Context Protocol) server for AI agent integration
107+
integrations/ # Additional integration entry points
108+
eval/ # Evaluation framework and benchmarks
109+
test/ tests/ # Test suites (TypeScript + Python)
110+
docs/ # GitHub Pages documentation site
111+
demo/ # Demo scripts and recordings
112+
```
113+
114+
## Key Components
115+
116+
### 1. Ensemble Voting (P0)
117+
118+
The unique differentiator. Routes the same query to multiple providers in parallel, then merges responses using confidence-weighted voting. No other LLM router does this — everyone does sequential fallback (try A, then B, then C).
119+
120+
The ensemble flow:
121+
1. Query enters the routing engine
122+
2. Classifier extracts features (complexity, domain, length, code/math presence)
123+
3. Top-N candidate models selected by tier, cost, and quality profile
124+
4. Query dispatched to all N providers in parallel
125+
5. Responses collected and merged with confidence weighting
126+
6. Best merged result returned with fallback alternatives
127+
128+
### 2. Query Classification
129+
130+
The routing engine (`sdk.ts` → `extractQueryFeatures`) classifies queries on 10+ signals:
131+
132+
| Signal | Description |
133+
|--------|-------------|
134+
| complexity | 0.0–1.0, based on keyword density and reasoning indicators |
135+
| has_code | Code block or programming keyword presence |
136+
| has_math | Mathematical expression detection |
137+
| is_multilingual | Non-English character ratio |
138+
| is_translation | Translation verb detection |
139+
| is_creative | Creative writing indicators |
140+
| requires_reasoning | Step-by-step reasoning triggers |
141+
| domain | Detected domain (legal, medical, security, finance, devops, data) |
142+
143+
Classification routes to the `free` / `cheap` / `mid` / `premium` cost tier, targeting 99.5% accuracy within +/-1 tier (validated by independent benchmark).
144+
145+
### 3. Memory System
146+
147+
The `MemoryTree` (`memory/memoryTree.ts`) canonicalizes data into ≤3k-token chunks, scores each by relevance, and builds hierarchical summary trees. Supports:
148+
- **Search**: keyword matching with score ranking
149+
- **Context retrieval**: top-scored chunks for routing enrichment
150+
- **Obsidian export**: markdown serialization
151+
- **Stats**: tree depth, chunk count, memory utilization
152+
153+
Python memory variants (`agentic_memory.py`, `semantic_memory.py`, `working_memory.py`) provide agent-specific memory stores for the orchestration layer.
154+
155+
### 4. Provider Routing
156+
157+
The provider system (`providers/providerConfig.ts`) defines 47+ providers across five tiers:
158+
159+
| Tier | Providers | Purpose |
160+
|------|-----------|---------|
161+
| free | Ollama, LM Studio, vLLM, Google (free tier), NVIDIA NIM | Local / zero-cost |
162+
| cheap | Groq, Cerebras, DeepInfra, Together, Fireworks, Novita, SambaNova, Anyscale, Replicate | Inference-optimized |
163+
| mid | DeepSeek, Mistral, Perplexity, Cohere, AI21, Qwen (DashScope), StepFun | Good quality/price |
164+
| premium | OpenAI, Anthropic, xAI (Grok) | Frontier models |
165+
| enterprise | Azure OpenAI, AWS Bedrock, Google Vertex | Cloud-managed |
166+
167+
Each provider has:
168+
- `baseUrl`, `apiKeyEnv` (env var name), `models` list
169+
- `costPerK` (input/output), `tier`, `format` (openai/anthropic/google/cohere/aws-bedrock/google-vertex)
170+
- `type` (api/cli/local), `priority` (selection order), `maxTokens`
171+
172+
Configuration sources (in priority order):
173+
1. Environment variables (`*_API_KEY`)
174+
2. `~/.config/a3m-router/providers.json`
175+
3. Runtime registration via `registerProvider()`
176+
177+
### 5. Security (Guardrails Engine)
178+
179+
The `GuardrailEngine` (`security/guardrails.ts`) provides configurable input/output checks:
180+
- **Prompt injection**: score-based detection (0–100)
181+
- **PII detection and redaction**: emails, phones, SSNs, credit cards, IPs
182+
- **Content filtering**: configurable blocklist, regex patterns
183+
- **Language detection**: for intelligent routing decisions
184+
- **Output validation**: quality checks, hallucination detection
185+
- **Custom guardrails**: user-defined check functions
186+
187+
### 6. Observability
188+
189+
Three subsystems:
190+
- **Tracer**: distributed tracing with span creation, completion, and route trace construction
191+
- **MetricsCollector**: runtime metrics — request counts, latencies, error rates, cache hit rates
192+
- **Middlewares**: Express-style `observabilityMiddleware`, `observabilityPlugin`, `budgetAlertMiddleware`
193+
194+
### 7. Semantic Cache
195+
196+
Embedding-based cache (`cache/semanticCache.ts`) stores query-response pairs. On lookup, computes cosine similarity against stored embeddings. Supports configurable threshold (default 0.92), TTL, LRU eviction (1000 entries), and multiple embedders (nomic via Ollama, OpenAI, or local).
197+
198+
### 8. Cost Tracking
199+
200+
Tiered cost management:
201+
- **CostTracker**: per-request recording with provider, model, tokens, latency
202+
- **CostAnalytics**: savings reports, monthly projections, provider breakdowns, CSV/JSON export
203+
- **BudgetEnforcer**: hard budget caps with pre-request checks and alerts
204+
205+
### 9. Proxy Server
206+
207+
OpenAI-compatible HTTP proxy (`server/proxyServer.ts`) using only Node.js built-in `http` module. Endpoints:
208+
- `POST /v1/chat/completions` — OpenAI-compatible chat
209+
- `POST /v1/completions` — Text completions
210+
- `GET /v1/models` — Available models
211+
- `GET /health` — Provider health status
212+
213+
Any OpenAI SDK can point to this proxy to get A3M routing automatically.
214+
215+
### 10. HALO Orchestration (Python)
216+
217+
Hierarchical Autonomous Logic-Oriented Orchestration based on arXiv:2505.13516. Three tiers:
218+
219+
1. **TaskPlanner**: decomposes complex tasks into subtasks with dependency resolution
220+
2. **RoleAssigner**: assigns specialized agents (roles) to each subtask
221+
3. **ExecutionEngine**: executes subtasks in parallel with verification and adaptive refinement
222+
223+
Optionally uses **MCTS** (Monte Carlo Tree Search) to explore different execution strategies and learn optimal workflows per task type.
224+
225+
### 11. MCP Server
226+
227+
Model Context Protocol server for AI agent integration. Allows AI agents (Claude, etc.) to use the A3M Router as a tool for parallel multi-LLM execution.
228+
229+
### 12. LangChain Integration
230+
231+
`A3MChatModel` (`integrations/langchainAdapter.ts`) is a drop-in replacement for `ChatOpenAI`. Routes all LLM calls through A3M for cost optimization and intelligent provider selection. Supports streaming, tool calling, and batch processing.
232+
233+
## Data Flow
234+
235+
```
236+
1. User sends query (via SDK, proxy, CLI, TUI, or LangChain)
237+
2. GuardrailsEngine checks input (injection, PII, content, length)
238+
3. SemanticCache looks up embedding match (skip if cache hit)
239+
4. RoutingEngine classifies query (complexity, domain, features)
240+
5. Router selects optimal provider(s) using:
241+
- Learned quality profiles (UniversalModelRouter)
242+
- Cost constraints (BudgetEnforcer)
243+
- Retry configuration (ProviderRetryHandler)
244+
6. (Optional) Multiple providers called in parallel for ensemble voting
245+
7. ProviderRetryHandler executes with exponential backoff + jitter
246+
8. GuardrailsEngine validates output
247+
9. Response returned + recorded in:
248+
- CostTracker (per-request cost)
249+
- CostAnalytics (aggregate stats)
250+
- Observability (tracing + metrics)
251+
- SemanticCache (store for future hits)
252+
- MemoryTree (context enrichment)
253+
```
254+
255+
## Design Decisions and Trade-offs
256+
257+
| Decision | Rationale | Trade-off |
258+
|----------|-----------|-----------|
259+
| **TypeScript primary** | npm ecosystem reach, serverless compatibility, Vercel/Netlify/Cloudflare Workers | Python users need separate SDK |
260+
| **Node.js built-in http** for proxy | Zero dependencies, 19.5 KB total bundle | Less feature-rich than Express |
261+
| **Embedding-based cache** | Semantic similarity beats exact-match for LLM queries | Requires Ollama or OpenAI embedder |
262+
| **Per-provider retry config** | Chinese providers need longer timeouts + more retries (network latency, rate limits) | More config surface |
263+
| **In-memory storage** | Zero infra, instant setup, 19.5 KB | No persistence across restarts (memory tree serializable to markdown) |
264+
| **Online learning (Python router)** | Adapts to unseen models and changing quality | Requires feedback loop, cold start with heuristics |
265+
| **MCTS for workflow search** | Finds optimal strategies for complex tasks | 3-10x slower than greedy for simple tasks |
266+
| **47+ baked-in providers** | Zero-config multi-provider out of box | Maintenance burden as APIs change |
267+
268+
## Extension Points
269+
270+
### Adding a New Provider
271+
272+
```typescript
273+
import { registerProvider, ProviderDefinition } from 'adaptive-memory-multi-model-router';
274+
275+
registerProvider('my-provider', {
276+
name: 'My Provider',
277+
baseUrl: 'https://api.myprovider.com/v1/chat/completions',
278+
apiKeyEnv: 'MY_PROVIDER_API_KEY',
279+
models: ['model-name'],
280+
costPerK: { input: 1.0, output: 2.0 },
281+
tier: 'mid', // free | cheap | mid | premium | enterprise
282+
format: 'openai', // openai | anthropic | google | cohere | aws-bedrock | google-vertex
283+
type: 'api', // api | cli | local
284+
priority: 15,
285+
maxTokens: 8192,
286+
});
287+
```
288+
289+
Or via config file at `~/.config/a3m-router/providers.json`:
290+
```json
291+
{
292+
"providers": {
293+
"my-provider": {
294+
"name": "My Provider",
295+
"baseUrl": "https://api.myprovider.com/v1/chat/completions",
296+
"apiKeyEnv": "MY_PROVIDER_API_KEY",
297+
"models": ["model-name"],
298+
"tier": "mid"
299+
}
300+
}
301+
}
302+
```
303+
304+
### Adding a Custom Retry Strategy
305+
306+
```typescript
307+
import { createRetryHandler } from 'adaptive-memory-multi-model-router';
308+
309+
const handler = createRetryHandler({
310+
'my-slow-provider': {
311+
timeout: 60000,
312+
retry: { maxRetries: 5, initialDelayMs: 5000 },
313+
},
314+
});
315+
```
316+
317+
### Adding Custom Guardrails
318+
319+
```typescript
320+
import { GuardrailEngine } from 'adaptive-memory-multi-model-router';
321+
322+
const guardrails = new GuardrailEngine({
323+
userGuardrails: [
324+
(content) => ({
325+
passed: !content.includes('blocked-term'),
326+
blocked: content.includes('blocked-term'),
327+
reason: content.includes('blocked-term') ? 'Blocked term detected' : undefined,
328+
}),
329+
],
330+
});
331+
```
332+
333+
### Adding Ensemble Voting Strategies
334+
335+
The ensemble system is extensible by adding new voting strategies to the parallel execution pipeline. Current strategy: confidence-weighted average across multiple provider responses.
336+
337+
### Custom Routing Strategies
338+
339+
The `UniversalModelRouter` (Python) learns routing profiles from execution data. To implement a custom strategy:
340+
1. Subclass or wrap `routeQuery` in TypeScript
341+
2. Or extend `UniversalModelRouter._calculate_combined_score` in Python
342+
3. Register custom feature extractors via `extractQueryFeatures`
343+
344+
### MCP Server Extensions
345+
346+
The MCP server at `mcp-server/` exposes routing as tools. Add tools by extending the MCP tool definitions.

0 commit comments

Comments
 (0)