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,508 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ TMLPD Improvement Council - Multi-LLM Decision Making
4
+
5
+ Uses multiple AI providers to analyze, debate, and vote on
6
+ the best improvement path for TMLPD v2.0.
7
+
8
+ Council Members:
9
+ 1. Anthropic Claude (Architectural perspective)
10
+ 2. OpenAI GPT-4 (Practical implementation)
11
+ 3. Google Gemini (Research alignment)
12
+ 4. Cerebras Llama (Cost/benefit analysis)
13
+ """
14
+
15
+ import asyncio
16
+ import json
17
+ from datetime import datetime
18
+ from pathlib import Path
19
+ from typing import Dict, List, Any
20
+
21
+ # Mock implementations (in real system, use actual API calls)
22
+ class CouncilMember:
23
+ """A council member with specific perspective"""
24
+
25
+ def __init__(self, name: str, provider: str, perspective: str):
26
+ self.name = name
27
+ self.provider = provider
28
+ self.perspective = perspective
29
+
30
+ async def deliberate(self, proposals: List[Dict]) -> Dict[str, Any]:
31
+ """
32
+ Analyze proposals and provide recommendations
33
+
34
+ Returns: Ranking with reasoning
35
+ """
36
+ # In production, call actual LLM API
37
+ # For now, return perspective-based analysis
38
+
39
+ analysis = {
40
+ "member": self.name,
41
+ "provider": self.provider,
42
+ "perspective": self.perspective,
43
+ "rankings": [],
44
+ "reasoning": ""
45
+ }
46
+
47
+ # Different perspectives weight factors differently
48
+ if self.perspective == "architectural":
49
+ # Prioritize: System design, scalability, maintainability
50
+ priority_factors = ["scalability", "maintainability", "abstraction"]
51
+ analysis["reasoning"] = (
52
+ "Focus on solid architectural foundations that enable "
53
+ "future growth. Multi-provider system and difficulty-aware "
54
+ "routing provide the best extensibility."
55
+ )
56
+
57
+ elif self.perspective == "practical":
58
+ # Prioritize: Implementation speed, user value, quick wins
59
+ priority_factors = ["implementation_speed", "user_value", "quick_wins"]
60
+ analysis["reasoning"] = (
61
+ "Prioritize features that provide immediate user value. "
62
+ "CLI interface and error handling give instant usability "
63
+ "improvements."
64
+ )
65
+
66
+ elif self.perspective == "research":
67
+ # Prioritize: Research backing, innovation, alignment with trends
68
+ priority_factors = ["research_support", "innovation", "trend_alignment"]
69
+ analysis["reasoning"] = (
70
+ "Emphasize improvements with strong research backing. "
71
+ "Advanced memory systems and difficulty-aware routing have "
72
+ "solid arXiv validation."
73
+ )
74
+
75
+ elif self.perspective == "cost_benefit":
76
+ # Prioritize: Cost reduction, ROI, efficiency
77
+ priority_factors = ["cost_savings", "roi", "efficiency"]
78
+ analysis["reasoning"] = (
79
+ "Focus on improvements that reduce operational costs and "
80
+ "increase efficiency. Multi-provider routing enables 40-60% "
81
+ "cost reduction (MONK benchmarks)."
82
+ )
83
+
84
+ # Score each proposal
85
+ for proposal in proposals:
86
+ score = self._score_proposal(proposal, priority_factors)
87
+ analysis["rankings"].append({
88
+ "proposal": proposal["name"],
89
+ "score": score,
90
+ "justification": self._justify_score(proposal, score)
91
+ })
92
+
93
+ # Sort by score
94
+ analysis["rankings"].sort(key=lambda x: x["score"], reverse=True)
95
+
96
+ return analysis
97
+
98
+ def _score_proposal(self, proposal: Dict, factors: List[str]) -> float:
99
+ """Score a proposal based on perspective factors"""
100
+ score = 0.0
101
+
102
+ # Base score from value rating
103
+ score += proposal.get("value", 0) * 20 # 0-100 points
104
+
105
+ # Adjust for effort (lower effort = better)
106
+ effort_days = proposal.get("effort_days", 5)
107
+ score += (10 - effort_days) * 5 # Prefer quicker implementations
108
+
109
+ # Research backing boost
110
+ if proposal.get("research_backed"):
111
+ if "research" in factors:
112
+ score += 15
113
+
114
+ # Impact boost
115
+ impact = proposal.get("impact", 0)
116
+ if impact >= 4 and "user_value" in factors:
117
+ score += 10
118
+
119
+ return min(score, 100)
120
+
121
+ def _justify_score(self, proposal: Dict, score: float) -> str:
122
+ """Generate justification for the score"""
123
+ justifications = []
124
+
125
+ if score >= 80:
126
+ justifications.append("Critical priority")
127
+ elif score >= 60:
128
+ justifications.append("High priority")
129
+ elif score >= 40:
130
+ justifications.append("Medium priority")
131
+ else:
132
+ justifications.append("Lower priority")
133
+
134
+ if proposal.get("research_backed"):
135
+ justifications.append("Strong research support")
136
+
137
+ if proposal.get("effort_days", 5) <= 2:
138
+ justifications.append("Quick to implement")
139
+
140
+ return ", ".join(justifications)
141
+
142
+
143
+ class ImprovementCouncil:
144
+ """Council of AI experts for decision making"""
145
+
146
+ def __init__(self):
147
+ self.members = [
148
+ CouncilMember(
149
+ name="Claude (Architect)",
150
+ provider="anthropic",
151
+ perspective="architectural"
152
+ ),
153
+ CouncilMember(
154
+ name="GPT-4 (Pragmatist)",
155
+ provider="openai",
156
+ perspective="practical"
157
+ ),
158
+ CouncilMember(
159
+ name="Gemini (Researcher)",
160
+ provider="google",
161
+ perspective="research"
162
+ ),
163
+ CouncilMember(
164
+ name="Llama (Cost Analyst)",
165
+ provider="cerebras",
166
+ perspective="cost_benefit"
167
+ )
168
+ ]
169
+
170
+ self.proposals = [
171
+ {
172
+ "name": "Multi-Provider System with Health Monitoring",
173
+ "effort_days": 3,
174
+ "value": 5,
175
+ "impact": 5,
176
+ "research_backed": True,
177
+ "citations": [
178
+ "https://arxiv.org/html/2506.12508v1",
179
+ "https://arxiv.org/abs/2511.15755"
180
+ ],
181
+ "description": "Enable switching between Anthropic, OpenAI, Cerebras, etc. with health monitoring and automatic failover. MONK benchmarks show 40-60% cost reduction."
182
+ },
183
+ {
184
+ "name": "Difficulty-Aware Routing",
185
+ "effort_days": 2,
186
+ "value": 5,
187
+ "impact": 5,
188
+ "research_backed": True,
189
+ "citations": [
190
+ "https://arxiv.org/html/2509.11079v2"
191
+ ],
192
+ "description": "Classify tasks by difficulty (trivial/simple/medium/complex/expert) and route to optimal providers. Research shows 35% decision quality improvement."
193
+ },
194
+ {
195
+ "name": "Advanced Memory System (Memoria-inspired)",
196
+ "effort_days": 4,
197
+ "value": 5,
198
+ "impact": 5,
199
+ "research_backed": True,
200
+ "citations": [
201
+ "https://www.arxiv.org/abs/2512.12686",
202
+ "https://arxiv.org/abs/2502.12110"
203
+ ],
204
+ "description": "Multi-tier memory: episodic (JSON), semantic (vector DB), working (in-memory). Research shows 50% improvement in long-term coherence."
205
+ },
206
+ {
207
+ "name": "Workflow Executors (Chaining & Parallelization)",
208
+ "effort_days": 3,
209
+ "value": 5,
210
+ "impact": 4,
211
+ "research_backed": True,
212
+ "citations": [
213
+ "https://arxiv.org/abs/2511.15755"
214
+ ],
215
+ "description": "Implement chaining (sequential) and parallelization (concurrent) executors. Unlocks the 15% workflow use case."
216
+ },
217
+ {
218
+ "name": "CLI Interface with Rich Output",
219
+ "effort_days": 3,
220
+ "value": 4,
221
+ "impact": 4,
222
+ "research_backed": False,
223
+ "description": "Command-line tool with tmlpd execute, route, memory commands. Makes TMLPD practical for daily use."
224
+ },
225
+ {
226
+ "name": "Function Calling / Tool Use Enhancement",
227
+ "effort_days": 2,
228
+ "value": 4,
229
+ "impact": 4,
230
+ "research_backed": True,
231
+ "citations": [
232
+ "https://arxiv.org/html/2409.00920v2"
233
+ ],
234
+ "description": "Skills as callable functions with structured parameters. Research shows 40% reliability improvement."
235
+ },
236
+ {
237
+ "name": "Git-Versioned Context Management",
238
+ "effort_days": 2,
239
+ "value": 3,
240
+ "impact": 3,
241
+ "research_backed": True,
242
+ "citations": [
243
+ "https://arxiv.org/abs/2508.00031"
244
+ ],
245
+ "description": "Git-like branching and versioning for checkpoints. Enables experiment tracking and reproducibility."
246
+ },
247
+ {
248
+ "name": "Better Error Messages & Logging",
249
+ "effort_days": 1,
250
+ "value": 3,
251
+ "impact": 3,
252
+ "research_backed": False,
253
+ "description": "Actionable error messages with suggestions. Comprehensive logging for debugging."
254
+ }
255
+ ]
256
+
257
+ async def deliberate(self) -> Dict[str, Any]:
258
+ """
259
+ Run council deliberation process
260
+
261
+ Steps:
262
+ 1. Each member analyzes proposals independently
263
+ 2. Aggregate rankings
264
+ 3. Identify consensus and disagreements
265
+ 4. Generate final recommendation
266
+ """
267
+ print("\n" + "=" * 70)
268
+ print(" TMLPD IMPROVEMENT COUNCIL - MULTI-LLM DECISION MAKING")
269
+ print("=" * 70 + "\n")
270
+
271
+ # Step 1: Individual deliberations
272
+ print("Step 1: Gathering individual council member opinions...\n")
273
+
274
+ analyses = []
275
+ for member in self.members:
276
+ print(f" šŸ¤” {member.name} ({member.provider}) deliberating...")
277
+ analysis = await member.deliberate(self.proposals)
278
+ analyses.append(analysis)
279
+ print(f" āœ“ Complete")
280
+
281
+ # Step 2: Aggregate rankings
282
+ print("\nStep 2: Aggregating rankings and identifying consensus...\n")
283
+
284
+ aggregated = self._aggregate_rankings(analyses)
285
+
286
+ # Step 3: Display results
287
+ self._display_council_results(analyses, aggregated)
288
+
289
+ # Step 4: Generate final recommendation
290
+ recommendation = self._generate_recommendation(aggregated)
291
+
292
+ # Save results
293
+ self._save_council_decision(analyses, aggregated, recommendation)
294
+
295
+ return {
296
+ "individual_analyses": analyses,
297
+ "aggregated_rankings": aggregated,
298
+ "recommendation": recommendation
299
+ }
300
+
301
+ def _aggregate_rankings(self, analyses: List[Dict]) -> Dict[str, Any]:
302
+ """Aggregate rankings from all council members"""
303
+
304
+ # Calculate average scores for each proposal
305
+ proposal_scores = {p["name"]: {"total": 0, "count": 0, "scores": []} for p in self.proposals}
306
+
307
+ for analysis in analyses:
308
+ for ranking in analysis["rankings"]:
309
+ proposal_name = ranking["proposal"]
310
+ score = ranking["score"]
311
+
312
+ proposal_scores[proposal_name]["total"] += score
313
+ proposal_scores[proposal_name]["count"] += 1
314
+ proposal_scores[proposal_name]["scores"].append(score)
315
+
316
+ # Calculate averages
317
+ aggregated = []
318
+ for proposal_name, scores in proposal_scores.items():
319
+ avg_score = scores["total"] / scores["count"]
320
+ std_dev = self._calculate_std_dev(scores["scores"])
321
+
322
+ # Find consensus level (low std_dev = high consensus)
323
+ if std_dev < 10:
324
+ consensus = "strong"
325
+ elif std_dev < 20:
326
+ consensus = "moderate"
327
+ else:
328
+ consensus = "weak"
329
+
330
+ aggregated.append({
331
+ "proposal": proposal_name,
332
+ "average_score": avg_score,
333
+ "std_deviation": std_dev,
334
+ "consensus": consensus
335
+ })
336
+
337
+ # Sort by average score
338
+ aggregated.sort(key=lambda x: x["average_score"], reverse=True)
339
+
340
+ return aggregated
341
+
342
+ def _calculate_std_dev(self, scores: List[float]) -> float:
343
+ """Calculate standard deviation"""
344
+ if len(scores) < 2:
345
+ return 0.0
346
+
347
+ mean = sum(scores) / len(scores)
348
+ variance = sum((s - mean) ** 2 for s in scores) / len(scores)
349
+ return variance ** 0.5
350
+
351
+ def _display_council_results(self, analyses: List[Dict], aggregated: List[Dict]):
352
+ """Display council deliberation results"""
353
+
354
+ print("\n" + "=" * 70)
355
+ print(" COUNCIL MEMBER OPINIONS")
356
+ print("=" * 70 + "\n")
357
+
358
+ for analysis in analyses:
359
+ print(f"šŸ¤– {analysis['member']} ({analysis['provider']})")
360
+ print(f" Perspective: {analysis['perspective']}")
361
+ print(f" Reasoning: {analysis['reasoning']}")
362
+ print(f"\n Top Rankings:")
363
+
364
+ for i, ranking in enumerate(analysis["rankings"][:3], 1):
365
+ print(f" {i}. {ranking['proposal']}: {ranking['score']:.1f}/100")
366
+ print(f" {ranking['justification']}")
367
+
368
+ print()
369
+
370
+ print("\n" + "=" * 70)
371
+ print(" AGGREGATED COUNCIL RANKINGS")
372
+ print("=" * 70 + "\n")
373
+
374
+ for i, item in enumerate(aggregated, 1):
375
+ consensus_indicator = {
376
+ "strong": "šŸ¤ Strong consensus",
377
+ "moderate": "🤷 Moderate agreement",
378
+ "weak": "āš ļø Disagreement"
379
+ }
380
+
381
+ print(f"{i}. **{item['proposal']}**")
382
+ print(f" Score: {item['average_score']:.1f}/100")
383
+ print(f" Consensus: {consensus_indicator[item['consensus']]}")
384
+ print()
385
+
386
+ def _generate_recommendation(self, aggregated: List[Dict]) -> Dict[str, Any]:
387
+ """Generate final council recommendation"""
388
+
389
+ # Top 3 proposals
390
+ top_3 = aggregated[:3]
391
+
392
+ # Check if there's strong consensus on #1
393
+ if top_3[0]["consensus"] == "strong":
394
+ implementation_strategy = "sequential"
395
+ reasoning = (
396
+ "Strong council consensus on top priority. "
397
+ "Implement sequentially for best results."
398
+ )
399
+ else:
400
+ implementation_strategy = "parallel"
401
+ reasoning = (
402
+ "Moderate disagreement on priorities. "
403
+ "Consider parallel implementation of top 2-3 items."
404
+ )
405
+
406
+ recommendation = {
407
+ "primary_recommendation": top_3[0]["proposal"],
408
+ "implementation_strategy": implementation_strategy,
409
+ "reasoning": reasoning,
410
+ "proposed_roadmap": []
411
+ }
412
+
413
+ # Generate roadmap based on strategy
414
+ if implementation_strategy == "sequential":
415
+ # Sequential roadmap
416
+ total_weeks = 0
417
+ for item in aggregated:
418
+ proposal = next(p for p in self.proposals if p["name"] == item["proposal"])
419
+ effort_days = proposal.get("effort_days", 5)
420
+ weeks = effort_days / 5
421
+
422
+ total_weeks += weeks
423
+
424
+ recommendation["proposed_roadmap"].append({
425
+ "phase": len(recommendation["proposed_roadmap"]) + 1,
426
+ "proposal": item["proposal"],
427
+ "duration_weeks": weeks,
428
+ "cumulative_weeks": total_weeks
429
+ })
430
+ else:
431
+ # Parallel roadmap (top items in parallel)
432
+ recommendation["proposed_roadmap"] = [
433
+ {
434
+ "phase": 1,
435
+ "proposal": "Parallel implementation of top 3",
436
+ "duration_weeks": 3,
437
+ "items": [item["proposal"] for item in top_3]
438
+ }
439
+ ]
440
+
441
+ return recommendation
442
+
443
+ def _save_council_decision(
444
+ self,
445
+ analyses: List[Dict],
446
+ aggregated: List[Dict],
447
+ recommendation: Dict
448
+ ):
449
+ """Save council decision to file"""
450
+
451
+ decision_doc = {
452
+ "timestamp": datetime.now().isoformat(),
453
+ "council_members": [m["member"] for m in analyses],
454
+ "individual_analyses": analyses,
455
+ "aggregated_rankings": aggregated,
456
+ "recommendation": recommendation
457
+ }
458
+
459
+ output_path = Path("/Users/Subho/tmlpd-skill/docs/COUNCIL_DECISION.json")
460
+
461
+ with open(output_path, 'w') as f:
462
+ json.dump(decision_doc, f, indent=2)
463
+
464
+ print(f"\nāœ… Council decision saved to: {output_path}")
465
+
466
+
467
+ async def main():
468
+ """Run improvement council"""
469
+
470
+ council = ImprovementCouncil()
471
+ decision = await council.deliberate()
472
+
473
+ print("\n" + "=" * 70)
474
+ print(" FINAL COUNCIL RECOMMENDATION")
475
+ print("=" * 70 + "\n")
476
+
477
+ rec = decision["recommendation"]
478
+
479
+ print(f"šŸŽÆ Primary Recommendation:")
480
+ print(f" {rec['primary_recommendation']}")
481
+ print()
482
+ print(f"šŸ“‹ Implementation Strategy:")
483
+ print(f" {rec['implementation_strategy']}")
484
+ print()
485
+ print(f"šŸ’” Reasoning:")
486
+ print(f" {rec['reasoning']}")
487
+ print()
488
+ print(f"šŸ—“ļø Proposed Roadmap:")
489
+ print()
490
+
491
+ for phase in rec["proposed_roadmap"]:
492
+ print(f" Phase {phase['phase']}:")
493
+ if "proposal" in phase:
494
+ print(f" - {phase['proposal']}")
495
+ print(f" - Duration: {phase['duration_weeks']:.1f} weeks")
496
+ else:
497
+ print(f" - {phase['proposal']}")
498
+ print(f" - Duration: {phase['duration_weeks']:.1f} weeks")
499
+ print(f" - Items: {', '.join(phase['items'])}")
500
+ print()
501
+
502
+ print("=" * 70)
503
+ print("\n✨ Council deliberation complete!")
504
+ print(" See docs/COUNCIL_DECISION.json for full details.\n")
505
+
506
+
507
+ if __name__ == "__main__":
508
+ asyncio.run(main())