adaptive-memory-multi-model-router 1.2.2 → 1.3.1

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 (195) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +146 -66
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/integrations/airtable.js +20 -0
  6. package/dist/integrations/discord.js +18 -0
  7. package/dist/integrations/github.js +23 -0
  8. package/dist/integrations/gmail.js +19 -0
  9. package/dist/integrations/google-calendar.js +18 -0
  10. package/dist/integrations/index.js +61 -0
  11. package/dist/integrations/jira.js +21 -0
  12. package/dist/integrations/linear.js +19 -0
  13. package/dist/integrations/notion.js +19 -0
  14. package/dist/integrations/slack.js +18 -0
  15. package/dist/integrations/telegram.js +19 -0
  16. package/dist/providers/registry.js +7 -3
  17. package/docs/ARCHITECTURAL-IMPROVEMENTS-2025.md +1391 -0
  18. package/docs/ARCHITECTURAL-IMPROVEMENTS-REVISED-2025.md +1051 -0
  19. package/docs/CONFIGURATION.md +476 -0
  20. package/docs/COUNCIL_DECISION.json +308 -0
  21. package/docs/COUNCIL_SUMMARY.md +265 -0
  22. package/docs/COUNCIL_V2.2_DECISION.md +416 -0
  23. package/docs/IMPROVEMENT_ROADMAP.md +515 -0
  24. package/docs/LLM_COUNCIL_DECISION.md +508 -0
  25. package/docs/QUICK_START_VISIBILITY.md +782 -0
  26. package/docs/REDDIT_GAP_ANALYSIS.md +299 -0
  27. package/docs/RESEARCH_BACKED_IMPROVEMENTS.md +1180 -0
  28. package/docs/TMLPD_QNA.md +751 -0
  29. package/docs/TMLPD_V2.1_COMPLETE.md +763 -0
  30. package/docs/TMLPD_V2.2_RESEARCH_ROADMAP.md +754 -0
  31. package/docs/V2.2_IMPLEMENTATION_COMPLETE.md +446 -0
  32. package/docs/V2_IMPLEMENTATION_GUIDE.md +388 -0
  33. package/docs/VISIBILITY_ADOPTION_PLAN.md +1005 -0
  34. package/docs/launch-content/LAUNCH_EXECUTION_CHECKLIST.md +421 -0
  35. package/docs/launch-content/README.md +457 -0
  36. package/docs/launch-content/assets/cost_comparison_100_tasks.png +0 -0
  37. package/docs/launch-content/assets/cumulative_savings.png +0 -0
  38. package/docs/launch-content/assets/parallel_speedup.png +0 -0
  39. package/docs/launch-content/assets/provider_pricing_comparison.png +0 -0
  40. package/docs/launch-content/assets/task_breakdown_comparison.png +0 -0
  41. package/docs/launch-content/generate_charts.py +313 -0
  42. package/docs/launch-content/hn_show_post.md +139 -0
  43. package/docs/launch-content/partner_outreach_templates.md +745 -0
  44. package/docs/launch-content/reddit_posts.md +467 -0
  45. package/docs/launch-content/twitter_thread.txt +460 -0
  46. package/examples/QUICKSTART.md +1 -1
  47. package/openclaw-alexa-bridge/ALL_REMAINING_FIXES_PLAN.md +313 -0
  48. package/openclaw-alexa-bridge/REMAINING_FIXES_SUMMARY.md +277 -0
  49. package/openclaw-alexa-bridge/src/alexa_handler_no_tmlpd.js +1234 -0
  50. package/openclaw-alexa-bridge/test_fixes.js +77 -0
  51. package/package.json +120 -29
  52. package/package.json.tmp +0 -0
  53. package/qna/TMLPD_QNA.md +3 -3
  54. package/skill/SKILL.md +2 -2
  55. package/src/__tests__/integration/tmpld_integration.test.py +540 -0
  56. package/src/agents/skill_enhanced_agent.py +318 -0
  57. package/src/memory/__init__.py +15 -0
  58. package/src/memory/agentic_memory.py +353 -0
  59. package/src/memory/semantic_memory.py +444 -0
  60. package/src/memory/simple_memory.py +466 -0
  61. package/src/memory/working_memory.py +447 -0
  62. package/src/orchestration/__init__.py +52 -0
  63. package/src/orchestration/execution_engine.py +353 -0
  64. package/src/orchestration/halo_orchestrator.py +367 -0
  65. package/src/orchestration/mcts_workflow.py +498 -0
  66. package/src/orchestration/role_assigner.py +473 -0
  67. package/src/orchestration/task_planner.py +522 -0
  68. package/src/providers/__init__.py +67 -0
  69. package/src/providers/anthropic.py +304 -0
  70. package/src/providers/base.py +241 -0
  71. package/src/providers/cerebras.py +373 -0
  72. package/src/providers/registry.py +476 -0
  73. package/src/routing/__init__.py +30 -0
  74. package/src/routing/universal_router.py +621 -0
  75. package/src/skills/TMLPD-QUICKREF.md +210 -0
  76. package/src/skills/TMLPD-SETUP-SUMMARY.md +157 -0
  77. package/src/skills/TMLPD.md +540 -0
  78. package/src/skills/__tests__/skill_manager.test.ts +328 -0
  79. package/src/skills/skill_manager.py +385 -0
  80. package/src/skills/test-tmlpd.sh +108 -0
  81. package/src/skills/tmlpd-category.yaml +67 -0
  82. package/src/skills/tmlpd-monitoring.yaml +188 -0
  83. package/src/skills/tmlpd-phase.yaml +132 -0
  84. package/src/state/__init__.py +17 -0
  85. package/src/state/simple_checkpoint.py +508 -0
  86. package/src/tmlpd_agent.py +464 -0
  87. package/src/tmpld_v2.py +427 -0
  88. package/src/workflows/__init__.py +18 -0
  89. package/src/workflows/advanced_difficulty_classifier.py +377 -0
  90. package/src/workflows/chaining_executor.py +417 -0
  91. package/src/workflows/difficulty_integration.py +209 -0
  92. package/src/workflows/orchestrator.py +469 -0
  93. package/src/workflows/orchestrator_executor.py +456 -0
  94. package/src/workflows/parallelization_executor.py +382 -0
  95. package/src/workflows/router.py +311 -0
  96. package/test_integration_simple.py +86 -0
  97. package/test_mcts_workflow.py +150 -0
  98. package/test_templd_integration.py +262 -0
  99. package/test_universal_router.py +275 -0
  100. package/tmlpd-pi-extension/README.md +36 -0
  101. package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts +114 -0
  102. package/tmlpd-pi-extension/dist/cache/prefixCache.d.ts.map +1 -0
  103. package/tmlpd-pi-extension/dist/cache/prefixCache.js +285 -0
  104. package/tmlpd-pi-extension/dist/cache/prefixCache.js.map +1 -0
  105. package/tmlpd-pi-extension/dist/cache/responseCache.d.ts +58 -0
  106. package/tmlpd-pi-extension/dist/cache/responseCache.d.ts.map +1 -0
  107. package/tmlpd-pi-extension/dist/cache/responseCache.js +153 -0
  108. package/tmlpd-pi-extension/dist/cache/responseCache.js.map +1 -0
  109. package/tmlpd-pi-extension/dist/cli.js +59 -0
  110. package/tmlpd-pi-extension/dist/cost/costTracker.d.ts +95 -0
  111. package/tmlpd-pi-extension/dist/cost/costTracker.d.ts.map +1 -0
  112. package/tmlpd-pi-extension/dist/cost/costTracker.js +240 -0
  113. package/tmlpd-pi-extension/dist/cost/costTracker.js.map +1 -0
  114. package/tmlpd-pi-extension/dist/index.d.ts +723 -0
  115. package/tmlpd-pi-extension/dist/index.d.ts.map +1 -0
  116. package/tmlpd-pi-extension/dist/index.js +239 -0
  117. package/tmlpd-pi-extension/dist/index.js.map +1 -0
  118. package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts +82 -0
  119. package/tmlpd-pi-extension/dist/memory/episodicMemory.d.ts.map +1 -0
  120. package/tmlpd-pi-extension/dist/memory/episodicMemory.js +145 -0
  121. package/tmlpd-pi-extension/dist/memory/episodicMemory.js.map +1 -0
  122. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts +102 -0
  123. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.d.ts.map +1 -0
  124. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js +207 -0
  125. package/tmlpd-pi-extension/dist/orchestration/haloOrchestrator.js.map +1 -0
  126. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts +85 -0
  127. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.d.ts.map +1 -0
  128. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js +210 -0
  129. package/tmlpd-pi-extension/dist/orchestration/mctsWorkflow.js.map +1 -0
  130. package/tmlpd-pi-extension/dist/providers/localProvider.d.ts +102 -0
  131. package/tmlpd-pi-extension/dist/providers/localProvider.d.ts.map +1 -0
  132. package/tmlpd-pi-extension/dist/providers/localProvider.js +338 -0
  133. package/tmlpd-pi-extension/dist/providers/localProvider.js.map +1 -0
  134. package/tmlpd-pi-extension/dist/providers/registry.d.ts +55 -0
  135. package/tmlpd-pi-extension/dist/providers/registry.d.ts.map +1 -0
  136. package/tmlpd-pi-extension/dist/providers/registry.js +138 -0
  137. package/tmlpd-pi-extension/dist/providers/registry.js.map +1 -0
  138. package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts +68 -0
  139. package/tmlpd-pi-extension/dist/routing/advancedRouter.d.ts.map +1 -0
  140. package/tmlpd-pi-extension/dist/routing/advancedRouter.js +332 -0
  141. package/tmlpd-pi-extension/dist/routing/advancedRouter.js.map +1 -0
  142. package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts +101 -0
  143. package/tmlpd-pi-extension/dist/tools/tmlpdTools.d.ts.map +1 -0
  144. package/tmlpd-pi-extension/dist/tools/tmlpdTools.js +368 -0
  145. package/tmlpd-pi-extension/dist/tools/tmlpdTools.js.map +1 -0
  146. package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts +96 -0
  147. package/tmlpd-pi-extension/dist/utils/batchProcessor.d.ts.map +1 -0
  148. package/tmlpd-pi-extension/dist/utils/batchProcessor.js +170 -0
  149. package/tmlpd-pi-extension/dist/utils/batchProcessor.js.map +1 -0
  150. package/tmlpd-pi-extension/dist/utils/compression.d.ts +61 -0
  151. package/tmlpd-pi-extension/dist/utils/compression.d.ts.map +1 -0
  152. package/tmlpd-pi-extension/dist/utils/compression.js +281 -0
  153. package/tmlpd-pi-extension/dist/utils/compression.js.map +1 -0
  154. package/tmlpd-pi-extension/dist/utils/reliability.d.ts +74 -0
  155. package/tmlpd-pi-extension/dist/utils/reliability.d.ts.map +1 -0
  156. package/tmlpd-pi-extension/dist/utils/reliability.js +177 -0
  157. package/tmlpd-pi-extension/dist/utils/reliability.js.map +1 -0
  158. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts +117 -0
  159. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.d.ts.map +1 -0
  160. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js +246 -0
  161. package/tmlpd-pi-extension/dist/utils/speculativeDecoding.js.map +1 -0
  162. package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts +50 -0
  163. package/tmlpd-pi-extension/dist/utils/tokenUtils.d.ts.map +1 -0
  164. package/tmlpd-pi-extension/dist/utils/tokenUtils.js +124 -0
  165. package/tmlpd-pi-extension/dist/utils/tokenUtils.js.map +1 -0
  166. package/tmlpd-pi-extension/examples/QUICKSTART.md +183 -0
  167. package/tmlpd-pi-extension/package-lock.json +75 -0
  168. package/tmlpd-pi-extension/package.json +172 -0
  169. package/tmlpd-pi-extension/python/examples.py +53 -0
  170. package/tmlpd-pi-extension/python/integrations.py +330 -0
  171. package/tmlpd-pi-extension/python/setup.py +28 -0
  172. package/tmlpd-pi-extension/python/tmlpd.py +369 -0
  173. package/tmlpd-pi-extension/qna/REDDIT_GAP_ANALYSIS.md +299 -0
  174. package/tmlpd-pi-extension/qna/TMLPD_QNA.md +751 -0
  175. package/tmlpd-pi-extension/skill/SKILL.md +238 -0
  176. package/{src → tmlpd-pi-extension/src}/index.ts +1 -1
  177. package/tmlpd-pi-extension/tsconfig.json +18 -0
  178. package/demo/research-demo.js +0 -266
  179. package/notebooks/quickstart.ipynb +0 -157
  180. package/rust/tmlpd.h +0 -268
  181. package/src/cache/prefixCache.ts +0 -365
  182. package/src/routing/advancedRouter.ts +0 -406
  183. package/src/utils/speculativeDecoding.ts +0 -344
  184. /package/{src → tmlpd-pi-extension/src}/cache/responseCache.ts +0 -0
  185. /package/{src → tmlpd-pi-extension/src}/cost/costTracker.ts +0 -0
  186. /package/{src → tmlpd-pi-extension/src}/memory/episodicMemory.ts +0 -0
  187. /package/{src → tmlpd-pi-extension/src}/orchestration/haloOrchestrator.ts +0 -0
  188. /package/{src → tmlpd-pi-extension/src}/orchestration/mctsWorkflow.ts +0 -0
  189. /package/{src → tmlpd-pi-extension/src}/providers/localProvider.ts +0 -0
  190. /package/{src → tmlpd-pi-extension/src}/providers/registry.ts +0 -0
  191. /package/{src → tmlpd-pi-extension/src}/tools/tmlpdTools.ts +0 -0
  192. /package/{src → tmlpd-pi-extension/src}/utils/batchProcessor.ts +0 -0
  193. /package/{src → tmlpd-pi-extension/src}/utils/compression.ts +0 -0
  194. /package/{src → tmlpd-pi-extension/src}/utils/reliability.ts +0 -0
  195. /package/{src → tmlpd-pi-extension/src}/utils/tokenUtils.ts +0 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * TMLPD Context Compression Utilities
