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
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Token Optimization Module - Phase 1 Implementation
3
+ *
4
+ * 6 patterns from arXiv:2608.17188 - Token Optimization and Context Window Management
5
+ *
6
+ * Patterns:
7
+ * 1. SemanticCache - Embedding-based similarity caching
8
+ * 2. ContextStratifier -分层 context levels
9
+ * 3. TokenAwareFallback - Token-count based model routing
10
+ * 4. SchemaContractor - Schema-referenced prompts
11
+ * 5. FetchOnceProcessor - Fetch once, process locally
12
+ * 6. InterAgentCompressor - Message compression
13
+ */
14
+
15
+ export { SemanticCache, SemanticCacheConfig, SemanticCacheEntry } from "./semanticCache";
16
+ export { ContextStratifier, ContextLevel, ContextStratifierConfig, StratificationResult } from "./contextStratifier";
17
+ export { TokenAwareFallback, TokenAwareFallbackConfig, FallbackDecision, TokenThreshold } from "./tokenAwareFallback";
18
+ export { SchemaContractor, SchemaContractConfig, SchemaInfo } from "./schemaContract";
19
+ export { FetchOnceProcessor, FetchOnceConfig, FetchOnceResult } from "./fetchOnceLocal";
20
+ export { InterAgentCompressor, Message, CompressionConfig, CompressionResult } from "./interAgentCompression";
21
+
22
+ /**
23
+ * Create a fully configured TokenOptimizer with all patterns
24
+ */
25
+ import { SemanticCache } from "./semanticCache";
26
+ import { ContextStratifier } from "./contextStratifier";
27
+ import { TokenAwareFallback } from "./tokenAwareFallback";
28
+ import { SchemaContractor } from "./schemaContract";
29
+ import { FetchOnceProcessor } from "./fetchOnceLocal";
30
+ import { InterAgentCompressor } from "./interAgentCompression";
31
+
32
+ export interface TokenOptimizerConfig {
33
+ semanticCache?: boolean;
34
+ contextStratification?: boolean;
35
+ tokenAwareFallback?: boolean;
36
+ schemaContraction?: boolean;
37
+ fetchOnce?: boolean;
38
+ agentCompression?: boolean;
39
+ }
40
+
41
+ export class TokenOptimizer {
42
+ semanticCache: SemanticCache;
43
+ contextStratifier: ContextStratifier;
44
+ tokenAwareFallback: TokenAwareFallback;
45
+ schemaContractor: SchemaContractor;
46
+ fetchOnceProcessor: FetchOnceProcessor;
47
+ agentCompressor: InterAgentCompressor;
48
+
49
+ private config: TokenOptimizerConfig;
50
+
51
+ constructor(config: TokenOptimizerConfig = {}) {
52
+ this.config = config;
53
+
54
+ this.semanticCache = new SemanticCache({
55
+ enabled: config.semanticCache ?? true,
56
+ });
57
+
58
+ this.contextStratifier = new ContextStratifier();
59
+
60
+ this.tokenAwareFallback = new TokenAwareFallback();
61
+
62
+ this.schemaContractor = new SchemaContractor();
63
+
64
+ this.fetchOnceProcessor = new FetchOnceProcessor();
65
+
66
+ this.agentCompressor = new InterAgentCompressor();
67
+ }
68
+
69
+ /**
70
+ * Optimize a query before sending to LLM
71
+ */
72
+ async optimizeQuery(
73
+ query: string,
74
+ history?: Array<{ role: string; content: string }>
75
+ ): Promise<{
76
+ query: string;
77
+ history: Array<{ role: string; content: string }>;
78
+ contextLevel: string;
79
+ recommendedModel: string;
80
+ cacheHit: boolean;
81
+ cachedResponse?: string;
82
+ }> {
83
+ // 1. Check semantic cache
84
+ const cacheResult = await this.semanticCache.get(query);
85
+ if (cacheResult) {
86
+ return {
87
+ query,
88
+ history: [],
89
+ contextLevel: "CACHED",
90
+ recommendedModel: "cached",
91
+ cacheHit: true,
92
+ cachedResponse: cacheResult.response,
93
+ };
94
+ }
95
+
96
+ // 2. Classify context level
97
+ const stratification = this.contextStratifier.classify(query, history);
98
+
99
+ // 3. Get token-aware model recommendation
100
+ const totalTokens = this.tokenAwareFallback.estimateTotalTokens(query, history);
101
+ const modelDecision = this.tokenAwareFallback.selectModel(totalTokens);
102
+
103
+ // 4. Stratify history
104
+ const stratifiedHistory = this.contextStratifier.stratifyHistory(
105
+ history as Array<{ role: string; content: string }>,
106
+ stratification.level
107
+ );
108
+
109
+ return {
110
+ query,
111
+ history: stratifiedHistory,
112
+ contextLevel: stratification.level,
113
+ recommendedModel: modelDecision.targetModel,
114
+ cacheHit: false,
115
+ };
116
+ }
117
+
118
+ /**
119
+ * Record a query-response pair in cache
120
+ */
121
+ async recordResponse(
122
+ query: string,
123
+ response: string,
124
+ options: {
125
+ model?: string;
126
+ tokens?: number;
127
+ cost?: number;
128
+ } = {}
129
+ ): Promise<void> {
130
+ await this.semanticCache.set(query, response, {
131
+ model: options.model,
132
+ tokensSaved: options.tokens,
133
+ costSaved: options.cost,
134
+ });
135
+ }
136
+
137
+ /**
138
+ * Get optimization statistics
139
+ */
140
+ getStats() {
141
+ return {
142
+ semanticCache: this.semanticCache.getStats(),
143
+ tokenAwareFallback: {
144
+ thresholds: this.tokenAwareFallback.getThresholds(),
145
+ },
146
+ };
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Helper to estimate token savings across all patterns
152
+ */
153
+ export function estimateTotalSavings(
154
+ patterns: ("semantic" | "context" | "fallback" | "schema" | "fetchOnce" | "compression")[],
155
+ queryTokens: number,
156
+ responseTokens: number
157
+ ): {
158
+ tokensSaved: number;
159
+ percentReduction: string;
160
+ patterns: string[];
161
+ } {
162
+ let totalTokens = queryTokens + responseTokens;
163
+ let saved = 0;
164
+ const appliedPatterns: string[] = [];
165
+
166
+ if (patterns.includes("semantic")) {
167
+ // ~20% cache hit rate after warmup
168
+ saved += totalTokens * 0.2;
169
+ appliedPatterns.push("Semantic Caching (-20%)");
170
+ }
171
+
172
+ if (patterns.includes("context")) {
173
+ // ~30% reduction from context stratification
174
+ saved += totalTokens * 0.3;
175
+ appliedPatterns.push("Context Stratification (-30%)");
176
+ }
177
+
178
+ if (patterns.includes("fallback")) {
179
+ // ~40% savings from cheap model routing
180
+ saved += totalTokens * 0.4;
181
+ appliedPatterns.push("Token-Aware Fallback (-40%)");
182
+ }
183
+
184
+ if (patterns.includes("compression")) {
185
+ // ~15% from message compression
186
+ saved += totalTokens * 0.15;
187
+ appliedPatterns.push("Inter-Agent Compression (-15%)");
188
+ }
189
+
190
+ const percentReduction = totalTokens > 0 ? ((saved / totalTokens) * 100).toFixed(1) : "0%";
191
+
192
+ return {
193
+ tokensSaved: Math.round(saved),
194
+ percentReduction: percentReduction + "%",
195
+ patterns: appliedPatterns,
196
+ };
197
+ }
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Inter-Agent Communication Compression - Token Optimization Pattern #6
3
+ *
4
+ * Compress messages between agents to reduce token usage.
5
+ * Uses summarization for long messages, preserves key info for short ones.
6
+ *
7
+ * Based on: arXiv:2608.17188 - Token Optimization and Context Window Management
8
+ */
9
+
10
+ export interface Message {
11
+ role: "user" | "assistant" | "system" | "tool";
12
+ content: string;
13
+ metadata?: Record<string, unknown>;
14
+ }
15
+
16
+ export interface CompressionConfig {
17
+ maxMessageLength: number;
18
+ summarizeThreshold: number;
19
+ preserveKeywords: string[];
20
+ summaryModel?: string;
21
+ }
22
+
23
+ export interface CompressionResult {
24
+ messages: Message[];
25
+ originalTokens: number;
26
+ compressedTokens: number;
27
+ compressionRatio: number;
28
+ }
29
+
30
+ /**
31
+ * Keywords that should be preserved in compression
32
+ */
33
+ const PRESERVE_KEYWORDS = [
34
+ "error", "warning", "fail", "success", "api", "url",
35
+ "id", "token", "key", "config", "path", "file",
36
+ "function", "class", "method", "variable", "import",
37
+ "json", "xml", "html", "css", "sql"
38
+ ];
39
+
40
+ /**
41
+ * Simple summarizer (in production, use actual LLM)
42
+ */
43
+ function simpleSummarize(text: string, maxLength: number): string {
44
+ if (text.length <= maxLength) return text;
45
+
46
+ // Truncate and add indicator
47
+ const summary = text.substring(0, maxLength - 20);
48
+ return summary + "... [truncated]";
49
+ }
50
+
51
+ export class InterAgentCompressor {
52
+ private config: CompressionConfig;
53
+
54
+ constructor(config: Partial<CompressionConfig> = {}) {
55
+ this.config = {
56
+ maxMessageLength: config.maxMessageLength ?? 500,
57
+ summarizeThreshold: config.summarizeThreshold ?? 300,
58
+ preserveKeywords: config.preserveKeywords ?? PRESERVE_KEYWORDS,
59
+ summaryModel: config.summaryModel ?? "gpt-4o-mini",
60
+ };
61
+ }
62
+
63
+ /**
64
+ * Estimate tokens in text (rough)
65
+ */
66
+ private estimateTokens(text: string): number {
67
+ return Math.ceil(text.length / 4);
68
+ }
69
+
70
+ /**
71
+ * Check if text contains preserved keywords
72
+ */
73
+ private containsPreservedKeyword(text: string): boolean {
74
+ const lower = text.toLowerCase();
75
+ return this.config.preserveKeywords.some(kw => lower.includes(kw));
76
+ }
77
+
78
+ /**
79
+ * Compress a single message
80
+ */
81
+ compressMessage(message: Message): Message {
82
+ const content = message.content ?? "";
83
+ const tokens = this.estimateTokens(content);
84
+
85
+ // If below threshold, no compression needed
86
+ if (tokens <= this.config.summarizeThreshold && !this.containsPreservedKeyword(content)) {
87
+ return message;
88
+ }
89
+
90
+ // If very long, truncate
91
+ if (content.length > this.config.maxMessageLength * 2) {
92
+ return {
93
+ ...message,
94
+ content: simpleSummarize(content, this.config.maxMessageLength),
95
+ };
96
+ }
97
+
98
+ // Otherwise, truncate to threshold
99
+ return {
100
+ ...message,
101
+ content: simpleSummarize(content, this.config.maxMessageLength),
102
+ };
103
+ }
104
+
105
+ /**
106
+ * Compress array of messages
107
+ */
108
+ compress(messages: Message[]): CompressionResult {
109
+ const originalTokens = messages.reduce(
110
+ (sum, msg) => sum + this.estimateTokens(msg.content ?? ""),
111
+ 0
112
+ );
113
+
114
+ const compressed = messages.map(msg => this.compressMessage(msg));
115
+
116
+ const compressedTokens = compressed.reduce(
117
+ (sum, msg) => sum + this.estimateTokens(msg.content ?? ""),
118
+ 0
119
+ );
120
+
121
+ return {
122
+ messages: compressed,
123
+ originalTokens,
124
+ compressedTokens,
125
+ compressionRatio: originalTokens > 0 ? compressedTokens / originalTokens : 1,
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Compress messages in-place (mutates array)
131
+ */
132
+ compressInPlace(messages: Message[]): void {
133
+ for (let i = 0; i < messages.length; i++) {
134
+ messages[i] = this.compressMessage(messages[i]);
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Get compression statistics
140
+ */
141
+ getStats(result: CompressionResult): {
142
+ tokensReduced: number;
143
+ percentReduction: string;
144
+ } {
145
+ const tokensReduced = result.originalTokens - result.compressedTokens;
146
+ const percentReduction = result.originalTokens > 0
147
+ ? ((tokensReduced / result.originalTokens) * 100).toFixed(1) + "%"
148
+ : "0%";
149
+
150
+ return {
151
+ tokensReduced,
152
+ percentReduction,
153
+ };
154
+ }
155
+ }
156
+
157
+ export default InterAgentCompressor;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Schema-Contracted Prompts - Token Optimization Pattern #4
3
+ *
4
+ * Use structured schemas to reduce prompt size.
5
+ * Instead of verbose descriptions, reference schema directly.
6
+ *
7
+ * Based on: arXiv:2608.17188 - Token Optimization and Context Window Management
8
+ */
9
+
10
+ export interface SchemaContractConfig {
11
+ includeExamples: boolean;
12
+ maxSchemaSize: number;
13
+ }
14
+
15
+ export interface SchemaInfo {
16
+ name: string;
17
+ description?: string;
18
+ schema: Record<string, unknown>;
19
+ examples?: Array<Record<string, unknown>>;
20
+ }
21
+
22
+ /**
23
+ * Generate schema instruction for prompt
24
+ */
25
+ function generateSchemaInstruction(schema: SchemaInfo): string {
26
+ const parts: string[] = [];
27
+
28
+ parts.push(`Response Schema: ${schema.name}`);
29
+
30
+ if (schema.description) {
31
+ parts.push(`Description: ${schema.description}`);
32
+ }
33
+
34
+ parts.push(`Schema: ${JSON.stringify(schema.schema)}`);
35
+
36
+ if (schema.examples && schema.examples.length > 0) {
37
+ parts.push(`Examples: ${JSON.stringify(schema.examples.slice(0, 2))}`);
38
+ }
39
+
40
+ return parts.join("\n");
41
+ }
42
+
43
+ export class SchemaContractor {
44
+ private config: SchemaContractConfig;
45
+
46
+ constructor(config: Partial<SchemaContractConfig> = {}) {
47
+ this.config = {
48
+ includeExamples: config.includeExamples ?? true,
49
+ maxSchemaSize: config.maxSchemaSize ?? 500,
50
+ };
51
+ }
52
+
53
+ /**
54
+ * Contract a prompt by injecting schema reference
55
+ */
56
+ contract(prompt: string, schema: SchemaInfo): string {
57
+ const schemaInstruction = generateSchemaInstruction(schema);
58
+
59
+ return `${prompt}
60
+
61
+ IMPORTANT: Your response MUST conform to this schema:
62
+ ${schemaInstruction}
63
+
64
+ Respond ONLY with valid JSON matching the above schema.`;
65
+ }
66
+
67
+ /**
68
+ * Contract with inline schema (smaller)
69
+ */
70
+ contractInline(prompt: string, schema: SchemaInfo): string {
71
+ const schemaJson = JSON.stringify(schema.schema).substring(0, this.config.maxSchemaSize);
72
+
73
+ return `${prompt}
74
+
75
+ Response Schema: ${schema.name}
76
+ ${schemaJson}`;
77
+ }
78
+
79
+ /**
80
+ * Extract schema from Pydantic-style model definition
81
+ */
82
+ static extractSchemaFromModel(modelDef: string): SchemaInfo {
83
+ // Simple parser for TypeScript/JavaScript interface or Python Pydantic
84
+ const nameMatch = modelDef.match(/class\s+(\w+)/);
85
+ const name = nameMatch ? nameMatch[1] : "Response";
86
+
87
+ // Extract field types (simplified)
88
+ const fields: Record<string, string> = {};
89
+ const fieldMatches = modelDef.matchAll(/(\w+)(\??):\s*(\w+)/g);
90
+ for (const match of fieldMatches) {
91
+ fields[match[1]] = match[3];
92
+ }
93
+
94
+ return {
95
+ name,
96
+ schema: fields as Record<string, unknown>,
97
+ };
98
+ }
99
+ }
100
+
101
+ export default SchemaContractor;
@@ -0,0 +1,248 @@
1
+ /**
2
+ * Semantic Cache - Token Optimization Pattern #1
3
+ *
4
+ * Cache semantically similar queries instead of exact-match caching.
5
+ * Uses embedding similarity (cosine) to find cached responses.
6
+ *
7
+ * Based on: arXiv:2608.17188 - Token Optimization and Context Window Management
8
+ */
9
+
10
+ export interface SemanticCacheConfig {
11
+ enabled: boolean;
12
+ similarityThreshold: number; // 0.85 default
13
+ maxEntries: number;
14
+ embeddingModel: string; // e.g., "sentence-transformers/all-MiniLM-L6-v2"
15
+ ttlSeconds: number;
16
+ cacheDir?: string;
17
+ }
18
+
19
+ export interface SemanticCacheEntry {
20
+ query: string;
21
+ embedding: number[];
22
+ response: string;
23
+ model: string;
24
+ tokensSaved: number;
25
+ costSaved: number;
26
+ cachedAt: number;
27
+ expiresAt: number;
28
+ }
29
+
30
+ /**
31
+ * Compute cosine similarity between two embeddings
32
+ */
33
+ function cosineSimilarity(a: number[], b: number[]): number {
34
+ if (a.length !== b.length) return 0;
35
+
36
+ let dotProduct = 0;
37
+ let normA = 0;
38
+ let normB = 0;
39
+
40
+ for (let i = 0; i < a.length; i++) {
41
+ dotProduct += a[i] * b[i];
42
+ normA += a[i] * a[i];
43
+ normB += b[i] * b[i];
44
+ }
45
+
46
+ const denominator = Math.sqrt(normA) * Math.sqrt(normB);
47
+ return denominator === 0 ? 0 : dotProduct / denominator;
48
+ }
49
+
50
+ /**
51
+ * Simple embedding generator using TF-IDF style vectors
52
+ * For production, replace with actual sentence transformer embeddings
53
+ */
54
+ function simpleHash(str: string): number {
55
+ let hash = 0;
56
+ for (let i = 0; i < str.length; i++) {
57
+ hash = ((hash << 5) - hash) + str.charCodeAt(i);
58
+ hash = hash & hash;
59
+ }
60
+ return Math.abs(hash);
61
+ }
62
+
63
+ function generateEmbedding(text: string, dimensions = 384): number[] {
64
+ const words = text.toLowerCase().split(/\s+/);
65
+ const embedding: number[] = new Array(dimensions).fill(0);
66
+
67
+ // Simple hash-based embedding for demo
68
+ // In production, use: sentence-transformers or OpenAI embeddings
69
+ words.forEach((word, idx) => {
70
+ const bucket = simpleHash(word) % dimensions;
71
+ embedding[bucket] += 1 / (idx + 1); // Position weighting
72
+ });
73
+
74
+ // Normalize
75
+ const norm = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
76
+ return norm > 0 ? embedding.map(v => v / norm) : embedding;
77
+ }
78
+
79
+ export class SemanticCache {
80
+ private cache: Map<string, SemanticCacheEntry> = new Map();
81
+ private config: SemanticCacheConfig;
82
+ private hits = 0;
83
+ private misses = 0;
84
+ private embeddingCache: Map<string, number[]> = new Map();
85
+
86
+ constructor(config: Partial<SemanticCacheConfig> = {}) {
87
+ this.config = {
88
+ enabled: config.enabled ?? true,
89
+ similarityThreshold: config.similarityThreshold ?? 0.85,
90
+ maxEntries: config.maxEntries ?? 1000,
91
+ embeddingModel: config.embeddingModel ?? "local-tfidf",
92
+ ttlSeconds: config.ttlSeconds ?? 3600,
93
+ cacheDir: config.cacheDir,
94
+ };
95
+ }
96
+
97
+ /**
98
+ * Get embedding for text (with caching)
99
+ */
100
+ private async getEmbedding(text: string): Promise<number[]> {
101
+ // Check cache first
102
+ const cached = this.embeddingCache.get(text);
103
+ if (cached) return cached;
104
+
105
+ // Generate embedding
106
+ const embedding = generateEmbedding(text);
107
+ this.embeddingCache.set(text, embedding);
108
+
109
+ // Limit cache size
110
+ if (this.embeddingCache.size > this.config.maxEntries * 2) {
111
+ const keys = Array.from(this.embeddingCache.keys());
112
+ keys.slice(0, keys.length - this.config.maxEntries).forEach(k => {
113
+ this.embeddingCache.delete(k);
114
+ });
115
+ }
116
+
117
+ return embedding;
118
+ }
119
+
120
+ /**
121
+ * Generate cache key from query
122
+ */
123
+ private generateKey(query: string): string {
124
+ // Simple hash function instead of crypto
125
+ const hash = simpleHash(query.toLowerCase().trim());
126
+ return hash.toString(16).padStart(8, '0') + simpleHash(query).toString(16).padStart(8, '0');
127
+ }
128
+
129
+ /**
130
+ * Find best matching cached entry using cosine similarity
131
+ */
132
+ async get(query: string): Promise<{ response: string; similarity: number; tokensSaved: number; costSaved: number } | null> {
133
+ if (!this.config.enabled) return null;
134
+
135
+ const queryEmbedding = await this.getEmbedding(query);
136
+ let bestMatch: { key: string; similarity: number } | null = null;
137
+
138
+ // Search for most similar cached entry
139
+ for (const [key, entry] of this.cache.entries()) {
140
+ // Check expiration
141
+ if (Date.now() > entry.expiresAt) {
142
+ this.cache.delete(key);
143
+ continue;
144
+ }
145
+
146
+ const similarity = cosineSimilarity(queryEmbedding, entry.embedding);
147
+ if (similarity >= this.config.similarityThreshold) {
148
+ if (!bestMatch || similarity > bestMatch.similarity) {
149
+ bestMatch = { key, similarity };
150
+ }
151
+ }
152
+ }
153
+
154
+ if (!bestMatch) {
155
+ this.misses++;
156
+ return null;
157
+ }
158
+
159
+ const entry = this.cache.get(bestMatch.key)!;
160
+ this.hits++;
161
+
162
+ return {
163
+ response: entry.response,
164
+ similarity: bestMatch.similarity,
165
+ tokensSaved: entry.tokensSaved,
166
+ costSaved: entry.costSaved,
167
+ };
168
+ }
169
+
170
+ /**
171
+ * Store query-response pair in semantic cache
172
+ */
173
+ async set(
174
+ query: string,
175
+ response: string,
176
+ options: {
177
+ model?: string;
178
+ tokensSaved?: number;
179
+ costSaved?: number;
180
+ } = {}
181
+ ): Promise<void> {
182
+ if (!this.config.enabled) return;
183
+
184
+ const embedding = await this.getEmbedding(query);
185
+ const now = Date.now();
186
+ const key = this.generateKey(query);
187
+
188
+ // Evict oldest if at capacity
189
+ if (this.cache.size >= this.config.maxEntries) {
190
+ this.evictOldest();
191
+ }
192
+
193
+ this.cache.set(key, {
194
+ query,
195
+ embedding,
196
+ response,
197
+ model: options.model ?? "unknown",
198
+ tokensSaved: options.tokensSaved ?? 0,
199
+ costSaved: options.costSaved ?? 0,
200
+ cachedAt: now,
201
+ expiresAt: now + this.config.ttlSeconds * 1000,
202
+ });
203
+ }
204
+
205
+ /**
206
+ * Evict oldest entry
207
+ */
208
+ private evictOldest(): void {
209
+ let oldestKey: string | null = null;
210
+ let oldestTime = Infinity;
211
+
212
+ for (const [key, entry] of this.cache.entries()) {
213
+ if (entry.cachedAt < oldestTime) {
214
+ oldestTime = entry.cachedAt;
215
+ oldestKey = key;
216
+ }
217
+ }
218
+
219
+ if (oldestKey) {
220
+ this.cache.delete(oldestKey);
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Get cache statistics
226
+ */
227
+ getStats(): { hits: number; misses: number; size: number; hitRate: number } {
228
+ const total = this.hits + this.misses;
229
+ return {
230
+ hits: this.hits,
231
+ misses: this.misses,
232
+ size: this.cache.size,
233
+ hitRate: total > 0 ? this.hits / total : 0,
234
+ };
235
+ }
236
+
237
+ /**
238
+ * Clear cache
239
+ */
240
+ clear(): void {
241
+ this.cache.clear();
242
+ this.embeddingCache.clear();
243
+ this.hits = 0;
244
+ this.misses = 0;
245
+ }
246
+ }
247
+
248
+ export default SemanticCache;