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
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structure Tests - Code Structure & Export Coverage
|
|
3
|
+
*
|
|
4
|
+
* Tests that verify all exported functions, classes, and types work correctly.
|
|
5
|
+
* This file provides comprehensive coverage of the public API surface.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
9
|
+
|
|
10
|
+
// Import all exports from the main module
|
|
11
|
+
const {
|
|
12
|
+
// Routing engine
|
|
13
|
+
routeQuery,
|
|
14
|
+
routeBatch,
|
|
15
|
+
recommendForTask,
|
|
16
|
+
extractQueryFeatures,
|
|
17
|
+
MODEL_PROFILES,
|
|
18
|
+
updateModelProfile,
|
|
19
|
+
getProviderHealth,
|
|
20
|
+
|
|
21
|
+
// Retry handling
|
|
22
|
+
ProviderRetryHandler,
|
|
23
|
+
createRetryHandler,
|
|
24
|
+
getDefaultRetryHandler,
|
|
25
|
+
DEFAULT_RETRY_CONFIG,
|
|
26
|
+
DEFAULT_PROVIDER_CONFIG,
|
|
27
|
+
PROVIDER_CONTEXT_LIMITS,
|
|
28
|
+
|
|
29
|
+
// Providers
|
|
30
|
+
DEFAULT_PROVIDERS,
|
|
31
|
+
getAvailableProviders,
|
|
32
|
+
registerProvider,
|
|
33
|
+
deregisterProvider,
|
|
34
|
+
updateProvider,
|
|
35
|
+
healthCheck,
|
|
36
|
+
checkAllProviders,
|
|
37
|
+
findCheapestAvailableProvider,
|
|
38
|
+
findFastestAvailableProvider,
|
|
39
|
+
loadConfig,
|
|
40
|
+
saveConfig,
|
|
41
|
+
|
|
42
|
+
// Cost tracking
|
|
43
|
+
CostTracker,
|
|
44
|
+
BudgetEnforcer,
|
|
45
|
+
BudgetExceededError,
|
|
46
|
+
createBudgetEnforcer,
|
|
47
|
+
|
|
48
|
+
// Memory
|
|
49
|
+
MemoryTree,
|
|
50
|
+
|
|
51
|
+
// Utilities
|
|
52
|
+
countTokens,
|
|
53
|
+
estimateTokens,
|
|
54
|
+
|
|
55
|
+
// Cache
|
|
56
|
+
SemanticCache,
|
|
57
|
+
|
|
58
|
+
// Security
|
|
59
|
+
GuardrailEngine,
|
|
60
|
+
|
|
61
|
+
// Analytics
|
|
62
|
+
CostAnalytics,
|
|
63
|
+
|
|
64
|
+
// Observability
|
|
65
|
+
Tracer,
|
|
66
|
+
getTracer,
|
|
67
|
+
createTracer,
|
|
68
|
+
MetricsCollector,
|
|
69
|
+
getMetrics,
|
|
70
|
+
createMetricsCollector,
|
|
71
|
+
observabilityMiddleware,
|
|
72
|
+
observabilityPlugin,
|
|
73
|
+
budgetAlertMiddleware,
|
|
74
|
+
|
|
75
|
+
// Ensemble
|
|
76
|
+
EnsembleOrchestrator,
|
|
77
|
+
|
|
78
|
+
// Factory
|
|
79
|
+
createA3MRouter,
|
|
80
|
+
} = require('../dist/index.js');
|
|
81
|
+
|
|
82
|
+
// ============================================================
|
|
83
|
+
// STRUCTURE TESTS
|
|
84
|
+
// ============================================================
|
|
85
|
+
|
|
86
|
+
describe('1. Structure - Routing Engine Exports', () => {
|
|
87
|
+
|
|
88
|
+
describe('routeQuery', () => {
|
|
89
|
+
it('is a function', () => {
|
|
90
|
+
expect(typeof routeQuery).toBe('function');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('returns object with primary_model', () => {
|
|
94
|
+
const result = routeQuery('test query');
|
|
95
|
+
expect(result).toHaveProperty('primary_model');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('returns object with fallback_models array', () => {
|
|
99
|
+
const result = routeQuery('test query');
|
|
100
|
+
expect(result).toHaveProperty('fallback_models');
|
|
101
|
+
expect(Array.isArray(result.fallback_models)).toBe(true);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('returns object with estimated_cost number', () => {
|
|
105
|
+
const result = routeQuery('test query');
|
|
106
|
+
expect(result).toHaveProperty('estimated_cost');
|
|
107
|
+
expect(typeof result.estimated_cost).toBe('number');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('returns object with confidence number', () => {
|
|
111
|
+
const result = routeQuery('test query');
|
|
112
|
+
expect(result).toHaveProperty('confidence');
|
|
113
|
+
expect(typeof result.confidence).toBe('number');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
describe('routeBatch', () => {
|
|
118
|
+
it('is a function', () => {
|
|
119
|
+
expect(typeof routeBatch).toBe('function');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('returns array of same length as input', () => {
|
|
123
|
+
const queries = ['a', 'b', 'c'];
|
|
124
|
+
const results = routeBatch(queries);
|
|
125
|
+
expect(results.length).toBe(queries.length);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe('recommendForTask', () => {
|
|
130
|
+
it('is a function', () => {
|
|
131
|
+
expect(typeof recommendForTask).toBe('function');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('returns object with primary field', () => {
|
|
135
|
+
const result = recommendForTask('coding');
|
|
136
|
+
expect(result).toHaveProperty('primary');
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
describe('extractQueryFeatures', () => {
|
|
141
|
+
it('is a function', () => {
|
|
142
|
+
expect(typeof extractQueryFeatures).toBe('function');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('returns object', () => {
|
|
146
|
+
const features = extractQueryFeatures('test');
|
|
147
|
+
expect(typeof features).toBe('object');
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
describe('MODEL_PROFILES', () => {
|
|
152
|
+
it('is an object', () => {
|
|
153
|
+
expect(typeof MODEL_PROFILES).toBe('object');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('has at least one model', () => {
|
|
157
|
+
expect(Object.keys(MODEL_PROFILES).length).toBeGreaterThan(0);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe('2. Structure - Provider Configuration Exports', () => {
|
|
163
|
+
|
|
164
|
+
describe('DEFAULT_PROVIDERS', () => {
|
|
165
|
+
it('is an object', () => {
|
|
166
|
+
expect(typeof DEFAULT_PROVIDERS).toBe('object');
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
describe('getAvailableProviders', () => {
|
|
171
|
+
it('is a function', () => {
|
|
172
|
+
expect(typeof getAvailableProviders).toBe('function');
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('returns an object', () => {
|
|
176
|
+
const providers = getAvailableProviders();
|
|
177
|
+
expect(typeof providers).toBe('object');
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
describe('registerProvider', () => {
|
|
182
|
+
it('is a function', () => {
|
|
183
|
+
expect(typeof registerProvider).toBe('function');
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe('deregisterProvider', () => {
|
|
188
|
+
it('is a function', () => {
|
|
189
|
+
expect(typeof deregisterProvider).toBe('function');
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
describe('updateProvider', () => {
|
|
194
|
+
it('is a function', () => {
|
|
195
|
+
expect(typeof updateProvider).toBe('function');
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
describe('healthCheck', () => {
|
|
200
|
+
it('is a function', () => {
|
|
201
|
+
expect(typeof healthCheck).toBe('function');
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
describe('3. Structure - Retry Handler Exports', () => {
|
|
207
|
+
|
|
208
|
+
describe('ProviderRetryHandler', () => {
|
|
209
|
+
it('is a class', () => {
|
|
210
|
+
expect(typeof ProviderRetryHandler).toBe('function');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('can be instantiated', () => {
|
|
214
|
+
const handler = new ProviderRetryHandler();
|
|
215
|
+
expect(handler).toBeInstanceOf(ProviderRetryHandler);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('has getConfig method', () => {
|
|
219
|
+
const handler = new ProviderRetryHandler();
|
|
220
|
+
expect(typeof handler.getConfig).toBe('function');
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('has isRetryableError method', () => {
|
|
224
|
+
const handler = new ProviderRetryHandler();
|
|
225
|
+
expect(typeof handler.isRetryableError).toBe('function');
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
describe('createRetryHandler', () => {
|
|
230
|
+
it('is a function', () => {
|
|
231
|
+
expect(typeof createRetryHandler).toBe('function');
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
describe('DEFAULT_RETRY_CONFIG', () => {
|
|
236
|
+
it('is an object', () => {
|
|
237
|
+
expect(typeof DEFAULT_RETRY_CONFIG).toBe('object');
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
describe('PROVIDER_CONTEXT_LIMITS', () => {
|
|
242
|
+
it('is an object', () => {
|
|
243
|
+
expect(typeof PROVIDER_CONTEXT_LIMITS).toBe('object');
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
describe('4. Structure - Cost Tracking Exports', () => {
|
|
249
|
+
|
|
250
|
+
describe('CostTracker', () => {
|
|
251
|
+
it('is a class', () => {
|
|
252
|
+
expect(typeof CostTracker).toBe('function');
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('can be instantiated', () => {
|
|
256
|
+
const tracker = new CostTracker();
|
|
257
|
+
expect(tracker).toBeTruthy();
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
describe('BudgetEnforcer', () => {
|
|
262
|
+
it('is a class', () => {
|
|
263
|
+
expect(typeof BudgetEnforcer).toBe('function');
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
describe('BudgetExceededError', () => {
|
|
268
|
+
it('is an Error class', () => {
|
|
269
|
+
expect(typeof BudgetExceededError).toBe('function');
|
|
270
|
+
const error = new BudgetExceededError('test');
|
|
271
|
+
expect(error).toBeInstanceOf(Error);
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
describe('5. Structure - Memory Exports', () => {
|
|
277
|
+
|
|
278
|
+
describe('MemoryTree', () => {
|
|
279
|
+
it('is a class', () => {
|
|
280
|
+
expect(typeof MemoryTree).toBe('function');
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it('can be instantiated', () => {
|
|
284
|
+
const memory = new MemoryTree({ maxSize: 100 });
|
|
285
|
+
expect(memory).toBeTruthy();
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('has add method', () => {
|
|
289
|
+
const memory = new MemoryTree({ maxSize: 100 });
|
|
290
|
+
expect(typeof memory.add).toBe('function');
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('has search method', () => {
|
|
294
|
+
const memory = new MemoryTree({ maxSize: 100 });
|
|
295
|
+
expect(typeof memory.search).toBe('function');
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
it('has getStats method', () => {
|
|
299
|
+
const memory = new MemoryTree({ maxSize: 100 });
|
|
300
|
+
expect(typeof memory.getStats).toBe('function');
|
|
301
|
+
});
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
describe('6. Structure - Utility Exports', () => {
|
|
306
|
+
|
|
307
|
+
describe('countTokens', () => {
|
|
308
|
+
it('is a function', () => {
|
|
309
|
+
expect(typeof countTokens).toBe('function');
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it('returns positive number for non-empty string', () => {
|
|
313
|
+
const tokens = countTokens('hello world');
|
|
314
|
+
expect(typeof tokens).toBe('number');
|
|
315
|
+
expect(tokens).toBeGreaterThan(0);
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
describe('estimateTokens', () => {
|
|
320
|
+
it('is a function', () => {
|
|
321
|
+
expect(typeof estimateTokens).toBe('function');
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
describe('7. Structure - Factory Exports', () => {
|
|
327
|
+
|
|
328
|
+
describe('createA3MRouter', () => {
|
|
329
|
+
it('is a function', () => {
|
|
330
|
+
expect(typeof createA3MRouter).toBe('function');
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it('returns an object', () => {
|
|
334
|
+
const router = createA3MRouter({});
|
|
335
|
+
expect(typeof router).toBe('object');
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
it('returns object with route function', () => {
|
|
339
|
+
const router = createA3MRouter({});
|
|
340
|
+
expect(typeof router.route).toBe('function');
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('returns object with costTracker', () => {
|
|
344
|
+
const router = createA3MRouter({});
|
|
345
|
+
expect(router.costTracker).toBeTruthy();
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it('returns object with memoryTree', () => {
|
|
349
|
+
const router = createA3MRouter({});
|
|
350
|
+
expect(router.memoryTree).toBeTruthy();
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
});
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge Case Tests - Failure Modes, Boundaries, and Error Paths
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive tests for edge cases, error conditions, and boundary values.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
8
|
+
|
|
9
|
+
// Import modules
|
|
10
|
+
const {
|
|
11
|
+
routeQuery,
|
|
12
|
+
routeBatch,
|
|
13
|
+
extractQueryFeatures,
|
|
14
|
+
countTokens,
|
|
15
|
+
MemoryTree,
|
|
16
|
+
ProviderRetryHandler,
|
|
17
|
+
CostTracker,
|
|
18
|
+
createA3MRouter,
|
|
19
|
+
} = require('../dist/index.js');
|
|
20
|
+
|
|
21
|
+
// ============================================================
|
|
22
|
+
// EDGE CASE TESTS - EMPTY AND NULL INPUTS
|
|
23
|
+
// ============================================================
|
|
24
|
+
|
|
25
|
+
describe('1. Edge Cases - Empty and Null Inputs', () => {
|
|
26
|
+
|
|
27
|
+
describe('routeQuery with empty/null inputs', () => {
|
|
28
|
+
it('handles empty string', () => {
|
|
29
|
+
const result = routeQuery('');
|
|
30
|
+
expect(result.primary_model).toBeTruthy();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('handles whitespace-only string', () => {
|
|
34
|
+
const result = routeQuery(' \n\t ');
|
|
35
|
+
expect(result.primary_model).toBeTruthy();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('routeBatch with empty inputs', () => {
|
|
40
|
+
it('handles empty array', () => {
|
|
41
|
+
const results = routeBatch([]);
|
|
42
|
+
expect(Array.isArray(results)).toBe(true);
|
|
43
|
+
expect(results.length).toBe(0);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('handles array with empty strings', () => {
|
|
47
|
+
const results = routeBatch(['', '', '']);
|
|
48
|
+
expect(results.length).toBe(3);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('countTokens with empty inputs', () => {
|
|
53
|
+
it('handles empty string', () => {
|
|
54
|
+
const tokens = countTokens('');
|
|
55
|
+
expect(typeof tokens).toBe('number');
|
|
56
|
+
expect(tokens).toBeGreaterThanOrEqual(0);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// ============================================================
|
|
62
|
+
// EDGE CASE TESTS - BOUNDARY VALUES
|
|
63
|
+
// ============================================================
|
|
64
|
+
|
|
65
|
+
describe('2. Edge Cases - Boundary Values', () => {
|
|
66
|
+
|
|
67
|
+
describe('routeQuery with extreme lengths', () => {
|
|
68
|
+
it('handles single character', () => {
|
|
69
|
+
const result = routeQuery('x');
|
|
70
|
+
expect(result.primary_model).toBeTruthy();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('handles very long query', () => {
|
|
74
|
+
const longQuery = 'a'.repeat(10000);
|
|
75
|
+
const result = routeQuery(longQuery);
|
|
76
|
+
expect(result.primary_model).toBeTruthy();
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe('MemoryTree with boundary sizes', () => {
|
|
81
|
+
it('handles maxSize of 0', () => {
|
|
82
|
+
const memory = new MemoryTree({ maxSize: 0 });
|
|
83
|
+
memory.add('test', { tags: [] });
|
|
84
|
+
expect(memory.getStats()).toBeTruthy();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('handles maxSize of 1', () => {
|
|
88
|
+
const memory = new MemoryTree({ maxSize: 1 });
|
|
89
|
+
memory.add('test1', { tags: [] });
|
|
90
|
+
memory.add('test2', { tags: [] });
|
|
91
|
+
expect(memory.getStats()).toBeTruthy();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// ============================================================
|
|
97
|
+
// EDGE CASE TESTS - ERROR HANDLING
|
|
98
|
+
// ============================================================
|
|
99
|
+
|
|
100
|
+
describe('3. Edge Cases - Error Handling', () => {
|
|
101
|
+
|
|
102
|
+
describe('ProviderRetryHandler errors', () => {
|
|
103
|
+
let handler: ProviderRetryHandler;
|
|
104
|
+
|
|
105
|
+
beforeEach(() => {
|
|
106
|
+
handler = new ProviderRetryHandler();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('isRetryableError returns false for null', () => {
|
|
110
|
+
expect(handler.isRetryableError(null)).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('isRetryableError returns false for undefined', () => {
|
|
114
|
+
expect(handler.isRetryableError(undefined)).toBe(false);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
it('isRetryableError returns false for 400 error', () => {
|
|
118
|
+
expect(handler.isRetryableError({ status: 400 })).toBe(false);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('isRetryableError returns true for 429 rate limit', () => {
|
|
122
|
+
expect(handler.isRetryableError({ status: 429 })).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('isRetryableError returns true for 500 server error', () => {
|
|
126
|
+
expect(handler.isRetryableError({ status: 500 })).toBe(true);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('isRetryableError returns true for ECONNRESET', () => {
|
|
130
|
+
expect(handler.isRetryableError({ code: 'ECONNRESET' })).toBe(true);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('isRetryableError returns true for ETIMEDOUT', () => {
|
|
134
|
+
expect(handler.isRetryableError({ code: 'ETIMEDOUT' })).toBe(true);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('isRateLimitError detects 429 in status', () => {
|
|
138
|
+
expect(handler.isRateLimitError({ status: 429 })).toBe(true);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('isRateLimitError returns false for 200', () => {
|
|
142
|
+
expect(handler.isRateLimitError({ status: 200 })).toBe(false);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe('Retry backoff calculations', () => {
|
|
147
|
+
let handler: ProviderRetryHandler;
|
|
148
|
+
|
|
149
|
+
beforeEach(() => {
|
|
150
|
+
handler = new ProviderRetryHandler();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('calculateBackoffDelay returns positive number', () => {
|
|
154
|
+
const config = {
|
|
155
|
+
maxRetries: 3,
|
|
156
|
+
initialDelayMs: 1000,
|
|
157
|
+
maxDelayMs: 30000,
|
|
158
|
+
backoffMultiplier: 2,
|
|
159
|
+
retryableErrors: ['ECONNRESET'],
|
|
160
|
+
};
|
|
161
|
+
const delay = handler.calculateBackoffDelay(0, config);
|
|
162
|
+
expect(delay).toBeGreaterThan(0);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('calculateBackoffDelay caps at maxDelayMs', () => {
|
|
166
|
+
const config = {
|
|
167
|
+
maxRetries: 10,
|
|
168
|
+
initialDelayMs: 1000,
|
|
169
|
+
maxDelayMs: 5000,
|
|
170
|
+
backoffMultiplier: 2,
|
|
171
|
+
retryableErrors: ['ECONNRESET'],
|
|
172
|
+
};
|
|
173
|
+
const delay = handler.calculateBackoffDelay(100, config);
|
|
174
|
+
expect(delay).toBeLessThanOrEqual(5000);
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// ============================================================
|
|
180
|
+
// EDGE CASE TESTS - TIMEOUT AND CONCURRENCY
|
|
181
|
+
// ============================================================
|
|
182
|
+
|
|
183
|
+
describe('4. Edge Cases - Timeout and Concurrency', () => {
|
|
184
|
+
|
|
185
|
+
describe('executeWithRetry timeout behavior', () => {
|
|
186
|
+
let handler: ProviderRetryHandler;
|
|
187
|
+
|
|
188
|
+
beforeEach(() => {
|
|
189
|
+
handler = new ProviderRetryHandler();
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('succeeds on first attempt', async () => {
|
|
193
|
+
const fn = vi.fn().mockResolvedValue('success');
|
|
194
|
+
const result = await handler.executeWithRetry('groq', fn);
|
|
195
|
+
expect(result).toBe('success');
|
|
196
|
+
expect(fn).toHaveBeenCalledTimes(1);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('retries on transient errors', async () => {
|
|
200
|
+
const fn = vi.fn()
|
|
201
|
+
.mockRejectedValueOnce({ code: 'ECONNRESET' })
|
|
202
|
+
.mockResolvedValue('success');
|
|
203
|
+
|
|
204
|
+
const result = await handler.executeWithRetry('groq', fn);
|
|
205
|
+
expect(result).toBe('success');
|
|
206
|
+
expect(fn).toHaveBeenCalledTimes(2);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it('fails after exhausting retries', async () => {
|
|
210
|
+
const fn = vi.fn().mockRejectedValue({ code: 'ECONNRESET' });
|
|
211
|
+
|
|
212
|
+
await expect(
|
|
213
|
+
handler.executeWithRetry('groq', fn)
|
|
214
|
+
).rejects.toThrow();
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('does not retry non-retryable errors', async () => {
|
|
218
|
+
const fn = vi.fn().mockRejectedValue({ status: 401 });
|
|
219
|
+
|
|
220
|
+
await expect(
|
|
221
|
+
handler.executeWithRetry('groq', fn)
|
|
222
|
+
).rejects.toThrow();
|
|
223
|
+
expect(fn).toHaveBeenCalledTimes(1);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
describe('MemoryTree concurrent access', () => {
|
|
228
|
+
it('handles concurrent add operations', async () => {
|
|
229
|
+
const memory = new MemoryTree({ maxSize: 1000 });
|
|
230
|
+
|
|
231
|
+
await Promise.all(
|
|
232
|
+
Array(50).fill(null).map((_, i) =>
|
|
233
|
+
memory.add(`entry ${i}`)
|
|
234
|
+
)
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
const results = memory.search('entry');
|
|
238
|
+
expect(Array.isArray(results)).toBe(true);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// ============================================================
|
|
244
|
+
// EDGE CASE TESTS - SPECIAL INPUTS
|
|
245
|
+
// ============================================================
|
|
246
|
+
|
|
247
|
+
describe('5. Edge Cases - Special Input Types', () => {
|
|
248
|
+
|
|
249
|
+
describe('Unicode handling', () => {
|
|
250
|
+
it('handles Japanese text', () => {
|
|
251
|
+
const result = routeQuery('こんにちは世界');
|
|
252
|
+
expect(result.primary_model).toBeTruthy();
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('handles Chinese text', () => {
|
|
256
|
+
const result = routeQuery('你好世界');
|
|
257
|
+
expect(result.primary_model).toBeTruthy();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('handles emoji', () => {
|
|
261
|
+
const result = routeQuery('Hello 👋🌍🎉');
|
|
262
|
+
expect(result.primary_model).toBeTruthy();
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
describe('Code snippet handling', () => {
|
|
267
|
+
it('handles JavaScript code', () => {
|
|
268
|
+
const result = routeQuery('function test() { return 42; }');
|
|
269
|
+
expect(result.primary_model).toBeTruthy();
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('handles SQL code', () => {
|
|
273
|
+
const result = routeQuery('SELECT * FROM users WHERE id = 1');
|
|
274
|
+
expect(result.primary_model).toBeTruthy();
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
describe('Translation detection', () => {
|
|
279
|
+
it('detects translation queries', () => {
|
|
280
|
+
const features = extractQueryFeatures('Translate hello to French');
|
|
281
|
+
expect(features.is_translation).toBe(true);
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// ============================================================
|
|
287
|
+
// EDGE CASE TESTS - STATE MANAGEMENT
|
|
288
|
+
// ============================================================
|
|
289
|
+
|
|
290
|
+
describe('6. Edge Cases - State Management', () => {
|
|
291
|
+
|
|
292
|
+
describe('MemoryTree state', () => {
|
|
293
|
+
it('persists state across operations', async () => {
|
|
294
|
+
const memory = new MemoryTree({ maxSize: 100 });
|
|
295
|
+
|
|
296
|
+
await memory.add('stateful entry');
|
|
297
|
+
const results1 = memory.search('stateful');
|
|
298
|
+
expect(Array.isArray(results1)).toBe(true);
|
|
299
|
+
|
|
300
|
+
const results2 = memory.search('stateful');
|
|
301
|
+
expect(results2.length).toBe(results1.length);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('getStats returns accurate stats', async () => {
|
|
305
|
+
const memory = new MemoryTree({ maxSize: 100 });
|
|
306
|
+
|
|
307
|
+
await memory.add('entry 1');
|
|
308
|
+
await memory.add('entry 2');
|
|
309
|
+
|
|
310
|
+
const stats = memory.getStats();
|
|
311
|
+
expect(stats.totalChunks).toBeGreaterThan(0);
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
describe('Retry handler state', () => {
|
|
316
|
+
let handler: ProviderRetryHandler;
|
|
317
|
+
|
|
318
|
+
beforeEach(() => {
|
|
319
|
+
handler = new ProviderRetryHandler();
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
it('getStats starts at zero', () => {
|
|
323
|
+
const stats = handler.getStats('groq');
|
|
324
|
+
expect(stats.totalRequests).toBe(0);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it('resetStats clears stats', () => {
|
|
328
|
+
handler.resetStats();
|
|
329
|
+
const allStats = handler.getAllStats();
|
|
330
|
+
for (const stats of Object.values(allStats)) {
|
|
331
|
+
expect(stats.totalRequests).toBe(0);
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
// ============================================================
|
|
338
|
+
// EDGE CASE TESTS - LARGE BATCH PROCESSING
|
|
339
|
+
// ============================================================
|
|
340
|
+
|
|
341
|
+
describe('7. Edge Cases - Memory and Resource Limits', () => {
|
|
342
|
+
|
|
343
|
+
describe('Large batch processing', () => {
|
|
344
|
+
it('handles 1000-item batch', () => {
|
|
345
|
+
const queries = Array(1000).fill('test query');
|
|
346
|
+
const results = routeBatch(queries);
|
|
347
|
+
expect(results.length).toBe(1000);
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
describe('Rapid successive calls', () => {
|
|
352
|
+
it('handles 100 rapid calls', async () => {
|
|
353
|
+
const promises = Array(100).fill(null).map(() =>
|
|
354
|
+
Promise.resolve(routeQuery('test'))
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
const results = await Promise.all(promises);
|
|
358
|
+
expect(results.length).toBe(100);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
});
|