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,447 @@
1
+ """
2
+ Phase 3c: Working Memory Cache
3
+
4
+ In-memory cache for active session context and frequently accessed data.
5
+ Based on Memoria framework (arXiv:2512.12686) working memory component.
6
+ """
7
+
8
+ import time
9
+ from typing import Dict, List, Any, Optional
10
+ from datetime import datetime, timedelta
11
+ from collections import OrderedDict
12
+
13
+
14
+ class WorkingMemoryCache:
15
+ """
16
+ Working memory: Fast in-memory cache for active session context.
17
+
18
+ Based on Memoria framework (arXiv:2512.12686)
19
+
20
+ Features:
21
+ - LRU (Least Recently Used) eviction policy
22
+ - TTL (Time To Live) for automatic expiration
23
+ - Session-based context tracking
24
+ - Fast lookups (< 1ms)
25
+ - Persistent across operations in a session
26
+ """
27
+
28
+ def __init__(
29
+ self,
30
+ max_size: int = 1000,
31
+ default_ttl_seconds: int = 3600
32
+ ):
33
+ """
34
+ Initialize working memory cache.
35
+
36
+ Args:
37
+ max_size: Maximum number of items to store
38
+ default_ttl_seconds: Default time-to-live for cache entries
39
+ """
40
+ self.max_size = max_size
41
+ self.default_ttl = default_ttl_seconds
42
+
43
+ # Main cache (OrderedDict for LRU)
44
+ self.cache: OrderedDict[str, Dict[str, Any]] = OrderedDict()
45
+
46
+ # Session context
47
+ self.session_context: Dict[str, Any] = {
48
+ "session_start": datetime.now().isoformat(),
49
+ "operations_count": 0,
50
+ "cache_hits": 0,
51
+ "cache_misses": 0
52
+ }
53
+
54
+ # Indexes for faster queries
55
+ self.tag_index: Dict[str, set] = {} # tag -> set of keys
56
+ self.category_index: Dict[str, set] = {} # category -> set of keys
57
+
58
+ def set(
59
+ self,
60
+ key: str,
61
+ value: Any,
62
+ ttl: Optional[int] = None,
63
+ tags: Optional[List[str]] = None,
64
+ category: Optional[str] = None,
65
+ metadata: Optional[Dict] = None
66
+ ):
67
+ """
68
+ Store value in cache.
69
+
70
+ Args:
71
+ key: Cache key
72
+ value: Value to store (must be JSON-serializable)
73
+ ttl: Time-to-live in seconds (uses default if not specified)
74
+ tags: Optional tags for categorization
75
+ category: Optional category
76
+ metadata: Optional metadata
77
+ """
78
+ # Check if we need to evict
79
+ if len(self.cache) >= self.max_size and key not in self.cache:
80
+ self._evict_lru()
81
+
82
+ # Calculate expiration
83
+ ttl = ttl if ttl is not None else self.default_ttl
84
+ expires_at = datetime.now() + timedelta(seconds=ttl)
85
+
86
+ # Create cache entry
87
+ entry = {
88
+ "value": value,
89
+ "created_at": datetime.now().isoformat(),
90
+ "expires_at": expires_at.isoformat(),
91
+ "accessed_at": datetime.now().isoformat(),
92
+ "access_count": 0,
93
+ "tags": tags or [],
94
+ "category": category,
95
+ "metadata": metadata or {},
96
+ "size_bytes": len(str(value)) # Approximate size
97
+ }
98
+
99
+ # Remove from indexes if updating existing key
100
+ if key in self.cache:
101
+ self._remove_from_indexes(key)
102
+
103
+ # Add to cache
104
+ self.cache[key] = entry
105
+
106
+ # Move to end (most recently used)
107
+ self.cache.move_to_end(key)
108
+
109
+ # Update indexes
110
+ self._add_to_indexes(key, entry)
111
+
112
+ def get(self, key: str) -> Optional[Any]:
113
+ """
114
+ Get value from cache.
115
+
116
+ Args:
117
+ key: Cache key
118
+
119
+ Returns:
120
+ Cached value or None if not found/expired
121
+ """
122
+ # Check if key exists
123
+ if key not in self.cache:
124
+ self.session_context["cache_misses"] += 1
125
+ return None
126
+
127
+ entry = self.cache[key]
128
+
129
+ # Check if expired
130
+ if self._is_expired(entry):
131
+ # Remove expired entry
132
+ del self.cache[key]
133
+ self._remove_from_indexes(key)
134
+ self.session_context["cache_misses"] += 1
135
+ return None
136
+
137
+ # Update access statistics
138
+ entry["accessed_at"] = datetime.now().isoformat()
139
+ entry["access_count"] += 1
140
+
141
+ # Move to end (most recently used)
142
+ self.cache.move_to_end(key)
143
+
144
+ self.session_context["cache_hits"] += 1
145
+
146
+ return entry["value"]
147
+
148
+ def get_many(self, keys: List[str]) -> Dict[str, Any]:
149
+ """
150
+ Get multiple values from cache.
151
+
152
+ Args:
153
+ keys: List of cache keys
154
+
155
+ Returns:
156
+ Dict of key -> value (only for found keys)
157
+ """
158
+ result = {}
159
+
160
+ for key in keys:
161
+ value = self.get(key)
162
+ if value is not None:
163
+ result[key] = value
164
+
165
+ return result
166
+
167
+ def set_many(self, items: Dict[str, Any], **kwargs):
168
+ """
169
+ Store multiple values in cache.
170
+
171
+ Args:
172
+ items: Dict of key -> value
173
+ **kwargs: Additional arguments passed to set()
174
+ """
175
+ for key, value in items.items():
176
+ self.set(key, value, **kwargs)
177
+
178
+ def delete(self, key: str) -> bool:
179
+ """
180
+ Delete entry from cache.
181
+
182
+ Args:
183
+ key: Cache key
184
+
185
+ Returns:
186
+ True if deleted, False if not found
187
+ """
188
+ if key in self.cache:
189
+ del self.cache[key]
190
+ self._remove_from_indexes(key)
191
+ return True
192
+
193
+ return False
194
+
195
+ def clear(self):
196
+ """Clear all cache entries"""
197
+ self.cache.clear()
198
+ self.tag_index.clear()
199
+ self.category_index.clear()
200
+
201
+ def get_by_tag(self, tag: str) -> List[Any]:
202
+ """
203
+ Get all entries with a specific tag.
204
+
205
+ Args:
206
+ tag: Tag to search for
207
+
208
+ Returns:
209
+ List of values with that tag
210
+ """
211
+ if tag not in self.tag_index:
212
+ return []
213
+
214
+ values = []
215
+ keys_to_remove = []
216
+
217
+ for key in self.tag_index[tag]:
218
+ value = self.get(key)
219
+ if value is not None:
220
+ values.append(value)
221
+ else:
222
+ keys_to_remove.append(key)
223
+
224
+ # Clean up expired keys from index
225
+ for key in keys_to_remove:
226
+ self.tag_index[tag].discard(key)
227
+
228
+ return values
229
+
230
+ def get_by_category(self, category: str) -> List[Any]:
231
+ """
232
+ Get all entries in a specific category.
233
+
234
+ Args:
235
+ category: Category to search for
236
+
237
+ Returns:
238
+ List of values in that category
239
+ """
240
+ if category not in self.category_index:
241
+ return []
242
+
243
+ values = []
244
+ keys_to_remove = []
245
+
246
+ for key in self.category_index[category]:
247
+ value = self.get(key)
248
+ if value is not None:
249
+ values.append(value)
250
+ else:
251
+ keys_to_remove.append(key)
252
+
253
+ # Clean up expired keys from index
254
+ for key in keys_to_remove:
255
+ self.category_index[category].discard(key)
256
+
257
+ return values
258
+
259
+ def search(
260
+ self,
261
+ query: str,
262
+ search_values: bool = True,
263
+ search_keys: bool = False,
264
+ search_metadata: bool = False
265
+ ) -> List[Dict[str, Any]]:
266
+ """
267
+ Search cache for entries matching query.
268
+
269
+ Args:
270
+ query: Search query (simple string matching)
271
+ search_values: Search in values
272
+ search_keys: Search in keys
273
+ search_metadata: Search in metadata
274
+
275
+ Returns:
276
+ List of matching entries with keys
277
+ """
278
+ results = []
279
+ query_lower = query.lower()
280
+
281
+ for key, entry in self.cache.items():
282
+ # Skip expired
283
+ if self._is_expired(entry):
284
+ continue
285
+
286
+ # Search key
287
+ if search_keys and query_lower in key.lower():
288
+ results.append({"key": key, "value": entry["value"]})
289
+ continue
290
+
291
+ # Search value
292
+ if search_values and query_lower in str(entry["value"]).lower():
293
+ results.append({"key": key, "value": entry["value"]})
294
+ continue
295
+
296
+ # Search metadata
297
+ if search_metadata:
298
+ metadata_str = str(entry["metadata"])
299
+ if query_lower in metadata_str.lower():
300
+ results.append({"key": key, "value": entry["value"]})
301
+ continue
302
+
303
+ return results
304
+
305
+ def cleanup_expired(self):
306
+ """Remove all expired entries"""
307
+ keys_to_remove = []
308
+
309
+ for key, entry in self.cache.items():
310
+ if self._is_expired(entry):
311
+ keys_to_remove.append(key)
312
+
313
+ for key in keys_to_remove:
314
+ del self.cache[key]
315
+ self._remove_from_indexes(key)
316
+
317
+ return len(keys_to_remove)
318
+
319
+ def _evict_lru(self):
320
+ """Evict least recently used entry"""
321
+ if self.cache:
322
+ # First item is least recently used
323
+ lru_key = next(iter(self.cache))
324
+ del self.cache[lru_key]
325
+ self._remove_from_indexes(lru_key)
326
+
327
+ def _is_expired(self, entry: Dict[str, Any]) -> bool:
328
+ """Check if entry is expired"""
329
+ expires_at = datetime.fromisoformat(entry["expires_at"])
330
+ return datetime.now() > expires_at
331
+
332
+ def _add_to_indexes(self, key: str, entry: Dict[str, Any]):
333
+ """Add entry to tag and category indexes"""
334
+ # Tag index
335
+ for tag in entry.get("tags", []):
336
+ if tag not in self.tag_index:
337
+ self.tag_index[tag] = set()
338
+ self.tag_index[tag].add(key)
339
+
340
+ # Category index
341
+ category = entry.get("category")
342
+ if category:
343
+ if category not in self.category_index:
344
+ self.category_index[category] = set()
345
+ self.category_index[category].add(key)
346
+
347
+ def _remove_from_indexes(self, key: str):
348
+ """Remove entry from tag and category indexes"""
349
+ # Tag index
350
+ for tag_set in self.tag_index.values():
351
+ tag_set.discard(key)
352
+
353
+ # Category index
354
+ for category_set in self.category_index.values():
355
+ category_set.discard(key)
356
+
357
+ def get_stats(self) -> Dict[str, Any]:
358
+ """Get cache statistics"""
359
+ # Calculate total size
360
+ total_size_bytes = sum(
361
+ entry["size_bytes"] for entry in self.cache.values()
362
+ )
363
+
364
+ # Calculate hit rate
365
+ total_requests = (
366
+ self.session_context["cache_hits"] +
367
+ self.session_context["cache_misses"]
368
+ )
369
+ hit_rate = (
370
+ self.session_context["cache_hits"] / total_requests
371
+ if total_requests > 0 else 0
372
+ )
373
+
374
+ # Calculate avg access count
375
+ if self.cache:
376
+ avg_access_count = sum(
377
+ entry["access_count"] for entry in self.cache.values()
378
+ ) / len(self.cache)
379
+ else:
380
+ avg_access_count = 0
381
+
382
+ # Session duration
383
+ session_start = datetime.fromisoformat(self.session_context["session_start"])
384
+ session_duration = (datetime.now() - session_start).total_seconds()
385
+
386
+ return {
387
+ "cache_size": len(self.cache),
388
+ "max_size": self.max_size,
389
+ "total_size_bytes": total_size_bytes,
390
+ "total_size_mb": total_size_bytes / (1024 * 1024),
391
+ "hit_rate": hit_rate,
392
+ "cache_hits": self.session_context["cache_hits"],
393
+ "cache_misses": self.session_context["cache_misses"],
394
+ "avg_access_count": avg_access_count,
395
+ "tags_count": len(self.tag_index),
396
+ "categories_count": len(self.category_index),
397
+ "session_duration_seconds": session_duration,
398
+ "operations_count": self.session_context["operations_count"]
399
+ }
400
+
401
+ def export_cache(self, include_expired: bool = False) -> List[Dict[str, Any]]:
402
+ """
403
+ Export cache entries as list.
404
+
405
+ Args:
406
+ include_expired: Whether to include expired entries
407
+
408
+ Returns:
409
+ List of cache entries
410
+ """
411
+ entries = []
412
+
413
+ for key, entry in self.cache.items():
414
+ # Skip expired if requested
415
+ if not include_expired and self._is_expired(entry):
416
+ continue
417
+
418
+ entry_copy = entry.copy()
419
+ entry_copy["key"] = key
420
+ entries.append(entry_copy)
421
+
422
+ return entries
423
+
424
+ def import_cache(self, entries: List[Dict[str, Any]]):
425
+ """
426
+ Import cache entries from list.
427
+
428
+ Args:
429
+ entries: List of cache entries (from export_cache)
430
+ """
431
+ for entry in entries:
432
+ key = entry.pop("key")
433
+ value = entry.pop("value")
434
+
435
+ self.set(key, value, **entry)
436
+
437
+ def __len__(self):
438
+ """Get cache size"""
439
+ return len(self.cache)
440
+
441
+ def __contains__(self, key: str):
442
+ """Check if key exists in cache"""
443
+ return key in self.cache and not self._is_expired(self.cache[key])
444
+
445
+ def __repr__(self):
446
+ """String representation"""
447
+ return f"WorkingMemoryCache(size={len(self.cache)}, max_size={self.max_size})"
@@ -0,0 +1,52 @@
1
+ """
2
+ HALO Orchestration Module
3
+
4
+ Hierarchical Autonomous Logic-Oriented Orchestration for TMLPD v2.2
5
+
6
+ Based on:
7
+ - arXiv:2505.13516 (HALO - 3-tier hierarchical planning)
8
+ - arXiv:2506.12508v3 (AgentOrchestra)
9
+
10
+ Components:
11
+ - TaskPlanner: High-level task decomposition
12
+ - RoleAssigner: Specialized agent assignment
13
+ - ExecutionEngine: Parallel execution with verification
14
+ - HALOOrchestrator: Main coordinator (3-tier system)
15
+ - MCTSWorkflowSearch: MCTS-based workflow optimization
16
+ """
17
+
18
+ from .task_planner import TaskPlanner, TaskDecomposition, SubTask, TaskType
19
+ from .role_assigner import RoleAssigner, AgentAssignment, AgentConfig, AgentRole
20
+ from .execution_engine import ExecutionEngine, ExecutionResult, ExecutionSummary
21
+ from .halo_orchestrator import HALOOrchestrator, HALOOrchestrationResult
22
+ from .mcts_workflow import MCTSWorkflowSearch, WorkflowNode, WorkflowStrategy
23
+
24
+ __all__ = [
25
+ # Task Planning
26
+ "TaskPlanner",
27
+ "TaskDecomposition",
28
+ "SubTask",
29
+ "TaskType",
30
+
31
+ # Role Assignment
32
+ "RoleAssigner",
33
+ "AgentAssignment",
34
+ "AgentConfig",
35
+ "AgentRole",
36
+
37
+ # Execution
38
+ "ExecutionEngine",
39
+ "ExecutionResult",
40
+ "ExecutionSummary",
41
+
42
+ # Main Orchestrator
43
+ "HALOOrchestrator",
44
+ "HALOOrchestrationResult",
45
+
46
+ # Workflow Optimization
47
+ "MCTSWorkflowSearch",
48
+ "WorkflowNode",
49
+ "WorkflowStrategy"
50
+ ]
51
+
52
+ __version__ = "2.2.0-alpha"