adaptive-memory-multi-model-router 2.16.0 → 2.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/.github/workflows/adapters-ci.yml +142 -0
  2. package/.github/workflows/auto-submit-sitemap.yml +41 -0
  3. package/.github/workflows/ci.yml +2 -5
  4. package/.github/workflows/mcp-pypi-publish.yml +34 -0
  5. package/.github/workflows/pypi-publish.yml +146 -0
  6. package/.github/workflows/tmlpd-publish.yml +23 -0
  7. package/README.md +245 -148
  8. package/RELEASE_v2.16.0.md +149 -0
  9. package/TECHNICAL_README.md +253 -0
  10. package/adapters/README.md +36 -0
  11. package/adapters/__init__.py +25 -0
  12. package/adapters/a3m_adapter/__init__.py +51 -0
  13. package/adapters/a3m_adapter/adapter/__init__.py +22 -0
  14. package/adapters/a3m_adapter/adapter/autogen.py +169 -0
  15. package/adapters/a3m_adapter/adapter/config.py +100 -0
  16. package/adapters/a3m_adapter/adapter/haystack.py +197 -0
  17. package/adapters/a3m_adapter/adapter/langchain.py +155 -0
  18. package/adapters/a3m_adapter/adapter/langgraph.py +196 -0
  19. package/adapters/a3m_adapter/adapter/llamaindex.py +162 -0
  20. package/adapters/a3m_adapter/adapter/pinecone.py +217 -0
  21. package/adapters/a3m_adapter/adapter/vercel.py +188 -0
  22. package/adapters/a3m_adapter/tests/__init__.py +1 -0
  23. package/adapters/a3m_adapter/tests/test_adapters.py +118 -0
  24. package/adapters/a3m_adapter/tests/test_integration.py +80 -0
  25. package/adapters/requirements-dev.txt +6 -0
  26. package/adapters/requirements.txt +4 -0
  27. package/adapters/setup.py +23 -0
  28. package/demo.py +251 -0
  29. package/discoverability-diagnosis.md +280 -0
  30. package/dist/analytics/costAnalytics.d.ts.map +1 -1
  31. package/dist/benchmark/reproducible.d.ts.map +1 -1
  32. package/dist/cache/semanticCache.d.ts.map +1 -1
  33. package/dist/cli/setupWizard.d.ts +257 -50
  34. package/dist/cli/setupWizard.d.ts.map +1 -1
  35. package/dist/cli/setupWizard.js +419 -109
  36. package/dist/cli/setupWizard.js.map +1 -1
  37. package/dist/cli/tui.d.ts +6 -0
  38. package/dist/cli/tui.js +96 -67
  39. package/dist/cli/tui.js.map +1 -0
  40. package/dist/cli.js +9 -0
  41. package/dist/cost/budgetEnforcer.d.ts.map +1 -1
  42. package/dist/cost/costTracker.d.ts.map +1 -1
  43. package/dist/ensemble/multiRoundDialog.d.ts.map +1 -1
  44. package/dist/ensemble/shapleyValue.d.ts.map +1 -1
  45. package/dist/ensemble.d.ts +1 -1
  46. package/dist/ensemble.js +141 -0
  47. package/dist/integrations/langchainAdapter.d.ts.map +1 -1
  48. package/dist/integrations/langchainAdapter.js +3 -3
  49. package/dist/integrations/langchainAdapter.js.map +1 -1
  50. package/dist/integrations/oauth.d.ts.map +1 -1
  51. package/dist/integrations/scienceAdapter.d.ts.map +1 -1
  52. package/dist/memory/autoFetch.d.ts.map +1 -1
  53. package/dist/memory/hybridMemory.d.ts.map +1 -1
  54. package/dist/memory/memoryTree.d.ts.map +1 -1
  55. package/dist/memory/obsidianVault.d.ts.map +1 -1
  56. package/dist/memory/reasoningBank.d.ts.map +1 -1
  57. package/dist/observability/metrics.d.ts.map +1 -1
  58. package/dist/observability/tracer.d.ts.map +1 -1
  59. package/dist/providers/providerConfig.d.ts.map +1 -1
  60. package/dist/providers/providerConfig.js +32 -17
  61. package/dist/providers/providerConfig.js.map +1 -1
  62. package/dist/routing/advancedRouter.d.ts.map +1 -1
  63. package/dist/routing/advancedRouter.js +106 -14
  64. package/dist/routing/advancedRouter.js.map +1 -1
  65. package/dist/routing/providerHealth.d.ts.map +1 -1
  66. package/dist/routing/providerRetry.d.ts.map +1 -1
  67. package/dist/routing/shadowSampler.d.ts.map +1 -0
  68. package/dist/routing/shadowSampler.js.map +1 -1
  69. package/dist/security/guardrails.d.ts.map +1 -1
  70. package/dist/server/handlers/chatHandler.d.ts.map +1 -1
  71. package/dist/server/handlers/completionsHandler.d.ts.map +1 -1
  72. package/dist/server/handlers/embeddingsHandler.d.ts.map +1 -1
  73. package/dist/server/handlers/healthHandler.d.ts.map +1 -1
  74. package/dist/server/handlers/metricsHandler.d.ts.map +1 -1
  75. package/dist/server/handlers/modelsHandler.d.ts.map +1 -1
  76. package/dist/server/metrics.d.ts.map +1 -1
  77. package/dist/server/proxyServer.d.ts.map +1 -1
  78. package/dist/server/router.d.ts.map +1 -1
  79. package/dist/server/state.d.ts.map +1 -1
  80. package/dist/skills/__tests__/skill_manager.test.js +5 -265
  81. package/dist/skills/__tests__/skill_manager.test.js.map +1 -1
  82. package/dist/utils/tokenUtils.d.ts.map +1 -1
  83. package/docker-compose.yml +84 -60
  84. package/docs/ARTICLE_Biology_Inspired_Routing.md +208 -0
  85. package/docs/ARTICLE_Master.md +78 -0
  86. package/docs/ARTICLE_Master_CN.md +78 -0
  87. package/docs/ARTICLE_OpenRouter_Stripe.md +140 -0
  88. package/docs/DEVPTO_ARTICLE.md +84 -0
  89. package/docs/HUMAN_STYLE_GUIDE.md +75 -0
  90. package/docs/IMPRINT_PLAN.md +88 -0
  91. package/docs/OPENROUTER_ALTERNATIVE.md +184 -0
  92. package/docs/SOCIAL_CAMPAIGN.md +316 -0
  93. package/docs/anthropic.html +45 -0
  94. package/docs/best-llm-routers-2025.html +157 -0
  95. package/docs/cerebras.html +43 -0
  96. package/docs/cli-cheatsheet.md +286 -212
  97. package/docs/comparison.md +2 -2
  98. package/docs/deepseek.html +44 -0
  99. package/docs/google.html +47 -0
  100. package/docs/groq.html +44 -0
  101. package/docs/llms-full.txt +360 -138
  102. package/docs/llms.txt +70 -71
  103. package/docs/mistral.html +43 -0
  104. package/docs/ollama.html +50 -0
  105. package/docs/openai.html +57 -0
  106. package/docs/sitemap.xml +69 -57
  107. package/docs-site/blog/best-llm-routers-2025.html +157 -0
  108. package/docs-site/index.html +68 -9
  109. package/docs-site/providers/anthropic.html +45 -0
  110. package/docs-site/providers/cerebras.html +43 -0
  111. package/docs-site/providers/deepseek.html +44 -0
  112. package/docs-site/providers/google.html +47 -0
  113. package/docs-site/providers/groq.html +44 -0
  114. package/docs-site/providers/index.html +41 -0
  115. package/docs-site/providers/mistral.html +43 -0
  116. package/docs-site/providers/ollama.html +50 -0
  117. package/docs-site/providers/openai.html +57 -0
  118. package/docs-site/sitemap.xml +69 -0
  119. package/llms.txt +70 -62
  120. package/package.json +44 -182
  121. package/packages/agentkit-adapter/LICENSE +21 -0
  122. package/packages/agentkit-adapter/README.md +126 -0
  123. package/packages/agentkit-adapter/examples/agentkit-example.ts +139 -0
  124. package/packages/agentkit-adapter/package.json +57 -0
  125. package/packages/agentkit-adapter/src/adapter.ts +381 -0
  126. package/packages/agentkit-adapter/src/index.ts +36 -0
  127. package/packages/agentkit-adapter/src/types.ts +105 -0
  128. package/packages/agentkit-adapter/src/util.ts +13 -0
  129. package/packages/agentkit-adapter/tsconfig.json +22 -0
  130. package/prometheus.yml +8 -0
  131. package/python/README.md +35 -81
  132. package/python/a3m/__init__.py +32 -3
  133. package/python/a3m/adapters/__init__.py +21 -0
  134. package/python/a3m/adapters/langchain.py +190 -0
  135. package/python/a3m/adapters/llamaindex.py +249 -0
  136. package/python/a3m/adapters/qdrant.py +240 -0
  137. package/python/a3m/adapters/weaviate.py +263 -0
  138. package/python/a3m/client.py +5 -0
  139. package/python/build_verify.sh +32 -0
  140. package/python/mcp-server/README.md +172 -0
  141. package/python/mcp-server/a3m_mcp/__init__.py +25 -0
  142. package/python/mcp-server/a3m_mcp/__main__.py +15 -0
  143. package/python/mcp-server/a3m_mcp/server.py +205 -0
  144. package/python/mcp-server/pyproject.toml +24 -0
  145. package/python/pyproject.toml +60 -6
  146. package/python/setup.py +3 -28
  147. package/scripts/submit-sitemap.sh +52 -0
  148. package/src/__types__/registry.d.ts +14 -0
  149. package/src/cli/setupWizard.ts +443 -112
  150. package/src/cli/tui.ts +159 -0
  151. package/src/ensemble.ts +154 -1
  152. package/src/integrations/langchainAdapter.ts +2 -2
  153. package/src/providers/providerConfig.ts +32 -17
  154. package/src/providers/registry.js +27 -0
  155. package/src/routing/advancedRouter.ts +99 -14
  156. package/src/routing/shadowSampler.ts +1 -1
  157. package/test-install/package.json +12 -0
  158. package/tests/tsconfig.json +0 -1
  159. package/tmlpd-pi-extension/README.md +105 -44
  160. package/tmlpd-pi-extension/docs/demo.svg +33 -0
  161. package/tmlpd-pi-extension/package.json +35 -106
  162. package/tmlpd-pi-extension/src/tokenOptimization/contextStratifier.ts +163 -0
  163. package/tmlpd-pi-extension/src/tokenOptimization/fetchOnceLocal.ts +136 -0
  164. package/tmlpd-pi-extension/src/tokenOptimization/index.ts +197 -0
  165. package/tmlpd-pi-extension/src/tokenOptimization/interAgentCompression.ts +157 -0
  166. package/tmlpd-pi-extension/src/tokenOptimization/schemaContract.ts +101 -0
  167. package/tmlpd-pi-extension/src/tokenOptimization/semanticCache.ts +248 -0
  168. package/tmlpd-pi-extension/src/tokenOptimization/tokenAwareFallback.ts +192 -0
  169. package/tmlpd-pi-extension/test/verify.js +21 -0
  170. package/tsconfig.build.json +3 -2
  171. package/packages/a3m-vercel-ai/dist/a3m-language-model.d.ts +0 -12
  172. package/packages/a3m-vercel-ai/dist/a3m-language-model.d.ts.map +0 -1
  173. package/packages/a3m-vercel-ai/dist/a3m-language-model.js +0 -289
  174. package/packages/a3m-vercel-ai/dist/a3m-language-model.js.map +0 -1
  175. package/packages/a3m-vercel-ai/dist/index.d.ts +0 -82
  176. package/packages/a3m-vercel-ai/dist/index.d.ts.map +0 -1
  177. package/packages/a3m-vercel-ai/dist/index.js +0 -79
  178. package/packages/a3m-vercel-ai/dist/index.js.map +0 -1
  179. package/packages/a3m-vercel-ai/dist/types.d.ts +0 -97
  180. package/packages/a3m-vercel-ai/dist/types.d.ts.map +0 -1
  181. package/packages/a3m-vercel-ai/dist/types.js +0 -5
  182. package/packages/a3m-vercel-ai/dist/types.js.map +0 -1
  183. package/src/skills/__tests__/skill_manager.test.ts +0 -328
  184. package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts +0 -114
  185. package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts.map +0 -1
  186. package/tmlpd-pi-extension/dist/cache/prefixCache.js +0 -285
  187. package/tmlpd-pi-extension/dist/cache/prefixCache.js.map +0 -1
  188. package/tmlpd-pi-extension/dist/cache/responseCache.d.ts +0 -58
  189. package/tmlpd-pi-extension/dist/cache/responseCache.d.ts.map +0 -1
  190. package/tmlpd-pi-extension/dist/cache/responseCache.js +0 -153
  191. package/tmlpd-pi-extension/dist/cache/responseCache.js.map +0 -1
  192. package/tmlpd-pi-extension/dist/cli.js +0 -59
  193. package/tmlpd-pi-extension/dist/cost/costTracker.d.ts +0 -95
  194. package/tmlpd-pi-extension/dist/cost/costTracker.d.ts.map +0 -1
  195. package/tmlpd-pi-extension/dist/cost/costTracker.js +0 -240
  196. package/tmlpd-pi-extension/dist/cost/costTracker.js.map +0 -1
  197. package/tmlpd-pi-extension/dist/index.d.ts +0 -723
  198. package/tmlpd-pi-extension/dist/index.d.ts.map +0 -1
  199. package/tmlpd-pi-extension/dist/index.js +0 -239
  200. package/tmlpd-pi-extension/dist/index.js.map +0 -1
  201. package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts +0 -82
  202. package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts.map +0 -1
  203. package/tmlpd-pi-extension/dist/memory/episodicMemory.js +0 -145
  204. package/tmlpd-pi-extension/dist/memory/episodicMemory.js.map +0 -1
  205. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts +0 -102
  206. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts.map +0 -1
  207. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js +0 -207
  208. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js.map +0 -1
  209. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts +0 -85
  210. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts.map +0 -1
  211. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js +0 -210
  212. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js.map +0 -1
  213. package/tmlpd-pi-extension/dist/providers/localProvider.d.ts +0 -102
  214. package/tmlpd-pi-extension/dist/providers/localProvider.d.ts.map +0 -1
  215. package/tmlpd-pi-extension/dist/providers/localProvider.js +0 -338
  216. package/tmlpd-pi-extension/dist/providers/localProvider.js.map +0 -1
  217. package/tmlpd-pi-extension/dist/providers/registry.d.ts +0 -55
  218. package/tmlpd-pi-extension/dist/providers/registry.d.ts.map +0 -1
  219. package/tmlpd-pi-extension/dist/providers/registry.js +0 -138
  220. package/tmlpd-pi-extension/dist/providers/registry.js.map +0 -1
  221. package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts +0 -68
  222. package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts.map +0 -1
  223. package/tmlpd-pi-extension/dist/routing/advancedRouter.js +0 -332
  224. package/tmlpd-pi-extension/dist/routing/advancedRouter.js.map +0 -1
  225. package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts +0 -101
  226. package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts.map +0 -1
  227. package/tmlpd-pi-extension/dist/tools/tmlpdTools.js +0 -368
  228. package/tmlpd-pi-extension/dist/tools/tmlpdTools.js.map +0 -1
  229. package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts +0 -96
  230. package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts.map +0 -1
  231. package/tmlpd-pi-extension/dist/utils/batchProcessor.js +0 -170
  232. package/tmlpd-pi-extension/dist/utils/batchProcessor.js.map +0 -1
  233. package/tmlpd-pi-extension/dist/utils/compression.d.ts +0 -61
  234. package/tmlpd-pi-extension/dist/utils/compression.d.ts.map +0 -1
  235. package/tmlpd-pi-extension/dist/utils/compression.js +0 -281
  236. package/tmlpd-pi-extension/dist/utils/compression.js.map +0 -1
  237. package/tmlpd-pi-extension/dist/utils/reliability.d.ts +0 -74
  238. package/tmlpd-pi-extension/dist/utils/reliability.d.ts.map +0 -1
  239. package/tmlpd-pi-extension/dist/utils/reliability.js +0 -177
  240. package/tmlpd-pi-extension/dist/utils/reliability.js.map +0 -1
  241. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts +0 -117
  242. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts.map +0 -1
  243. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js +0 -246
  244. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js.map +0 -1
  245. package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts +0 -50
  246. package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts.map +0 -1
  247. package/tmlpd-pi-extension/dist/utils/tokenUtils.js +0 -124
  248. package/tmlpd-pi-extension/dist/utils/tokenUtils.js.map +0 -1
