adaptive-memory-multi-model-router 2.13.17 → 2.13.20
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/.dockerignore +82 -0
- package/.env.example +303 -0
- package/.github/DISCUSSIONS_WELCOME.md +27 -0
- package/.github/DISCUSSION_TEMPLATE.yml +5 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +83 -12
- package/.github/ISSUE_TEMPLATE/config.yml +12 -6
- package/.github/ISSUE_TEMPLATE/feature_request.md +61 -10
- package/.github/PULL_REQUEST_TEMPLATE.md +53 -26
- package/.github/dependabot.yml +9 -0
- package/.github/workflows/codeql.yml +38 -0
- package/.github/workflows/npm-publish.yml +20 -0
- package/.github/workflows/stale.yml +56 -0
- package/ARCHITECTURE.md +346 -0
- package/AUDIT_REPORT.md +28 -0
- package/CHANGELOG.md +386 -22
- package/CONTRIBUTORS.md +20 -0
- package/Dockerfile +53 -0
- package/Dockerfile.proxy +33 -0
- package/PR_STATUS_REPORT.md +148 -0
- package/README.md +22 -0
- package/RUNKIT.md +83 -0
- package/_schema.html +61 -15
- package/articles/AI_AGENT_LLM_ROUTING.md +150 -0
- package/articles/FROM_ZERO_TO_10K.md +107 -0
- package/articles/LLM_BENCHMARK_DEEP_DIVE.md +153 -0
- package/articles/TWEETS_10K_DOWNLOADS.md +47 -0
- package/articles/TWEETS_BENCHMARK_FIRST.md +46 -0
- package/articles/TWEETS_MCP_PLAY.md +51 -0
- package/articles/TWEETS_SEQUENTIAL_BROKEN.md +49 -0
- package/articles/TWEETS_WHY_BUILD.md +54 -0
- package/benchmark-results.json +26 -45
- package/cli/a3m +840 -0
- package/demo/package.json +13 -0
- package/demo/public/index.html +762 -0
- package/demo/server.js +405 -0
- package/dist/cli.js +4 -0
- package/docker-compose.yml +74 -0
- package/docs/.nojekyll +0 -0
- package/docs/BENCHMARK.md +96 -22
- package/docs/_config.yml +49 -0
- package/docs/api.html +513 -0
- package/docs/benchmark.html +387 -0
- package/docs/cli-cheatsheet.md +339 -0
- package/docs/comparison.md +108 -0
- package/docs/curl-examples.md +247 -0
- package/docs/index.html +390 -99
- package/docs/openapi.yaml +1318 -0
- package/docs/quick-start.html +366 -0
- package/docs/robots.txt +1 -1
- package/docs/sitemap.xml +23 -5
- package/docs/styles.css +682 -0
- package/examples/README.md +61 -0
- package/examples/a3m-sdk.js +124 -0
- package/examples/basic-route.js +54 -0
- package/examples/chat-loop.js +202 -0
- package/examples/classify-then-route.js +102 -0
- package/examples/cost-compare.js +120 -0
- package/examples/ensemble.js +160 -0
- package/hf-space/README.md +22 -0
- package/hf-space/app.py +97 -0
- package/integrations/langchain/README.md +216 -0
- package/integrations/langchain/a3m_langchain.ts +1360 -0
- package/integrations/langchain/example.ts +287 -0
- package/integrations/vercel-ai-sdk/README.md +49 -0
- package/integrations/vercel-ai-sdk/a3m_provider.ts +78 -0
- package/integrations/vercel-ai-sdk/example.ts +25 -0
- package/llms-full.txt +43 -0
- package/llms.txt +9 -0
- package/mcp-server/README.md +188 -0
- package/mcp-server/package.json +29 -0
- package/mcp-server/src/index.ts +744 -0
- package/mcp-server/tsconfig.json +19 -0
- package/package.json +3 -3
- package/proxy/README.md +227 -0
- package/proxy/package-lock.json +831 -0
- package/proxy/package.json +17 -0
- package/proxy/rate-limit.js +145 -0
- package/proxy/rate-limit.test.js +311 -0
- package/proxy/server.js +970 -0
- package/scripts/banner.js +29 -0
- package/scripts/compare-providers.sh +230 -0
- package/scripts/cross_post.py +443 -0
- package/scripts/publish_fcc.py +106 -0
- package/scripts/push-to-gitee.sh +52 -0
- package/src/tui/dashboard.ts +13 -0
- package/tests/__mocks__/tokenUtils.ts +22 -0
- package/tests/memory/episodicMemory.test.ts +227 -0
- package/tests/package-lock.json +1628 -0
- package/tests/package.json +18 -0
- package/tests/routing/ensembleVoting.test.ts +236 -0
- package/tests/routing/providerRetry.test.ts +360 -0
- package/tests/routing/queryTypePresets.test.ts +206 -0
- package/tests/tsconfig.json +21 -0
- package/tests/vitest.config.ts +18 -0
- package/.env +0 -2
- package/media/a3m-tui-screenshot.png +0 -0
|
@@ -1,44 +1,71 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Description
|
|
2
2
|
|
|
3
|
-
Please include a summary of the change and which issue
|
|
3
|
+
Please include a summary of the change and which issue it fixes. Explain the motivation and context — what problem does this solve and why is this the right approach?
|
|
4
4
|
|
|
5
5
|
Fixes # (issue)
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Type of Change
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Check all that apply:
|
|
10
10
|
|
|
11
|
-
- [ ] 🐛 Bug fix (non-breaking change
|
|
12
|
-
- [ ] ✨ New feature (non-breaking change
|
|
13
|
-
- [ ] 💥 Breaking change (fix or feature that would
|
|
14
|
-
- [ ] 📚 Documentation
|
|
15
|
-
- [ ] 🎨
|
|
16
|
-
- [ ] ⚡ Performance
|
|
17
|
-
- [ ] 🔒 Security
|
|
11
|
+
- [ ] 🐛 **Bug fix** (non-breaking change that fixes an issue)
|
|
12
|
+
- [ ] ✨ **New feature** (non-breaking change that adds functionality)
|
|
13
|
+
- [ ] 💥 **Breaking change** (fix or feature that would break existing functionality)
|
|
14
|
+
- [ ] 📚 **Documentation** (README, API docs, inline comments, or examples)
|
|
15
|
+
- [ ] 🎨 **Style** (formatting, code style — no logic change)
|
|
16
|
+
- [ ] ⚡ **Performance** (improves speed, memory, or latency without behavior change)
|
|
17
|
+
- [ ] 🔒 **Security** (fixes a vulnerability or improves security posture)
|
|
18
|
+
- [ ] ♻️ **Refactor** (code change that neither fixes a bug nor adds a feature)
|
|
19
|
+
- [ ] 🧪 **Tests** (adds or updates tests, not production code)
|
|
18
20
|
|
|
19
|
-
##
|
|
21
|
+
## Testing
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
Describe the tests you ran to verify your changes:
|
|
22
24
|
|
|
23
25
|
- [ ] All existing tests pass (`npm test`)
|
|
24
26
|
- [ ] Added new tests for the changes
|
|
25
|
-
- [ ] Tested manually
|
|
27
|
+
- [ ] Tested manually (describe the commands or SDK calls used)
|
|
28
|
+
- [ ] Tested with real provider API calls (if applicable)
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
```bash
|
|
31
|
+
# Provide commands to reproduce your testing
|
|
32
|
+
node test/some-test.js
|
|
33
|
+
npx a3m-router route "Test query"
|
|
34
|
+
```
|
|
28
35
|
|
|
29
|
-
|
|
36
|
+
## Checklist
|
|
37
|
+
|
|
38
|
+
- [ ] My code follows the project's coding style and conventions
|
|
30
39
|
- [ ] I have performed a self-review of my own code
|
|
31
|
-
- [ ] I have commented
|
|
32
|
-
- [ ] I have
|
|
33
|
-
- [ ] My changes
|
|
34
|
-
- [ ] I have added tests that prove my fix is effective or
|
|
35
|
-
- [ ] New and existing unit tests pass locally
|
|
36
|
-
- [ ] Any dependent changes
|
|
40
|
+
- [ ] I have commented complex logic, especially in hard-to-understand areas
|
|
41
|
+
- [ ] I have updated the documentation (README, API docs, JSDoc comments) if needed
|
|
42
|
+
- [ ] My changes produce no new warnings (no `console.log` left behind, no TypeScript errors)
|
|
43
|
+
- [ ] I have added tests that prove my fix is effective or my feature works
|
|
44
|
+
- [ ] New and existing unit tests pass locally
|
|
45
|
+
- [ ] Any dependent changes are merged and published in downstream modules
|
|
46
|
+
- [ ] I have checked that my changes are backward-compatible (or documented breaking changes)
|
|
47
|
+
|
|
48
|
+
## Screenshots (if applicable)
|
|
49
|
+
|
|
50
|
+
If the change affects the terminal UI, dashboard, or any visual output, include screenshots:
|
|
51
|
+
|
|
52
|
+
| Before | After |
|
|
53
|
+
|--------|-------|
|
|
54
|
+
| _screenshot_ | _screenshot_ |
|
|
55
|
+
|
|
56
|
+
## Additional Context
|
|
57
|
+
|
|
58
|
+
- Related issues or PRs
|
|
59
|
+
- Performance impact (latency, memory, bundle size)
|
|
60
|
+
- Configuration changes required
|
|
61
|
+
- Migration guide (if breaking change)
|
|
37
62
|
|
|
38
|
-
##
|
|
63
|
+
## Changelog Entry
|
|
39
64
|
|
|
40
|
-
|
|
65
|
+
Suggest a one-line changelog entry for this change:
|
|
41
66
|
|
|
42
|
-
|
|
67
|
+
```
|
|
68
|
+
- {type}: {short description} ({issue/PR link})
|
|
69
|
+
```
|
|
43
70
|
|
|
44
|
-
|
|
71
|
+
Example: `- feat: add language-based routing override (#42)`
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: "CodeQL"
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
schedule:
|
|
9
|
+
- cron: '0 0 * * 0'
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
analyze:
|
|
13
|
+
name: Analyze
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
actions: read
|
|
17
|
+
contents: read
|
|
18
|
+
security-events: write
|
|
19
|
+
|
|
20
|
+
strategy:
|
|
21
|
+
fail-fast: false
|
|
22
|
+
matrix:
|
|
23
|
+
language: ['javascript-typescript']
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- name: Checkout repository
|
|
27
|
+
uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Initialize CodeQL
|
|
30
|
+
uses: github/codeql-action/init@v3
|
|
31
|
+
with:
|
|
32
|
+
languages: ${{ matrix.language }}
|
|
33
|
+
|
|
34
|
+
- name: Autobuild
|
|
35
|
+
uses: github/codeql-action/autobuild@v3
|
|
36
|
+
|
|
37
|
+
- name: Perform CodeQL Analysis
|
|
38
|
+
uses: github/codeql-action/analyze@v3
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- uses: actions/checkout@v4
|
|
12
|
+
- uses: actions/setup-node@v4
|
|
13
|
+
with:
|
|
14
|
+
node-version: '20'
|
|
15
|
+
registry-url: 'https://registry.npmjs.org'
|
|
16
|
+
- run: npm ci
|
|
17
|
+
- run: npm run build
|
|
18
|
+
- run: npm publish
|
|
19
|
+
env:
|
|
20
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Stale Issue and PR Management
|
|
2
|
+
# Marks issues and PRs as stale after 60 days of inactivity,
|
|
3
|
+
# then closes them 7 days later if no further activity.
|
|
4
|
+
#
|
|
5
|
+
# https://github.com/actions/stale
|
|
6
|
+
|
|
7
|
+
name: "Stale Issue & PR"
|
|
8
|
+
on:
|
|
9
|
+
schedule:
|
|
10
|
+
- cron: "0 6 * * 1" # Every Monday at 6:00 UTC
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
issues: write
|
|
14
|
+
pull-requests: write
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
stale:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/stale@v9
|
|
21
|
+
with:
|
|
22
|
+
# -- General Configuration --
|
|
23
|
+
days-before-stale: 60
|
|
24
|
+
days-before-close: 7
|
|
25
|
+
operations-per-run: 100
|
|
26
|
+
|
|
27
|
+
# -- Messaging --
|
|
28
|
+
stale-issue-message: >
|
|
29
|
+
This issue has been automatically marked as stale because it has been
|
|
30
|
+
inactive for 60 days. If this is still relevant, please leave a comment
|
|
31
|
+
to keep it open. Otherwise, it will be closed in 7 days.
|
|
32
|
+
close-issue-message: >
|
|
33
|
+
This issue has been automatically closed due to inactivity.
|
|
34
|
+
Feel free to reopen if the issue persists or is still relevant.
|
|
35
|
+
stale-pr-message: >
|
|
36
|
+
This pull request has been automatically marked as stale because it has
|
|
37
|
+
been inactive for 60 days. Please update or comment to keep it active.
|
|
38
|
+
It will be closed in 7 days.
|
|
39
|
+
close-pr-message: >
|
|
40
|
+
This pull request has been automatically closed due to inactivity.
|
|
41
|
+
Feel free to reopen with updates when you're ready to continue.
|
|
42
|
+
|
|
43
|
+
# -- Labels --
|
|
44
|
+
stale-issue-label: stale
|
|
45
|
+
stale-pr-label: stale
|
|
46
|
+
exempt-issue-labels: "pinned,security,blocked,awaiting-review"
|
|
47
|
+
exempt-pr-labels: "pinned,security,blocked,awaiting-review"
|
|
48
|
+
exempt-all-milestones: true
|
|
49
|
+
|
|
50
|
+
# -- Exempt from stale --
|
|
51
|
+
# Never mark these as stale
|
|
52
|
+
exempt-issue-labels: "pinned,security,blocked,awaiting-review,help-wanted,good-first-issue"
|
|
53
|
+
exempt-pr-labels: "pinned,security,blocked,awaiting-review,WIP"
|
|
54
|
+
|
|
55
|
+
# -- Delete stale branches on close --
|
|
56
|
+
delete-branch: false
|
package/ARCHITECTURE.md
ADDED
|
@@ -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.
|
package/AUDIT_REPORT.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Dependency Audit Report
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-05-28
|
|
4
|
+
**Project:** adaptive-memory-multi-model-router (v2.13.18)
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
| Metric | Value |
|
|
9
|
+
|--------|-------|
|
|
10
|
+
| Total dependencies | 5 (3 prod + 2 dev) |
|
|
11
|
+
| Vulnerabilities | 0 (none found) |
|
|
12
|
+
| Outdated packages | 1 updated |
|
|
13
|
+
|
|
14
|
+
## Vulnerabilities
|
|
15
|
+
|
|
16
|
+
**0 vulnerabilities found.** The dependency tree is clean with no reported security issues across all direct and transitive dependencies.
|
|
17
|
+
|
|
18
|
+
## Updated Packages
|
|
19
|
+
|
|
20
|
+
| Package | From | To | Type | Reason |
|
|
21
|
+
|---------|------|----|------|--------|
|
|
22
|
+
| `@types/node` | 25.8.0 | 25.9.1 | devDependency | Updated via `npm update` within `^25.8.0` semver range |
|
|
23
|
+
|
|
24
|
+
## Notes
|
|
25
|
+
|
|
26
|
+
- `@langchain/core` is listed as `MISSING` in `npm outdated` output — this is expected. It is an **optional peer dependency** (`"optional": true` in `peerDependenciesMeta`) and is not required for core functionality.
|
|
27
|
+
- All other dependencies (`blessed@0.1.81`, `nanoid@5.1.11`, `typescript@6.0.3`) are up-to-date within their semver ranges.
|
|
28
|
+
- No breaking changes were introduced — `npm update` only applied compatible version bumps within declared semver ranges.
|