adaptive-memory-multi-model-router 2.14.46 → 2.14.48

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.
Files changed (598) hide show
  1. package/{docs/llms.txt → llms.txt.bak} +6 -6
  2. package/package.json +270 -72
  3. package/src/routing/advancedRouter.ts.bak +650 -0
  4. package/test.js.bak +376 -0
  5. package/.dockerignore +0 -82
  6. package/.env.example +0 -303
  7. package/.github/DISCUSSIONS_WELCOME.md +0 -27
  8. package/.github/DISCUSSION_TEMPLATE.yml +0 -5
  9. package/.github/FUNDING.yml +0 -2
  10. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -94
  11. package/.github/ISSUE_TEMPLATE/config.yml +0 -17
  12. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -71
  13. package/.github/PULL_REQUEST_TEMPLATE.md +0 -71
  14. package/.github/dependabot.yml +0 -9
  15. package/.github/workflows/auto-publish.yml +0 -51
  16. package/.github/workflows/ci.yml +0 -263
  17. package/.github/workflows/codeql.yml +0 -38
  18. package/.github/workflows/npm-publish.yml +0 -20
  19. package/.github/workflows/pages.yml +0 -37
  20. package/.github/workflows/stale.yml +0 -54
  21. package/.publish-tick +0 -1
  22. package/.well-known/ai-plugin.json +0 -16
  23. package/AGENT_COUNCIL_FINDINGS.md +0 -142
  24. package/ARCHITECTURE.md +0 -346
  25. package/AUDIT_REPORT.md +0 -28
  26. package/CODE_OF_CONDUCT.md +0 -128
  27. package/CONTRIBUTING.md +0 -50
  28. package/CONTRIBUTORS.md +0 -20
  29. package/Dockerfile +0 -53
  30. package/Dockerfile.proxy +0 -33
  31. package/HEALTH_REPORT.md +0 -118
  32. package/IMPROVEMENT_PLAN.md +0 -107
  33. package/LANDING.md +0 -43
  34. package/LAUNCH-PAIN-DRIVEN.md +0 -339
  35. package/LAUNCH.md +0 -337
  36. package/LAUNCH_CHECKLIST.md +0 -141
  37. package/LAUNCH_SNAPSHOT.md +0 -260
  38. package/MANIFESTO.md +0 -41
  39. package/POPULARITY_BOOSTERS.md +0 -285
  40. package/PR_STATUS_REPORT.md +0 -148
  41. package/REDESIGN.md +0 -95
  42. package/RUNKIT.md +0 -83
  43. package/SECURITY.md +0 -29
  44. package/SUBMISSIONS.md +0 -43
  45. package/_schema.html +0 -53
  46. package/ai-plugin.json +0 -16
  47. package/articles/AI_AGENT_LLM_ROUTING.md +0 -150
  48. package/articles/CHINESE_DIRECTORIES.md +0 -100
  49. package/articles/CHINESE_SUBMISSIONS_READY.md +0 -322
  50. package/articles/COMPETITOR_ALERTS.md +0 -31
  51. package/articles/COMPLETE_POSTING_DIRECTORY.md +0 -147
  52. package/articles/CONTENT_STRUCTURE.md +0 -292
  53. package/articles/DEVTO_COST_GUIDE.md +0 -473
  54. package/articles/DEVTO_FINAL.md +0 -416
  55. package/articles/DEVTO_MULTI_PROVIDER.md +0 -542
  56. package/articles/DEVTO_READY.md +0 -255
  57. package/articles/DEVTO_V2_ANNOUNCEMENT.md +0 -160
  58. package/articles/DEVTO_VIRAL_GROWTH.md +0 -280
  59. package/articles/FRESH_devto.md +0 -460
  60. package/articles/FRESH_devto_2026_05.md +0 -73
  61. package/articles/FRESH_hackernews.md +0 -14
  62. package/articles/FRESH_reddit_ml.md +0 -90
  63. package/articles/FRESH_reddit_node.md +0 -198
  64. package/articles/FRESH_reddit_sideproject.md +0 -72
  65. package/articles/FRESH_reddit_webdev.md +0 -130
  66. package/articles/FROM_ZERO_TO_10K.md +0 -107
  67. package/articles/HN_10X_BETTER.md +0 -430
  68. package/articles/HN_ACCOUNT_GUIDE.md +0 -21
  69. package/articles/HN_CHINESE_STYLE.md +0 -308
  70. package/articles/HN_FINAL.md +0 -148
  71. package/articles/HN_POSTED_VERSION.md +0 -56
  72. package/articles/HN_POST_READY.md +0 -137
  73. package/articles/HN_RESEARCH.md +0 -364
  74. package/articles/HN_SHOW_routerarena.md +0 -17
  75. package/articles/HN_TIMING_GUIDE.md +0 -52
  76. package/articles/INDIEHACKERS_POST.md +0 -52
  77. package/articles/INDIEHACKERS_READY.md +0 -120
  78. package/articles/LLM_BENCHMARK_DEEP_DIVE.md +0 -153
  79. package/articles/MASTER_POSTING_DIRECTORY.md +0 -189
  80. package/articles/NEWSLETTER_SEND_NOW.md +0 -259
  81. package/articles/NEWSLETTER_SUBMISSIONS.md +0 -112
  82. package/articles/PAIN-DRIVEN-devto-v2.md +0 -308
  83. package/articles/PAIN-DRIVEN-devto-v3.md +0 -268
  84. package/articles/PAIN-DRIVEN-devto.md +0 -242
  85. package/articles/PAIN-DRIVEN-hackernews-v2.md +0 -138
  86. package/articles/PAIN-DRIVEN-hackernews-v3.md +0 -151
  87. package/articles/PAIN-DRIVEN-hackernews.md +0 -131
  88. package/articles/PAIN-DRIVEN-reddit-v2.md +0 -301
  89. package/articles/PAIN-DRIVEN-reddit-v3.md +0 -236
  90. package/articles/PAIN-DRIVEN-reddit.md +0 -218
  91. package/articles/PAIN-DRIVEN-twitter-v2.md +0 -110
  92. package/articles/PAIN-DRIVEN-twitter-v3.md +0 -121
  93. package/articles/PAIN-DRIVEN-twitter.md +0 -120
  94. package/articles/PORTKEY_VS_A3M.md +0 -147
  95. package/articles/POSTING_KIT_2026_05.md +0 -67
  96. package/articles/PRESS_KIT_routerarena.md +0 -77
  97. package/articles/PRODUCTHUNT_LISTING.md +0 -48
  98. package/articles/PRODUCTHUNT_READY.md +0 -106
  99. package/articles/PR_PLAN_vault.md +0 -125
  100. package/articles/REDDIT_FINAL.md +0 -232
  101. package/articles/REDDIT_POST.md +0 -67
  102. package/articles/REDDIT_SUBMISSION_READY.md +0 -348
  103. package/articles/ROUTERARENA_LEADER.md +0 -45
  104. package/articles/SHOW_HN_FINAL.md +0 -29
  105. package/articles/TWEETS_10K_DOWNLOADS.md +0 -47
  106. package/articles/TWEETS_BENCHMARK_FIRST.md +0 -46
  107. package/articles/TWEETS_MCP_PLAY.md +0 -51
  108. package/articles/TWEETS_SEQUENTIAL_BROKEN.md +0 -49
  109. package/articles/TWEETS_WHY_BUILD.md +0 -54
  110. package/articles/TWEETS_routerarena_leader.md +0 -53
  111. package/articles/TWEET_STORM_READY.md +0 -165
  112. package/articles/TWITTER_FINAL.md +0 -167
  113. package/articles/WHY_10X_BETTER.md +0 -261
  114. package/articles/WHY_CHINESE_STYLE_BETTER.md +0 -323
  115. package/articles/ai-discoverability-llm-routing.md +0 -210
  116. package/articles/devto-llm-routing.md +0 -138
  117. package/articles/hackernews-show-hn.md +0 -54
  118. package/articles/hashnode-llm-cost-optimization.md +0 -125
  119. package/articles/hn_show_2026_05.md +0 -11
  120. package/articles/medium-building-llm-router.md +0 -205
  121. package/articles/reddit-ml.md +0 -76
  122. package/articles/twitter-thread-cost-savings.md +0 -50
  123. package/articles/youtube-tutorial-script.md +0 -262
  124. package/assets/a3m_3blue1brown.mp4 +0 -0
  125. package/assets/banner.svg +0 -109
  126. package/assets/chart-cost-v2.svg +0 -91
  127. package/assets/chart-cost-v3.svg +0 -143
  128. package/assets/chart-features-v2.svg +0 -132
  129. package/assets/chart-features-v3.svg +0 -211
  130. package/assets/chart-growth-v2.svg +0 -122
  131. package/assets/chart-growth-v3.svg +0 -189
  132. package/assets/cost-comparison.svg +0 -134
  133. package/assets/cost-simple.svg +0 -64
  134. package/assets/demo-hn.gif +0 -0
  135. package/assets/feature-matrix.svg +0 -136
  136. package/assets/growth-chart-animated.svg +0 -76
  137. package/assets/growth-chart.svg +0 -82
  138. package/assets/growth-simple.svg +0 -69
  139. package/assets/hero-diagram.svg +0 -81
  140. package/assets/logo-new.svg +0 -21
  141. package/assets/logo.svg +0 -68
  142. package/assets/provider-comparison.svg +0 -121
  143. package/assets/social-preview-new.svg +0 -100
  144. package/assets/social-preview.svg +0 -194
  145. package/assets/social-v2.svg +0 -130
  146. package/assets/social-v3.svg +0 -212
  147. package/benchmark-provider-results.json +0 -245
  148. package/benchmark-results.json +0 -54
  149. package/council-votes/architecture-vote.md +0 -121
  150. package/council-votes/coverage-vote.md +0 -93
  151. package/data/adaptive-benchmark.json +0 -92
  152. package/data/benchmark-results.json +0 -47
  153. package/data/labeled-benchmark.json +0 -88
  154. package/demo/3blue1brown_video.py +0 -285
  155. package/demo/3blue1brown_video_v2.py +0 -310
  156. package/demo/IMPROVED_PROMPTS.md +0 -229
  157. package/demo/VEO3_PROMPTS.md +0 -269
  158. package/demo/VIDEO_PRODUCTION_GUIDE.md +0 -333
  159. package/demo/a3m_3blue1brown.mp4 +0 -0
  160. package/demo/asciinema-demo.sh +0 -195
  161. package/demo/demo-hn.tape +0 -74
  162. package/demo/demo-script.md +0 -53
  163. package/demo/demo-script.sh +0 -62
  164. package/demo/demo.svg +0 -75
  165. package/demo/frame1_ai_data_center.png +0 -0
  166. package/demo/frame1_sunset_video.mp4 +0 -0
  167. package/demo/frame2_cost_comparison.png +0 -0
  168. package/demo/frame2_cost_comparison_fallback.png +0 -0
  169. package/demo/frame3_parallel_execution.png +0 -0
  170. package/demo/frame3_parallel_execution_fallback.png +0 -0
  171. package/demo/frame4_providers.png +0 -0
  172. package/demo/frame4_providers_fallback.png +0 -0
  173. package/demo/frame5_endcard.png +0 -0
  174. package/demo/frame5_endcard_fallback.png +0 -0
  175. package/demo/new_frame1_hook.png +0 -0
  176. package/demo/new_frame2_proof.png +0 -0
  177. package/demo/new_frame3_wow.png +0 -0
  178. package/demo/new_frame4_social.png +0 -0
  179. package/demo/new_frame5_cta.png +0 -0
  180. package/demo/package.json +0 -13
  181. package/demo/product-video-final.mp4 +0 -0
  182. package/demo/product-video-hype-v1.mp4 +0 -0
  183. package/demo/product-video-v1.mp4 +0 -0
  184. package/demo/public/index.html +0 -762
  185. package/demo/recording.cast +0 -55
  186. package/demo/server.js +0 -405
  187. package/demo-new.tape +0 -71
  188. package/demo-real.sh +0 -198
  189. package/demo-simple.tape +0 -205
  190. package/demo.html +0 -520
  191. package/demo.sh +0 -85
  192. package/demo.tape +0 -259
  193. package/dist/analytics/costAnalytics.d.ts.map +0 -1
  194. package/dist/analytics/costAnalytics.js.map +0 -1
  195. package/dist/benchmark/comprehensive.js.map +0 -1
  196. package/dist/benchmark/reproducible.d.ts.map +0 -1
  197. package/dist/benchmark/reproducible.js.map +0 -1
  198. package/dist/cache/prefixCache.d.ts.map +0 -1
  199. package/dist/cache/prefixCache.js.map +0 -1
  200. package/dist/cache/responseCache.d.ts.map +0 -1
  201. package/dist/cache/responseCache.js.map +0 -1
  202. package/dist/cache/semanticCache.d.ts.map +0 -1
  203. package/dist/cache/semanticCache.js.map +0 -1
  204. package/dist/cli/setupWizard.d.ts.map +0 -1
  205. package/dist/cli/setupWizard.js.map +0 -1
  206. package/dist/cost/budgetEnforcer.d.ts.map +0 -1
  207. package/dist/cost/budgetEnforcer.js.map +0 -1
  208. package/dist/cost/costTracker.d.ts.map +0 -1
  209. package/dist/cost/costTracker.js.map +0 -1
  210. package/dist/ensemble/multiRoundDialog.js.map +0 -1
  211. package/dist/ensemble/shapleyValue.js.map +0 -1
  212. package/dist/integrations/langchainAdapter.d.ts.map +0 -1
  213. package/dist/integrations/langchainAdapter.js.map +0 -1
  214. package/dist/integrations/oauth.d.ts.map +0 -1
  215. package/dist/integrations/oauth.js.map +0 -1
  216. package/dist/integrations/scienceAdapter.js.map +0 -1
  217. package/dist/memory/autoFetch.d.ts.map +0 -1
  218. package/dist/memory/autoFetch.js.map +0 -1
  219. package/dist/memory/episodicMemory.d.ts.map +0 -1
  220. package/dist/memory/episodicMemory.js.map +0 -1
  221. package/dist/memory/hybridMemory.js.map +0 -1
  222. package/dist/memory/memoryTree.d.ts.map +0 -1
  223. package/dist/memory/memoryTree.js.map +0 -1
  224. package/dist/memory/obsidianVault.d.ts.map +0 -1
  225. package/dist/memory/obsidianVault.js.map +0 -1
  226. package/dist/memory/reasoningBank.js.map +0 -1
  227. package/dist/observability/changeWatch.d.ts.map +0 -1
  228. package/dist/observability/changeWatch.js.map +0 -1
  229. package/dist/observability/fatigueDetector.d.ts.map +0 -1
  230. package/dist/observability/fatigueDetector.js.map +0 -1
  231. package/dist/observability/index.d.ts.map +0 -1
  232. package/dist/observability/index.js.map +0 -1
  233. package/dist/observability/metrics.d.ts.map +0 -1
  234. package/dist/observability/metrics.js.map +0 -1
  235. package/dist/observability/middleware.d.ts.map +0 -1
  236. package/dist/observability/middleware.js.map +0 -1
  237. package/dist/observability/tracer.d.ts.map +0 -1
  238. package/dist/observability/tracer.js.map +0 -1
  239. package/dist/observability/types.d.ts.map +0 -1
  240. package/dist/observability/types.js.map +0 -1
  241. package/dist/orchestration/haloOrchestrator.d.ts.map +0 -1
  242. package/dist/orchestration/haloOrchestrator.js.map +0 -1
  243. package/dist/orchestration/mctsWorkflow.d.ts.map +0 -1
  244. package/dist/orchestration/mctsWorkflow.js.map +0 -1
  245. package/dist/providers/localProvider.d.ts.map +0 -1
  246. package/dist/providers/localProvider.js.map +0 -1
  247. package/dist/providers/providerConfig.d.ts.map +0 -1
  248. package/dist/providers/providerConfig.js.map +0 -1
  249. package/dist/providers/registry.d.ts.map +0 -1
  250. package/dist/providers/registry.js.map +0 -1
  251. package/dist/routing/advancedRouter.d.ts.map +0 -1
  252. package/dist/routing/advancedRouter.js.map +0 -1
  253. package/dist/routing/crossModelValidation.d.ts.map +0 -1
  254. package/dist/routing/crossModelValidation.js.map +0 -1
  255. package/dist/routing/providerHealth.d.ts.map +0 -1
  256. package/dist/routing/providerHealth.js.map +0 -1
  257. package/dist/routing/providerRetry.d.ts.map +0 -1
  258. package/dist/routing/providerRetry.js.map +0 -1
  259. package/dist/scripts/banner.js +0 -29
  260. package/dist/security/guardrails.d.ts.map +0 -1
  261. package/dist/security/guardrails.js.map +0 -1
  262. package/dist/server/dashboard.d.ts.map +0 -1
  263. package/dist/server/dashboard.js.map +0 -1
  264. package/dist/server/modelMapper.d.ts.map +0 -1
  265. package/dist/server/modelMapper.js.map +0 -1
  266. package/dist/server/proxyServer.d.ts.map +0 -1
  267. package/dist/server/proxyServer.js.map +0 -1
  268. package/dist/skills/__tests__/skill_manager.test.d.ts +0 -2
  269. package/dist/skills/__tests__/skill_manager.test.d.ts.map +0 -1
  270. package/dist/skills/__tests__/skill_manager.test.js +0 -268
  271. package/dist/skills/__tests__/skill_manager.test.js.map +0 -1
  272. package/dist/tools/tmlpdTools.d.ts.map +0 -1
  273. package/dist/tools/tmlpdTools.js.map +0 -1
  274. package/dist/tui/dashboard.d.ts.map +0 -1
  275. package/dist/tui/dashboard.js.map +0 -1
  276. package/dist/tui/index.d.ts.map +0 -1
  277. package/dist/tui/index.js.map +0 -1
  278. package/dist/utils/batchProcessor.d.ts.map +0 -1
  279. package/dist/utils/batchProcessor.js.map +0 -1
  280. package/dist/utils/compression.d.ts.map +0 -1
  281. package/dist/utils/compression.js.map +0 -1
  282. package/dist/utils/costUtils.d.ts.map +0 -1
  283. package/dist/utils/costUtils.js.map +0 -1
  284. package/dist/utils/reliability.d.ts.map +0 -1
  285. package/dist/utils/reliability.js.map +0 -1
  286. package/dist/utils/sorting.d.ts.map +0 -1
  287. package/dist/utils/sorting.js.map +0 -1
  288. package/dist/utils/speculativeDecoding.d.ts.map +0 -1
  289. package/dist/utils/speculativeDecoding.js.map +0 -1
  290. package/dist/utils/tokenUtils.d.ts.map +0 -1
  291. package/dist/utils/tokenUtils.js.map +0 -1
  292. package/docs/.nojekyll +0 -0
  293. package/docs/ANALYSIS_PRINCIPLES.md +0 -162
  294. package/docs/API.md +0 -855
  295. package/docs/ARCHITECTURAL-IMPROVEMENTS-2025.md +0 -1391
  296. package/docs/ARCHITECTURAL-IMPROVEMENTS-REVISED-2025.md +0 -1051
  297. package/docs/BENCHMARK.md +0 -170
  298. package/docs/CHINESE_PROVIDER_RELIABILITY.md +0 -37
  299. package/docs/CITATIONS.md +0 -74
  300. package/docs/CLAIMS_AND_EVIDENCE.md +0 -58
  301. package/docs/CONFIGURATION.md +0 -476
  302. package/docs/COUNCIL_DECISION.json +0 -816
  303. package/docs/COUNCIL_SUMMARY.md +0 -319
  304. package/docs/COUNCIL_V2.2_DECISION.md +0 -416
  305. package/docs/ENGINEERING_SPEC.md +0 -55
  306. package/docs/FACTORY_RESET.md +0 -34
  307. package/docs/GEO.md +0 -66
  308. package/docs/GEO_OPTIMIZATION.md +0 -30
  309. package/docs/GEO_ROOT_CAUSE.md +0 -136
  310. package/docs/GEO_STATUS.md +0 -85
  311. package/docs/GEO_TEST_RESULTS.md +0 -176
  312. package/docs/HN_CHECKLIST.md +0 -38
  313. package/docs/HN_FOUNDER_COMMENT.md +0 -17
  314. package/docs/HN_SUBMISSION_FINAL.md +0 -180
  315. package/docs/HN_SUBMISSION_V3.md +0 -56
  316. package/docs/IMPROVEMENT_ROADMAP.md +0 -515
  317. package/docs/INTEGRATIONS.md +0 -420
  318. package/docs/LANGCHAIN_INTEGRATION.md +0 -147
  319. package/docs/LLM_COUNCIL_DECISION.md +0 -508
  320. package/docs/MIDDLEWARE_CHAIN.md +0 -35
  321. package/docs/PROMO_CHECKLIST.md +0 -200
  322. package/docs/QUICKSTART.md +0 -271
  323. package/docs/QUICK_START.md +0 -43
  324. package/docs/QUICK_START_VISIBILITY.md +0 -782
  325. package/docs/REDDIT_GAP_ANALYSIS.md +0 -299
  326. package/docs/RELEASE_CHECKLIST.md +0 -32
  327. package/docs/REPRODUCIBILITY.md +0 -63
  328. package/docs/RESEARCH_BACKED_IMPROVEMENTS.md +0 -1180
  329. package/docs/ROUTING_RUBRIC.md +0 -197
  330. package/docs/SEO_AUDIT.md +0 -186
  331. package/docs/SOCIAL_LISTENING.md +0 -219
  332. package/docs/TMLPD_QNA.md +0 -751
  333. package/docs/TMLPD_V2.1_COMPLETE.md +0 -763
  334. package/docs/TMLPD_V2.2_RESEARCH_ROADMAP.md +0 -754
  335. package/docs/UPDATE_TOPICS.md +0 -15
  336. package/docs/USE_CASES.md +0 -59
  337. package/docs/V2.2_IMPLEMENTATION_COMPLETE.md +0 -446
  338. package/docs/V2_IMPLEMENTATION_GUIDE.md +0 -388
  339. package/docs/VERCEL_AI_SDK.md +0 -209
  340. package/docs/VISIBILITY_ADOPTION_PLAN.md +0 -1005
  341. package/docs/_config.yml +0 -49
  342. package/docs/ai-plugin.json +0 -16
  343. package/docs/api.html +0 -513
  344. package/docs/architecture-diagram.md +0 -40
  345. package/docs/benchmark-chart.png +0 -0
  346. package/docs/benchmark.html +0 -387
  347. package/docs/blog/routerarena-number-one.html +0 -73
  348. package/docs/cli-cheatsheet.md +0 -339
  349. package/docs/compare.md +0 -109
  350. package/docs/comparison-litellm.md +0 -88
  351. package/docs/comparison.md +0 -108
  352. package/docs/cost-chart-ascii.md +0 -42
  353. package/docs/cost-comparison-chart.svg +0 -88
  354. package/docs/curl-examples.md +0 -247
  355. package/docs/demo-auto.html +0 -264
  356. package/docs/demo.html +0 -416
  357. package/docs/geo/GENERATIVE_ENGINE_OPTIMIZATION.md +0 -232
  358. package/docs/index.html +0 -507
  359. package/docs/launch-content/LAUNCH_EXECUTION_CHECKLIST.md +0 -421
  360. package/docs/launch-content/README.md +0 -457
  361. package/docs/launch-content/assets/cost_comparison_100_tasks.png +0 -0
  362. package/docs/launch-content/assets/cumulative_savings.png +0 -0
  363. package/docs/launch-content/assets/parallel_speedup.png +0 -0
  364. package/docs/launch-content/assets/provider_pricing_comparison.png +0 -0
  365. package/docs/launch-content/assets/task_breakdown_comparison.png +0 -0
  366. package/docs/launch-content/generate_charts.py +0 -313
  367. package/docs/launch-content/hn_show_post.md +0 -139
  368. package/docs/launch-content/partner_outreach_templates.md +0 -745
  369. package/docs/launch-content/reddit_posts.md +0 -467
  370. package/docs/launch-content/twitter_thread.txt +0 -460
  371. package/docs/npm-downloads-chart.svg +0 -43
  372. package/docs/openapi.json +0 -139
  373. package/docs/openapi.yaml +0 -1318
  374. package/docs/quick-start.html +0 -366
  375. package/docs/robots.txt +0 -52
  376. package/docs/sitemap.xml +0 -57
  377. package/docs/styles.css +0 -682
  378. package/docs/well-known/ai-plugin.json +0 -16
  379. package/docs/wellknown/ai-plugin.json +0 -16
  380. package/docs-site/assets/og-banner.svg +0 -194
  381. package/docs-site/index.html +0 -632
  382. package/eval/README.md +0 -46
  383. package/eval/baselines/main.json +0 -12
  384. package/eval/benchmark_dataset.jsonl +0 -16
  385. package/eval/check_golden_routes.js +0 -64
  386. package/eval/datasets/catalog.json +0 -33
  387. package/eval/datasets/slices/cn_provider_reliability_v1.jsonl +0 -3
  388. package/eval/datasets/slices/cost_pressure_v1.jsonl +0 -3
  389. package/eval/datasets/slices/safety_guardrails_v1.jsonl +0 -3
  390. package/eval/evals.json +0 -199
  391. package/eval/fault_injection_thresholds.json +0 -3
  392. package/eval/generate_report.js +0 -128
  393. package/eval/golden_routes.json +0 -114
  394. package/eval/lib/experiment_registry.js +0 -24
  395. package/eval/run_eval.js +0 -197
  396. package/eval/run_fault_injection.js +0 -201
  397. package/eval/run_shadow_eval.js +0 -85
  398. package/eval/thresholds.json +0 -9
  399. package/examples/QUICKSTART.md +0 -183
  400. package/examples/README.md +0 -61
  401. package/examples/a3m-sdk.js +0 -124
  402. package/examples/basic-route.js +0 -54
  403. package/examples/chat-loop.js +0 -202
  404. package/examples/classify-then-route.js +0 -102
  405. package/examples/cost-compare.js +0 -120
  406. package/examples/ensemble.js +0 -160
  407. package/examples/whatsapp-telegram-bridge-demo.js +0 -302
  408. package/examples/whatsapp-telegram-bridge.js +0 -269
  409. package/hf-space/README.md +0 -23
  410. package/hf-space/app.py +0 -240
  411. package/hf-space/requirements.txt +0 -1
  412. package/huggingface_space/README.md +0 -35
  413. package/huggingface_space/app.py +0 -126
  414. package/huggingface_space/create_space.py +0 -208
  415. package/huggingface_space/requirements.txt +0 -1
  416. package/mcp-server/README.md +0 -188
  417. package/mcp-server/package.json +0 -29
  418. package/mcp-server/src/index.ts +0 -744
  419. package/mcp-server/tsconfig.json +0 -19
  420. package/openclaw-alexa-bridge/ALL_REMAINING_FIXES_PLAN.md +0 -313
  421. package/openclaw-alexa-bridge/REMAINING_FIXES_SUMMARY.md +0 -277
  422. package/openclaw-alexa-bridge/src/alexa_handler_no_tmlpd.js +0 -1234
  423. package/openclaw-alexa-bridge/test_fixes.js +0 -77
  424. package/playground/README.md +0 -51
  425. package/playground/codesandbox.json +0 -12
  426. package/playground/index.js +0 -39
  427. package/proxy/README.md +0 -227
  428. package/proxy/package-lock.json +0 -831
  429. package/proxy/package.json +0 -17
  430. package/proxy/rate-limit.js +0 -145
  431. package/proxy/rate-limit.test.js +0 -311
  432. package/proxy/server.js +0 -970
  433. package/python/README.md +0 -102
  434. package/python/a3m/__init__.py +0 -6
  435. package/python/a3m/client.py +0 -190
  436. package/python/a3m/models.py +0 -40
  437. package/python/a3m/sync_client.py +0 -61
  438. package/python/examples.py +0 -53
  439. package/python/integrations.py +0 -330
  440. package/python/pyproject.toml +0 -23
  441. package/python/setup.py +0 -28
  442. package/python/tmlpd.py +0 -369
  443. package/qna/REDDIT_GAP_ANALYSIS.md +0 -299
  444. package/qna/TMLPD_QNA.md +0 -751
  445. package/research/FINDING_001_safety.md +0 -28
  446. package/research/FINDING_002_error_diversity.md +0 -32
  447. package/research/FINDING_003_confidence_weighted_voting.md +0 -32
  448. package/research/FINDING_004_cross_model_semantic_detection.md +0 -37
  449. package/research/FINDING_005_knowledge_gap_orthogonality.md +0 -34
  450. package/research/HALLUCINATION_RESEARCH.md +0 -27
  451. package/research/ensemble-voting.md +0 -324
  452. package/research/loss-functions.md +0 -545
  453. package/research-log.md +0 -49
  454. package/scripts/banner.js +0 -29
  455. package/scripts/benchmark-local-routerarena.ts +0 -176
  456. package/scripts/benchmark.js +0 -145
  457. package/scripts/benchmark.sh +0 -61
  458. package/scripts/compare-providers.sh +0 -230
  459. package/scripts/content-planner.js +0 -25
  460. package/scripts/create-labeled-benchmark.ts +0 -105
  461. package/scripts/cross_post.py +0 -443
  462. package/scripts/local-router-benchmark.ts +0 -154
  463. package/scripts/post-all.sh +0 -41
  464. package/scripts/publish_fcc.py +0 -106
  465. package/scripts/push-to-gitee.sh +0 -25
  466. package/scripts/routerarena_ensemble.js +0 -144
  467. package/scripts/routing-benchmark-v2.js +0 -373
  468. package/scripts/routing-benchmark-v3.js +0 -118
  469. package/scripts/routing-benchmark.js +0 -462
  470. package/scripts/run-labeled-benchmark.mjs +0 -104
  471. package/scripts/run-mmlu-benchmark.js +0 -176
  472. package/scripts/run-provider-benchmark.js +0 -244
  473. package/scripts/update-npm-badges.js +0 -158
  474. package/skill/SKILL.md +0 -238
  475. package/src/__tests__/integration/tmpld_integration.test.py +0 -540
  476. package/src/skills/__tests__/skill_manager.test.ts +0 -328
  477. package/submissions/benchmarks/ALL_PLATFORMS_SUBMISSION.md +0 -94
  478. package/submissions/benchmarks/LLMROUTERBENCH_SUBMISSION.md +0 -121
  479. package/submissions/benchmarks/MMRBENCH_SUBMISSION.md +0 -94
  480. package/submissions/benchmarks/ROUTERARENA_UPDATE.md +0 -83
  481. package/submissions/benchmarks/ROUTERBENCH_SUBMISSION.md +0 -225
  482. package/test-council/1-structure-tests.test.js +0 -353
  483. package/test-council/1-structure-tests.test.ts +0 -353
  484. package/test-council/2-edge-case-tests.test.ts +0 -361
  485. package/test-council/3-performance-tests.test.ts +0 -669
  486. package/test-council/4-integration-tests.test.ts +0 -391
  487. package/test-council/5-agent-council-eval.test.ts +0 -413
  488. package/test-council/AGENT_COUNCIL_ARCHITECTURE.md +0 -349
  489. package/test-council/TEST_COUNCIL_REPORT.md +0 -201
  490. package/test-council/agents/edge-case-agent.ts +0 -363
  491. package/test-council/agents/performance-agent.ts +0 -426
  492. package/test-council/agents/structure-agent.ts +0 -227
  493. package/test-council/council.md +0 -183
  494. package/tests/__mocks__/tokenUtils.ts +0 -8
  495. package/tests/memory/episodicMemory.test.ts +0 -227
  496. package/tests/package-lock.json +0 -1628
  497. package/tests/package.json +0 -18
  498. package/tests/routing/ensembleVoting.test.ts +0 -236
  499. package/tests/routing/providerRetry.test.ts +0 -360
  500. package/tests/routing/queryTypePresets.test.ts +0 -208
  501. package/tests/security/guardrailEngine.test.ts +0 -700
  502. package/tests/tsconfig.json +0 -21
  503. package/tests/vitest.config.ts +0 -18
  504. package/tmlpd-pi-extension/README.md +0 -66
  505. package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts +0 -114
  506. package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts.map +0 -1
  507. package/tmlpd-pi-extension/dist/cache/prefixCache.js +0 -285
  508. package/tmlpd-pi-extension/dist/cache/prefixCache.js.map +0 -1
  509. package/tmlpd-pi-extension/dist/cache/responseCache.d.ts +0 -58
  510. package/tmlpd-pi-extension/dist/cache/responseCache.d.ts.map +0 -1
  511. package/tmlpd-pi-extension/dist/cache/responseCache.js +0 -153
  512. package/tmlpd-pi-extension/dist/cache/responseCache.js.map +0 -1
  513. package/tmlpd-pi-extension/dist/cli.js +0 -59
  514. package/tmlpd-pi-extension/dist/cost/costTracker.d.ts +0 -95
  515. package/tmlpd-pi-extension/dist/cost/costTracker.d.ts.map +0 -1
  516. package/tmlpd-pi-extension/dist/cost/costTracker.js +0 -240
  517. package/tmlpd-pi-extension/dist/cost/costTracker.js.map +0 -1
  518. package/tmlpd-pi-extension/dist/index.d.ts +0 -723
  519. package/tmlpd-pi-extension/dist/index.d.ts.map +0 -1
  520. package/tmlpd-pi-extension/dist/index.js +0 -239
  521. package/tmlpd-pi-extension/dist/index.js.map +0 -1
  522. package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts +0 -82
  523. package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts.map +0 -1
  524. package/tmlpd-pi-extension/dist/memory/episodicMemory.js +0 -145
  525. package/tmlpd-pi-extension/dist/memory/episodicMemory.js.map +0 -1
  526. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts +0 -102
  527. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts.map +0 -1
  528. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js +0 -207
  529. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js.map +0 -1
  530. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts +0 -85
  531. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts.map +0 -1
  532. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js +0 -210
  533. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js.map +0 -1
  534. package/tmlpd-pi-extension/dist/providers/localProvider.d.ts +0 -102
  535. package/tmlpd-pi-extension/dist/providers/localProvider.d.ts.map +0 -1
  536. package/tmlpd-pi-extension/dist/providers/localProvider.js +0 -338
  537. package/tmlpd-pi-extension/dist/providers/localProvider.js.map +0 -1
  538. package/tmlpd-pi-extension/dist/providers/registry.d.ts +0 -55
  539. package/tmlpd-pi-extension/dist/providers/registry.d.ts.map +0 -1
  540. package/tmlpd-pi-extension/dist/providers/registry.js +0 -138
  541. package/tmlpd-pi-extension/dist/providers/registry.js.map +0 -1
  542. package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts +0 -68
  543. package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts.map +0 -1
  544. package/tmlpd-pi-extension/dist/routing/advancedRouter.js +0 -332
  545. package/tmlpd-pi-extension/dist/routing/advancedRouter.js.map +0 -1
  546. package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts +0 -101
  547. package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts.map +0 -1
  548. package/tmlpd-pi-extension/dist/tools/tmlpdTools.js +0 -368
  549. package/tmlpd-pi-extension/dist/tools/tmlpdTools.js.map +0 -1
  550. package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts +0 -96
  551. package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts.map +0 -1
  552. package/tmlpd-pi-extension/dist/utils/batchProcessor.js +0 -170
  553. package/tmlpd-pi-extension/dist/utils/batchProcessor.js.map +0 -1
  554. package/tmlpd-pi-extension/dist/utils/compression.d.ts +0 -61
  555. package/tmlpd-pi-extension/dist/utils/compression.d.ts.map +0 -1
  556. package/tmlpd-pi-extension/dist/utils/compression.js +0 -281
  557. package/tmlpd-pi-extension/dist/utils/compression.js.map +0 -1
  558. package/tmlpd-pi-extension/dist/utils/reliability.d.ts +0 -74
  559. package/tmlpd-pi-extension/dist/utils/reliability.d.ts.map +0 -1
  560. package/tmlpd-pi-extension/dist/utils/reliability.js +0 -177
  561. package/tmlpd-pi-extension/dist/utils/reliability.js.map +0 -1
  562. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts +0 -117
  563. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts.map +0 -1
  564. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js +0 -246
  565. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js.map +0 -1
  566. package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts +0 -50
  567. package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts.map +0 -1
  568. package/tmlpd-pi-extension/dist/utils/tokenUtils.js +0 -124
  569. package/tmlpd-pi-extension/dist/utils/tokenUtils.js.map +0 -1
  570. package/tmlpd-pi-extension/examples/QUICKSTART.md +0 -183
  571. package/tmlpd-pi-extension/package-lock.json +0 -79
  572. package/tmlpd-pi-extension/package.json +0 -172
  573. package/tmlpd-pi-extension/python/examples.py +0 -53
  574. package/tmlpd-pi-extension/python/integrations.py +0 -330
  575. package/tmlpd-pi-extension/python/setup.py +0 -28
  576. package/tmlpd-pi-extension/python/tmlpd.py +0 -369
  577. package/tmlpd-pi-extension/qna/REDDIT_GAP_ANALYSIS.md +0 -299
  578. package/tmlpd-pi-extension/qna/TMLPD_QNA.md +0 -751
  579. package/tmlpd-pi-extension/skill/SKILL.md +0 -238
  580. package/tmlpd-pi-extension/src/cache/responseCache.ts +0 -147
  581. package/tmlpd-pi-extension/src/cost/costTracker.ts +0 -302
  582. package/tmlpd-pi-extension/src/index.ts +0 -232
  583. package/tmlpd-pi-extension/src/memory/episodicMemory.ts +0 -257
  584. package/tmlpd-pi-extension/src/orchestration/haloOrchestrator.ts +0 -266
  585. package/tmlpd-pi-extension/src/orchestration/mctsWorkflow.ts +0 -262
  586. package/tmlpd-pi-extension/src/providers/localProvider.ts +0 -406
  587. package/tmlpd-pi-extension/src/providers/registry.ts +0 -164
  588. package/tmlpd-pi-extension/src/routing/ensembleVoting.ts +0 -159
  589. package/tmlpd-pi-extension/src/routing/queryTypePresets.ts +0 -136
  590. package/tmlpd-pi-extension/src/tools/tmlpdTools.ts +0 -433
  591. package/tmlpd-pi-extension/src/utils/batchProcessor.ts +0 -232
  592. package/tmlpd-pi-extension/src/utils/compression.ts +0 -325
  593. package/tmlpd-pi-extension/src/utils/reliability.ts +0 -221
  594. package/tmlpd-pi-extension/src/utils/tokenUtils.ts +0 -145
  595. package/tmlpd-pi-extension/tsconfig.json +0 -18
  596. package/tsconfig.build.json +0 -29
  597. package/tsconfig.json +0 -18
  598. /package/{docs/llms-full.txt → llms-full.txt.bak} +0 -0