@@ -1,66 +1,127 @@
1
- # TMLPDParallel Multi-LLM Execution Module
1
+ # tmlpd-piRun N LLMs in parallel, keep the best answer
2
2
 
3
- > **Part of the [A3M Router](https://github.com/Das-rebel/a3m-router) ecosystem the fastest-growing npm LLM router (10K downloads in 14 days).**
3
+ **Picking one LLM means gambling: the cheap model fumbles hard queries, the expensive model burns money on easy ones. tmlpd-pi calls every provider **simultaneously**, scores each answer, and returns the winner with the receipts (per-provider scores, latency, cost).**
4
4
 
5
- Parallel multi-LLM execution with confidence-weighted ensemble merging. Runs providers simultaneously, scores each result, and returns the best answer with transparent reasoning.
5
+ `pi` = extension for the [PI coding agent](https://github.com/badlogic/pi-mono). TMLPD = parallel multi-LLM execution with confidence-weighted ensemble merging. Part of the [A3M Router](https://github.com/Das-rebel/a3m-router) ecosystem.
6
6
 
7
- ## What This Is
7
+ [![npm version](https://img.shields.io/npm/v/tmlpd-pi)](https://www.npmjs.com/package/tmlpd-pi)
8
+ [![npm downloads](https://img.shields.io/npm/dm/tmlpd-pi)](https://www.npmjs.com/package/tmlpd-pi)
9
+ [![license](https://img.shields.io/npm/l/tmlpd-pi)](https://github.com/Das-rebel/tmlpd-skill/blob/main/LICENSE)
10
+ [![node](https://img.shields.io/node/v/tmlpd-pi)](https://www.npmjs.com/package/tmlpd-pi)
11
+ [![GitHub stars](https://img.shields.io/github/stars/Das-rebel/tmlpd-skill)](https://github.com/Das-rebel/tmlpd-skill)
8
12
 
9
- A TypeScript library for executing prompts across multiple LLM providers **in parallel** not sequentially. Every provider runs at the same time, results are scored on quality, and the best answer is selected with a clear explanation of why it won.
13
+ ![tmlpd-pi parallel ensemble demo](docs/demo.svg)
10
14
 
11
- ## Core Features
15
+ ## In 30 seconds
12
16
 
13
- | Feature | Description |
14
- |:--------|:------------|
15
- | **Parallel execution** | Run N providers simultaneously, not sequentially |
16
- | **Ensemble scoring** | Score results on specificity, structure, and relevance |
17
- | **Query-type presets** | Auto-configure provider + temp per task type |
18
- | **Cost tracking** | Per-query cost display with provider breakdown |
19
- | **Persistent memory** | Cross-session `.memory.json` with keyword indexing |
20
- | **Prefix caching** | RadixAttention-style caching for repeated prefixes |
21
- | **Speculative decoding** | Medusa/EAGLE-style multi-token prediction |
22
- | **Token compression** | ISON encoding for ~40% token reduction |
23
-
24
- ## Usage
17
+ ```bash
18
+ npm install tmlpd-pi
19
+ ```
25
20
 
26
21
  ```typescript
27
- import { executeEnsemble, createPresetRouter, EpisodicMemoryStore } from "tmlpd-pi";
22
+ import { executeEnsemble } from "tmlpd-pi";
28
23
 
29
- // Parallel ensemble: run all providers simultaneously, pick best
24
+ // 3 providers race in parallel. Best answer wins. You keep every score.
30
25
  const result = await executeEnsemble(
31
26
  "Explain vector databases",
32
- systemPrompt,
33
- context,
34
- { nvidia: callNvidia, groq: callGroq }
27
+ "You are a precise engineering mentor.",
28
+ "",
29
+ {
30
+ groq: callGroq, // your existing provider calls
31
+ nvidia: callNvidia,
32
+ openai: callOpenAI,
33
+ }
35
34
  );
36
- console.log(`Winner: ${result.winner} (score: ${result.scores[result.winner]})`);
37
35
 
38
- // Query-type presets: auto-configure per task
39
- const router = createPresetRouter();
40
- const preset = router.classify("Write a Python sort function"); // 'code'
36
+ console.log(result.winner); // "groq"
37
+ console.log(result.scores); // { groq: 0.91, nvidia: 0.84, openai: 0.88 }
38
+ console.log(result.timing.totalMs); // wall-clock = slowest provider, not the sum
39
+ ```
40
+
41
+ **Same latency as your slowest provider — not the sum of all three.** Sequential fallback is 3x slower and commits you to the first answer before you've seen the alternatives.
42
+
43
+ ## Why parallel ensemble instead of sequential fallback?
44
+
45
+ | | Sequential fallback | tmlpd-pi ensemble |
46
+ |:--|:--|:--|
47
+ | Latency for N providers | sum of all attempts | slowest single provider |
48
+ | Answer quality | first non-failing model | confidence-scored best-of-N |
49
+ | Failure handling | try next on error | failed providers simply don't score |
50
+ | Cost visibility | hidden per-call | per-provider cost breakdown |
51
+ | Evidence | none | transparent `reasoning` for the pick |
52
+
53
+ Complements (not replaces) routers like [A3M Router](https://github.com/Das-rebel/a3m-router) or LiteLLM: routers pick *one* model per request; tmlpd-pi is the layer that picks the best *answer* when you run several.
54
+
55
+ ## Features
56
+
57
+ | Feature | What it does |
58
+ |:--------|:-------------|
59
+ | **Parallel execution** | Run N providers simultaneously with configurable concurrency |
60
+ | **Ensemble scoring** | Score answers on specificity, structure, and relevance; merge complementary results |
61
+ | **Query-type presets** | Auto-configure provider + temperature per task type (code, reasoning, chat) |
62
+ | **Token Optimization** | 6 patterns for 40-60% token reduction (details below) |
63
+ | **Cost tracking** | Per-query cost with provider breakdown + budget enforcement |
64
+ | **Persistent memory** | Cross-session `.memory.json` with keyword indexing |
65
+ | **Caching layers** | Semantic cache + RadixAttention-style prefix caching |
66
+ | **Reliability** | Circuit breaker, retry with exponential backoff |
67
+ | **Local LLMs** | Ollama / vLLM / LM Studio providers for zero-cost, private runs |
68
+ | **Batch processing** | Priority-queue batch executor with progress callbacks |
69
+ | **Python bindings** | `tmlpd` on PyPI — LangChain / LlamaIndex / AutoGen / CrewAI integrations |
70
+
71
+ ## Token Optimization — 6 patterns (40-60% token reduction)
72
+
73
+ Research-backed patterns from [arXiv:2608.17188](https://arxiv.org/abs/2608.17188):
41
74
 
42
- // Persistent memory
43
- const memory = new EpisodicMemoryStore(1000, './memory.json');
44
- const similar = memory.getSimilarTasks("Python async API", 5);
75
+ | Pattern | Description |
76
+ |:--------|:------------|
77
+ | **Semantic Cache** | Embedding-based similarity caching (cosine > 0.85 threshold) |
78
+ | **Context Stratification** | Tiered context levels (LOW: 512 tokens, MEDIUM: 2048, HIGH: 8192) |
79
+ | **Token-Aware Fallback** | Route to cheap/medium/expensive models by token count |
80
+ | **Schema Contraction** | Inject schema reference instead of full description |
81
+ | **Fetch-Once/Process-Local** | One expensive fetch, extract with cheap model |
82
+ | **Inter-Agent Compression** | Compress messages between agents |
83
+
84
+ ```typescript
85
+ import { TokenOptimizer } from "tmlpd-pi";
86
+
87
+ const optimizer = new TokenOptimizer();
88
+ const optimized = await optimizer.optimizeQuery("Explain quantum computing", history);
89
+ console.log(optimized.contextLevel); // "LOW" | "MEDIUM" | "HIGH"
90
+ console.log(optimized.recommendedModel); // cheapest capable model
91
+ console.log(optimized.cacheHit); // true = skip the call entirely
45
92
  ```
46
93
 
47
- ## Exports
94
+ ## Key exports
95
+
96
+ - `executeEnsemble`, `mergeComplementary`, `recordFeedback` — ensemble voting
97
+ - `createPresetRouter`, `getPresetForQuery`, `DEFAULT_PRESETS` — query presets
98
+ - `TokenOptimizer`, `SemanticCache`, `ContextStratifier`, `TokenAwareFallback` — token optimization
99
+ - `createTMLPD`, `TMLPDTools` — core parallel execution
100
+ - `CostTracker`, `BudgetEnforcer` — cost tracking
101
+ - `EpisodicMemoryStore` — persistent memory with auto-save
102
+ - `ResponseCache`, `PrefixCache` — caching layers
103
+ - `createOllamaProvider`, `createVLLMProvider`, `createLMStudioProvider` — local LLMs
104
+ - `executeBatch`, `BatchProcessor` — batch processing
105
+ - `HALOOrchestrator`, `MCTSWorkflowOptimizer` — advanced orchestration
106
+
107
+ ## Research backing
108
+
109
+ - **Token Optimization** ([arXiv:2608.17188](https://arxiv.org/abs/2608.17188)) — 6 patterns for 40-60% token reduction
110
+ - **RouteLLM** ([arXiv:2404.06035](https://arxiv.org/abs/2404.06035)) — learned cost-quality routing
111
+ - **RadixAttention** ([arXiv:2312.07104](https://arxiv.org/abs/2312.07104)) — 5-10x speedup via prefix caching
112
+ - **Medusa** ([arXiv:2401.10774](https://arxiv.org/abs/2401.10774)) — 2-3x faster generation
113
+ - **A-Mem** ([arXiv:2502.12110](https://arxiv.org/abs/2502.12110)) — episodic memory patterns
114
+
115
+ ## Links
48
116
 
49
- - `createTMLPD`, `TMLPDTools`Core parallel execution
50
- - `executeEnsemble`, `mergeComplementary`, `recordFeedback` — P0 Ensemble voting
51
- - `createPresetRouter`, `getPresetForQuery`, `DEFAULT_PRESETS` P1 Query presets
52
- - `EpisodicMemoryStore` — P3 Persistent memory with auto-save
53
- - `CostTracker`, `BudgetEnforcer` — P2 Cost tracking
54
- - `ResponseCache`, `PrefixCache` — Caching layers
55
- - `HALOOrchestrator`, `MCTSWorkflowOptimizer` — Advanced orchestration
117
+ - [Python package (tmlpd on PyPI)](python/) LangChain/LlamaIndex/AutoGen/CrewAI bindings
118
+ - [Quickstart examples](examples/QUICKSTART.md)
119
+ - [A3M Router](https://github.com/Das-rebel/a3m-router)intelligent LLM routing gateway
56
120
 
57
- ## Research Backing
121
+ ## License
58
122
 
59
- - **RouteLLM** (arXiv:2404.06035) — Learned cost-quality routing
60
- - **RadixAttention** (arXiv:2312.07104) — 5-10x speedup via prefix caching
61
- - **Medusa** (arXiv:2401.10774) — 2-3x faster generation
62
- - **A-Mem** (arXiv:2502.12110) — Episodic memory patterns
123
+ MIT see [LICENSE](LICENSE).
63
124
 
64
125
  ---
65
126
 
66
- *Part of the A3M Router ecosystem. "Nobody does parallel multi-LLM execution with result merging. Everyone does sequential fallback."*
127
+ *"Nobody does parallel multi-LLM execution with result merging. Everyone does sequential fallback."*
@@ -0,0 +1,33 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="880" height="440" viewBox="0 0 880 440" font-family="Menlo, Monaco, 'Courier New', monospace">
2
+ <!-- terminal window -->
3
+ <rect x="0" y="0" width="880" height="440" rx="12" fill="#0d1117"/>
4
+ <rect x="0" y="0" width="880" height="44" rx="12" fill="#161b22"/>
5
+ <circle cx="24" cy="22" r="6" fill="#ff5f57"/>
6
+ <circle cx="44" cy="22" r="6" fill="#febc2e"/>
7
+ <circle cx="64" cy="22" r="6" fill="#28c840"/>
8
+ <text x="440" y="27" fill="#8b949e" font-size="13" text-anchor="middle">tmlpd-pi — parallel ensemble</text>
9
+
10
+ <!-- prompt -->
11
+ <text x="24" y="78" fill="#79c0ff" font-size="14">$ <tspan fill="#c9d1d9">npm install tmlpd-pi</tspan></text>
12
+ <text x="24" y="102" fill="#8b949e" font-size="13">added 1 package in 1.2s</text>
13
+
14
+ <text x="24" y="136" fill="#79c0ff" font-size="14">$ <tspan fill="#c9d1d9">node demo.mjs</tspan></text>
15
+
16
+ <!-- racing providers -->
17
+ <text x="24" y="170" fill="#c9d1d9" font-size="14">Query: "Explain vector databases"</text>
18
+ <text x="24" y="194" fill="#c9d1d9" font-size="14">Racing 3 providers in parallel...</text>
19
+
20
+ <!-- provider bars -->
21
+ <text x="40" y="226" fill="#3fb950" font-size="14">groq ████████████████ 820ms score 0.91 ★ WINNER</text>
22
+ <text x="40" y="250" fill="#d29922" font-size="14">openai ██████████████ 1240ms score 0.88</text>
23
+ <text x="40" y="274" fill="#d29922" font-size="14">nvidia ███████████ 1610ms score 0.84</text>
24
+
25
+ <!-- result -->
26
+ <text x="24" y="312" fill="#c9d1d9" font-size="14">Wall-clock: 1.61s (sequential would be 3.67s)</text>
27
+ <text x="24" y="336" fill="#c9d1d9" font-size="14">Cost: $0.00082 (groq $0.00021 · openai $0.00045 · nvidia $0.00016)</text>
28
+
29
+ <text x="24" y="372" fill="#8b949e" font-size="13">reasoning: groq answer more specific (mentions HNSW, IVF),</text>
30
+ <text x="24" y="392" fill="#8b949e" font-size="13">best structure, directly addresses query intent</text>
31
+
32
+ <text x="24" y="420" fill="#79c0ff" font-size="14">$ <tspan fill="#3fb950">✔ kept best of 3 answers for the price of the slowest</tspan></text>
33
+ </svg>
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "tmlpd-pi",
3
- "version": "1.2.2",
4
- "version_description": "v1.2.0 - Research-backed Multi-LLM Router based on arXiv: RouteLLM (2404.06035), RadixAttention (2312.07104), Medusa (2401.10774), FlashAttention (2407.07403). 120+ keywords for LLM/ML discoverability. 13 PI tools.",
5
- "description": "Research-backed Multi-LLM Router with parallel execution, learned routing (RouteLLM), prefix caching (RadixAttention), speculative decoding (Medusa/EAGLE), token compression (ISON), local LLM support (Ollama/vLLM/LM Studio), batch processing. Python bindings for LangChain/LlamaIndex/AutoGen/CrewAI. 120+ keywords: routellm, prefix-caching, speculative-decoding, medusa, flashattention, pagedattention, kv-cache, arxiv, research-backed, icml, neurips, iclr.",
3
+ "version": "1.3.3",
4
+ "version_description": "v1.3.2 - Discoverability release: value-prop description, reallocated keywords, README rewrite with demo. Run N LLMs in parallel, keep the best answer.",
5
+ "description": "Run N LLMs in parallel, keep the best answer. Confidence-scored ensemble merging beats sequential fallback on latency and quality. 40-60% token savings built in.",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "bin": {
@@ -16,128 +16,57 @@
16
16
  "python:examples": "python3 python/examples.py"
17
17
  },
18
18
  "keywords": [
19
- "pi-extension",
20
- "pi",
21
- "pi-package",
22
- "pi-coding-agent",
23
- "pi-agent",
24
- "tmlpd",
25
- "treequest",
26
- "multi-llm",
19
+ "parallel-llm",
20
+ "ensemble-llm",
21
+ "multi-model",
22
+ "llm-fallback",
23
+ "llm-ensemble",
27
24
  "parallel-ai",
25
+ "multi-llm",
28
26
  "llm-orchestration",
29
27
  "llm",
28
+ "llm-router",
29
+ "model-routing",
30
30
  "agent-orchestration",
31
31
  "multi-agent",
32
- "agent",
33
- "parallel",
32
+ "ai-agents",
33
+ "autonomous-agents",
34
34
  "streaming",
35
35
  "cost-tracking",
36
36
  "cost-optimization",
37
+ "llm-cost-reduction",
38
+ "token-optimization",
39
+ "token-compression",
40
+ "context-compression",
41
+ "semantic-caching",
37
42
  "cache",
38
43
  "caching",
44
+ "prefix-caching",
45
+ "kv-cache",
46
+ "speculative-decoding",
39
47
  "circuit-breaker",
40
48
  "retry",
41
- "exponential-backoff",
42
- "mcts",
43
- "monte-carlo-tree-search",
44
- "workflow-optimization",
45
- "hierarchical-planning",
46
- "halo",
47
- "episodic-memory",
48
- "semantic-memory",
49
- "agent-memory",
50
- "python",
51
- "python-bindings",
52
- "pypi",
53
- "langchain",
54
- "llamaindex",
55
- "llama-index",
56
- "autogen",
57
- "crewai",
58
- "huggingface",
59
- "transformers",
60
- "agent-codegen",
61
- "ai-coding",
49
+ "batch-processing",
50
+ "local-llm",
51
+ "ollama",
52
+ "vllm",
62
53
  "openai",
63
54
  "anthropic",
64
- "google",
65
- "groq",
66
- "cerebras",
67
- "mistral",
68
- "xai",
69
- "zai",
70
55
  "claude",
71
- "gpt-4",
72
56
  "gemini",
73
- "llama",
74
- "model-router",
75
- "model-routing",
76
- "llm-router",
77
- "ai-agents",
78
- "autonomous-agents",
79
- "memory-based-router",
80
- "memory-based-llm-router",
81
- "multi-llm-router",
82
- "llm-memory-router",
83
- "adaptive-router",
84
- "adaptive-llm-router",
85
- "intelligent-router",
86
- "intelligent-llm-router",
87
- "learning-router",
88
- "contextual-router",
89
- "context-aware-router",
90
- "task-aware-router",
91
- "memory-augmented",
92
- "memory-augmented-llm",
93
- "episodic-memory-router",
94
- "semantic-memory-router",
95
- "task-memory",
96
- "cross-context-memory",
97
- "token-compression",
98
- "context-compression",
99
- "ison-format",
100
- "message-truncation",
101
- "context-management",
102
- "local-llm",
103
- "ollama",
104
- "vllm",
105
- "lmstudio",
106
- "local-model",
107
- "privacy-llm",
108
- "batch-processing",
109
- "batch-execution",
110
- "priority-queue",
111
- "rate-limiting",
112
- "token-counting",
113
- "cost-estimation",
114
- "cost-prediction",
115
- "parallel-execution",
57
+ "groq",
58
+ "langchain",
59
+ "llamaindex",
60
+ "autogen",
61
+ "crewai",
62
+ "python",
63
+ "tmlpd",
64
+ "pi-coding-agent",
65
+ "routellm",
116
66
  "multi-provider",
117
67
  "fallback-chain",
118
- "intelligent-failover",
119
- "kv-cache",
120
- "routellm",
121
- "prefix-caching",
122
- "radix-attention",
123
- "speculative-decoding",
124
- "medusa",
125
- "eagle",
126
- "flashattention",
127
- "pagedattention",
128
- "kv-cache-quantization",
129
- "llmlingua",
130
- "streamingllm",
131
- "multimodel-orchestration",
132
- "multi-agent-debate",
133
68
  "self-consistency",
134
- "tensor-parallelism",
135
- "continuous-batching",
136
- "arxiv",
137
- "research-backed",
138
- "icml",
139
- "neurips",
140
- "iclr"
69
+ "best-of-n"
141
70
  ],
142
71
  "author": "Subho Das",
143
72
  "license": "MIT",
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Context Stratifier - Token Optimization Pattern #2
3
+ *
4
+ * Different context levels for different query types.
5
+ * Reduces tokens by matching context depth to query complexity.
6
+ *
7
+ * Based on: arXiv:2608.17188 - Token Optimization and Context Window Management
8
+ */
9
+
10
+ export type ContextLevel = "LOW" | "MEDIUM" | "HIGH";
11
+
12
+ export interface ContextStratifierConfig {
13
+ levels: {
14
+ LOW: ContextLevelConfig;
15
+ MEDIUM: ContextLevelConfig;
16
+ HIGH: ContextLevelConfig;
17
+ };
18
+ autoClassify: boolean;
19
+ }
20
+
21
+ export interface ContextLevelConfig {
22
+ maxTokens: number;
23
+ includeHistory: boolean;
24
+ maxHistoryMessages: number;
25
+ }
26
+
27
+ export interface StratificationResult {
28
+ level: ContextLevel;
29
+ maxTokens: number;
30
+ includeHistory: boolean;
31
+ maxHistoryMessages: number;
32
+ reasoning: string;
33
+ }
34
+
35
+ /**
36
+ * Keywords that indicate HIGH complexity queries
37
+ */
38
+ const HIGH_COMPLEXITY_KEYWORDS = [
39
+ "analyze", "compare", "evaluate", "design", "architect",
40
+ "explain in detail", "comprehensive", "thorough",
41
+ "debug", "troubleshoot", "optimize", "improve",
42
+ "research", "investigate", "synthesize", "comprehensive"
43
+ ];
44
+
45
+ /**
46
+ * Keywords that indicate LOW complexity queries
47
+ */
48
+ const LOW_COMPLEXITY_KEYWORDS = [
49
+ "what is", "who is", "define", "simple", "quick",
50
+ "brief", "summary", "list", "count", "yes or no",
51
+ "translate", "convert", "calculate", "single word"
52
+ ];
53
+
54
+ export class ContextStratifier {
55
+ private config: ContextStratifierConfig;
56
+
57
+ constructor(config: Partial<ContextStratifierConfig> = {}) {
58
+ this.config = {
59
+ levels: {
60
+ LOW: {
61
+ maxTokens: config?.levels?.LOW?.maxTokens ?? 512,
62
+ includeHistory: config?.levels?.LOW?.includeHistory ?? false,
63
+ maxHistoryMessages: config?.levels?.LOW?.maxHistoryMessages ?? 0,
64
+ },
65
+ MEDIUM: {
66
+ maxTokens: config?.levels?.MEDIUM?.maxTokens ?? 2048,
67
+ includeHistory: config?.levels?.MEDIUM?.includeHistory ?? true,
68
+ maxHistoryMessages: config?.levels?.MEDIUM?.maxHistoryMessages ?? 3,
69
+ },
70
+ HIGH: {
71
+ maxTokens: config?.levels?.HIGH?.maxTokens ?? 8192,
72
+ includeHistory: config?.levels?.HIGH?.includeHistory ?? true,
73
+ maxHistoryMessages: config?.levels?.HIGH?.maxHistoryMessages ?? 10,
74
+ },
75
+ },
76
+ autoClassify: config.autoClassify ?? true,
77
+ };
78
+ }
79
+
80
+ /**
81
+ * Classify query complexity and return appropriate context level
82
+ */
83
+ classify(query: string, history?: Array<{ role: string; content: string }>): StratificationResult {
84
+ const queryLower = query.toLowerCase();
85
+ const queryLength = query.split(/\s+/).length;
86
+
87
+ // Check keyword indicators
88
+ const highScore = HIGH_COMPLEXITY_KEYWORDS.filter(kw => queryLower.includes(kw)).length;
89
+ const lowScore = LOW_COMPLEXITY_KEYWORDS.filter(kw => queryLower.includes(kw)).length;
90
+
91
+ let level: ContextLevel;
92
+
93
+ // Decision logic
94
+ if (queryLength < 10 || lowScore > highScore) {
95
+ level = "LOW";
96
+ } else if (queryLength > 50 || highScore > lowScore) {
97
+ level = "HIGH";
98
+ } else {
99
+ level = "MEDIUM";
100
+ }
101
+
102
+ const levelConfig = this.config.levels[level];
103
+
104
+ return {
105
+ level,
106
+ maxTokens: levelConfig.maxTokens,
107
+ includeHistory: levelConfig.includeHistory,
108
+ maxHistoryMessages: levelConfig.maxHistoryMessages,
109
+ reasoning: `Query classified as ${level} (length: ${queryLength}, high_kw: ${highScore}, low_kw: ${lowScore})`,
110
+ };
111
+ }
112
+
113
+ /**
114
+ * Stratify history based on context level
115
+ */
116
+ stratifyHistory(
117
+ history: Array<{ role: string; content: string }>,
118
+ level: ContextLevel
119
+ ): Array<{ role: string; content: string }> {
120
+ const levelConfig = this.config.levels[level];
121
+
122
+ if (!levelConfig.includeHistory) {
123
+ return [];
124
+ }
125
+
126
+ // Take most recent messages
127
+ return history.slice(-levelConfig.maxHistoryMessages);
128
+ }
129
+
130
+ /**
131
+ * Truncate content to fit within level's token budget
132
+ */
133
+ truncateToLevel(content: string, level: ContextLevel): string {
134
+ const maxTokens = this.config.levels[level].maxTokens;
135
+ // Rough estimate: ~4 chars per token
136
+ const maxChars = maxTokens * 4;
137
+
138
+ if (content.length <= maxChars) {
139
+ return content;
140
+ }
141
+
142
+ return content.substring(0, maxChars - 3) + "...";
143
+ }
144
+
145
+ /**
146
+ * Get configuration for a level
147
+ */
148
+ getLevelConfig(level: ContextLevel): ContextLevelConfig {
149
+ return this.config.levels[level];
150
+ }
151
+
152
+ /**
153
+ * Update level configuration
154
+ */
155
+ setLevelConfig(level: ContextLevel, config: Partial<ContextLevelConfig>): void {
156
+ this.config.levels[level] = {
157
+ ...this.config.levels[level],
158
+ ...config,
159
+ };
160
+ }
161
+ }
162
+
163
+ export default ContextStratifier;
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Fetch-Once/Process-Locally - Token Optimization Pattern #5
3
+ *
4
+ * Fetch data once with expensive model, then process locally with cheap model.
5
+ * Reduces API calls by extracting only needed info from fetched content.
6
+ *
7
+ * Based on: arXiv:2608.17188 - Token Optimization and Context Window Management
8
+ */
9
+
10
+ export interface FetchOnceConfig {
11
+ expensiveModel?: string;
12
+ cheapModel?: string;
13
+ extractionPrompt?: string;
14
+ }
15
+
16
+ export interface FetchOnceResult {
17
+ extractedData: string;
18
+ fullFetched: boolean;
19
+ tokensSaved: number;
20
+ costSaved: number;
21
+ }
22
+
23
+ /**
24
+ * Simulated content fetcher (replace with actual HTTP client)
25
+ */
26
+ async function fetchContent(url: string): Promise<string> {
27
+ // In production, use: fetch, axios, or similar
28
+ // This is a placeholder
29
+ // console.log(`[FetchOnce] Fetching: ${url}`);
30
+ return `[Content from ${url}]...`;
31
+ }
32
+
33
+ /**
34
+ * Extract specific data from content using cheap model
35
+ */
36
+ async function extractWithCheapModel(
37
+ content: string,
38
+ task: string,
39
+ cheapModel: string
40
+ ): Promise<string> {
41
+ // In production, call cheap LLM here
42
+ // console.log(`[FetchOnce] Extracting "${task}" using ${cheapModel}`);
43
+ return `[Extracted ${task} from content]`;
44
+ }
45
+
46
+ export class FetchOnceProcessor {
47
+ private config: FetchOnceConfig;
48
+
49
+ constructor(config: Partial<FetchOnceConfig> = {}) {
50
+ this.config = {
51
+ expensiveModel: config.expensiveModel ?? "gpt-4o",
52
+ cheapModel: config.cheapModel ?? "gpt-4o-mini",
53
+ extractionPrompt: config.extractionPrompt ?? `Extract only the following from the content: {task}. Be concise.`,
54
+ };
55
+ }
56
+
57
+ /**
58
+ * Fetch URL content once, then extract needed data locally
59
+ */
60
+ async process(
61
+ url: string,
62
+ task: string,
63
+ options: {
64
+ fullContent?: boolean;
65
+ expensiveModel?: string;
66
+ cheapModel?: string;
67
+ } = {}
68
+ ): Promise<FetchOnceResult> {
69
+ const expensiveModel = options.expensiveModel ?? this.config.expensiveModel!;
70
+ const cheapModel = options.cheapModel ?? this.config.cheapModel!;
71
+
72
+ // Step 1: Fetch content (one expensive call)
73
+ const fullContent = await fetchContent(url);
74
+ const fullTokens = Math.ceil(fullContent.length / 4);
75
+ const fullCost = this.estimateCost(fullTokens, expensiveModel);
76
+
77
+ // If full content requested, return it
78
+ if (options.fullContent) {
79
+ return {
80
+ extractedData: fullContent,
81
+ fullFetched: true,
82
+ tokensSaved: 0,
83
+ costSaved: 0,
84
+ };
85
+ }
86
+
87
+ // Step 2: Extract only needed data (cheap call)
88
+ const extracted = await extractWithCheapModel(fullContent, task, cheapModel);
89
+ const extractedTokens = Math.ceil(extracted.length / 4);
90
+ const extractedCost = this.estimateCost(extractedTokens, cheapModel);
91
+
92
+ // Calculate savings
93
+ const cheapFullCost = this.estimateCost(fullTokens, cheapModel);
94
+ const tokensSaved = fullTokens - extractedTokens;
95
+ const costSaved = cheapFullCost - extractedCost;
96
+
97
+ return {
98
+ extractedData: extracted,
99
+ fullFetched: false,
100
+ tokensSaved,
101
+ costSaved,
102
+ };
103
+ }
104
+
105
+ /**
106
+ * Batch process multiple URLs for same extraction task
107
+ */
108
+ async processBatch(
109
+ urls: string[],
110
+ task: string,
111
+ options: {
112
+ expensiveModel?: string;
113
+ cheapModel?: string;
114
+ } = {}
115
+ ): Promise<FetchOnceResult[]> {
116
+ return Promise.all(
117
+ urls.map(url => this.process(url, task, options))
118
+ );
119
+ }
120
+
121
+ /**
122
+ * Estimate cost (simplified)
123
+ */
124
+ private estimateCost(tokens: number, model: string): number {
125
+ const costsPerMillion: Record<string, number> = {
126
+ "gpt-4o": 2.50,
127
+ "gpt-4o-mini": 0.15,
128
+ "claude-opus": 15.00,
129
+ "claude-haiku": 0.25,
130
+ };
131
+ const costPerMillion = costsPerMillion[model] ?? 1.0;
132
+ return (tokens / 1_000_000) * costPerMillion;
133
+ }
134
+ }
135
+
136
+ export default FetchOnceProcessor;