3
+ *
4
+ * Strategies for reducing context window usage:
5
+ * - Smart truncation
6
+ * - Message summarization
7
+ * - ISON-style encoding (inspired by Reddit ISON format)
8
+ * - Context window management
9
+ */
10
+ export interface Message {
11
+ role: "system" | "user" | "assistant";
12
+ content: string;
13
+ name?: string;
14
+ tool_calls?: any[];
15
+ tool_call_id?: string;
16
+ }
17
+ export type CompressionStrategy = "smart" | "first" | "last" | "isentropy";
18
+ export interface CompressionResult {
19
+ original_tokens: number;
20
+ compressed_tokens: number;
21
+ ratio: number;
22
+ compressed_text: string;
23
+ }
24
+ /**
25
+ * ISON encode text for token reduction.
26
+ */
27
+ export declare function isonEncode(text: string): string;
28
+ /**
29
+ * Decode ISON encoded text.
30
+ */
31
+ export declare function isonDecode(text: string): string;
32
+ /**
33
+ * Compress text using ISON encoding.
34
+ */
35
+ export declare function compressText(text: string): CompressionResult;
36
+ /**
37
+ * Truncate messages to fit within token budget.
38
+ *
39
+ * @param messages - Conversation messages
40
+ * @param max_tokens - Maximum tokens allowed
41
+ * @param strategy - "smart" (preserve system + recent), "first" (keep start), "last" (keep end)
42
+ */
43
+ export declare function truncateMessages(messages: Message[], max_tokens: number, strategy?: CompressionStrategy): Message[];
44
+ /**
45
+ * Truncate a single string to fit within token budget.
46
+ */
47
+ export declare function truncateToTokenBudget(text: string, max_tokens: number): string;
48
+ /**
49
+ * Calculate compression ratio for context.
50
+ */
51
+ export declare function calculateCompressionRatio(messages: Message[], max_tokens: number): number;
52
+ declare const _default: {
53
+ isonEncode: typeof isonEncode;
54
+ isonDecode: typeof isonDecode;
55
+ compressText: typeof compressText;
56
+ truncateMessages: typeof truncateMessages;
57
+ truncateToTokenBudget: typeof truncateToTokenBudget;
58
+ calculateCompressionRatio: typeof calculateCompressionRatio;
59
+ };
60
+ export default _default;
61
+ //# sourceMappingURL=compression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../../src/utils/compression.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,WAAW,CAAC;AAuE3E,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY/C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAW5D;AAUD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,OAAO,EAAE,EACnB,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,mBAA6B,GACtC,OAAO,EAAE,CAiHX;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAuB9E;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAOzF;;;;;;;;;AAED,wBAOE"}
@@ -0,0 +1,281 @@
1
+ "use strict";
2
+ /**
3
+ * TMLPD Context Compression Utilities
4
+ *
5
+ * Strategies for reducing context window usage:
6
+ * - Smart truncation
7
+ * - Message summarization
8
+ * - ISON-style encoding (inspired by Reddit ISON format)
9
+ * - Context window management
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.isonEncode = isonEncode;
13
+ exports.isonDecode = isonDecode;
14
+ exports.compressText = compressText;
15
+ exports.truncateMessages = truncateMessages;
16
+ exports.truncateToTokenBudget = truncateToTokenBudget;
17
+ exports.calculateCompressionRatio = calculateCompressionRatio;
18
+ /**
19
+ * ISON (Intelligence-Sparse Object Notation)
20
+ *
21
+ * A compression format that reduces token count by:
22
+ * - Removing redundant whitespace
23
+ * - Shortening common phrases
24
+ * - Using abbreviations strategically
25
+ *
26
+ * Example: "The quick brown fox jumps over the lazy dog"
27
+ * → "quick brown fox jumps lazy dog" (removes articles, repeated words)
28
+ */
29
+ const ISON_REPLACEMENTS = [
30
+ // Common phrase abbreviations
31
+ [/\bthe\b/g, ""],
32
+ [/\ba\b/g, ""],
33
+ [/\ban\b/g, ""],
34
+ [/\bthat\b/g, "that"],
35
+ [/\bthis\b/g, "this"],
36
+ [/\bwith\b/g, "w/"],
37
+ [/\bwithout\b/g, "w/o"],
38
+ [/\band\b/g, "&"],
39
+ [/\bor\b/g, "|"],
40
+ [/\bfor\b/g, "4"],
41
+ [/\bto\b/g, "2"],
42
+ [/\binto\b/g, "2"],
43
+ [/\bfrom\b/g, "fr"],
44
+ [/\bplease\b/gi, ""],
45
+ [/\bthank you\b/gi, "thx"],
46
+ [/\byou are\b/gi, "u r"],
47
+ [/\byou can\b/gi, "u c"],
48
+ [/\bcan you\b/gi, "c?"],
49
+ [/\bhow do\b/gi, "how 2"],
50
+ [/\bwhat is\b/gi, "wat"],
51
+ [/\bwhat are\b/gi, "wat"],
52
+ // Whitespace normalization
53
+ [/\s+/g, " "],
54
+ [/^\s+|\s+$/g, ""],
55
+ // Remove repeated characters
56
+ [/(\w)\1{2,}/g, "$1$1"],
57
+ // Shorten common technical terms
58
+ [/\binformation\b/gi, "info"],
59
+ [/\bprocessing\b/gi, "proc"],
60
+ [/\bdevelopment\b/gi, "dev"],
61
+ [/\bapplication\b/gi, "app"],
62
+ [/\bconfiguration\b/gi, "config"],
63
+ [/\brepresentation\b/gi, "repr"],
64
+ [/\bunderstanding\b/gi, "unders"],
65
+ [/\brecommendation\b/gi, "rec"],
66
+ ];
67
+ const ISON_UNREPLACEMENTS = [
68
+ [/w\//g, "with "],
69
+ [/w\/o/g, "without "],
70
+ [/&/g, " and "],
71
+ [/\b4\b/g, " for "],
72
+ [/\b2\b/g, " to "],
73
+ [/\bfr\b/g, "from "],
74
+ [/\bthx\b/gi, "thank you"],
75
+ [/\bu r\b/gi, "you are"],
76
+ [/\bu c\b/gi, "you can"],
77
+ [/\bc\?\b/g, "can you"],
78
+ [/how 2\b/gi, "how do"],
79
+ [/\bwat\b/g, "what is"],
80
+ ];
81
+ /**
82
+ * ISON encode text for token reduction.
83
+ */
84
+ function isonEncode(text) {
85
+ let result = text;
86
+ // Apply replacements
87
+ for (const [pattern, replacement] of ISON_REPLACEMENTS) {
88
+ result = result.replace(pattern, replacement);
89
+ }
90
+ // Remove extra spaces and trim
91
+ result = result.replace(/\s+/g, " ").trim();
92
+ return result;
93
+ }
94
+ /**
95
+ * Decode ISON encoded text.
96
+ */
97
+ function isonDecode(text) {
98
+ let result = text;
99
+ // Apply un-replacements
100
+ for (const [pattern, replacement] of ISON_UNREPLACEMENTS) {
101
+ result = result.replace(pattern, replacement);
102
+ }
103
+ return result;
104
+ }
105
+ /**
106
+ * Compress text using ISON encoding.
107
+ */
108
+ function compressText(text) {
109
+ const original_tokens = estimateTokens(text);
110
+ const compressed = isonEncode(text);
111
+ const compressed_tokens = estimateTokens(compressed);
112
+ return {
113
+ original_tokens,
114
+ compressed_tokens,
115
+ ratio: compressed_tokens / original_tokens,
116
+ compressed_text: compressed
117
+ };
118
+ }
119
+ /**
120
+ * Estimate tokens (fallback if no model specified).
121
+ */
122
+ function estimateTokens(text) {
123
+ const words = text.trim().split(/\s+/).filter(w => w.length > 0);
124
+ return Math.ceil(words.length * 1.3);
125
+ }
126
+ /**
127
+ * Truncate messages to fit within token budget.
128
+ *
129
+ * @param messages - Conversation messages
130
+ * @param max_tokens - Maximum tokens allowed
131
+ * @param strategy - "smart" (preserve system + recent), "first" (keep start), "last" (keep end)
132
+ */
133
+ function truncateMessages(messages, max_tokens, strategy = "smart") {
134
+ if (!messages || messages.length === 0)
135
+ return [];
136
+ // Calculate total tokens
137
+ const totalTokens = (msg) => {
138
+ const content = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);
139
+ return estimateTokens(content) + 4; // +4 for role/format overhead
140
+ };
141
+ let currentTokens = messages.reduce((sum, m) => sum + totalTokens(m), 0);
142
+ if (currentTokens <= max_tokens) {
143
+ return messages; // Already fits
144
+ }
145
+ const result = [];
146
+ if (strategy === "first") {
147
+ // Keep system (first) messages, truncate from middle
148
+ let keepTokens = 0;
149
+ for (const msg of messages) {
150
+ const msgTokens = totalTokens(msg);
151
+ if (keepTokens + msgTokens <= max_tokens) {
152
+ result.push(msg);
153
+ keepTokens += msgTokens;
154
+ }
155
+ else if (msg.role === "system" && result.length === 0) {
156
+ // Always keep system message, possibly truncated
157
+ const systemContent = typeof msg.content === 'string' ? msg.content : "";
158
+ const truncated = truncateToTokenBudget(systemContent, max_tokens - 4);
159
+ result.push({ ...msg, content: truncated });
160
+ break;
161
+ }
162
+ else {
163
+ break;
164
+ }
165
+ }
166
+ }
167
+ else if (strategy === "last") {
168
+ // Keep only most recent messages
169
+ for (let i = messages.length - 1; i >= 0; i--) {
170
+ const msg = messages[i];
171
+ const msgTokens = totalTokens(msg);
172
+ if (currentTokens - msgTokens <= max_tokens) {
173
+ result.unshift(msg);
174
+ currentTokens -= msgTokens;
175
+ }
176
+ else if (msg.role === "user") {
177
+ // Try to keep a truncated user message
178
+ const truncated = truncateToTokenBudget(msg.content, max_tokens - currentTokens);
179
+ if (truncated.length > 20) {
180
+ result.unshift({ ...msg, content: truncated });
181
+ }
182
+ break;
183
+ }
184
+ }
185
+ }
186
+ else if (strategy === "smart") {
187
+ // Keep system, compress middle, keep recent
188
+ const systemMessages = [];
189
+ const middleMessages = [];
190
+ const recentMessages = [];
191
+ for (const msg of messages) {
192
+ if (msg.role === "system") {
193
+ systemMessages.push(msg);
194
+ }
195
+ else if (messages.indexOf(msg) >= messages.length - 3) {
196
+ recentMessages.push(msg);
197
+ }
198
+ else {
199
+ middleMessages.push(msg);
200
+ }
201
+ }
202
+ // Start with system
203
+ for (const msg of systemMessages) {
204
+ const msgTokens = totalTokens(msg);
205
+ if (currentTokens <= max_tokens) {
206
+ result.push(msg);
207
+ currentTokens -= msgTokens;
208
+ }
209
+ else {
210
+ // Truncate system message
211
+ const truncated = truncateToTokenBudget(msg.content, max_tokens - currentTokens - 10);
212
+ result.push({ ...msg, content: truncated });
213
+ currentTokens = max_tokens;
214
+ break;
215
+ }
216
+ }
217
+ // Add compressed middle
218
+ if (currentTokens > max_tokens / 2 && middleMessages.length > 0) {
219
+ // Compress middle messages into a summary
220
+ const middleContent = middleMessages
221
+ .map(m => m.content)
222
+ .join("\n");
223
+ const summaryTokenBudget = Math.min(max_tokens / 4, max_tokens - currentTokens);
224
+ const summary = truncateToTokenBudget(`[Previous ${middleMessages.length} messages]: ${middleContent}`, summaryTokenBudget);
225
+ result.push({ role: "assistant", content: summary });
226
+ currentTokens -= estimateTokens(summary);
227
+ }
228
+ // Add recent messages if room
229
+ for (const msg of recentMessages) {
230
+ const msgTokens = totalTokens(msg);
231
+ if (currentTokens + msgTokens <= max_tokens) {
232
+ result.push(msg);
233
+ currentTokens += msgTokens;
234
+ }
235
+ }
236
+ }
237
+ return result;
238
+ }
239
+ /**
240
+ * Truncate a single string to fit within token budget.
241
+ */
242
+ function truncateToTokenBudget(text, max_tokens) {
243
+ const words = text.split(/\s+/);
244
+ let current = 0;
245
+ const targetWords = [];
246
+ for (const word of words) {
247
+ const wordTokens = estimateTokens(word);
248
+ if (current + wordTokens <= max_tokens) {
249
+ targetWords.push(word);
250
+ current += wordTokens;
251
+ }
252
+ else {
253
+ break;
254
+ }
255
+ }
256
+ let result = targetWords.join(" ");
257
+ // If we truncated, add ellipsis
258
+ if (result.length < text.length) {
259
+ result += "...";
260
+ }
261
+ return result;
262
+ }
263
+ /**
264
+ * Calculate compression ratio for context.
265
+ */
266
+ function calculateCompressionRatio(messages, max_tokens) {
267
+ const totalTokens = messages.reduce((sum, m) => {
268
+ const content = typeof m.content === 'string' ? m.content : JSON.stringify(m.content);
269
+ return sum + estimateTokens(content) + 4;
270
+ }, 0);
271
+ return Math.min(1, max_tokens / totalTokens);
272
+ }
273
+ exports.default = {
274
+ isonEncode,
275
+ isonDecode,
276
+ compressText,
277
+ truncateMessages,
278
+ truncateToTokenBudget,
279
+ calculateCompressionRatio
280
+ };
281
+ //# sourceMappingURL=compression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compression.js","sourceRoot":"","sources":["../../src/utils/compression.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * TMLPD Reliability Engine
3
+ *
4
+ * Circuit breaker, retry with jitter, and enhanced cooldown logic.
5
+ * Designed to handle flaky API calls gracefully.
6
+ */
7
+ export interface RetryConfig {
8
+ max_attempts: number;
9
+ base_delay_ms: number;
10
+ max_delay_ms: number;
11
+ jitter: number;
12
+ retryable_status_codes: number[];
13
+ }
14
+ export interface CircuitBreakerConfig {
15
+ failure_threshold: number;
16
+ recovery_timeout_ms: number;
17
+ half_open_max_calls: number;
18
+ }
19
+ export interface CircuitState {
20
+ status: "closed" | "open" | "half_open";
21
+ failure_count: number;
22
+ last_failure_time: number | null;
23
+ last_success_time: number | null;
24
+ consecutive_successes: number;
25
+ }
26
+ export declare const DEFAULT_RETRY_CONFIG: RetryConfig;
27
+ export declare const DEFAULT_CIRCUIT_BREAKER_CONFIG: CircuitBreakerConfig;
28
+ /**
29
+ * Calculate delay with exponential backoff and jitter
30
+ */
31
+ export declare function calculateRetryDelay(attempt: number, config?: RetryConfig): number;
32
+ /**
33
+ * Check if status code is retryable
34
+ */
35
+ export declare function isRetryableStatus(statusCode: number | null, config?: RetryConfig): boolean;
36
+ /**
37
+ * Circuit Breaker implementation
38
+ */
39
+ export declare class CircuitBreaker {
40
+ private config;
41
+ private state;
42
+ private half_open_calls;
43
+ constructor(config?: Partial<CircuitBreakerConfig>);
44
+ /**
45
+ * Check if circuit allows requests
46
+ */
47
+ canExecute(): boolean;
48
+ /**
49
+ * Record a successful execution
50
+ */
51
+ recordSuccess(): void;
52
+ /**
53
+ * Record a failed execution
54
+ */
55
+ recordFailure(): void;
56
+ /**
57
+ * Get current circuit state
58
+ */
59
+ getState(): CircuitState;
60
+ /**
61
+ * Force reset circuit
62
+ */
63
+ reset(): void;
64
+ }
65
+ /**
66
+ * Enhanced retry wrapper with circuit breaker integration
67
+ */
68
+ export declare function withRetry<T>(fn: () => Promise<T>, config?: Partial<RetryConfig>, circuitBreaker?: CircuitBreaker): Promise<{
69
+ result: T | null;
70
+ error: Error | null;
71
+ attempts: number;
72
+ circuit_tripped: boolean;
73
+ }>;
74
+ //# sourceMappingURL=reliability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reliability.d.ts","sourceRoot":"","sources":["../../src/utils/reliability.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,oBAAoB,EAAE,WAMlC,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,oBAI5C,CAAC;AAEF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,WAAkC,GACzC,MAAM,CAYR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,GAAE,WAAkC,GAAG,OAAO,CAGhH;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,eAAe,CAAK;gBAEhB,MAAM,GAAE,OAAO,CAAC,oBAAoB,CAAM;IAWtD;;OAEG;IACH,UAAU,IAAI,OAAO;IAiBrB;;OAEG;IACH,aAAa,IAAI,IAAI;IAiBrB;;OAEG;IACH,aAAa,IAAI,IAAI;IAarB;;OAEG;IACH,QAAQ,IAAI,YAAY;IAIxB;;OAEG;IACH,KAAK,IAAI,IAAI;CAUd;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,EACjC,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC;IAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,CAAC,CA6ChG"}
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ /**
3
+ * TMLPD Reliability Engine
4
+ *
5
+ * Circuit breaker, retry with jitter, and enhanced cooldown logic.
6
+ * Designed to handle flaky API calls gracefully.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.CircuitBreaker = exports.DEFAULT_CIRCUIT_BREAKER_CONFIG = exports.DEFAULT_RETRY_CONFIG = void 0;
10
+ exports.calculateRetryDelay = calculateRetryDelay;
11
+ exports.isRetryableStatus = isRetryableStatus;
12
+ exports.withRetry = withRetry;
13
+ exports.DEFAULT_RETRY_CONFIG = {
14
+ max_attempts: 3,
15
+ base_delay_ms: 500,
16
+ max_delay_ms: 30000,
17
+ jitter: 0.3,
18
+ retryable_status_codes: [408, 429, 500, 502, 503, 504],
19
+ };
20
+ exports.DEFAULT_CIRCUIT_BREAKER_CONFIG = {
21
+ failure_threshold: 5,
22
+ recovery_timeout_ms: 60000,
23
+ half_open_max_calls: 3,
24
+ };
25
+ /**
26
+ * Calculate delay with exponential backoff and jitter
27
+ */
28
+ function calculateRetryDelay(attempt, config = exports.DEFAULT_RETRY_CONFIG) {
29
+ // Exponential backoff
30
+ const exponential_delay = config.base_delay_ms * Math.pow(2, attempt - 1);
31
+ // Cap at max delay
32
+ const capped_delay = Math.min(exponential_delay, config.max_delay_ms);
33
+ // Add jitter
34
+ const jitter_range = capped_delay * config.jitter;
35
+ const jitter = (Math.random() * 2 - 1) * jitter_range;
36
+ return Math.round(capped_delay + jitter);
37
+ }
38
+ /**
39
+ * Check if status code is retryable
40
+ */
41
+ function isRetryableStatus(statusCode, config = exports.DEFAULT_RETRY_CONFIG) {
42
+ if (statusCode === null)
43
+ return true; // Network errors are retryable
44
+ return config.retryable_status_codes.includes(statusCode);
45
+ }
46
+ /**
47
+ * Circuit Breaker implementation
48
+ */
49
+ class CircuitBreaker {
50
+ config;
51
+ state;
52
+ half_open_calls = 0;
53
+ constructor(config = {}) {
54
+ this.config = { ...exports.DEFAULT_CIRCUIT_BREAKER_CONFIG, ...config };
55
+ this.state = {
56
+ status: "closed",
57
+ failure_count: 0,
58
+ last_failure_time: null,
59
+ last_success_time: null,
60
+ consecutive_successes: 0,
61
+ };
62
+ }
63
+ /**
64
+ * Check if circuit allows requests
65
+ */
66
+ canExecute() {
67
+ if (this.state.status === "closed")
68
+ return true;
69
+ if (this.state.status === "open") {
70
+ // Check if recovery timeout has passed
71
+ if (this.state.last_failure_time && Date.now() - this.state.last_failure_time >= this.config.recovery_timeout_ms) {
72
+ this.state.status = "half_open";
73
+ this.half_open_calls = 0;
74
+ return true;
75
+ }
76
+ return false;
77
+ }
78
+ // half_open
79
+ return this.half_open_calls < this.config.half_open_max_calls;
80
+ }
81
+ /**
82
+ * Record a successful execution
83
+ */
84
+ recordSuccess() {
85
+ this.state.last_success_time = Date.now();
86
+ this.half_open_calls++;
87
+ if (this.state.status === "half_open") {
88
+ this.state.consecutive_successes++;
89
+ if (this.state.consecutive_successes >= this.config.half_open_max_calls) {
90
+ // Circuit recovered
91
+ this.state.status = "closed";
92
+ this.state.failure_count = 0;
93
+ this.state.consecutive_successes = 0;
94
+ }
95
+ }
96
+ else {
97
+ this.state.failure_count = 0;
98
+ }
99
+ }
100
+ /**
101
+ * Record a failed execution
102
+ */
103
+ recordFailure() {
104
+ this.state.last_failure_time = Date.now();
105
+ this.state.failure_count++;
106
+ this.state.consecutive_successes = 0;
107
+ if (this.state.status === "half_open") {
108
+ // Trip circuit back open
109
+ this.state.status = "open";
110
+ }
111
+ else if (this.state.failure_count >= this.config.failure_threshold) {
112
+ this.state.status = "open";
113
+ }
114
+ }
115
+ /**
116
+ * Get current circuit state
117
+ */
118
+ getState() {
119
+ return { ...this.state };
120
+ }
121
+ /**
122
+ * Force reset circuit
123
+ */
124
+ reset() {
125
+ this.state = {
126
+ status: "closed",
127
+ failure_count: 0,
128
+ last_failure_time: null,
129
+ last_success_time: null,
130
+ consecutive_successes: 0,
131
+ };
132
+ this.half_open_calls = 0;
133
+ }
134
+ }
135
+ exports.CircuitBreaker = CircuitBreaker;
136
+ /**
137
+ * Enhanced retry wrapper with circuit breaker integration
138
+ */
139
+ async function withRetry(fn, config = {}, circuitBreaker) {
140
+ const retryConfig = { ...exports.DEFAULT_RETRY_CONFIG, ...config };
141
+ let lastError = null;
142
+ let attempts = 0;
143
+ let circuit_tripped = false;
144
+ for (let i = 0; i < retryConfig.max_attempts; i++) {
145
+ attempts++;
146
+ try {
147
+ // Check circuit breaker before attempt
148
+ if (circuitBreaker && !circuitBreaker.canExecute()) {
149
+ circuit_tripped = true;
150
+ throw new Error("Circuit breaker is open");
151
+ }
152
+ const result = await fn();
153
+ if (circuitBreaker) {
154
+ circuitBreaker.recordSuccess();
155
+ }
156
+ return { result, error: null, attempts, circuit_tripped };
157
+ }
158
+ catch (error) {
159
+ lastError = error instanceof Error ? error : new Error(String(error));
160
+ // Check if should retry
161
+ const statusCode = error.statusCode || error.response?.statusCode || null;
162
+ if (!isRetryableStatus(statusCode, retryConfig)) {
163
+ return { result: null, error: lastError, attempts, circuit_tripped };
164
+ }
165
+ if (circuitBreaker) {
166
+ circuitBreaker.recordFailure();
167
+ }
168
+ // Don't wait after last attempt
169
+ if (i < retryConfig.max_attempts - 1) {
170
+ const delay = calculateRetryDelay(i + 1, retryConfig);
171
+ await new Promise((resolve) => setTimeout(resolve, delay));
172
+ }
173
+ }
174
+ }
175
+ return { result: null, error: lastError, attempts, circuit_tripped };
176
+ }
177
+ //# sourceMappingURL=reliability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reliability.js","sourceRoot":"","sources":["../../src/utils/reliability.ts"],"names":[],"mappings":"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"}