@@ -1,18 +0,0 @@
1
- {
2
- "name": "a3m-router-tests",
3
- "version": "1.0.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "test": "vitest run",
8
- "test:watch": "vitest",
9
- "test:coverage": "vitest run --coverage"
10
- },
11
- "devDependencies": {
12
- "typescript": "^5.8.0",
13
- "vitest": "^3.1.0"
14
- },
15
- "dependencies": {
16
- "nanoid": "^5.0.0"
17
- }
18
- }
@@ -1,236 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import {
3
- executeEnsemble,
4
- mergeComplementary,
5
- recordFeedback,
6
- } from '../../tmlpd-pi-extension/src/routing/ensembleVoting';
7
-
8
- describe('executeEnsemble', () => {
9
- const defaultExecutors: Record<string, (q: string, s: string, c: string) => Promise<string | null>> = {
10
- groq: vi.fn().mockResolvedValue(
11
- 'Simple answer with no details.'
12
- ),
13
- nvidia: vi.fn().mockResolvedValue(
14
- 'Detailed answer including 42 numerical references. The API endpoint app.ts handles requests. ' +
15
- '* Point one\n* Point two\n* Point three\n* Point four\n* Point five\n' +
16
- 'The system uses Docker, Redis, and GCS for infrastructure. npm install is required.'
17
- ),
18
- };
19
-
20
- it('scores detailed responses higher than short ones', async () => {
21
- const result = await executeEnsemble(
22
- 'test query',
23
- 'system prompt',
24
- '',
25
- defaultExecutors,
26
- { providers: ['groq', 'nvidia'] }
27
- );
28
-
29
- expect(result.scores['nvidia']).toBeGreaterThan(result.scores['groq']);
30
- expect(result.winner).toBe('nvidia');
31
- });
32
-
33
- it('selects the provider with the highest score as winner', async () => {
34
- const executors = {
35
- low: vi.fn().mockResolvedValue('Hi'),
36
- mid: vi.fn().mockResolvedValue('A moderate answer with some text.'),
37
- high: vi.fn().mockResolvedValue(
38
- 'Excellent comprehensive response. Contains 3 key points. The API integration uses app.ts. ' +
39
- '* Point A\n* Point B\n* Point C\n* Point D\n* Point E'
40
- ),
41
- };
42
-
43
- const result = await executeEnsemble(
44
- 'query',
45
- 'sys',
46
- '',
47
- executors,
48
- { providers: ['low', 'mid', 'high'] }
49
- );
50
-
51
- expect(result.winner).toBe('high');
52
- });
53
-
54
- it('handles providers returning null (errors)', async () => {
55
- const executors = {
56
- good: vi.fn().mockResolvedValue('Valid answer here.'),
57
- bad: vi.fn().mockRejectedValue(new Error('API failure')),
58
- };
59
-
60
- const result = await executeEnsemble(
61
- 'query',
62
- 'sys',
63
- '',
64
- executors,
65
- { providers: ['good', 'bad'] }
66
- );
67
-
68
- expect(result.allResults['good']).toBe('Valid answer here.');
69
- expect(result.allResults['bad']).toBeNull();
70
- expect(result.scores['bad']).toBe(0);
71
- expect(result.winner).toBe('good');
72
- });
73
-
74
- it('handles all providers failing', async () => {
75
- const executors = {
76
- a: vi.fn().mockRejectedValue(new Error('fail')),
77
- b: vi.fn().mockRejectedValue(new Error('fail')),
78
- };
79
-
80
- const result = await executeEnsemble(
81
- 'query',
82
- 'sys',
83
- '',
84
- executors,
85
- { providers: ['a', 'b'] }
86
- );
87
-
88
- expect(result.best).toBe('');
89
- expect(Object.values(result.scores).every(s => s === 0)).toBe(true);
90
- });
91
-
92
- it('applies length penalty for very short responses', async () => {
93
- const executors = {
94
- short: vi.fn().mockResolvedValue('Hi'),
95
- normal: vi.fn().mockResolvedValue('A normal length answer with several words in it.'),
96
- };
97
-
98
- const result = await executeEnsemble(
99
- 'query',
100
- 'sys',
101
- '',
102
- executors,
103
- { providers: ['short', 'normal'] }
104
- );
105
-
106
- expect(result.scores["short"]).toBeLessThanOrEqual(result.scores["normal"]);
107
- });
108
-
109
- it('applies specificity bonus for responses with numbers', async () => {
110
- const executors = {
111
- vague: vi.fn().mockResolvedValue('The system works well and is quite good.'),
112
- specific: vi.fn().mockResolvedValue('The system processes 42 requests per second with 99.9% uptime.'),
113
- };
114
-
115
- const result = await executeEnsemble(
116
- 'query',
117
- 'sys',
118
- '',
119
- executors,
120
- { providers: ['vague', 'specific'] }
121
- );
122
-
123
- expect(result.scores['specific']).toBeGreaterThan(result.scores['vague']);
124
- });
125
-
126
- it('applies structure bonus for multi-line responses', async () => {
127
- const executors = {
128
- oneLine: vi.fn().mockResolvedValue('Just a single line answer here.'),
129
- multiLine: vi.fn().mockResolvedValue('Line one\nLine two\nLine three\nLine four\nLine five'),
130
- };
131
-
132
- const result = await executeEnsemble(
133
- 'query',
134
- 'sys',
135
- '',
136
- executors,
137
- { providers: ['oneLine', 'multiLine'] }
138
- );
139
-
140
- expect(result.scores['multiLine']).toBeGreaterThan(result.scores['oneLine']);
141
- });
142
-
143
- it('includes timing information in result', async () => {
144
- const executors = {
145
- fast: vi.fn().mockImplementation(
146
- () => new Promise(r => setTimeout(() => r('Quick answer.'), 5))
147
- ),
148
- };
149
-
150
- const result = await executeEnsemble(
151
- 'query',
152
- 'sys',
153
- '',
154
- executors,
155
- { providers: ['fast'] }
156
- );
157
-
158
- expect(result.timing.totalMs).toBeGreaterThanOrEqual(0);
159
- expect(result.timing.perProvider['fast']).toBeGreaterThanOrEqual(0);
160
- });
161
-
162
- it('produces reasoning string explaining winner selection', async () => {
163
- const executors = {
164
- a: vi.fn().mockResolvedValue('Answer A with some detail.'),
165
- b: vi.fn().mockResolvedValue('Answer B with more specific 42 details and technical API references.'),
166
- };
167
-
168
- const result = await executeEnsemble(
169
- 'query',
170
- 'sys',
171
- '',
172
- executors,
173
- { providers: ['a', 'b'] }
174
- );
175
-
176
- expect(result.reasoning).toBeTruthy();
177
- expect(result.reasoning).toContain(result.winner);
178
- });
179
- });
180
-
181
- describe('mergeComplementary', () => {
182
- it('merges multiple results into sections', () => {
183
- const merged = mergeComplementary(['Answer one', 'Answer two']);
184
- expect(merged).toContain('### Provider 1');
185
- expect(merged).toContain('### Provider 2');
186
- expect(merged).toContain('Answer one');
187
- expect(merged).toContain('Answer two');
188
- expect(merged).toContain('---');
189
- });
190
-
191
- it('filters out empty results', () => {
192
- const merged = mergeComplementary(['Valid', '', 'Also valid']);
193
- expect(merged).toContain('### Provider 1');
194
- expect(merged).toContain('### Provider 2');
195
- expect(merged).not.toContain('### Provider 3');
196
- });
197
-
198
- it('truncates at maxLength', () => {
199
- const long = 'A'.repeat(3000);
200
- const merged = mergeComplementary([long, long], 500);
201
- expect(merged.length).toBeLessThanOrEqual(500);
202
- });
203
-
204
- it('returns empty string for all-empty input', () => {
205
- expect(mergeComplementary([])).toBe('');
206
- expect(mergeComplementary(['', '', null as unknown as string])).toBe('');
207
- });
208
- });
209
-
210
- describe('recordFeedback', () => {
211
- it('increments good count for helpful feedback', () => {
212
- const history: Record<string, { good: number; bad: number }> = {};
213
- const updated = recordFeedback('groq', true, history);
214
- expect(updated['groq'].good).toBe(1);
215
- expect(updated['groq'].bad).toBe(0);
216
- });
217
-
218
- it('increments bad count for unhelpful feedback', () => {
219
- const history: Record<string, { good: number; bad: number }> = { groq: { good: 1, bad: 0 } };
220
- const updated = recordFeedback('groq', false, history);
221
- expect(updated['groq'].good).toBe(1);
222
- expect(updated['groq'].bad).toBe(1);
223
- });
224
-
225
- it('initializes history entry if missing', () => {
226
- const history: Record<string, { good: number; bad: number }> = {};
227
- const updated = recordFeedback('new-provider', true, history);
228
- expect(updated['new-provider']).toEqual({ good: 1, bad: 0 });
229
- });
230
-
231
- it('returns the same history object (mutates in place)', () => {
232
- const history: Record<string, { good: number; bad: number }> = {};
233
- const updated = recordFeedback('groq', true, history);
234
- expect(updated).toBe(history);
235
- });
236
- });
@@ -1,360 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
-
3
- // Mock tokenUtils BEFORE importing providerRetry
4
- vi.mock('../../src/utils/tokenUtils', () => ({
5
- countTokens: (text: string) => {
6
- if (!text || text.length === 0) return 0;
7
- return Math.ceil(text.trim().split(/\s+/).length * 1.3);
8
- },
9
- estimateTokens: (text: string) => {
10
- if (!text || text.length === 0) return 0;
11
- return Math.ceil(text.trim().split(/\s+/).length * 1.3);
12
- },
13
- }));
14
-
15
- import {
16
- ProviderRetryHandler,
17
- createRetryHandler,
18
- DEFAULT_RETRY_CONFIG,
19
- DEFAULT_PROVIDER_CONFIG,
20
- PROVIDER_CONTEXT_LIMITS,
21
- RetryConfig,
22
- ProviderRetryConfig,
23
- } from '../../src/routing/providerRetry';
24
-
25
- // ============================================================
26
- // HELPERS
27
- // ============================================================
28
-
29
- function expectInRange(actual: number, min: number, max: number, label: string): void {
30
- expect(actual >= min && actual <= max).toBe(true);
31
- }
32
-
33
- // ============================================================
34
- // SUITE
35
- // ============================================================
36
-
37
- describe('ProviderRetryHandler', () => {
38
- let handler: ProviderRetryHandler;
39
-
40
- beforeEach(() => {
41
- handler = new ProviderRetryHandler();
42
- });
43
-
44
- describe('constructor', () => {
45
- it('initializes with default configs', () => {
46
- expect(handler).toBeInstanceOf(ProviderRetryHandler);
47
- });
48
-
49
- it('initializes with custom provider configs', () => {
50
- const custom: ProviderRetryConfig = {
51
- customProvider: {
52
- timeout: 5000,
53
- retry: { maxRetries: 2, initialDelayMs: 500, maxDelayMs: 10000, backoffMultiplier: 2 },
54
- rateLimitRetries: 3,
55
- },
56
- };
57
- const customHandler = new ProviderRetryHandler(custom);
58
- const cfg = customHandler.getConfig('customProvider');
59
- expect(cfg.timeout).toBe(5000);
60
- });
61
- });
62
-
63
- describe('getConfig', () => {
64
- it('returns deepseek config with correct values', () => {
65
- const cfg = handler.getConfig('deepseek');
66
- expect(cfg.timeout).toBe(30000);
67
- expect(cfg.retry.maxRetries).toBe(5);
68
- expect(cfg.rateLimitRetries).toBe(3);
69
- });
70
-
71
- it('returns groq config with short timeout', () => {
72
- const cfg = handler.getConfig('groq');
73
- expect(cfg.timeout).toBe(10000);
74
- expect(cfg.retry.maxRetries).toBe(2);
75
- expect(cfg.rateLimitRetries).toBe(1);
76
- });
77
-
78
- it('falls back to default for unknown providers', () => {
79
- const cfg = handler.getConfig('nonexistent');
80
- expect(cfg.timeout).toBe(15000);
81
- expect(cfg.retry.maxRetries).toBe(3);
82
- });
83
- });
84
-
85
- describe('configureProvider', () => {
86
- it('adds a new custom provider', () => {
87
- handler.configureProvider('my-provider', {
88
- timeout: 9999,
89
- retry: { maxRetries: 10, initialDelayMs: 100, maxDelayMs: 5000, backoffMultiplier: 1.5 },
90
- rateLimitRetries: 5,
91
- });
92
- const cfg = handler.getConfig('my-provider');
93
- expect(cfg.timeout).toBe(9999);
94
- expect(cfg.retry.maxRetries).toBe(10);
95
- expect(cfg.retry.initialDelayMs).toBe(100);
96
- expect(cfg.rateLimitRetries).toBe(5);
97
- });
98
-
99
- it('overrides existing provider partially', () => {
100
- handler.configureProvider('groq', { timeout: 50000 });
101
- const cfg = handler.getConfig('groq');
102
- expect(cfg.timeout).toBe(50000);
103
- // Other values unchanged
104
- expect(cfg.retry.maxRetries).toBe(2);
105
- expect(cfg.rateLimitRetries).toBe(1);
106
- });
107
- });
108
-
109
- describe('isRetryableError', () => {
110
- it('returns true for common transient errors', () => {
111
- expect(handler.isRetryableError({ code: 'ECONNRESET' })).toBe(true);
112
- expect(handler.isRetryableError({ code: 'ETIMEDOUT' })).toBe(true);
113
- expect(handler.isRetryableError({ code: 'ECONNREFUSED' })).toBe(true);
114
- expect(handler.isRetryableError({ code: 'EAI_AGAIN' })).toBe(true);
115
- });
116
-
117
- it('returns true for 5xx status codes', () => {
118
- expect(handler.isRetryableError({ status: 500 })).toBe(true);
119
- expect(handler.isRetryableError({ status: 502 })).toBe(true);
120
- expect(handler.isRetryableError({ status: 503 })).toBe(true);
121
- expect(handler.isRetryableError({ status: 504 })).toBe(true);
122
- });
123
-
124
- it('returns true for 429 rate limit', () => {
125
- expect(handler.isRetryableError({ status: 429 })).toBe(true);
126
- expect(handler.isRetryableError({ statusCode: 429 })).toBe(true);
127
- });
128
-
129
- it('returns false for 4xx client errors', () => {
130
- expect(handler.isRetryableError({ status: 400 })).toBe(false);
131
- expect(handler.isRetryableError({ status: 404 })).toBe(false);
132
- });
133
-
134
- it('returns false for permanent provider state errors', () => {
135
- expect(handler.isRetryableError({ status: 401 })).toBe(false);
136
- expect(handler.isRetryableError({ status: 403 })).toBe(false);
137
- expect(handler.isRetryableError({ message: 'insufficient balance' })).toBe(false);
138
- expect(handler.isRetryableError({ message: 'invalid API key' })).toBe(false);
139
- expect(handler.isRetryableError({ message: 'quota exhausted' })).toBe(false);
140
- });
141
-
142
- it('returns false for null/undefined error', () => {
143
- expect(handler.isRetryableError(null)).toBe(false);
144
- expect(handler.isRetryableError(undefined)).toBe(false);
145
- });
146
- });
147
-
148
- describe('isRateLimitError', () => {
149
- it('detects 429 in status field', () => {
150
- expect(handler.isRateLimitError({ status: 429 })).toBe(true);
151
- });
152
-
153
- it('detects 429 in statusCode field', () => {
154
- expect(handler.isRateLimitError({ statusCode: 429 })).toBe(true);
155
- });
156
-
157
- it('returns false for non-429 errors', () => {
158
- expect(handler.isRateLimitError({ status: 200 })).toBe(false);
159
- expect(handler.isRateLimitError({ status: 500 })).toBe(false);
160
- expect(handler.isRateLimitError({})).toBe(false);
161
- });
162
- });
163
-
164
- describe('calculateBackoffDelay', () => {
165
- const defaultConfig: RetryConfig = {
166
- maxRetries: 3,
167
- initialDelayMs: 1000,
168
- maxDelayMs: 30000,
169
- backoffMultiplier: 2,
170
- retryableErrors: ['ECONNRESET'],
171
- };
172
-
173
- it('returns delay in range [0.5*base, base] for attempt 0', () => {
174
- const delay = handler.calculateBackoffDelay(0, defaultConfig);
175
- // base = 1000, jitter = [500, 1000]
176
- expectInRange(delay, 500, 1000, 'Attempt 0 delay');
177
- });
178
-
179
- it('returns delay in range [0.5*base, base] for attempt 1', () => {
180
- const delay = handler.calculateBackoffDelay(1, defaultConfig);
181
- // base = 1000 * 2^1 = 2000, jitter = [1000, 2000]
182
- expectInRange(delay, 1000, 2000, 'Attempt 1 delay');
183
- });
184
-
185
- it('returns delay in range [0.5*base, base] for attempt 2', () => {
186
- const delay = handler.calculateBackoffDelay(2, defaultConfig);
187
- // base = 1000 * 2^2 = 4000, jitter = [2000, 4000]
188
- expectInRange(delay, 2000, 4000, 'Attempt 2 delay');
189
- });
190
-
191
- it('caps delay at maxDelayMs', () => {
192
- const cappedConfig: RetryConfig = { ...defaultConfig, maxDelayMs: 5000 };
193
- const delay = handler.calculateBackoffDelay(10, cappedConfig);
194
- expect(delay).toBeLessThanOrEqual(5000);
195
- });
196
-
197
- it('respects Retry-After header for 429 errors', () => {
198
- const rateLimitError = {
199
- status: 429,
200
- headers: { 'retry-after': '5' },
201
- };
202
- const delay = handler.calculateBackoffDelay(0, defaultConfig, rateLimitError);
203
- // Retry-After: 5 seconds = 5000ms, with some tolerance
204
- expectInRange(delay, 4500, 5500, 'Retry-After delay');
205
- });
206
- });
207
-
208
- describe('validateContextWindow', () => {
209
- it('returns valid for short prompts', () => {
210
- const result = handler.validateContextWindow('openai', 'Short prompt');
211
- expect(result.valid).toBe(true);
212
- });
213
-
214
- it('returns invalid for long prompts on small-context providers', () => {
215
- const longText = Array(10000).join('word '); // ~9 chars * 10000 = ~90K chars
216
- const result = handler.validateContextWindow('cerebras', longText);
217
- expect(result.valid).toBe(false);
218
- expect(result.reason).toBeTruthy();
219
- expect(result.suggestedProvider).toBeTruthy();
220
- });
221
-
222
- it('suggests a provider with larger context when validation fails', () => {
223
- const longText = Array(10000).join('word ');
224
- const result = handler.validateContextWindow('cerebras', longText);
225
- expect(result.suggestedProvider).toBeTruthy();
226
- const suggestedLimit = PROVIDER_CONTEXT_LIMITS[result.suggestedProvider!] || 0;
227
- const cerebrasLimit = PROVIDER_CONTEXT_LIMITS['cerebras'] || 0;
228
- expect(suggestedLimit).toBeGreaterThan(cerebrasLimit);
229
- });
230
-
231
- it('returns valid for large prompts on large-context providers', () => {
232
- const longText = Array(10000).join('word ');
233
- const result = handler.validateContextWindow('minimax', longText);
234
- expect(result.valid).toBe(true);
235
- });
236
-
237
- it('accepts explicit token count parameter', () => {
238
- const result = handler.validateContextWindow('groq', 'test', 100);
239
- expect(result.valid).toBe(true);
240
- });
241
- });
242
-
243
- describe('stats tracking', () => {
244
- it('starts with zeroed stats', () => {
245
- const stats = handler.getStats('openai');
246
- expect(stats.totalRequests).toBe(0);
247
- expect(stats.successfulRequests).toBe(0);
248
- expect(stats.failedRequests).toBe(0);
249
- expect(stats.totalRetries).toBe(0);
250
- });
251
-
252
- it('getAllStats returns all providers', () => {
253
- const allStats = handler.getAllStats();
254
- expect(allStats['openai']).toBeDefined();
255
- expect(allStats['deepseek']).toBeDefined();
256
- expect(allStats['groq']).toBeDefined();
257
- expect(Object.keys(allStats).length).toBeGreaterThan(5);
258
- });
259
-
260
- it('resetStats clears single provider', () => {
261
- handler.resetStats('openai');
262
- const stats = handler.getStats('openai');
263
- expect(stats.totalRequests).toBe(0);
264
- });
265
-
266
- it('resetStats with no arg clears all', () => {
267
- handler.resetStats();
268
- const allStats = handler.getAllStats();
269
- for (const stats of Object.values(allStats)) {
270
- expect(stats.totalRequests).toBe(0);
271
- }
272
- });
273
- });
274
-
275
- describe('executeWithRetry', () => {
276
- it('succeeds on first attempt', async () => {
277
- const fn = vi.fn().mockResolvedValue('success');
278
- const result = await handler.executeWithRetry('groq', fn);
279
- expect(result).toBe('success');
280
- expect(fn).toHaveBeenCalledTimes(1);
281
- });
282
-
283
- it('retries on transient errors then succeeds', async () => {
284
- const fn = vi.fn()
285
- .mockRejectedValueOnce({ code: 'ECONNRESET', message: 'Connection reset' })
286
- .mockRejectedValueOnce({ code: 'ECONNRESET', message: 'Connection reset' })
287
- .mockResolvedValue('success after retry');
288
-
289
- const result = await handler.executeWithRetry('groq', fn, {
290
- onRetry: vi.fn(),
291
- });
292
- expect(result).toBe('success after retry');
293
- expect(fn).toHaveBeenCalledTimes(3);
294
- });
295
-
296
- it('fails after exhausting retries', async () => {
297
- const fn = vi.fn().mockRejectedValue({ code: 'ECONNRESET', message: 'Persistent failure' });
298
-
299
- await expect(
300
- handler.executeWithRetry('groq', fn)
301
- ).rejects.toThrow();
302
- expect(fn).toHaveBeenCalledTimes(3); // initial + 2 retries (groq maxRetries=2)
303
- });
304
-
305
- it('does not retry on non-retryable errors', async () => {
306
- const fn = vi.fn().mockRejectedValue({ status: 401, message: 'Unauthorized' });
307
-
308
- await expect(
309
- handler.executeWithRetry('groq', fn)
310
- ).rejects.toThrow();
311
- expect(fn).toHaveBeenCalledTimes(1);
312
- });
313
-
314
- it('calls onRetry callback on each retry', async () => {
315
- const fn = vi.fn()
316
- .mockRejectedValueOnce({ code: 'ECONNRESET' })
317
- .mockResolvedValue('ok');
318
- const onRetry = vi.fn();
319
-
320
- await handler.executeWithRetry('groq', fn, { onRetry });
321
- expect(onRetry).toHaveBeenCalledTimes(1);
322
- expect(onRetry).toHaveBeenCalledWith(1, { code: 'ECONNRESET' }, expect.any(Number));
323
- });
324
-
325
- it('respects custom timeout', async () => {
326
- const slowFn = vi.fn().mockImplementation(
327
- () => new Promise(r => setTimeout(r, 100))
328
- );
329
-
330
- // Short timeout should reject
331
- await expect(
332
- handler.executeWithRetry('groq', slowFn, { timeout: 5 })
333
- ).rejects.toThrow(/timed out/i);
334
- });
335
- });
336
-
337
- describe('PROVIDER_CONTEXT_LIMITS', () => {
338
- it('contains expected providers', () => {
339
- expect(PROVIDER_CONTEXT_LIMITS['openai']).toBe(128000);
340
- expect(PROVIDER_CONTEXT_LIMITS['anthropic']).toBe(200000);
341
- expect(PROVIDER_CONTEXT_LIMITS['minimax']).toBe(1000000);
342
- expect(PROVIDER_CONTEXT_LIMITS['groq']).toBe(32000);
343
- expect(PROVIDER_CONTEXT_LIMITS['default']).toBe(8192);
344
- });
345
- });
346
-
347
- describe('createRetryHandler', () => {
348
- it('creates handler with custom configs', () => {
349
- const custom = createRetryHandler({
350
- testProv: {
351
- timeout: 1000,
352
- retry: { maxRetries: 1, initialDelayMs: 100, maxDelayMs: 5000, backoffMultiplier: 2 },
353
- rateLimitRetries: 1,
354
- },
355
- });
356
- const cfg = custom.getConfig('testProv');
357
- expect(cfg.timeout).toBe(1000);
358
- });
359
- });
360
- });