adaptive-memory-multi-model-router 2.14.49 → 2.14.51
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/FUNDING.yml +2 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +94 -0
- package/.github/ISSUE_TEMPLATE/config.yml +17 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +71 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +71 -0
- package/.github/dependabot.yml +9 -0
- package/.github/workflows/auto-publish.yml +51 -0
- package/.github/workflows/ci.yml +263 -0
- package/.github/workflows/codeql.yml +38 -0
- package/.github/workflows/npm-publish.yml +20 -0
- package/.github/workflows/pages.yml +37 -0
- package/.github/workflows/stale.yml +54 -0
- package/.publish-tick +1 -0
- package/.well-known/ai-plugin.json +16 -0
- package/AGENT_COUNCIL_FINDINGS.md +142 -0
- package/ARCHITECTURE.md +346 -0
- package/AUDIT_REPORT.md +28 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/CONTRIBUTING.md +50 -0
- package/CONTRIBUTORS.md +20 -0
- package/Dockerfile +53 -0
- package/Dockerfile.proxy +33 -0
- package/HEALTH_REPORT.md +118 -0
- package/IMPROVEMENT_PLAN.md +107 -0
- package/LANDING.md +43 -0
- package/LAUNCH-PAIN-DRIVEN.md +339 -0
- package/LAUNCH.md +337 -0
- package/LAUNCH_CHECKLIST.md +141 -0
- package/LAUNCH_SNAPSHOT.md +260 -0
- package/MANIFESTO.md +41 -0
- package/POPULARITY_BOOSTERS.md +285 -0
- package/PR_STATUS_REPORT.md +148 -0
- package/README.md +10 -0
- package/REDESIGN.md +95 -0
- package/RUNKIT.md +83 -0
- package/SECURITY.md +29 -0
- package/SUBMISSIONS.md +43 -0
- package/_schema.html +53 -0
- package/ai-plugin.json +16 -0
- package/articles/AI_AGENT_LLM_ROUTING.md +150 -0
- package/articles/CHINESE_DIRECTORIES.md +100 -0
- package/articles/CHINESE_SUBMISSIONS_READY.md +322 -0
- package/articles/COMPETITOR_ALERTS.md +31 -0
- package/articles/COMPLETE_POSTING_DIRECTORY.md +147 -0
- package/articles/CONTENT_STRUCTURE.md +292 -0
- package/articles/DEVTO_COST_GUIDE.md +473 -0
- package/articles/DEVTO_FINAL.md +416 -0
- package/articles/DEVTO_MULTI_PROVIDER.md +542 -0
- package/articles/DEVTO_READY.md +255 -0
- package/articles/DEVTO_V2_ANNOUNCEMENT.md +160 -0
- package/articles/DEVTO_VIRAL_GROWTH.md +280 -0
- package/articles/FRESH_devto.md +460 -0
- package/articles/FRESH_devto_2026_05.md +73 -0
- package/articles/FRESH_hackernews.md +14 -0
- package/articles/FRESH_reddit_ml.md +90 -0
- package/articles/FRESH_reddit_node.md +198 -0
- package/articles/FRESH_reddit_sideproject.md +72 -0
- package/articles/FRESH_reddit_webdev.md +130 -0
- package/articles/FROM_ZERO_TO_10K.md +107 -0
- package/articles/HN_10X_BETTER.md +430 -0
- package/articles/HN_ACCOUNT_GUIDE.md +21 -0
- package/articles/HN_CHINESE_STYLE.md +308 -0
- package/articles/HN_FINAL.md +148 -0
- package/articles/HN_POSTED_VERSION.md +56 -0
- package/articles/HN_POST_READY.md +137 -0
- package/articles/HN_RESEARCH.md +364 -0
- package/articles/HN_SHOW_routerarena.md +17 -0
- package/articles/HN_TIMING_GUIDE.md +52 -0
- package/articles/INDIEHACKERS_POST.md +52 -0
- package/articles/INDIEHACKERS_READY.md +120 -0
- package/articles/LLM_BENCHMARK_DEEP_DIVE.md +153 -0
- package/articles/MASTER_POSTING_DIRECTORY.md +189 -0
- package/articles/NEWSLETTER_SEND_NOW.md +259 -0
- package/articles/NEWSLETTER_SUBMISSIONS.md +112 -0
- package/articles/PAIN-DRIVEN-devto-v2.md +308 -0
- package/articles/PAIN-DRIVEN-devto-v3.md +268 -0
- package/articles/PAIN-DRIVEN-devto.md +242 -0
- package/articles/PAIN-DRIVEN-hackernews-v2.md +138 -0
- package/articles/PAIN-DRIVEN-hackernews-v3.md +151 -0
- package/articles/PAIN-DRIVEN-hackernews.md +131 -0
- package/articles/PAIN-DRIVEN-reddit-v2.md +301 -0
- package/articles/PAIN-DRIVEN-reddit-v3.md +236 -0
- package/articles/PAIN-DRIVEN-reddit.md +218 -0
- package/articles/PAIN-DRIVEN-twitter-v2.md +110 -0
- package/articles/PAIN-DRIVEN-twitter-v3.md +121 -0
- package/articles/PAIN-DRIVEN-twitter.md +120 -0
- package/articles/PORTKEY_VS_A3M.md +147 -0
- package/articles/POSTING_KIT_2026_05.md +67 -0
- package/articles/PRESS_KIT_routerarena.md +77 -0
- package/articles/PRODUCTHUNT_LISTING.md +48 -0
- package/articles/PRODUCTHUNT_READY.md +106 -0
- package/articles/PR_PLAN_vault.md +125 -0
- package/articles/REDDIT_FINAL.md +232 -0
- package/articles/REDDIT_POST.md +67 -0
- package/articles/REDDIT_SUBMISSION_READY.md +348 -0
- package/articles/ROUTERARENA_LEADER.md +45 -0
- package/articles/SHOW_HN_FINAL.md +29 -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/articles/TWEETS_routerarena_leader.md +53 -0
- package/articles/TWEET_STORM_READY.md +165 -0
- package/articles/TWITTER_FINAL.md +167 -0
- package/articles/WHY_10X_BETTER.md +261 -0
- package/articles/WHY_CHINESE_STYLE_BETTER.md +323 -0
- package/articles/ai-discoverability-llm-routing.md +210 -0
- package/articles/devto-llm-routing.md +138 -0
- package/articles/hackernews-show-hn.md +54 -0
- package/articles/hashnode-llm-cost-optimization.md +125 -0
- package/articles/hn_show_2026_05.md +11 -0
- package/articles/medium-building-llm-router.md +205 -0
- package/articles/reddit-ml.md +76 -0
- package/articles/twitter-thread-cost-savings.md +50 -0
- package/articles/youtube-tutorial-script.md +262 -0
- package/assets/a3m_3blue1brown.mp4 +0 -0
- package/assets/banner.svg +109 -0
- package/assets/chart-cost-v2.svg +91 -0
- package/assets/chart-cost-v3.svg +143 -0
- package/assets/chart-features-v2.svg +132 -0
- package/assets/chart-features-v3.svg +211 -0
- package/assets/chart-growth-v2.svg +122 -0
- package/assets/chart-growth-v3.svg +189 -0
- package/assets/cost-comparison.svg +134 -0
- package/assets/cost-simple.svg +64 -0
- package/assets/demo-hn.gif +0 -0
- package/assets/feature-matrix.svg +136 -0
- package/assets/growth-chart-animated.svg +76 -0
- package/assets/growth-chart.svg +82 -0
- package/assets/growth-simple.svg +69 -0
- package/assets/hero-diagram.svg +81 -0
- package/assets/logo-new.svg +21 -0
- package/assets/logo.svg +68 -0
- package/assets/provider-comparison.svg +121 -0
- package/assets/social-preview-new.svg +100 -0
- package/assets/social-preview.svg +194 -0
- package/assets/social-v2.svg +130 -0
- package/assets/social-v3.svg +212 -0
- package/benchmark-provider-results.json +245 -0
- package/benchmark-results.json +54 -0
- package/council-votes/architecture-vote.md +121 -0
- package/council-votes/coverage-vote.md +93 -0
- package/data/adaptive-benchmark.json +92 -0
- package/data/benchmark-results.json +47 -0
- package/data/labeled-benchmark.json +88 -0
- package/demo/3blue1brown_video.py +285 -0
- package/demo/3blue1brown_video_v2.py +310 -0
- package/demo/IMPROVED_PROMPTS.md +229 -0
- package/demo/VEO3_PROMPTS.md +269 -0
- package/demo/VIDEO_PRODUCTION_GUIDE.md +333 -0
- package/demo/a3m_3blue1brown.mp4 +0 -0
- package/demo/asciinema-demo.sh +195 -0
- package/demo/demo-hn.tape +74 -0
- package/demo/demo-script.md +53 -0
- package/demo/demo-script.sh +62 -0
- package/demo/demo.svg +75 -0
- package/demo/frame1_ai_data_center.png +0 -0
- package/demo/frame1_sunset_video.mp4 +0 -0
- package/demo/frame2_cost_comparison.png +0 -0
- package/demo/frame2_cost_comparison_fallback.png +0 -0
- package/demo/frame3_parallel_execution.png +0 -0
- package/demo/frame3_parallel_execution_fallback.png +0 -0
- package/demo/frame4_providers.png +0 -0
- package/demo/frame4_providers_fallback.png +0 -0
- package/demo/frame5_endcard.png +0 -0
- package/demo/frame5_endcard_fallback.png +0 -0
- package/demo/new_frame1_hook.png +0 -0
- package/demo/new_frame2_proof.png +0 -0
- package/demo/new_frame3_wow.png +0 -0
- package/demo/new_frame4_social.png +0 -0
- package/demo/new_frame5_cta.png +0 -0
- package/demo/package.json +13 -0
- package/demo/product-video-final.mp4 +0 -0
- package/demo/product-video-hype-v1.mp4 +0 -0
- package/demo/product-video-v1.mp4 +0 -0
- package/demo/public/index.html +762 -0
- package/demo/recording.cast +55 -0
- package/demo/server.js +405 -0
- package/demo-new.tape +71 -0
- package/demo-real.sh +198 -0
- package/demo-simple.tape +205 -0
- package/demo.html +520 -0
- package/demo.sh +85 -0
- package/demo.tape +259 -0
- package/dist/analytics/costAnalytics.d.ts.map +1 -0
- package/dist/analytics/costAnalytics.js.map +1 -0
- package/dist/benchmark/comprehensive.js.map +1 -0
- package/dist/benchmark/reproducible.d.ts.map +1 -0
- package/dist/benchmark/reproducible.js.map +1 -0
- package/dist/cache/prefixCache.d.ts.map +1 -0
- package/dist/cache/prefixCache.js.map +1 -0
- package/dist/cache/responseCache.d.ts.map +1 -0
- package/dist/cache/responseCache.js.map +1 -0
- package/dist/cache/semanticCache.d.ts.map +1 -0
- package/dist/cache/semanticCache.js.map +1 -0
- package/dist/cli/setupWizard.d.ts.map +1 -0
- package/dist/cli/setupWizard.js.map +1 -0
- package/dist/cost/budgetEnforcer.d.ts.map +1 -0
- package/dist/cost/budgetEnforcer.js.map +1 -0
- package/dist/cost/costTracker.d.ts.map +1 -0
- package/dist/cost/costTracker.js.map +1 -0
- package/dist/ensemble/multiRoundDialog.js.map +1 -0
- package/dist/ensemble/shapleyValue.js.map +1 -0
- package/dist/integrations/langchainAdapter.d.ts.map +1 -0
- package/dist/integrations/langchainAdapter.js.map +1 -0
- package/dist/integrations/oauth.d.ts.map +1 -0
- package/dist/integrations/oauth.js.map +1 -0
- package/dist/integrations/scienceAdapter.js.map +1 -0
- package/dist/memory/autoFetch.d.ts.map +1 -0
- package/dist/memory/autoFetch.js.map +1 -0
- package/dist/memory/episodicMemory.d.ts.map +1 -0
- package/dist/memory/episodicMemory.js.map +1 -0
- package/dist/memory/hybridMemory.js.map +1 -0
- package/dist/memory/memoryTree.d.ts.map +1 -0
- package/dist/memory/memoryTree.js.map +1 -0
- package/dist/memory/obsidianVault.d.ts.map +1 -0
- package/dist/memory/obsidianVault.js.map +1 -0
- package/dist/memory/reasoningBank.js.map +1 -0
- package/dist/observability/changeWatch.d.ts.map +1 -0
- package/dist/observability/changeWatch.js.map +1 -0
- package/dist/observability/fatigueDetector.d.ts.map +1 -0
- package/dist/observability/fatigueDetector.js.map +1 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/middleware.d.ts.map +1 -0
- package/dist/observability/middleware.js.map +1 -0
- package/dist/observability/tracer.d.ts.map +1 -0
- package/dist/observability/tracer.js.map +1 -0
- package/dist/observability/types.d.ts.map +1 -0
- package/dist/observability/types.js.map +1 -0
- package/dist/orchestration/haloOrchestrator.d.ts.map +1 -0
- package/dist/orchestration/haloOrchestrator.js.map +1 -0
- package/dist/orchestration/mctsWorkflow.d.ts.map +1 -0
- package/dist/orchestration/mctsWorkflow.js.map +1 -0
- package/dist/providers/localProvider.d.ts.map +1 -0
- package/dist/providers/localProvider.js.map +1 -0
- package/dist/providers/providerConfig.d.ts.map +1 -0
- package/dist/providers/providerConfig.js.map +1 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/routing/advancedRouter.d.ts.map +1 -0
- package/dist/routing/advancedRouter.js +1 -1
- package/dist/routing/advancedRouter.js.map +1 -0
- package/dist/routing/crossModelValidation.d.ts.map +1 -0
- package/dist/routing/crossModelValidation.js.map +1 -0
- package/dist/routing/providerHealth.d.ts.map +1 -0
- package/dist/routing/providerHealth.js.map +1 -0
- package/dist/routing/providerRetry.d.ts.map +1 -0
- package/dist/routing/providerRetry.js.map +1 -0
- package/dist/scripts/banner.js +29 -0
- package/dist/security/guardrails.d.ts.map +1 -0
- package/dist/security/guardrails.js.map +1 -0
- package/dist/server/dashboard.d.ts.map +1 -0
- package/dist/server/dashboard.js.map +1 -0
- package/dist/server/modelMapper.d.ts.map +1 -0
- package/dist/server/modelMapper.js.map +1 -0
- package/dist/server/proxyServer.d.ts.map +1 -0
- package/dist/server/proxyServer.js.map +1 -0
- package/dist/skills/__tests__/skill_manager.test.d.ts +2 -0
- package/dist/skills/__tests__/skill_manager.test.d.ts.map +1 -0
- package/dist/skills/__tests__/skill_manager.test.js +268 -0
- package/dist/skills/__tests__/skill_manager.test.js.map +1 -0
- package/dist/tools/tmlpdTools.d.ts.map +1 -0
- package/dist/tools/tmlpdTools.js.map +1 -0
- package/dist/tui/dashboard.d.ts.map +1 -0
- package/dist/tui/dashboard.js.map +1 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/utils/batchProcessor.d.ts.map +1 -0
- package/dist/utils/batchProcessor.js.map +1 -0
- package/dist/utils/compression.d.ts.map +1 -0
- package/dist/utils/compression.js.map +1 -0
- package/dist/utils/costUtils.d.ts.map +1 -0
- package/dist/utils/costUtils.js.map +1 -0
- package/dist/utils/reliability.d.ts.map +1 -0
- package/dist/utils/reliability.js.map +1 -0
- package/dist/utils/sorting.d.ts.map +1 -0
- package/dist/utils/sorting.js.map +1 -0
- package/dist/utils/speculativeDecoding.d.ts.map +1 -0
- package/dist/utils/speculativeDecoding.js.map +1 -0
- package/dist/utils/tokenUtils.d.ts.map +1 -0
- package/dist/utils/tokenUtils.js.map +1 -0
- package/docs/.nojekyll +0 -0
- package/docs/ANALYSIS_PRINCIPLES.md +162 -0
- package/docs/API.md +855 -0
- package/docs/ARCHITECTURAL-IMPROVEMENTS-2025.md +1391 -0
- package/docs/ARCHITECTURAL-IMPROVEMENTS-REVISED-2025.md +1051 -0
- package/docs/BENCHMARK.md +170 -0
- package/docs/CHINESE_PROVIDER_RELIABILITY.md +37 -0
- package/docs/CITATIONS.md +74 -0
- package/docs/CLAIMS_AND_EVIDENCE.md +58 -0
- package/docs/CONFIGURATION.md +476 -0
- package/docs/COUNCIL_DECISION.json +816 -0
- package/docs/COUNCIL_SUMMARY.md +319 -0
- package/docs/COUNCIL_V2.2_DECISION.md +416 -0
- package/docs/ENGINEERING_SPEC.md +55 -0
- package/docs/FACTORY_RESET.md +34 -0
- package/docs/GEO.md +66 -0
- package/docs/GEO_OPTIMIZATION.md +30 -0
- package/docs/GEO_ROOT_CAUSE.md +136 -0
- package/docs/GEO_STATUS.md +85 -0
- package/docs/GEO_TEST_RESULTS.md +176 -0
- package/docs/HN_CHECKLIST.md +38 -0
- package/docs/HN_FOUNDER_COMMENT.md +17 -0
- package/docs/HN_SUBMISSION_FINAL.md +180 -0
- package/docs/HN_SUBMISSION_V3.md +56 -0
- package/docs/IMPROVEMENT_ROADMAP.md +515 -0
- package/docs/INTEGRATIONS.md +420 -0
- package/docs/LANGCHAIN_INTEGRATION.md +147 -0
- package/docs/LLM_COUNCIL_DECISION.md +508 -0
- package/docs/MIDDLEWARE_CHAIN.md +35 -0
- package/docs/PROMO_CHECKLIST.md +200 -0
- package/docs/QUICKSTART.md +271 -0
- package/docs/QUICK_START.md +43 -0
- package/docs/QUICK_START_VISIBILITY.md +782 -0
- package/docs/REDDIT_GAP_ANALYSIS.md +299 -0
- package/docs/RELEASE_CHECKLIST.md +32 -0
- package/docs/REPRODUCIBILITY.md +63 -0
- package/docs/RESEARCH_BACKED_IMPROVEMENTS.md +1180 -0
- package/docs/ROUTING_RUBRIC.md +197 -0
- package/docs/SEO_AUDIT.md +186 -0
- package/docs/SOCIAL_LISTENING.md +219 -0
- package/docs/TMLPD_QNA.md +751 -0
- package/docs/TMLPD_V2.1_COMPLETE.md +763 -0
- package/docs/TMLPD_V2.2_RESEARCH_ROADMAP.md +754 -0
- package/docs/UPDATE_TOPICS.md +15 -0
- package/docs/USE_CASES.md +59 -0
- package/docs/V2.2_IMPLEMENTATION_COMPLETE.md +446 -0
- package/docs/V2_IMPLEMENTATION_GUIDE.md +388 -0
- package/docs/VERCEL_AI_SDK.md +209 -0
- package/docs/VISIBILITY_ADOPTION_PLAN.md +1005 -0
- package/docs/_config.yml +49 -0
- package/docs/ai-plugin.json +16 -0
- package/docs/api.html +513 -0
- package/docs/architecture-diagram.md +40 -0
- package/docs/benchmark-chart.png +0 -0
- package/docs/benchmark.html +387 -0
- package/docs/blog/routerarena-number-one.html +73 -0
- package/docs/cli-cheatsheet.md +339 -0
- package/docs/compare.md +109 -0
- package/docs/comparison-litellm.md +88 -0
- package/docs/comparison.md +108 -0
- package/docs/cost-chart-ascii.md +42 -0
- package/docs/cost-comparison-chart.svg +88 -0
- package/docs/curl-examples.md +247 -0
- package/docs/demo-auto.html +264 -0
- package/docs/demo.html +416 -0
- package/docs/geo/GENERATIVE_ENGINE_OPTIMIZATION.md +232 -0
- package/docs/index.html +507 -0
- package/docs/launch-content/LAUNCH_EXECUTION_CHECKLIST.md +421 -0
- package/docs/launch-content/README.md +457 -0
- package/docs/launch-content/assets/cost_comparison_100_tasks.png +0 -0
- package/docs/launch-content/assets/cumulative_savings.png +0 -0
- package/docs/launch-content/assets/parallel_speedup.png +0 -0
- package/docs/launch-content/assets/provider_pricing_comparison.png +0 -0
- package/docs/launch-content/assets/task_breakdown_comparison.png +0 -0
- package/docs/launch-content/generate_charts.py +313 -0
- package/docs/launch-content/hn_show_post.md +139 -0
- package/docs/launch-content/partner_outreach_templates.md +745 -0
- package/docs/launch-content/reddit_posts.md +467 -0
- package/docs/launch-content/twitter_thread.txt +460 -0
- package/{llms.txt.bak → docs/llms.txt} +6 -6
- package/docs/npm-downloads-chart.svg +43 -0
- package/docs/openapi.json +139 -0
- package/docs/openapi.yaml +1318 -0
- package/docs/quick-start.html +366 -0
- package/docs/robots.txt +52 -0
- package/docs/sitemap.xml +57 -0
- package/docs/styles.css +682 -0
- package/docs/well-known/ai-plugin.json +16 -0
- package/docs/wellknown/ai-plugin.json +16 -0
- package/docs-site/assets/og-banner.svg +194 -0
- package/docs-site/index.html +632 -0
- package/eval/README.md +46 -0
- package/eval/baselines/main.json +12 -0
- package/eval/benchmark_dataset.jsonl +16 -0
- package/eval/check_golden_routes.js +64 -0
- package/eval/datasets/catalog.json +33 -0
- package/eval/datasets/slices/cn_provider_reliability_v1.jsonl +3 -0
- package/eval/datasets/slices/cost_pressure_v1.jsonl +3 -0
- package/eval/datasets/slices/safety_guardrails_v1.jsonl +3 -0
- package/eval/evals.json +199 -0
- package/eval/fault_injection_thresholds.json +3 -0
- package/eval/generate_report.js +128 -0
- package/eval/golden_routes.json +114 -0
- package/eval/lib/experiment_registry.js +24 -0
- package/eval/run_eval.js +197 -0
- package/eval/run_fault_injection.js +201 -0
- package/eval/run_shadow_eval.js +85 -0
- package/eval/thresholds.json +9 -0
- package/examples/QUICKSTART.md +183 -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/examples/whatsapp-telegram-bridge-demo.js +302 -0
- package/examples/whatsapp-telegram-bridge.js +269 -0
- package/hf-space/README.md +23 -0
- package/hf-space/app.py +240 -0
- package/hf-space/requirements.txt +1 -0
- package/huggingface_space/README.md +35 -0
- package/huggingface_space/app.py +126 -0
- package/huggingface_space/create_space.py +208 -0
- package/huggingface_space/requirements.txt +1 -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/openclaw-alexa-bridge/ALL_REMAINING_FIXES_PLAN.md +313 -0
- package/openclaw-alexa-bridge/REMAINING_FIXES_SUMMARY.md +277 -0
- package/openclaw-alexa-bridge/src/alexa_handler_no_tmlpd.js +1234 -0
- package/openclaw-alexa-bridge/test_fixes.js +77 -0
- package/package.json +73 -270
- package/playground/README.md +51 -0
- package/playground/codesandbox.json +12 -0
- package/playground/index.js +39 -0
- 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/python/README.md +102 -0
- package/python/a3m/__init__.py +6 -0
- package/python/a3m/client.py +190 -0
- package/python/a3m/models.py +40 -0
- package/python/a3m/sync_client.py +61 -0
- package/python/examples.py +53 -0
- package/python/integrations.py +330 -0
- package/python/pyproject.toml +23 -0
- package/python/setup.py +28 -0
- package/python/tmlpd.py +369 -0
- package/qna/REDDIT_GAP_ANALYSIS.md +299 -0
- package/qna/TMLPD_QNA.md +751 -0
- package/research/FINDING_001_safety.md +28 -0
- package/research/FINDING_002_error_diversity.md +32 -0
- package/research/FINDING_003_confidence_weighted_voting.md +32 -0
- package/research/FINDING_004_cross_model_semantic_detection.md +37 -0
- package/research/FINDING_005_knowledge_gap_orthogonality.md +34 -0
- package/research/HALLUCINATION_RESEARCH.md +27 -0
- package/research/PUBLISH_LOG.md +3 -0
- package/research/ensemble-voting.md +324 -0
- package/research/loss-functions.md +545 -0
- package/research-log.md +49 -0
- package/scripts/banner.js +29 -0
- package/scripts/benchmark-local-routerarena.ts +176 -0
- package/scripts/benchmark.js +145 -0
- package/scripts/benchmark.sh +61 -0
- package/scripts/compare-providers.sh +230 -0
- package/scripts/content-planner.js +25 -0
- package/scripts/create-labeled-benchmark.ts +105 -0
- package/scripts/cross_post.py +443 -0
- package/scripts/local-router-benchmark.ts +154 -0
- package/scripts/post-all.sh +41 -0
- package/scripts/publish_fcc.py +106 -0
- package/scripts/push-to-gitee.sh +25 -0
- package/scripts/routerarena_ensemble.js +144 -0
- package/scripts/routing-benchmark-v2.js +373 -0
- package/scripts/routing-benchmark-v3.js +118 -0
- package/scripts/routing-benchmark.js +462 -0
- package/scripts/run-labeled-benchmark.mjs +104 -0
- package/scripts/run-mmlu-benchmark.js +176 -0
- package/scripts/run-provider-benchmark.js +244 -0
- package/scripts/update-npm-badges.js +158 -0
- package/skill/SKILL.md +238 -0
- package/src/__tests__/integration/tmpld_integration.test.py +540 -0
- package/src/routing/advancedRouter.ts +1 -1
- package/src/skills/__tests__/skill_manager.test.ts +328 -0
- package/submissions/benchmarks/ALL_PLATFORMS_SUBMISSION.md +94 -0
- package/submissions/benchmarks/LLMROUTERBENCH_SUBMISSION.md +121 -0
- package/submissions/benchmarks/MMRBENCH_SUBMISSION.md +94 -0
- package/submissions/benchmarks/ROUTERARENA_UPDATE.md +83 -0
- package/submissions/benchmarks/ROUTERBENCH_SUBMISSION.md +225 -0
- package/test-council/1-structure-tests.test.js +353 -0
- package/test-council/1-structure-tests.test.ts +353 -0
- package/test-council/2-edge-case-tests.test.ts +361 -0
- package/test-council/3-performance-tests.test.ts +669 -0
- package/test-council/4-integration-tests.test.ts +391 -0
- package/test-council/5-agent-council-eval.test.ts +413 -0
- package/test-council/AGENT_COUNCIL_ARCHITECTURE.md +349 -0
- package/test-council/TEST_COUNCIL_REPORT.md +201 -0
- package/test-council/agents/edge-case-agent.ts +363 -0
- package/test-council/agents/performance-agent.ts +426 -0
- package/test-council/agents/structure-agent.ts +227 -0
- package/test-council/council.md +183 -0
- package/tests/__mocks__/tokenUtils.ts +8 -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 +208 -0
- package/tests/security/guardrailEngine.test.ts +700 -0
- package/tests/tsconfig.json +21 -0
- package/tests/vitest.config.ts +18 -0
- package/tmlpd-pi-extension/README.md +66 -0
- package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts +114 -0
- package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/cache/prefixCache.js +285 -0
- package/tmlpd-pi-extension/dist/cache/prefixCache.js.map +1 -0
- package/tmlpd-pi-extension/dist/cache/responseCache.d.ts +58 -0
- package/tmlpd-pi-extension/dist/cache/responseCache.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/cache/responseCache.js +153 -0
- package/tmlpd-pi-extension/dist/cache/responseCache.js.map +1 -0
- package/tmlpd-pi-extension/dist/cli.js +59 -0
- package/tmlpd-pi-extension/dist/cost/costTracker.d.ts +95 -0
- package/tmlpd-pi-extension/dist/cost/costTracker.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/cost/costTracker.js +240 -0
- package/tmlpd-pi-extension/dist/cost/costTracker.js.map +1 -0
- package/tmlpd-pi-extension/dist/index.d.ts +723 -0
- package/tmlpd-pi-extension/dist/index.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/index.js +239 -0
- package/tmlpd-pi-extension/dist/index.js.map +1 -0
- package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts +82 -0
- package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/memory/episodicMemory.js +145 -0
- package/tmlpd-pi-extension/dist/memory/episodicMemory.js.map +1 -0
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts +102 -0
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js +207 -0
- package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js.map +1 -0
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts +85 -0
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js +210 -0
- package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js.map +1 -0
- package/tmlpd-pi-extension/dist/providers/localProvider.d.ts +102 -0
- package/tmlpd-pi-extension/dist/providers/localProvider.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/providers/localProvider.js +338 -0
- package/tmlpd-pi-extension/dist/providers/localProvider.js.map +1 -0
- package/tmlpd-pi-extension/dist/providers/registry.d.ts +55 -0
- package/tmlpd-pi-extension/dist/providers/registry.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/providers/registry.js +138 -0
- package/tmlpd-pi-extension/dist/providers/registry.js.map +1 -0
- package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts +68 -0
- package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/routing/advancedRouter.js +332 -0
- package/tmlpd-pi-extension/dist/routing/advancedRouter.js.map +1 -0
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts +101 -0
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.js +368 -0
- package/tmlpd-pi-extension/dist/tools/tmlpdTools.js.map +1 -0
- package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts +96 -0
- package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/utils/batchProcessor.js +170 -0
- package/tmlpd-pi-extension/dist/utils/batchProcessor.js.map +1 -0
- package/tmlpd-pi-extension/dist/utils/compression.d.ts +61 -0
- package/tmlpd-pi-extension/dist/utils/compression.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/utils/compression.js +281 -0
- package/tmlpd-pi-extension/dist/utils/compression.js.map +1 -0
- package/tmlpd-pi-extension/dist/utils/reliability.d.ts +74 -0
- package/tmlpd-pi-extension/dist/utils/reliability.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/utils/reliability.js +177 -0
- package/tmlpd-pi-extension/dist/utils/reliability.js.map +1 -0
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts +117 -0
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js +246 -0
- package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js.map +1 -0
- package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts +50 -0
- package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts.map +1 -0
- package/tmlpd-pi-extension/dist/utils/tokenUtils.js +124 -0
- package/tmlpd-pi-extension/dist/utils/tokenUtils.js.map +1 -0
- package/tmlpd-pi-extension/examples/QUICKSTART.md +183 -0
- package/tmlpd-pi-extension/package-lock.json +79 -0
- package/tmlpd-pi-extension/package.json +172 -0
- package/tmlpd-pi-extension/python/examples.py +53 -0
- package/tmlpd-pi-extension/python/integrations.py +330 -0
- package/tmlpd-pi-extension/python/setup.py +28 -0
- package/tmlpd-pi-extension/python/tmlpd.py +369 -0
- package/tmlpd-pi-extension/qna/REDDIT_GAP_ANALYSIS.md +299 -0
- package/tmlpd-pi-extension/qna/TMLPD_QNA.md +751 -0
- package/tmlpd-pi-extension/skill/SKILL.md +238 -0
- package/tmlpd-pi-extension/src/cache/responseCache.ts +147 -0
- package/tmlpd-pi-extension/src/cost/costTracker.ts +302 -0
- package/tmlpd-pi-extension/src/index.ts +232 -0
- package/tmlpd-pi-extension/src/memory/episodicMemory.ts +257 -0
- package/tmlpd-pi-extension/src/orchestration/haloOrchestrator.ts +266 -0
- package/tmlpd-pi-extension/src/orchestration/mctsWorkflow.ts +262 -0
- package/tmlpd-pi-extension/src/providers/localProvider.ts +406 -0
- package/tmlpd-pi-extension/src/providers/registry.ts +164 -0
- package/tmlpd-pi-extension/src/routing/ensembleVoting.ts +159 -0
- package/tmlpd-pi-extension/src/routing/queryTypePresets.ts +136 -0
- package/tmlpd-pi-extension/src/tools/tmlpdTools.ts +433 -0
- package/tmlpd-pi-extension/src/utils/batchProcessor.ts +232 -0
- package/tmlpd-pi-extension/src/utils/compression.ts +325 -0
- package/tmlpd-pi-extension/src/utils/reliability.ts +221 -0
- package/tmlpd-pi-extension/src/utils/tokenUtils.ts +145 -0
- package/tmlpd-pi-extension/tsconfig.json +18 -0
- package/tsconfig.build.json +29 -0
- package/tsconfig.json +18 -0
- package/README.md.bak +0 -1185
- package/src/routing/advancedRouter.ts.bak +0 -650
- package/test.js.bak +0 -376
- /package/{llms-full.txt.bak → docs/llms-full.txt} +0 -0
package/docs/API.md
ADDED
|
@@ -0,0 +1,855 @@
|
|
|
1
|
+
# A3M Router API Reference
|
|
2
|
+
|
|
3
|
+
Complete reference for the A3M Router — TypeScript SDK, Python SDK, CLI, REST API, and integrations.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [TypeScript SDK](#typescript-sdk)
|
|
10
|
+
- [Python SDK](#python-sdk)
|
|
11
|
+
- [CLI](#cli)
|
|
12
|
+
- [REST API](#rest-api)
|
|
13
|
+
- [OpenAI SDK Compatibility](#openai-sdk-compatibility)
|
|
14
|
+
- [LangChain Integration](#langchain-integration)
|
|
15
|
+
- [Configuration](#configuration)
|
|
16
|
+
- [Error Handling](#error-handling)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## TypeScript SDK
|
|
21
|
+
|
|
22
|
+
### Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install adaptive-memory-multi-model-router
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Import
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { A3MRouter } from 'adaptive-memory-multi-model-router/sdk';
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Constructor
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
const router = new A3MRouter(config?: A3MRouterConfig);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**A3MRouterConfig:**
|
|
41
|
+
|
|
42
|
+
| Option | Type | Default | Description |
|
|
43
|
+
|--------|------|---------|-------------|
|
|
44
|
+
| `defaultModel` | `string` | — | Fallback model when routing is ambiguous |
|
|
45
|
+
| `maxCostPerQuery` | `number` | — | Max cost per query in USD |
|
|
46
|
+
| `preferSpeedOverQuality` | `boolean` | `false` | Prefer fast models over higher quality |
|
|
47
|
+
| `providers` | `string[]` | all | Restrict routing to these provider IDs |
|
|
48
|
+
|
|
49
|
+
### Methods
|
|
50
|
+
|
|
51
|
+
#### `route(query: string): RoutingResult`
|
|
52
|
+
|
|
53
|
+
Route a query to the best available model. Returns the decision without executing the query.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const decision = router.route("Write a Python function to sort a list");
|
|
57
|
+
|
|
58
|
+
console.log(decision.model); // "groq/llama-3.3-70b-versatile"
|
|
59
|
+
console.log(decision.tier); // "cheap"
|
|
60
|
+
console.log(decision.cost); // 0.00035
|
|
61
|
+
console.log(decision.complexity); // 0.35
|
|
62
|
+
console.log(decision.reasoning); // "Selected Groq/llama-3.3-70b for code detected"
|
|
63
|
+
console.log(decision.fallbackModels); // ["cerebras/llama-3.3-70b", "mistral/mistral-small"]
|
|
64
|
+
console.log(decision.isFree); // false
|
|
65
|
+
console.log(decision.isExpert); // false
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**RoutingResult:**
|
|
69
|
+
|
|
70
|
+
| Field | Type | Description |
|
|
71
|
+
|-------|------|-------------|
|
|
72
|
+
| `model` | `string` | Selected model identifier |
|
|
73
|
+
| `tier` | `'free' \| 'cheap' \| 'mid' \| 'premium'` | Cost tier |
|
|
74
|
+
| `cost` | `number` | Estimated cost in USD |
|
|
75
|
+
| `complexity` | `number` | Query complexity score (0.0–1.0) |
|
|
76
|
+
| `reasoning` | `string` | Human-readable routing reason |
|
|
77
|
+
| `fallbackModels` | `string[]` | Alternative models in priority order |
|
|
78
|
+
| `isFree` | `boolean` | Whether the selected model is free |
|
|
79
|
+
| `isExpert` | `boolean` | Whether this is an expert-level query |
|
|
80
|
+
|
|
81
|
+
#### `routeBatch(queries: string[]): RoutingResult[]`
|
|
82
|
+
|
|
83
|
+
Route multiple queries at once.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
const decisions = router.routeBatch([
|
|
87
|
+
"What is 2+2?",
|
|
88
|
+
"Design a distributed database",
|
|
89
|
+
"Translate to French"
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
decisions.forEach((d, i) => {
|
|
93
|
+
console.log(`Query ${i}: ${d.model} ($${d.cost.toFixed(6)})`);
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
#### `recommend(task: string): RoutingResult`
|
|
98
|
+
|
|
99
|
+
Get model recommendation for a task category.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const rec = router.recommend("code generation");
|
|
103
|
+
console.log(rec.model); // "deepseek/deepseek-chat"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### `analyze(query: string): QueryFeatures`
|
|
107
|
+
|
|
108
|
+
Extract detailed features from a query for debugging.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
const features = router.analyze("Design a secure authentication system for a healthcare app");
|
|
112
|
+
|
|
113
|
+
console.log(features.complexity); // 0.72
|
|
114
|
+
console.log(features.has_code); // false
|
|
115
|
+
console.log(features.requires_reasoning); // true
|
|
116
|
+
console.log(features.is_security); // true
|
|
117
|
+
console.log(features.detected_domain); // "security"
|
|
118
|
+
console.log(features.domain_score); // 0.30
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**QueryFeatures:**
|
|
122
|
+
|
|
123
|
+
| Field | Type | Description |
|
|
124
|
+
|-------|------|-------------|
|
|
125
|
+
| `complexity` | `number` | Overall complexity score (0.0–1.0) |
|
|
126
|
+
| `length` | `number` | Word count |
|
|
127
|
+
| `has_code` | `boolean` | Code-related keywords detected |
|
|
128
|
+
| `has_math` | `boolean` | Math-related keywords detected |
|
|
129
|
+
| `is_multilingual` | `boolean` | Non-ASCII characters detected |
|
|
130
|
+
| `is_translation` | `boolean` | Translation request detected |
|
|
131
|
+
| `is_creative` | `boolean` | Creative writing request |
|
|
132
|
+
| `requires_reasoning` | `boolean` | Analytical/reasoning verbs detected |
|
|
133
|
+
| `is_security` | `boolean` | Security domain keywords |
|
|
134
|
+
| `is_devops` | `boolean` | DevOps/infrastructure keywords |
|
|
135
|
+
| `is_data` | `boolean` | Data/ML keywords |
|
|
136
|
+
| `detected_domain` | `string` | Best matching domain (legal, medical, finance, security, architecture, ml_research) |
|
|
137
|
+
| `domain_score` | `number` | Domain match confidence |
|
|
138
|
+
|
|
139
|
+
#### `serve(port?: number): Promise<string>`
|
|
140
|
+
|
|
141
|
+
Start the OpenAI-compatible proxy server.
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const proxyURL = await router.serve(8787);
|
|
145
|
+
console.log(proxyURL); // "http://localhost:8787/v1"
|
|
146
|
+
|
|
147
|
+
// Now use with any OpenAI SDK
|
|
148
|
+
import OpenAI from 'openai';
|
|
149
|
+
const client = new OpenAI({ baseURL: proxyURL, apiKey: 'not-needed' });
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### `proxyURL` (getter)
|
|
153
|
+
|
|
154
|
+
Returns the proxy URL. Available after `serve()` is called, otherwise returns the default.
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
router.serve(3000);
|
|
158
|
+
console.log(router.proxyURL); // "http://localhost:3000/v1"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Tier Classification
|
|
162
|
+
|
|
163
|
+
Complexity scores map to tiers:
|
|
164
|
+
|
|
165
|
+
| Tier | Complexity Range | Typical Models | Cost/1M tokens |
|
|
166
|
+
|------|:----------------:|----------------|:--------------:|
|
|
167
|
+
| `free` | 0.00 – 0.19 | CommandCode, Ollama, LM Studio | $0.00 |
|
|
168
|
+
| `cheap` | 0.20 – 0.44 | Groq Llama, Cerebras, DeepSeek | ~$0.60 |
|
|
169
|
+
| `mid` | 0.45 – 0.64 | Mistral Small, GPT-4o-mini | ~$1.50 |
|
|
170
|
+
| `premium` | 0.65 – 1.00 | GPT-4o, Claude Sonnet, Gemini Pro | $2.50+ |
|
|
171
|
+
|
|
172
|
+
### Low-Level API
|
|
173
|
+
|
|
174
|
+
The SDK wraps these lower-level exports, also available directly:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import {
|
|
178
|
+
routeQuery,
|
|
179
|
+
routeBatch,
|
|
180
|
+
recommendForTask,
|
|
181
|
+
extractQueryFeatures,
|
|
182
|
+
createA3MRouter,
|
|
183
|
+
getAvailableProviders,
|
|
184
|
+
registerProvider,
|
|
185
|
+
createProxyServer,
|
|
186
|
+
} from 'adaptive-memory-multi-model-router';
|
|
187
|
+
|
|
188
|
+
// Direct routing
|
|
189
|
+
const result = routeQuery("What is 2+2?");
|
|
190
|
+
// => { primary_model, fallback_models, confidence, reasoning, estimated_cost, ... }
|
|
191
|
+
|
|
192
|
+
// Router instance (v1 style)
|
|
193
|
+
const router = createA3MRouter();
|
|
194
|
+
const decision = router.route("Hello");
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Python SDK
|
|
200
|
+
|
|
201
|
+
### Installation
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
pip install a3m-router
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Usage
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
from a3m import A3MRouter
|
|
211
|
+
|
|
212
|
+
# Create router instance
|
|
213
|
+
router = A3MRouter()
|
|
214
|
+
|
|
215
|
+
# Route a query
|
|
216
|
+
decision = router.route("Write a Python function")
|
|
217
|
+
print(decision.model) # "groq/llama-3.3-70b"
|
|
218
|
+
print(decision.tier) # "cheap"
|
|
219
|
+
print(decision.cost) # 0.0004
|
|
220
|
+
print(decision.complexity) # 0.35
|
|
221
|
+
|
|
222
|
+
# Chat through the router (auto-selects model)
|
|
223
|
+
response = router.chat("What is 2+2?")
|
|
224
|
+
print(response.content) # "4"
|
|
225
|
+
print(response.model) # "groq/llama-3.3-70b"
|
|
226
|
+
|
|
227
|
+
# Analyze query features
|
|
228
|
+
features = router.analyze("Design a microservice architecture")
|
|
229
|
+
print(features.complexity) # 0.58
|
|
230
|
+
print(features.has_code) # False
|
|
231
|
+
print(features.detected_domain) # "architecture"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Async Usage
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
import asyncio
|
|
238
|
+
from a3m import A3MRouter
|
|
239
|
+
|
|
240
|
+
async def main():
|
|
241
|
+
router = A3MRouter()
|
|
242
|
+
|
|
243
|
+
# Async chat
|
|
244
|
+
response = await router.achat("Explain quantum computing")
|
|
245
|
+
print(response.content)
|
|
246
|
+
|
|
247
|
+
# Batch routing
|
|
248
|
+
decisions = router.route_batch([
|
|
249
|
+
"What is 2+2?",
|
|
250
|
+
"Design a distributed system",
|
|
251
|
+
"Write a poem"
|
|
252
|
+
])
|
|
253
|
+
for d in decisions:
|
|
254
|
+
print(f"{d.model} ({d.tier}) — ${d.cost:.6f}")
|
|
255
|
+
|
|
256
|
+
asyncio.run(main())
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### With OpenAI Python SDK
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
from openai import OpenAI
|
|
263
|
+
|
|
264
|
+
# Point OpenAI SDK at the A3M proxy
|
|
265
|
+
client = OpenAI(
|
|
266
|
+
base_url="http://localhost:8787/v1",
|
|
267
|
+
api_key="not-needed"
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
response = client.chat.completions.create(
|
|
271
|
+
model="auto",
|
|
272
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
273
|
+
)
|
|
274
|
+
print(response.choices[0].message.content)
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## CLI
|
|
280
|
+
|
|
281
|
+
### Installation
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
npm install -g adaptive-memory-multi-model-router
|
|
285
|
+
# or use without installing:
|
|
286
|
+
npx a3m-router <command>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Commands
|
|
290
|
+
|
|
291
|
+
#### `route` — Route a query
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
npx a3m-router route "Your query here"
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Output:
|
|
298
|
+
```
|
|
299
|
+
Primary: groq/llama-3.3-70b-versatile
|
|
300
|
+
Fallbacks: cerebras/llama-3.3-70b, mistral/mistral-small
|
|
301
|
+
Est. Cost: $0.000350
|
|
302
|
+
Type: api
|
|
303
|
+
Reason: Selected Groq for code detected, fast tier
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
#### `serve` — Start proxy server
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
npx a3m-router serve --port 8787
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Options:
|
|
313
|
+
- `--port` / `-p` — Port to listen on (default: 8787)
|
|
314
|
+
|
|
315
|
+
#### `benchmark` — Run routing accuracy benchmark
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
npx a3m-router benchmark
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### `providers` — List configured providers
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
npx a3m-router providers
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### `models` — List known models
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
npx a3m-router models
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
#### `recommend` — Get model recommendation for a task
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
npx a3m-router recommend "code generation"
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
#### `cost` — Estimate token cost
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
npx a3m-router cost "Your text here"
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
#### `token` — Count tokens
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
npx a3m-router token "Your text here"
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### `batch` — Route multiple queries
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
npx a3m-router batch "What is 2+2?" "Design a system" "Write a poem"
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### `compare` — Compare providers side by side
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
npx a3m-router compare "Your query"
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
#### `test` — Test all configured providers
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
npx a3m-router test
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
#### `memory` — Memory operations
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
npx a3m-router memory add "key" "value"
|
|
373
|
+
npx a3m-router memory search "query"
|
|
374
|
+
npx a3m-router memory stats
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
#### `status` — Show router status
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
npx a3m-router status
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## REST API
|
|
386
|
+
|
|
387
|
+
Start the server:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
npx a3m-router serve --port 8787
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
Base URL: `http://localhost:8787`
|
|
394
|
+
|
|
395
|
+
### POST /v1/chat/completions
|
|
396
|
+
|
|
397
|
+
OpenAI-compatible chat endpoint. Supports both streaming and non-streaming.
|
|
398
|
+
|
|
399
|
+
**Request:**
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
curl http://localhost:8787/v1/chat/completions \
|
|
403
|
+
-H "Content-Type: application/json" \
|
|
404
|
+
-d '{
|
|
405
|
+
"model": "auto",
|
|
406
|
+
"messages": [
|
|
407
|
+
{"role": "system", "content": "You are a helpful assistant."},
|
|
408
|
+
{"role": "user", "content": "What is 2+2?"}
|
|
409
|
+
],
|
|
410
|
+
"temperature": 0.7,
|
|
411
|
+
"max_tokens": 1024,
|
|
412
|
+
"stream": false
|
|
413
|
+
}'
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**Request Body:**
|
|
417
|
+
|
|
418
|
+
| Field | Type | Default | Description |
|
|
419
|
+
|-------|------|---------|-------------|
|
|
420
|
+
| `model` | `string` | `"auto"` | Model to use. `"auto"` triggers routing. Accepts `provider/model` format. |
|
|
421
|
+
| `messages` | `array` | required | OpenAI-format message array |
|
|
422
|
+
| `temperature` | `number` | provider default | Sampling temperature (0–2) |
|
|
423
|
+
| `max_tokens` | `number` | `1024` | Maximum tokens to generate |
|
|
424
|
+
| `stream` | `boolean` | `false` | Enable SSE streaming |
|
|
425
|
+
| `stop` | `string \| string[]` | — | Stop sequences |
|
|
426
|
+
|
|
427
|
+
**Non-streaming response:**
|
|
428
|
+
|
|
429
|
+
```json
|
|
430
|
+
{
|
|
431
|
+
"id": "chatcmpl-a1b2c3d4",
|
|
432
|
+
"object": "chat.completion",
|
|
433
|
+
"created": 1716000000,
|
|
434
|
+
"model": "llama-3.3-70b-versatile",
|
|
435
|
+
"choices": [
|
|
436
|
+
{
|
|
437
|
+
"index": 0,
|
|
438
|
+
"message": {
|
|
439
|
+
"role": "assistant",
|
|
440
|
+
"content": "2 + 2 = 4"
|
|
441
|
+
},
|
|
442
|
+
"finish_reason": "stop"
|
|
443
|
+
}
|
|
444
|
+
],
|
|
445
|
+
"usage": {
|
|
446
|
+
"prompt_tokens": 24,
|
|
447
|
+
"completion_tokens": 5,
|
|
448
|
+
"total_tokens": 29
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**Streaming response:**
|
|
454
|
+
|
|
455
|
+
```
|
|
456
|
+
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":...,"model":"...","choices":[{"index":0,"delta":{"content":"2"},"finish_reason":null}]}
|
|
457
|
+
|
|
458
|
+
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":...,"model":"...","choices":[{"index":0,"delta":{"content":" +"},"finish_reason":null}]}
|
|
459
|
+
|
|
460
|
+
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":...,"model":"...","choices":[{"index":0,"delta":{"content":" 2 = 4"},"finish_reason":null}]}
|
|
461
|
+
|
|
462
|
+
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":...,"model":"...","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
|
|
463
|
+
|
|
464
|
+
data: [DONE]
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
**Model routing:**
|
|
468
|
+
|
|
469
|
+
| Model value | Behavior |
|
|
470
|
+
|-------------|----------|
|
|
471
|
+
| `"auto"` | Routes based on query complexity (recommended) |
|
|
472
|
+
| `"groq/llama-3.3-70b-versatile"` | Uses specific provider/model |
|
|
473
|
+
| `"gpt-4o"` | Maps to configured OpenAI provider |
|
|
474
|
+
| `"claude-sonnet"` | Maps to configured Anthropic provider |
|
|
475
|
+
|
|
476
|
+
### POST /v1/completions
|
|
477
|
+
|
|
478
|
+
OpenAI-compatible text completions endpoint.
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
curl http://localhost:8787/v1/completions \
|
|
482
|
+
-H "Content-Type: application/json" \
|
|
483
|
+
-d '{
|
|
484
|
+
"model": "auto",
|
|
485
|
+
"prompt": "The capital of France is",
|
|
486
|
+
"max_tokens": 50
|
|
487
|
+
}'
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
**Response:**
|
|
491
|
+
|
|
492
|
+
```json
|
|
493
|
+
{
|
|
494
|
+
"id": "chatcmpl-...",
|
|
495
|
+
"object": "text_completion",
|
|
496
|
+
"created": 1716000000,
|
|
497
|
+
"model": "llama-3.3-70b-versatile",
|
|
498
|
+
"choices": [
|
|
499
|
+
{
|
|
500
|
+
"text": " Paris.",
|
|
501
|
+
"index": 0,
|
|
502
|
+
"finish_reason": "stop"
|
|
503
|
+
}
|
|
504
|
+
],
|
|
505
|
+
"usage": {
|
|
506
|
+
"prompt_tokens": 5,
|
|
507
|
+
"completion_tokens": 2,
|
|
508
|
+
"total_tokens": 7
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### POST /v1/route
|
|
514
|
+
|
|
515
|
+
Route a query without executing it. Returns the routing decision.
|
|
516
|
+
|
|
517
|
+
```bash
|
|
518
|
+
curl -X POST http://localhost:8787/v1/route \
|
|
519
|
+
-H "Content-Type: application/json" \
|
|
520
|
+
-d '{"query": "Write a Python function to sort a list"}'
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**Response:**
|
|
524
|
+
|
|
525
|
+
```json
|
|
526
|
+
{
|
|
527
|
+
"primary_model": "groq/llama-3.3-70b-versatile",
|
|
528
|
+
"fallback_models": ["cerebras/llama-3.3-70b", "mistral/mistral-small"],
|
|
529
|
+
"confidence": 0.82,
|
|
530
|
+
"reasoning": "Selected Groq for code detected, fast tier",
|
|
531
|
+
"estimated_cost": 0.00035,
|
|
532
|
+
"estimated_latency_ms": 800,
|
|
533
|
+
"features": {
|
|
534
|
+
"complexity": 0.35,
|
|
535
|
+
"has_code": true,
|
|
536
|
+
"has_math": false,
|
|
537
|
+
"requires_reasoning": false,
|
|
538
|
+
"detected_domain": ""
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### GET /v1/models
|
|
544
|
+
|
|
545
|
+
List all available models.
|
|
546
|
+
|
|
547
|
+
```bash
|
|
548
|
+
curl http://localhost:8787/v1/models
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
**Response:**
|
|
552
|
+
|
|
553
|
+
```json
|
|
554
|
+
{
|
|
555
|
+
"object": "list",
|
|
556
|
+
"data": [
|
|
557
|
+
{
|
|
558
|
+
"id": "groq/llama-3.3-70b-versatile",
|
|
559
|
+
"object": "model",
|
|
560
|
+
"owned_by": "groq"
|
|
561
|
+
}
|
|
562
|
+
]
|
|
563
|
+
}
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### GET /health
|
|
567
|
+
|
|
568
|
+
Health check with provider status and cost summary.
|
|
569
|
+
|
|
570
|
+
```bash
|
|
571
|
+
curl http://localhost:8787/health
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
**Response:**
|
|
575
|
+
|
|
576
|
+
```json
|
|
577
|
+
{
|
|
578
|
+
"status": "ok",
|
|
579
|
+
"version": "2.1.0",
|
|
580
|
+
"providers": {
|
|
581
|
+
"total": 12,
|
|
582
|
+
"healthy": 8,
|
|
583
|
+
"details": {
|
|
584
|
+
"groq": {
|
|
585
|
+
"name": "Groq",
|
|
586
|
+
"type": "api",
|
|
587
|
+
"models": 3,
|
|
588
|
+
"available": true
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
"cost": {
|
|
593
|
+
"total": 0.0042,
|
|
594
|
+
"requests": 127
|
|
595
|
+
},
|
|
596
|
+
"uptime": 86400.5,
|
|
597
|
+
"recentRequests": []
|
|
598
|
+
}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### GET /dashboard
|
|
602
|
+
|
|
603
|
+
Interactive web dashboard (if `public/` directory is present).
|
|
604
|
+
|
|
605
|
+
```
|
|
606
|
+
http://localhost:8787/
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
---
|
|
610
|
+
|
|
611
|
+
## OpenAI SDK Compatibility
|
|
612
|
+
|
|
613
|
+
The A3M Router proxy is fully compatible with the OpenAI SDK. Point the `baseURL` at the proxy and use `model: "auto"` for routing.
|
|
614
|
+
|
|
615
|
+
### JavaScript/TypeScript
|
|
616
|
+
|
|
617
|
+
```javascript
|
|
618
|
+
import OpenAI from 'openai';
|
|
619
|
+
|
|
620
|
+
const client = new OpenAI({
|
|
621
|
+
baseURL: 'http://localhost:8787/v1',
|
|
622
|
+
apiKey: 'not-needed'
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
// Auto-routing
|
|
626
|
+
const response = await client.chat.completions.create({
|
|
627
|
+
model: 'auto',
|
|
628
|
+
messages: [{ role: 'user', content: 'Hello!' }]
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
// Specific model
|
|
632
|
+
const response2 = await client.chat.completions.create({
|
|
633
|
+
model: 'groq/llama-3.3-70b-versatile',
|
|
634
|
+
messages: [{ role: 'user', content: 'Hello!' }]
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
// Streaming
|
|
638
|
+
const stream = await client.chat.completions.create({
|
|
639
|
+
model: 'auto',
|
|
640
|
+
messages: [{ role: 'user', content: 'Tell me a story' }],
|
|
641
|
+
stream: true
|
|
642
|
+
});
|
|
643
|
+
for await (const chunk of stream) {
|
|
644
|
+
process.stdout.write(chunk.choices[0]?.delta?.content || '');
|
|
645
|
+
}
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
### Python
|
|
649
|
+
|
|
650
|
+
```python
|
|
651
|
+
from openai import OpenAI
|
|
652
|
+
|
|
653
|
+
client = OpenAI(
|
|
654
|
+
base_url="http://localhost:8787/v1",
|
|
655
|
+
api_key="not-needed"
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
response = client.chat.completions.create(
|
|
659
|
+
model="auto",
|
|
660
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
661
|
+
)
|
|
662
|
+
print(response.choices[0].message.content)
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
### cURL
|
|
666
|
+
|
|
667
|
+
```bash
|
|
668
|
+
curl http://localhost:8787/v1/chat/completions \
|
|
669
|
+
-H "Content-Type: application/json" \
|
|
670
|
+
-d '{"model":"auto","messages":[{"role":"user","content":"Hello!"}]}'
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
---
|
|
674
|
+
|
|
675
|
+
## LangChain Integration
|
|
676
|
+
|
|
677
|
+
```typescript
|
|
678
|
+
import { A3MChatModel } from 'adaptive-memory-multi-model-router/langchain';
|
|
679
|
+
import { HumanMessage } from '@langchain/core/messages';
|
|
680
|
+
|
|
681
|
+
const model = new A3MChatModel({
|
|
682
|
+
modelName: 'auto', // or specific model
|
|
683
|
+
temperature: 0.7,
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
// Invoke
|
|
687
|
+
const response = await model.invoke([
|
|
688
|
+
new HumanMessage("What is 2+2?")
|
|
689
|
+
]);
|
|
690
|
+
console.log(response.content);
|
|
691
|
+
|
|
692
|
+
// Streaming
|
|
693
|
+
const stream = await model.stream([
|
|
694
|
+
new HumanMessage("Tell me a story")
|
|
695
|
+
]);
|
|
696
|
+
for await (const chunk of stream) {
|
|
697
|
+
process.stdout.write(chunk.content);
|
|
698
|
+
}
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
**Prerequisites:**
|
|
702
|
+
|
|
703
|
+
```bash
|
|
704
|
+
npm install @langchain/core @langchain/openai
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
LangChain is a peer dependency — install it separately.
|
|
708
|
+
|
|
709
|
+
---
|
|
710
|
+
|
|
711
|
+
## Configuration
|
|
712
|
+
|
|
713
|
+
### Environment Variables
|
|
714
|
+
|
|
715
|
+
| Variable | Description | Default |
|
|
716
|
+
|----------|-------------|---------|
|
|
717
|
+
| `PORT` | Proxy server port | `8787` |
|
|
718
|
+
| `GROQ_API_KEY` | Groq provider API key | — |
|
|
719
|
+
| `CEREBRAS_API_KEY` | Cerebras provider API key | — |
|
|
720
|
+
| `OPENAI_API_KEY` | OpenAI provider API key | — |
|
|
721
|
+
| `ANTHROPIC_API_KEY` | Anthropic provider API key | — |
|
|
722
|
+
| `GOOGLE_API_KEY` | Google/Gemini provider API key | — |
|
|
723
|
+
| `MISTRAL_API_KEY` | Mistral provider API key | — |
|
|
724
|
+
| `DEEPSEEK_API_KEY` | DeepSeek provider API key | — |
|
|
725
|
+
| `OPENROUTER_API_KEY` | OpenRouter provider API key | — |
|
|
726
|
+
|
|
727
|
+
### Config File
|
|
728
|
+
|
|
729
|
+
Provider configuration is stored at `~/.config/a3m-router/providers.json`:
|
|
730
|
+
|
|
731
|
+
```json
|
|
732
|
+
{
|
|
733
|
+
"providers": {
|
|
734
|
+
"groq": {
|
|
735
|
+
"apiKey": "gsk_...",
|
|
736
|
+
"models": ["llama-3.3-70b-versatile", "mixtral-8x7b"]
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
### Programmatic Provider Registration
|
|
743
|
+
|
|
744
|
+
```typescript
|
|
745
|
+
import { registerProvider } from 'adaptive-memory-multi-model-router';
|
|
746
|
+
|
|
747
|
+
registerProvider('my-provider', {
|
|
748
|
+
name: 'My Provider',
|
|
749
|
+
type: 'api',
|
|
750
|
+
apiKey: 'sk-...',
|
|
751
|
+
baseUrl: 'https://api.my-provider.com/v1/chat/completions',
|
|
752
|
+
models: ['my-model-v1'],
|
|
753
|
+
costPerK: { input: 0.50, output: 1.50 },
|
|
754
|
+
maxTokens: 8192,
|
|
755
|
+
priority: 5,
|
|
756
|
+
});
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
---
|
|
760
|
+
|
|
761
|
+
## Error Handling
|
|
762
|
+
|
|
763
|
+
### HTTP Error Responses
|
|
764
|
+
|
|
765
|
+
All errors follow the OpenAI error format:
|
|
766
|
+
|
|
767
|
+
```json
|
|
768
|
+
{
|
|
769
|
+
"error": {
|
|
770
|
+
"message": "No provider available for model \"gpt-4o\". Configure API keys.",
|
|
771
|
+
"type": "server_error",
|
|
772
|
+
"code": 503
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
| Status | Type | Description |
|
|
778
|
+
|--------|------|-------------|
|
|
779
|
+
| 400 | `invalid_request_error` | Malformed request body or missing fields |
|
|
780
|
+
| 404 | `not_found` | Unknown endpoint |
|
|
781
|
+
| 502 | `upstream_error` | Provider returned an error |
|
|
782
|
+
| 503 | `server_error` | No providers available |
|
|
783
|
+
|
|
784
|
+
### Fallback Behavior
|
|
785
|
+
|
|
786
|
+
When the primary provider fails, the proxy automatically tries alternative providers in order:
|
|
787
|
+
|
|
788
|
+
1. Primary provider (routed or specified)
|
|
789
|
+
2. Other configured API providers
|
|
790
|
+
3. Returns 502 if all providers fail
|
|
791
|
+
|
|
792
|
+
### SDK Error Handling
|
|
793
|
+
|
|
794
|
+
```typescript
|
|
795
|
+
const router = new A3MRouter();
|
|
796
|
+
|
|
797
|
+
try {
|
|
798
|
+
const decision = router.route("Your query");
|
|
799
|
+
if (decision.model === 'unknown') {
|
|
800
|
+
// No providers available
|
|
801
|
+
}
|
|
802
|
+
} catch (err) {
|
|
803
|
+
console.error('Routing failed:', err);
|
|
804
|
+
}
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
---
|
|
808
|
+
|
|
809
|
+
## Provider Support
|
|
810
|
+
|
|
811
|
+
### Supported Provider Types
|
|
812
|
+
|
|
813
|
+
| Type | Providers | Protocol |
|
|
814
|
+
|------|-----------|----------|
|
|
815
|
+
| **API** | Groq, Cerebras, OpenAI, Anthropic, Google, Mistral, DeepSeek, OpenRouter | REST API |
|
|
816
|
+
| **Local** | Ollama, vLLM, LM Studio | OpenAI-compatible local API |
|
|
817
|
+
| **CLI** | CommandCode, OpenCode | Local CLI tools |
|
|
818
|
+
|
|
819
|
+
### Adding Custom Providers
|
|
820
|
+
|
|
821
|
+
```typescript
|
|
822
|
+
import { registerProvider } from 'adaptive-memory-multi-model-router';
|
|
823
|
+
|
|
824
|
+
registerProvider('custom', {
|
|
825
|
+
name: 'Custom LLM',
|
|
826
|
+
type: 'api',
|
|
827
|
+
apiKey: process.env.CUSTOM_API_KEY,
|
|
828
|
+
baseUrl: 'https://api.custom.com/v1/chat/completions',
|
|
829
|
+
models: ['custom-v1'],
|
|
830
|
+
costPerK: { input: 1.0, output: 2.0 },
|
|
831
|
+
maxTokens: 4096,
|
|
832
|
+
priority: 5,
|
|
833
|
+
});
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
---
|
|
837
|
+
|
|
838
|
+
## Architecture
|
|
839
|
+
|
|
840
|
+
```
|
|
841
|
+
┌──────────────┐ ┌──────────────────────────────────────────┐
|
|
842
|
+
│ Your Code │────>│ A3M Router │
|
|
843
|
+
│ │ │ │
|
|
844
|
+
│ OpenAI SDK │ │ ┌─────────┐ ┌──────────────────┐ │
|
|
845
|
+
│ LangChain │ │ │ Routing │───>│ Model Selection │ │
|
|
846
|
+
│ Python SDK │ │ │ Engine │ │ (cost/quality) │ │
|
|
847
|
+
│ CLI │ │ └─────────┘ └──────┬───────────┘ │
|
|
848
|
+
│ cURL │ │ │ │
|
|
849
|
+
└──────────────┘ │ ┌─────────────────────▼────────────┐ │
|
|
850
|
+
│ │ Provider Layer │ │
|
|
851
|
+
│ │ Groq | Cerebras | OpenAI | ... │ │
|
|
852
|
+
│ │ Ollama | vLLM | LM Studio │ │
|
|
853
|
+
│ └───────────────────────────────────┘ │
|
|
854
|
+
└──────────────────────────────────────────┘
|
|
855
|
+
```
|