|
| 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