adaptive-memory-multi-model-router 2.16.0 → 2.16.2
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/.github/workflows/adapters-ci.yml +142 -0
- package/.github/workflows/auto-submit-sitemap.yml +41 -0
- package/.github/workflows/ci.yml +2 -5
- package/.github/workflows/mcp-pypi-publish.yml +34 -0
- package/.github/workflows/pypi-publish.yml +146 -0
- package/.github/workflows/tmlpd-publish.yml +23 -0
- package/README.md +245 -148
- package/RELEASE_v2.16.0.md +149 -0
- package/TECHNICAL_README.md +253 -0
- package/adapters/README.md +36 -0
- package/adapters/__init__.py +25 -0
- package/adapters/a3m_adapter/__init__.py +51 -0
- package/adapters/a3m_adapter/adapter/__init__.py +22 -0
- package/adapters/a3m_adapter/adapter/autogen.py +169 -0
- package/adapters/a3m_adapter/adapter/config.py +100 -0
- package/adapters/a3m_adapter/adapter/haystack.py +197 -0
- package/adapters/a3m_adapter/adapter/langchain.py +155 -0
- package/adapters/a3m_adapter/adapter/langgraph.py +196 -0
- package/adapters/a3m_adapter/adapter/llamaindex.py +162 -0
- package/adapters/a3m_adapter/adapter/pinecone.py +217 -0
- package/adapters/a3m_adapter/adapter/vercel.py +188 -0
- package/adapters/a3m_adapter/tests/__init__.py +1 -0
- package/adapters/a3m_adapter/tests/test_adapters.py +118 -0
- package/adapters/a3m_adapter/tests/test_integration.py +80 -0
- package/adapters/requirements-dev.txt +6 -0
- package/adapters/requirements.txt +4 -0
- package/adapters/setup.py +23 -0
- package/demo.py +251 -0
- package/discoverability-diagnosis.md +280 -0
- package/dist/analytics/costAnalytics.d.ts.map +1 -1
- package/dist/benchmark/reproducible.d.ts.map +1 -1
- package/dist/cache/semanticCache.d.ts.map +1 -1
- package/dist/cli/setupWizard.d.ts +257 -50
- package/dist/cli/setupWizard.d.ts.map +1 -1
- package/dist/cli/setupWizard.js +419 -109
- package/dist/cli/setupWizard.js.map +1 -1
- package/dist/cli/tui.d.ts +6 -0
- package/dist/cli/tui.js +96 -67
- package/dist/cli/tui.js.map +1 -0
- package/dist/cli.js +9 -0
- package/dist/cost/budgetEnforcer.d.ts.map +1 -1
- package/dist/cost/costTracker.d.ts.map +1 -1
- package/dist/ensemble/multiRoundDialog.d.ts.map +1 -1
- package/dist/ensemble/shapleyValue.d.ts.map +1 -1
- package/dist/ensemble.d.ts +1 -1
- package/dist/ensemble.js +141 -0
- package/dist/integrations/langchainAdapter.d.ts.map +1 -1
- package/dist/integrations/langchainAdapter.js +3 -3
- package/dist/integrations/langchainAdapter.js.map +1 -1
- package/dist/integrations/oauth.d.ts.map +1 -1
- package/dist/integrations/scienceAdapter.d.ts.map +1 -1
- package/dist/memory/autoFetch.d.ts.map +1 -1
- package/dist/memory/hybridMemory.d.ts.map +1 -1
- package/dist/memory/memoryTree.d.ts.map +1 -1
- package/dist/memory/obsidianVault.d.ts.map +1 -1
- package/dist/memory/reasoningBank.d.ts.map +1 -1
- package/dist/observability/metrics.d.ts.map +1 -1
- package/dist/observability/tracer.d.ts.map +1 -1
- package/dist/providers/providerConfig.d.ts.map +1 -1
- package/dist/providers/providerConfig.js +32 -17
- package/dist/providers/providerConfig.js.map +1 -1
- package/dist/routing/advancedRouter.d.ts.map +1 -1
- package/dist/routing/advancedRouter.js +106 -14
- package/dist/routing/advancedRouter.js.map +1 -1
- package/dist/routing/providerHealth.d.ts.map +1 -1
- package/dist/routing/providerRetry.d.ts.map +1 -1
- package/dist/routing/shadowSampler.d.ts.map +1 -0
- package/dist/routing/shadowSampler.js.map +1 -1
- package/dist/security/guardrails.d.ts.map +1 -1
- package/dist/server/handlers/chatHandler.d.ts.map +1 -1
- package/dist/server/handlers/completionsHandler.d.ts.map +1 -1
- package/dist/server/handlers/embeddingsHandler.d.ts.map +1 -1
- package/dist/server/handlers/healthHandler.d.ts.map +1 -1
- package/dist/server/handlers/metricsHandler.d.ts.map +1 -1
- package/dist/server/handlers/modelsHandler.d.ts.map +1 -1
- package/dist/server/metrics.d.ts.map +1 -1
- package/dist/server/proxyServer.d.ts.map +1 -1
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/state.d.ts.map +1 -1
- package/dist/skills/__tests__/skill_manager.test.js +5 -265
- package/dist/skills/__tests__/skill_manager.test.js.map +1 -1
- package/dist/utils/tokenUtils.d.ts.map +1 -1
- package/docker-compose.yml +84 -60
- package/docs/ARTICLE_Biology_Inspired_Routing.md +208 -0
- package/docs/ARTICLE_Master.md +78 -0
- package/docs/ARTICLE_Master_CN.md +78 -0
- package/docs/ARTICLE_OpenRouter_Stripe.md +140 -0
- package/docs/DEVPTO_ARTICLE.md +84 -0
- package/docs/HUMAN_STYLE_GUIDE.md +75 -0
- package/docs/IMPRINT_PLAN.md +88 -0
- package/docs/OPENROUTER_ALTERNATIVE.md +184 -0
- package/docs/SOCIAL_CAMPAIGN.md +316 -0
- package/docs/anthropic.html +45 -0
- package/docs/best-llm-routers-2025.html +157 -0
- package/docs/cerebras.html +43 -0
- package/docs/cli-cheatsheet.md +286 -212
- package/docs/comparison.md +2 -2
- package/docs/deepseek.html +44 -0
- package/docs/google.html +47 -0
- package/docs/groq.html +44 -0
- package/docs/llms-full.txt +360 -138
- package/docs/llms.txt +70 -71
- package/docs/mistral.html +43 -0
- package/docs/ollama.html +50 -0
- package/docs/openai.html +57 -0
- package/docs/sitemap.xml +69 -57
- package/docs-site/blog/best-llm-routers-2025.html +157 -0
- package/docs-site/index.html +68 -9
- package/docs-site/providers/anthropic.html +45 -0
- package/docs-site/providers/cerebras.html +43 -0
- package/docs-site/providers/deepseek.html +44 -0
- package/docs-site/providers/google.html +47 -0
- package/docs-site/providers/groq.html +44 -0
- package/docs-site/providers/index.html +41 -0
- package/docs-site/providers/mistral.html +43 -0
- package/docs-site/providers/ollama.html +50 -0
- package/docs-site/providers/openai.html +57 -0
- package/docs-site/sitemap.xml +69 -0
- package/llms.txt +70 -62
- package/package.json +44 -182
- package/packages/agentkit-adapter/LICENSE +21 -0
- package/packages/agentkit-adapter/README.md +126 -0
- package/packages/agentkit-adapter/examples/agentkit-example.ts +139 -0
- package/packages/agentkit-adapter/package.json +57 -0
- package/packages/agentkit-adapter/src/adapter.ts +381 -0
- package/packages/agentkit-adapter/src/index.ts +36 -0
- package/packages/agentkit-adapter/src/types.ts +105 -0
- package/packages/agentkit-adapter/src/util.ts +13 -0
- package/packages/agentkit-adapter/tsconfig.json +22 -0
- package/prometheus.yml +8 -0
- package/python/README.md +35 -81
- package/python/a3m/__init__.py +32 -3
- package/python/a3m/adapters/__init__.py +21 -0
- package/python/a3m/adapters/langchain.py +190 -0
- package/python/a3m/adapters/llamaindex.py +249 -0
- package/python/a3m/adapters/qdrant.py +240 -0
- package/python/a3m/adapters/weaviate.py +263 -0
- package/python/a3m/client.py +5 -0
- package/python/build_verify.sh +32 -0
- package/python/mcp-server/README.md +172 -0
- package/python/mcp-server/a3m_mcp/__init__.py +25 -0
- package/python/mcp-server/a3m_mcp/__main__.py +15 -0
- package/python/mcp-server/a3m_mcp/server.py +205 -0
- package/python/mcp-server/pyproject.toml +24 -0
- package/python/pyproject.toml +60 -6
- package/python/setup.py +3 -28
- package/scripts/submit-sitemap.sh +52 -0
- package/src/__types__/registry.d.ts +14 -0
- package/src/cli/setupWizard.ts +443 -112
- package/src/cli/tui.ts +159 -0
- package/src/ensemble.ts +154 -1
- package/src/integrations/langchainAdapter.ts +2 -2
- package/src/providers/providerConfig.ts +32 -17
- package/src/providers/registry.js +27 -0
- package/src/routing/advancedRouter.ts +99 -14
- package/src/routing/shadowSampler.ts +1 -1
- package/test-install/package.json +12 -0
- package/tests/tsconfig.json +0 -1
- package/tmlpd-pi-extension/README.md +105 -44
- package/tmlpd-pi-extension/docs/demo.svg +33 -0
- package/tmlpd-pi-extension/package.json +35 -106
- package/tmlpd-pi-extension/src/tokenOptimization/contextStratifier.ts +163 -0
- package/tmlpd-pi-extension/src/tokenOptimization/fetchOnceLocal.ts +136 -0
- package/tmlpd-pi-extension/src/tokenOptimization/index.ts +197 -0
- package/tmlpd-pi-extension/src/tokenOptimization/interAgentCompression.ts +157 -0
- package/tmlpd-pi-extension/src/tokenOptimization/schemaContract.ts +101 -0
- package/tmlpd-pi-extension/src/tokenOptimization/semanticCache.ts +248 -0
- package/tmlpd-pi-extension/src/tokenOptimization/tokenAwareFallback.ts +192 -0
- package/tmlpd-pi-extension/test/verify.js +21 -0
- package/tsconfig.build.json +3 -2
- package/packages/a3m-vercel-ai/dist/a3m-language-model.d.ts +0 -12
- package/packages/a3m-vercel-ai/dist/a3m-language-model.d.ts.map +0 -1
- package/packages/a3m-vercel-ai/dist/a3m-language-model.js +0 -289
- package/packages/a3m-vercel-ai/dist/a3m-language-model.js.map +0 -1
- package/packages/a3m-vercel-ai/dist/index.d.ts +0 -82
- package/packages/a3m-vercel-ai/dist/index.d.ts.map +0 -1
- package/packages/a3m-vercel-ai/dist/index.js +0 -79
- package/packages/a3m-vercel-ai/dist/index.js.map +0 -1
- package/packages/a3m-vercel-ai/dist/types.d.ts +0 -97
- package/packages/a3m-vercel-ai/dist/types.d.ts.map +0 -1
- package/packages/a3m-vercel-ai/dist/types.js +0 -5
- package/packages/a3m-vercel-ai/dist/types.js.map +0 -1
- package/src/skills/__tests__/skill_manager.test.ts +0 -328
- package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts +0 -114
- package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/cache/prefixCache.js +0 -285
- package/tmlpd-pi-extension/dist/cache/prefixCache.js.map +0 -1
- package/tmlpd-pi-extension/dist/cache/responseCache.d.ts +0 -58
- package/tmlpd-pi-extension/dist/cache/responseCache.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/cache/responseCache.js +0 -153
- package/tmlpd-pi-extension/dist/cache/responseCache.js.map +0 -1
- package/tmlpd-pi-extension/dist/cli.js +0 -59
- package/tmlpd-pi-extension/dist/cost/costTracker.d.ts +0 -95
- package/tmlpd-pi-extension/dist/cost/costTracker.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/cost/costTracker.js +0 -240
- package/tmlpd-pi-extension/dist/cost/costTracker.js.map +0 -1
- package/tmlpd-pi-extension/dist/index.d.ts +0 -723
- package/tmlpd-pi-extension/dist/index.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/index.js +0 -239
- package/tmlpd-pi-extension/dist/index.js.map +0 -1
- package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts +0 -82
- package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/memory/episodicMemory.js +0 -145
- package/tmlpd-pi-extension/dist/memory/episodicMemory.js.map +0 -1
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts +0 -102
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js +0 -207
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js.map +0 -1
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts +0 -85
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js +0 -210
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js.map +0 -1
- package/tmlpd-pi-extension/dist/providers/localProvider.d.ts +0 -102
- package/tmlpd-pi-extension/dist/providers/localProvider.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/providers/localProvider.js +0 -338
- package/tmlpd-pi-extension/dist/providers/localProvider.js.map +0 -1
- package/tmlpd-pi-extension/dist/providers/registry.d.ts +0 -55
- package/tmlpd-pi-extension/dist/providers/registry.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/providers/registry.js +0 -138
- package/tmlpd-pi-extension/dist/providers/registry.js.map +0 -1
- package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts +0 -68
- package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/routing/advancedRouter.js +0 -332
- package/tmlpd-pi-extension/dist/routing/advancedRouter.js.map +0 -1
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts +0 -101
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.js +0 -368
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.js.map +0 -1
- package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts +0 -96
- package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/utils/batchProcessor.js +0 -170
- package/tmlpd-pi-extension/dist/utils/batchProcessor.js.map +0 -1
- package/tmlpd-pi-extension/dist/utils/compression.d.ts +0 -61
- package/tmlpd-pi-extension/dist/utils/compression.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/utils/compression.js +0 -281
- package/tmlpd-pi-extension/dist/utils/compression.js.map +0 -1
- package/tmlpd-pi-extension/dist/utils/reliability.d.ts +0 -74
- package/tmlpd-pi-extension/dist/utils/reliability.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/utils/reliability.js +0 -177
- package/tmlpd-pi-extension/dist/utils/reliability.js.map +0 -1
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts +0 -117
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js +0 -246
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js.map +0 -1
- package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts +0 -50
- package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts.map +0 -1
- package/tmlpd-pi-extension/dist/utils/tokenUtils.js +0 -124
- package/tmlpd-pi-extension/dist/utils/tokenUtils.js.map +0 -1
package/docs/llms-full.txt
CHANGED
|
@@ -1,199 +1,421 @@
|
|
|
1
|
-
# A3M Router —
|
|
1
|
+
# A3M Router — Full Technical Documentation
|
|
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.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
**Repository:** `Das-rebel/a3m-router` (GitHub)
|
|
8
|
-
**Language:** TypeScript (Node.js)
|
|
9
|
-
**License:** MIT
|
|
5
|
+
A3M Router is a stateless proxy that routes LLM requests to the optimal provider based on query complexity analysis, cost, and availability.
|
|
10
6
|
|
|
11
|
-
|
|
7
|
+
## Routing Algorithm
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
### Complexity Scoring
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
Five signals are combined into a composite score:
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
| Abnormal entries | 0 |
|
|
24
|
-
| Queries evaluated | 8,400 |
|
|
13
|
+
1. **Domain Detection**
|
|
14
|
+
- Legal: contract, lawsuit, compliance, patent
|
|
15
|
+
- Medical: diagnosis, treatment, prescription, symptoms
|
|
16
|
+
- Code: function, class, API, debugging, refactor
|
|
17
|
+
- Finance: investment, portfolio, risk, return, audit
|
|
18
|
+
- ML: training, inference, gradient, loss, model
|
|
25
19
|
|
|
26
|
-
|
|
20
|
+
2. **Task Classification**
|
|
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
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
3. **Structural Analysis**
|
|
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
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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 |
|
|
33
|
+
4. **Verb Intensity**
|
|
34
|
+
- Complex verbs: design, architect, optimize, synthesize
|
|
35
|
+
- Simple verbs: what, who, find, get
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
5. **Multi-Modal Hints**
|
|
38
|
+
- Image references: explain this diagram
|
|
39
|
+
- Code blocks: debug this function
|
|
40
|
+
- Data: analyze this dataset
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
|--------|-------|
|
|
41
|
-
| Exact tier match | 67% |
|
|
42
|
-
| Within 1 tier | 96% |
|
|
43
|
-
| Cost savings vs all-premium | 62.9% |
|
|
42
|
+
### Tier Assignment
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
Score maps to tier:
|
|
45
|
+
|
|
46
|
+
| Score Range | Tier | Providers | Example |
|
|
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 |
|
|
46
52
|
|
|
47
|
-
##
|
|
53
|
+
## Ensemble Execution
|
|
48
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
|
+
)
|
|
49
75
|
```
|
|
50
|
-
|
|
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
|
+
}
|
|
51
106
|
```
|
|
52
107
|
|
|
53
|
-
|
|
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
|
|
108
|
+
## Memory System
|
|
58
109
|
|
|
59
|
-
|
|
110
|
+
### Semantic Cache
|
|
60
111
|
|
|
61
|
-
|
|
112
|
+
```python
|
|
113
|
+
router = A3MRouter(
|
|
114
|
+
model="auto",
|
|
115
|
+
cache={
|
|
116
|
+
"type": "semantic",
|
|
117
|
+
"threshold": 0.85, # cosine similarity
|
|
118
|
+
"ttl_seconds": 3600,
|
|
119
|
+
},
|
|
120
|
+
)
|
|
121
|
+
```
|
|
62
122
|
|
|
63
|
-
###
|
|
123
|
+
### Conversation Context
|
|
64
124
|
|
|
65
|
-
|
|
125
|
+
```python
|
|
126
|
+
router = A3MRouter(
|
|
127
|
+
model="auto",
|
|
128
|
+
memory={
|
|
129
|
+
"type": "conversation",
|
|
130
|
+
"window": 10, # last 10 exchanges
|
|
131
|
+
"embedding_model": "text-embedding-3-small",
|
|
132
|
+
},
|
|
133
|
+
)
|
|
134
|
+
```
|
|
66
135
|
|
|
67
|
-
|
|
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) |
|
|
136
|
+
### Cross-Session Memory
|
|
74
137
|
|
|
75
|
-
|
|
138
|
+
```python
|
|
139
|
+
router = A3MRouter(
|
|
140
|
+
model="auto",
|
|
141
|
+
memory={
|
|
142
|
+
"type": "semantic",
|
|
143
|
+
"persistent": True,
|
|
144
|
+
"namespace": "user_123",
|
|
145
|
+
"similarity_threshold": 0.85,
|
|
146
|
+
},
|
|
147
|
+
)
|
|
148
|
+
```
|
|
76
149
|
|
|
77
|
-
|
|
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) |
|
|
150
|
+
## Guardrails
|
|
83
151
|
|
|
84
|
-
|
|
152
|
+
### Prompt Injection Detection
|
|
85
153
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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 |
|
|
154
|
+
```python
|
|
155
|
+
# Patterns detected:
|
|
156
|
+
# - System prompt override attempts
|
|
157
|
+
# - Delimiter injection (USER:, SANDBOX:)
|
|
158
|
+
# - Role confusion attacks
|
|
159
|
+
# - Privilege escalation patterns
|
|
160
|
+
```
|
|
106
161
|
|
|
107
|
-
|
|
162
|
+
### PII Detection
|
|
108
163
|
|
|
109
|
-
|
|
164
|
+
- Email addresses, phone numbers, SSNs
|
|
165
|
+
- Credit card numbers
|
|
166
|
+
- API keys and secrets
|
|
110
167
|
|
|
111
|
-
|
|
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.
|
|
168
|
+
## Health Scoring
|
|
113
169
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
170
|
+
Provider health updated via exponential moving average:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
health_score = (
|
|
174
|
+
0.7 * previous_score +
|
|
175
|
+
0.3 * (1 - error_rate)
|
|
176
|
+
) * latency_factor
|
|
121
177
|
```
|
|
122
178
|
|
|
123
|
-
|
|
124
|
-
|
|
179
|
+
Where `latency_factor` penalizes slow responses:
|
|
180
|
+
- <1s: 1.0
|
|
181
|
+
- 1-3s: 0.9
|
|
182
|
+
- 3-10s: 0.7
|
|
183
|
+
- >10s: 0.3
|
|
184
|
+
|
|
185
|
+
## Rate Limiting
|
|
186
|
+
|
|
187
|
+
### Charnov MVT Implementation
|
|
125
188
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
189
|
+
Optimal departure time from rate-limited provider:
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
depart_when: marginal_remaining_rate < average_rate_including_switch_cost
|
|
130
193
|
```
|
|
131
194
|
|
|
132
|
-
###
|
|
133
|
-
Prompt injection detection covers 17 patterns including jailbreak templates, system prompt overrides, and delimiter-based injection. PII detection supports common entity types.
|
|
195
|
+
### Rotation Strategy
|
|
134
196
|
|
|
135
|
-
|
|
136
|
-
|
|
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
|
|
137
201
|
|
|
138
|
-
|
|
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.
|
|
202
|
+
## EXP3 Diversity
|
|
140
203
|
|
|
141
|
-
###
|
|
142
|
-
Trip after 3 failures, 60s cooldown. Automatic fallback chain across provider tiers.
|
|
204
|
+
### Weight Update
|
|
143
205
|
|
|
144
|
-
|
|
145
|
-
|
|
206
|
+
```python
|
|
207
|
+
for provider in providers:
|
|
208
|
+
deviation = provider.share - (1 / n) # actual share vs fair share
|
|
209
|
+
penalty = GAMMA * deviation / provider.share
|
|
210
|
+
provider.weight *= exp(-penalty)
|
|
211
|
+
```
|
|
146
212
|
|
|
147
|
-
|
|
213
|
+
### Normalization
|
|
214
|
+
|
|
215
|
+
Weights normalized to sum to 1.0 after each update.
|
|
216
|
+
|
|
217
|
+
## Benchmark Methodology
|
|
218
|
+
|
|
219
|
+
RouterArena evaluation:
|
|
220
|
+
- 8,400 diverse queries
|
|
221
|
+
- 47 providers tested
|
|
222
|
+
- Accuracy measured via LLM judge comparison
|
|
223
|
+
- Cost tracked via actual API spend
|
|
224
|
+
- Robustness = successful requests / total requests
|
|
148
225
|
|
|
149
226
|
## API Reference
|
|
150
227
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Response:
|
|
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
|
|
331
|
+
|
|
332
|
+
MIT
|
|
157
333
|
|
|
158
334
|
---
|
|
159
335
|
|
|
160
|
-
##
|
|
336
|
+
## Framework Adapter Details
|
|
337
|
+
|
|
338
|
+
### LangChain Adapter
|
|
161
339
|
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
|
|
340
|
+
```python
|
|
341
|
+
from a3m_adapter import A3MLangChainAdapter
|
|
342
|
+
|
|
343
|
+
llm = A3MLangChainAdapter(
|
|
344
|
+
model="auto",
|
|
345
|
+
temperature=0.7,
|
|
346
|
+
parallel_ensemble=2
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
# Works with any LangChain chain
|
|
350
|
+
result = llm.invoke("What is RAG?")
|
|
165
351
|
```
|
|
166
352
|
|
|
353
|
+
### LlamaIndex Adapter
|
|
354
|
+
|
|
167
355
|
```python
|
|
168
|
-
|
|
356
|
+
from a3m_adapter import A3MLlamaIndexAdapter
|
|
357
|
+
|
|
358
|
+
llm = A3MLlamaIndexAdapter(model="auto")
|
|
359
|
+
response = llm.complete("Explain transformers")
|
|
169
360
|
```
|
|
170
361
|
|
|
362
|
+
### AutoGen Adapter
|
|
363
|
+
|
|
171
364
|
```python
|
|
172
|
-
from
|
|
173
|
-
|
|
174
|
-
|
|
365
|
+
from a3m_adapter import A3MAutoGenAdapter
|
|
366
|
+
|
|
367
|
+
llm = A3MAutoGenAdapter(model="auto", parallel_ensemble=2)
|
|
368
|
+
config = llm.create_agent_config()
|
|
369
|
+
|
|
370
|
+
assistant = ConversableAgent(name="assistant", llm_config=config)
|
|
175
371
|
```
|
|
176
372
|
|
|
177
|
-
|
|
373
|
+
### Vercel AI SDK Adapter
|
|
374
|
+
|
|
375
|
+
```python
|
|
376
|
+
from a3m_adapter import createA3MProvider
|
|
178
377
|
|
|
179
|
-
|
|
378
|
+
result = await generateText({
|
|
379
|
+
model: createA3MProvider({"model": "auto", "parallel_ensemble": 2}),
|
|
380
|
+
prompt: "What is 2+2?",
|
|
381
|
+
})
|
|
382
|
+
```
|
|
180
383
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
384
|
+
### Haystack Adapter (RAG)
|
|
385
|
+
|
|
386
|
+
```python
|
|
387
|
+
from a3m_adapter import A3MHaystackAdapter
|
|
388
|
+
|
|
389
|
+
adapter = A3MHaystackAdapter(model="auto")
|
|
390
|
+
result = adapter.predict(query="What is AI?", documents=retrieved_docs)
|
|
189
391
|
```
|
|
190
392
|
|
|
191
|
-
|
|
393
|
+
### Pinecone Adapter (Vector Search)
|
|
394
|
+
|
|
395
|
+
```python
|
|
396
|
+
from a3m_adapter import A3MPineconeAdapter
|
|
397
|
+
|
|
398
|
+
adapter = A3MPineconeAdapter(model="auto")
|
|
399
|
+
embedding = adapter.embed_query("quantum computing")
|
|
400
|
+
results = index.query(vector=embedding, top_k=5)
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### LangGraph Adapter (Stateful Agents)
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
from a3m_adapter import A3MLangGraphAdapter
|
|
407
|
+
|
|
408
|
+
adapter = A3MLangGraphAdapter(model="auto", parallel_ensemble=2)
|
|
409
|
+
agent = create_react_agent(adapter, tools=[...])
|
|
410
|
+
result = agent.invoke({"messages": [{"role": "user", "content": "Hello"}]})
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### CrewAI Adapter (Multi-Agent)
|
|
192
414
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
415
|
+
```python
|
|
416
|
+
from crewai.llms import A3MCompletion
|
|
417
|
+
|
|
418
|
+
agent = Agent(llm=A3MCompletion(model="auto"))
|
|
419
|
+
crew = Crew(agents=[agent], tasks=[task])
|
|
420
|
+
result = crew.kickoff()
|
|
421
|
+
```
|