empathy-framework 4.6.6__py3-none-any.whl → 4.7.0__py3-none-any.whl

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 (247) hide show
  1. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/METADATA +7 -6
  2. empathy_framework-4.7.0.dist-info/RECORD +354 -0
  3. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/top_level.txt +0 -2
  4. empathy_healthcare_plugin/monitors/monitoring/__init__.py +9 -9
  5. empathy_llm_toolkit/agent_factory/__init__.py +6 -6
  6. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +7 -10
  7. empathy_llm_toolkit/agents_md/__init__.py +22 -0
  8. empathy_llm_toolkit/agents_md/loader.py +218 -0
  9. empathy_llm_toolkit/agents_md/parser.py +271 -0
  10. empathy_llm_toolkit/agents_md/registry.py +307 -0
  11. empathy_llm_toolkit/commands/__init__.py +51 -0
  12. empathy_llm_toolkit/commands/context.py +375 -0
  13. empathy_llm_toolkit/commands/loader.py +301 -0
  14. empathy_llm_toolkit/commands/models.py +231 -0
  15. empathy_llm_toolkit/commands/parser.py +371 -0
  16. empathy_llm_toolkit/commands/registry.py +429 -0
  17. empathy_llm_toolkit/config/__init__.py +8 -8
  18. empathy_llm_toolkit/config/unified.py +3 -7
  19. empathy_llm_toolkit/context/__init__.py +22 -0
  20. empathy_llm_toolkit/context/compaction.py +455 -0
  21. empathy_llm_toolkit/context/manager.py +434 -0
  22. empathy_llm_toolkit/hooks/__init__.py +24 -0
  23. empathy_llm_toolkit/hooks/config.py +306 -0
  24. empathy_llm_toolkit/hooks/executor.py +289 -0
  25. empathy_llm_toolkit/hooks/registry.py +302 -0
  26. empathy_llm_toolkit/hooks/scripts/__init__.py +39 -0
  27. empathy_llm_toolkit/hooks/scripts/evaluate_session.py +201 -0
  28. empathy_llm_toolkit/hooks/scripts/first_time_init.py +285 -0
  29. empathy_llm_toolkit/hooks/scripts/pre_compact.py +207 -0
  30. empathy_llm_toolkit/hooks/scripts/session_end.py +183 -0
  31. empathy_llm_toolkit/hooks/scripts/session_start.py +163 -0
  32. empathy_llm_toolkit/hooks/scripts/suggest_compact.py +225 -0
  33. empathy_llm_toolkit/learning/__init__.py +30 -0
  34. empathy_llm_toolkit/learning/evaluator.py +438 -0
  35. empathy_llm_toolkit/learning/extractor.py +514 -0
  36. empathy_llm_toolkit/learning/storage.py +560 -0
  37. empathy_llm_toolkit/providers.py +4 -11
  38. empathy_llm_toolkit/security/__init__.py +17 -17
  39. empathy_llm_toolkit/utils/tokens.py +2 -5
  40. empathy_os/__init__.py +202 -70
  41. empathy_os/cache_monitor.py +5 -3
  42. empathy_os/cli/__init__.py +11 -55
  43. empathy_os/cli/__main__.py +29 -15
  44. empathy_os/cli/commands/inspection.py +21 -12
  45. empathy_os/cli/commands/memory.py +4 -12
  46. empathy_os/cli/commands/profiling.py +198 -0
  47. empathy_os/cli/commands/utilities.py +27 -7
  48. empathy_os/cli.py +28 -57
  49. empathy_os/cli_unified.py +525 -1164
  50. empathy_os/cost_tracker.py +9 -3
  51. empathy_os/dashboard/server.py +200 -2
  52. empathy_os/hot_reload/__init__.py +7 -7
  53. empathy_os/hot_reload/config.py +6 -7
  54. empathy_os/hot_reload/integration.py +35 -35
  55. empathy_os/hot_reload/reloader.py +57 -57
  56. empathy_os/hot_reload/watcher.py +28 -28
  57. empathy_os/hot_reload/websocket.py +2 -2
  58. empathy_os/memory/__init__.py +11 -4
  59. empathy_os/memory/claude_memory.py +1 -1
  60. empathy_os/memory/cross_session.py +8 -12
  61. empathy_os/memory/edges.py +6 -6
  62. empathy_os/memory/file_session.py +770 -0
  63. empathy_os/memory/graph.py +30 -30
  64. empathy_os/memory/nodes.py +6 -6
  65. empathy_os/memory/short_term.py +15 -9
  66. empathy_os/memory/unified.py +606 -140
  67. empathy_os/meta_workflows/agent_creator.py +3 -9
  68. empathy_os/meta_workflows/cli_meta_workflows.py +113 -53
  69. empathy_os/meta_workflows/form_engine.py +6 -18
  70. empathy_os/meta_workflows/intent_detector.py +64 -24
  71. empathy_os/meta_workflows/models.py +3 -1
  72. empathy_os/meta_workflows/pattern_learner.py +13 -31
  73. empathy_os/meta_workflows/plan_generator.py +55 -47
  74. empathy_os/meta_workflows/session_context.py +2 -3
  75. empathy_os/meta_workflows/workflow.py +20 -51
  76. empathy_os/models/cli.py +2 -2
  77. empathy_os/models/tasks.py +1 -2
  78. empathy_os/models/telemetry.py +4 -1
  79. empathy_os/models/token_estimator.py +3 -1
  80. empathy_os/monitoring/alerts.py +938 -9
  81. empathy_os/monitoring/alerts_cli.py +346 -183
  82. empathy_os/orchestration/execution_strategies.py +12 -29
  83. empathy_os/orchestration/pattern_learner.py +20 -26
  84. empathy_os/orchestration/real_tools.py +6 -15
  85. empathy_os/platform_utils.py +2 -1
  86. empathy_os/plugins/__init__.py +2 -2
  87. empathy_os/plugins/base.py +64 -64
  88. empathy_os/plugins/registry.py +32 -32
  89. empathy_os/project_index/index.py +49 -15
  90. empathy_os/project_index/models.py +1 -2
  91. empathy_os/project_index/reports.py +1 -1
  92. empathy_os/project_index/scanner.py +1 -0
  93. empathy_os/redis_memory.py +10 -7
  94. empathy_os/resilience/__init__.py +1 -1
  95. empathy_os/resilience/health.py +10 -10
  96. empathy_os/routing/__init__.py +7 -7
  97. empathy_os/routing/chain_executor.py +37 -37
  98. empathy_os/routing/classifier.py +36 -36
  99. empathy_os/routing/smart_router.py +40 -40
  100. empathy_os/routing/{wizard_registry.py → workflow_registry.py} +47 -47
  101. empathy_os/scaffolding/__init__.py +8 -8
  102. empathy_os/scaffolding/__main__.py +1 -1
  103. empathy_os/scaffolding/cli.py +28 -28
  104. empathy_os/socratic/__init__.py +3 -19
  105. empathy_os/socratic/ab_testing.py +25 -36
  106. empathy_os/socratic/blueprint.py +38 -38
  107. empathy_os/socratic/cli.py +34 -20
  108. empathy_os/socratic/collaboration.py +30 -28
  109. empathy_os/socratic/domain_templates.py +9 -1
  110. empathy_os/socratic/embeddings.py +17 -13
  111. empathy_os/socratic/engine.py +135 -70
  112. empathy_os/socratic/explainer.py +70 -60
  113. empathy_os/socratic/feedback.py +24 -19
  114. empathy_os/socratic/forms.py +15 -10
  115. empathy_os/socratic/generator.py +51 -35
  116. empathy_os/socratic/llm_analyzer.py +25 -23
  117. empathy_os/socratic/mcp_server.py +99 -159
  118. empathy_os/socratic/session.py +19 -13
  119. empathy_os/socratic/storage.py +98 -67
  120. empathy_os/socratic/success.py +38 -27
  121. empathy_os/socratic/visual_editor.py +51 -39
  122. empathy_os/socratic/web_ui.py +99 -66
  123. empathy_os/telemetry/cli.py +3 -1
  124. empathy_os/telemetry/usage_tracker.py +1 -3
  125. empathy_os/test_generator/__init__.py +3 -3
  126. empathy_os/test_generator/cli.py +28 -28
  127. empathy_os/test_generator/generator.py +64 -66
  128. empathy_os/test_generator/risk_analyzer.py +11 -11
  129. empathy_os/vscode_bridge.py +173 -0
  130. empathy_os/workflows/__init__.py +212 -120
  131. empathy_os/workflows/batch_processing.py +8 -24
  132. empathy_os/workflows/bug_predict.py +1 -1
  133. empathy_os/workflows/code_review.py +20 -5
  134. empathy_os/workflows/code_review_pipeline.py +13 -8
  135. empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
  136. empathy_os/workflows/manage_documentation.py +1 -0
  137. empathy_os/workflows/orchestrated_health_check.py +6 -11
  138. empathy_os/workflows/orchestrated_release_prep.py +3 -3
  139. empathy_os/workflows/pr_review.py +18 -10
  140. empathy_os/workflows/progressive/__init__.py +2 -12
  141. empathy_os/workflows/progressive/cli.py +14 -37
  142. empathy_os/workflows/progressive/core.py +12 -12
  143. empathy_os/workflows/progressive/orchestrator.py +166 -144
  144. empathy_os/workflows/progressive/reports.py +22 -31
  145. empathy_os/workflows/progressive/telemetry.py +8 -14
  146. empathy_os/workflows/progressive/test_gen.py +29 -48
  147. empathy_os/workflows/progressive/workflow.py +31 -70
  148. empathy_os/workflows/release_prep.py +21 -6
  149. empathy_os/workflows/release_prep_crew.py +1 -0
  150. empathy_os/workflows/secure_release.py +13 -6
  151. empathy_os/workflows/security_audit.py +8 -3
  152. empathy_os/workflows/test_coverage_boost_crew.py +3 -2
  153. empathy_os/workflows/test_maintenance_crew.py +1 -0
  154. empathy_os/workflows/test_runner.py +16 -12
  155. empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
  156. empathy_software_plugin/cli.py +0 -122
  157. coach_wizards/__init__.py +0 -45
  158. coach_wizards/accessibility_wizard.py +0 -91
  159. coach_wizards/api_wizard.py +0 -91
  160. coach_wizards/base_wizard.py +0 -209
  161. coach_wizards/cicd_wizard.py +0 -91
  162. coach_wizards/code_reviewer_README.md +0 -60
  163. coach_wizards/code_reviewer_wizard.py +0 -180
  164. coach_wizards/compliance_wizard.py +0 -91
  165. coach_wizards/database_wizard.py +0 -91
  166. coach_wizards/debugging_wizard.py +0 -91
  167. coach_wizards/documentation_wizard.py +0 -91
  168. coach_wizards/generate_wizards.py +0 -347
  169. coach_wizards/localization_wizard.py +0 -173
  170. coach_wizards/migration_wizard.py +0 -91
  171. coach_wizards/monitoring_wizard.py +0 -91
  172. coach_wizards/observability_wizard.py +0 -91
  173. coach_wizards/performance_wizard.py +0 -91
  174. coach_wizards/prompt_engineering_wizard.py +0 -661
  175. coach_wizards/refactoring_wizard.py +0 -91
  176. coach_wizards/scaling_wizard.py +0 -90
  177. coach_wizards/security_wizard.py +0 -92
  178. coach_wizards/testing_wizard.py +0 -91
  179. empathy_framework-4.6.6.dist-info/RECORD +0 -410
  180. empathy_llm_toolkit/wizards/__init__.py +0 -43
  181. empathy_llm_toolkit/wizards/base_wizard.py +0 -364
  182. empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
  183. empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
  184. empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
  185. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
  186. empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
  187. empathy_os/wizard_factory_cli.py +0 -170
  188. empathy_software_plugin/wizards/__init__.py +0 -42
  189. empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
  190. empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
  191. empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
  192. empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
  193. empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
  194. empathy_software_plugin/wizards/base_wizard.py +0 -288
  195. empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
  196. empathy_software_plugin/wizards/code_review_wizard.py +0 -604
  197. empathy_software_plugin/wizards/debugging/__init__.py +0 -50
  198. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
  199. empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
  200. empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
  201. empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
  202. empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
  203. empathy_software_plugin/wizards/debugging/verification.py +0 -369
  204. empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
  205. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
  206. empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
  207. empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
  208. empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
  209. empathy_software_plugin/wizards/performance/__init__.py +0 -9
  210. empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
  211. empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
  212. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
  213. empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
  214. empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
  215. empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
  216. empathy_software_plugin/wizards/security/__init__.py +0 -32
  217. empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
  218. empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
  219. empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
  220. empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
  221. empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
  222. empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
  223. empathy_software_plugin/wizards/testing/__init__.py +0 -27
  224. empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
  225. empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
  226. empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
  227. empathy_software_plugin/wizards/testing_wizard.py +0 -274
  228. wizards/__init__.py +0 -82
  229. wizards/admission_assessment_wizard.py +0 -644
  230. wizards/care_plan.py +0 -321
  231. wizards/clinical_assessment.py +0 -769
  232. wizards/discharge_planning.py +0 -77
  233. wizards/discharge_summary_wizard.py +0 -468
  234. wizards/dosage_calculation.py +0 -497
  235. wizards/incident_report_wizard.py +0 -454
  236. wizards/medication_reconciliation.py +0 -85
  237. wizards/nursing_assessment.py +0 -171
  238. wizards/patient_education.py +0 -654
  239. wizards/quality_improvement.py +0 -705
  240. wizards/sbar_report.py +0 -324
  241. wizards/sbar_wizard.py +0 -608
  242. wizards/shift_handoff_wizard.py +0 -535
  243. wizards/soap_note_wizard.py +0 -679
  244. wizards/treatment_plan.py +0 -15
  245. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/WHEEL +0 -0
  246. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/entry_points.txt +0 -0
  247. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/licenses/LICENSE +0 -0
@@ -11,11 +11,7 @@ The MetaOrchestrator is responsible for:
11
11
  import logging
12
12
  from typing import Any
13
13
 
14
- from empathy_os.workflows.progressive.core import (
15
- EscalationConfig,
16
- Tier,
17
- TierResult,
18
- )
14
+ from empathy_os.workflows.progressive.core import EscalationConfig, Tier, TierResult
19
15
 
20
16
  logger = logging.getLogger(__name__)
21
17
 
@@ -50,15 +46,11 @@ class MetaOrchestrator:
50
46
  self.tier_history: dict[Tier, list[float]] = {
51
47
  Tier.CHEAP: [],
52
48
  Tier.CAPABLE: [],
53
- Tier.PREMIUM: []
49
+ Tier.PREMIUM: [],
54
50
  }
55
51
 
56
52
  def should_escalate(
57
- self,
58
- tier: Tier,
59
- result: TierResult,
60
- attempt: int,
61
- config: EscalationConfig
53
+ self, tier: Tier, result: TierResult, attempt: int, config: EscalationConfig
62
54
  ) -> tuple[bool, str]:
63
55
  """Determine if tier should escalate to next tier.
64
56
 
@@ -104,9 +96,7 @@ class MetaOrchestrator:
104
96
  return False, "Premium tier is final"
105
97
 
106
98
  def _check_cheap_escalation(
107
- self,
108
- result: TierResult,
109
- config: EscalationConfig
99
+ self, result: TierResult, config: EscalationConfig
110
100
  ) -> tuple[bool, str]:
111
101
  """Check if cheap tier should escalate to capable.
112
102
 
@@ -127,24 +117,30 @@ class MetaOrchestrator:
127
117
 
128
118
  # Check syntax errors (prioritize over CQS)
129
119
  if syntax_error_count > config.cheap_to_capable_max_syntax_errors:
130
- return True, f"{syntax_error_count} syntax errors exceeds limit {config.cheap_to_capable_max_syntax_errors}"
120
+ return (
121
+ True,
122
+ f"{syntax_error_count} syntax errors exceeds limit {config.cheap_to_capable_max_syntax_errors}",
123
+ )
131
124
 
132
125
  # Check failure rate
133
126
  if failure_rate > config.cheap_to_capable_failure_rate:
134
- return True, f"Failure rate {failure_rate:.1%} exceeds threshold {config.cheap_to_capable_failure_rate:.1%}"
127
+ return (
128
+ True,
129
+ f"Failure rate {failure_rate:.1%} exceeds threshold {config.cheap_to_capable_failure_rate:.1%}",
130
+ )
135
131
 
136
132
  # Check CQS threshold
137
133
  if cqs < config.cheap_to_capable_min_cqs:
138
- return True, f"Quality score {cqs:.1f} below threshold {config.cheap_to_capable_min_cqs}"
134
+ return (
135
+ True,
136
+ f"Quality score {cqs:.1f} below threshold {config.cheap_to_capable_min_cqs}",
137
+ )
139
138
 
140
139
  # All checks passed, no escalation needed
141
140
  return False, f"Quality acceptable (CQS={cqs:.1f})"
142
141
 
143
142
  def _check_capable_escalation(
144
- self,
145
- result: TierResult,
146
- attempt: int,
147
- config: EscalationConfig
143
+ self, result: TierResult, attempt: int, config: EscalationConfig
148
144
  ) -> tuple[bool, str]:
149
145
  """Check if capable tier should escalate to premium.
150
146
 
@@ -165,15 +161,24 @@ class MetaOrchestrator:
165
161
 
166
162
  # Check max attempts first
167
163
  if attempt >= config.capable_max_attempts:
168
- return True, f"Max attempts ({config.capable_max_attempts}) reached without achieving target quality"
164
+ return (
165
+ True,
166
+ f"Max attempts ({config.capable_max_attempts}) reached without achieving target quality",
167
+ )
169
168
 
170
169
  # Check syntax errors (strict for capable tier)
171
170
  if syntax_error_count > config.capable_to_premium_max_syntax_errors:
172
- return True, f"{syntax_error_count} syntax errors exceeds limit {config.capable_to_premium_max_syntax_errors}"
171
+ return (
172
+ True,
173
+ f"{syntax_error_count} syntax errors exceeds limit {config.capable_to_premium_max_syntax_errors}",
174
+ )
173
175
 
174
176
  # Check failure rate
175
177
  if failure_rate > config.capable_to_premium_failure_rate:
176
- return True, f"Failure rate {failure_rate:.1%} exceeds threshold {config.capable_to_premium_failure_rate:.1%}"
178
+ return (
179
+ True,
180
+ f"Failure rate {failure_rate:.1%} exceeds threshold {config.capable_to_premium_failure_rate:.1%}",
181
+ )
177
182
 
178
183
  # Check stagnation (consecutive runs with <5% improvement)
179
184
  # Only check if we have enough history
@@ -181,7 +186,7 @@ class MetaOrchestrator:
181
186
  is_stagnant, stagnation_reason = self._detect_stagnation(
182
187
  self.tier_history[Tier.CAPABLE],
183
188
  config.improvement_threshold,
184
- config.consecutive_stagnation_limit
189
+ config.consecutive_stagnation_limit,
185
190
  )
186
191
 
187
192
  if is_stagnant:
@@ -189,16 +194,16 @@ class MetaOrchestrator:
189
194
 
190
195
  # Check CQS threshold (after stagnation check)
191
196
  if cqs < config.capable_to_premium_min_cqs and attempt >= config.capable_min_attempts:
192
- return True, f"Quality score {cqs:.1f} below threshold {config.capable_to_premium_min_cqs}"
197
+ return (
198
+ True,
199
+ f"Quality score {cqs:.1f} below threshold {config.capable_to_premium_min_cqs}",
200
+ )
193
201
 
194
202
  # No escalation needed
195
203
  return False, f"Quality acceptable (CQS={cqs:.1f}), continuing improvement"
196
204
 
197
205
  def _detect_stagnation(
198
- self,
199
- cqs_history: list[float],
200
- improvement_threshold: float,
201
- consecutive_limit: int
206
+ self, cqs_history: list[float], improvement_threshold: float, consecutive_limit: int
202
207
  ) -> tuple[bool, str]:
203
208
  """Detect if improvement has stagnated.
204
209
 
@@ -246,10 +251,7 @@ class MetaOrchestrator:
246
251
  return False, "No stagnation detected"
247
252
 
248
253
  def build_tier_prompt(
249
- self,
250
- tier: Tier,
251
- base_task: str,
252
- failure_context: dict[str, Any] | None = None
254
+ self, tier: Tier, base_task: str, failure_context: dict[str, Any] | None = None
253
255
  ) -> str:
254
256
  """Build XML-enhanced prompt with failure context.
255
257
 
@@ -304,11 +306,7 @@ class MetaOrchestrator:
304
306
  </instructions>
305
307
  </task>"""
306
308
 
307
- def _build_capable_prompt(
308
- self,
309
- base_task: str,
310
- failure_context: dict[str, Any] | None
311
- ) -> str:
309
+ def _build_capable_prompt(self, base_task: str, failure_context: dict[str, Any] | None) -> str:
312
310
  """Build enhanced prompt for capable tier with failure context.
313
311
 
314
312
  Args:
@@ -359,12 +357,14 @@ class MetaOrchestrator:
359
357
  # Add failure pattern analysis
360
358
  if failure_patterns:
361
359
  prompt_parts.append(" <failure_analysis>")
362
- prompt_parts.append(f" <total_failures>{failure_patterns.get('total_failures', 0)}</total_failures>")
360
+ prompt_parts.append(
361
+ f" <total_failures>{failure_patterns.get('total_failures', 0)}</total_failures>"
362
+ )
363
363
  prompt_parts.append(" <patterns>")
364
364
 
365
365
  error_types = failure_patterns.get("error_types", {})
366
366
  for error_type, count in sorted(error_types.items(), key=lambda x: -x[1]):
367
- prompt_parts.append(f" <pattern type=\"{error_type}\" count=\"{count}\" />")
367
+ prompt_parts.append(f' <pattern type="{error_type}" count="{count}" />')
368
368
 
369
369
  prompt_parts.append(" </patterns>")
370
370
 
@@ -382,68 +382,74 @@ class MetaOrchestrator:
382
382
  error = example.get("error", "Unknown error")
383
383
  code_snippet = example.get("code", "")[:200] # Limit snippet length
384
384
 
385
- prompt_parts.append(f" <example number=\"{i}\">")
385
+ prompt_parts.append(f' <example number="{i}">')
386
386
  prompt_parts.append(f" <error>{self._escape_xml(error)}</error>")
387
387
  if code_snippet:
388
- prompt_parts.append(f" <code_snippet>{self._escape_xml(code_snippet)}</code_snippet>")
388
+ prompt_parts.append(
389
+ f" <code_snippet>{self._escape_xml(code_snippet)}</code_snippet>"
390
+ )
389
391
  prompt_parts.append(" </example>")
390
392
 
391
393
  prompt_parts.append(" </failed_attempts>")
392
394
  prompt_parts.append("")
393
395
 
394
- prompt_parts.extend([
395
- " <improvement_needed>",
396
- " The cheap tier struggled with these items. Analyze the failure",
397
- " patterns above and generate improved solutions that specifically",
398
- " address these issues.",
399
- " </improvement_needed>",
400
- " </context_from_previous_tier>",
401
- "",
402
- " <your_task>",
403
- " Generate improved output that avoids the specific failure patterns identified above.",
404
- "",
405
- " <quality_requirements>",
406
- " <pass_rate>80%+</pass_rate>",
407
- " <coverage>70%+</coverage>",
408
- " <quality_score>80+</quality_score>",
409
- " </quality_requirements>",
410
- "",
411
- " <focus_areas>",
412
- ])
396
+ prompt_parts.extend(
397
+ [
398
+ " <improvement_needed>",
399
+ " The cheap tier struggled with these items. Analyze the failure",
400
+ " patterns above and generate improved solutions that specifically",
401
+ " address these issues.",
402
+ " </improvement_needed>",
403
+ " </context_from_previous_tier>",
404
+ "",
405
+ " <your_task>",
406
+ " Generate improved output that avoids the specific failure patterns identified above.",
407
+ "",
408
+ " <quality_requirements>",
409
+ " <pass_rate>80%+</pass_rate>",
410
+ " <coverage>70%+</coverage>",
411
+ " <quality_score>80+</quality_score>",
412
+ " </quality_requirements>",
413
+ "",
414
+ " <focus_areas>",
415
+ ]
416
+ )
413
417
 
414
418
  # Add targeted focus areas based on failure patterns
415
419
  if failure_patterns:
416
420
  error_types = failure_patterns.get("error_types", {})
417
421
  if "async_errors" in error_types:
418
- prompt_parts.append(" <focus area=\"async\">Proper async/await patterns and error handling</focus>")
422
+ prompt_parts.append(
423
+ ' <focus area="async">Proper async/await patterns and error handling</focus>'
424
+ )
419
425
  if "mocking_errors" in error_types:
420
- prompt_parts.append(" <focus area=\"mocking\">Correct mock setup and teardown</focus>")
426
+ prompt_parts.append(
427
+ ' <focus area="mocking">Correct mock setup and teardown</focus>'
428
+ )
421
429
  if "syntax_errors" in error_types:
422
- prompt_parts.append(" <focus area=\"syntax\">Valid Python syntax and imports</focus>")
430
+ prompt_parts.append(
431
+ ' <focus area="syntax">Valid Python syntax and imports</focus>'
432
+ )
423
433
  if "other_errors" in error_types:
424
- prompt_parts.append(" <focus area=\"general\">Edge cases and error handling</focus>")
434
+ prompt_parts.append(
435
+ ' <focus area="general">Edge cases and error handling</focus>'
436
+ )
425
437
  else:
426
438
  # Default focus areas
427
- prompt_parts.extend([
428
- " <focus area=\"syntax\">Correct syntax and structure</focus>",
429
- " <focus area=\"coverage\">Comprehensive test coverage</focus>",
430
- " <focus area=\"errors\">Proper error handling</focus>",
431
- " <focus area=\"edge_cases\">Edge case coverage</focus>",
432
- ])
433
-
434
- prompt_parts.extend([
435
- " </focus_areas>",
436
- " </your_task>",
437
- "</task>"
438
- ])
439
+ prompt_parts.extend(
440
+ [
441
+ ' <focus area="syntax">Correct syntax and structure</focus>',
442
+ ' <focus area="coverage">Comprehensive test coverage</focus>',
443
+ ' <focus area="errors">Proper error handling</focus>',
444
+ ' <focus area="edge_cases">Edge case coverage</focus>',
445
+ ]
446
+ )
447
+
448
+ prompt_parts.extend([" </focus_areas>", " </your_task>", "</task>"])
439
449
 
440
450
  return "\n".join(prompt_parts)
441
451
 
442
- def _build_premium_prompt(
443
- self,
444
- base_task: str,
445
- failure_context: dict[str, Any] | None
446
- ) -> str:
452
+ def _build_premium_prompt(self, base_task: str, failure_context: dict[str, Any] | None) -> str:
447
453
  """Build comprehensive prompt for premium tier.
448
454
 
449
455
  Args:
@@ -503,25 +509,35 @@ class MetaOrchestrator:
503
509
  # Add detailed failure analysis
504
510
  if failure_patterns:
505
511
  prompt_parts.append(" <persistent_issues>")
506
- prompt_parts.append(f" <total_failures>{failure_patterns.get('total_failures', 0)}</total_failures>")
512
+ prompt_parts.append(
513
+ f" <total_failures>{failure_patterns.get('total_failures', 0)}</total_failures>"
514
+ )
507
515
  prompt_parts.append(" <failure_patterns>")
508
516
 
509
517
  error_types = failure_patterns.get("error_types", {})
510
518
  for error_type, count in sorted(error_types.items(), key=lambda x: -x[1]):
511
- prompt_parts.append(f" <pattern type=\"{error_type}\" count=\"{count}\">")
519
+ prompt_parts.append(f' <pattern type="{error_type}" count="{count}">')
512
520
 
513
521
  # Add specific guidance per error type
514
522
  if error_type == "async_errors":
515
- prompt_parts.append(" <guidance>Use proper async/await patterns, handle timeouts correctly</guidance>")
523
+ prompt_parts.append(
524
+ " <guidance>Use proper async/await patterns, handle timeouts correctly</guidance>"
525
+ )
516
526
  elif error_type == "mocking_errors":
517
- prompt_parts.append(" <guidance>Ensure mocks are properly configured and reset</guidance>")
527
+ prompt_parts.append(
528
+ " <guidance>Ensure mocks are properly configured and reset</guidance>"
529
+ )
518
530
  elif error_type == "syntax_errors":
519
- prompt_parts.append(" <guidance>Double-check syntax, imports, and type annotations</guidance>")
531
+ prompt_parts.append(
532
+ " <guidance>Double-check syntax, imports, and type annotations</guidance>"
533
+ )
520
534
 
521
535
  prompt_parts.append(" </pattern>")
522
536
 
523
537
  prompt_parts.append(" </failure_patterns>")
524
- prompt_parts.append(f" <primary_issue>{failure_patterns.get('primary_issue', 'unknown')}</primary_issue>")
538
+ prompt_parts.append(
539
+ f" <primary_issue>{failure_patterns.get('primary_issue', 'unknown')}</primary_issue>"
540
+ )
525
541
  prompt_parts.append(" </persistent_issues>")
526
542
  prompt_parts.append("")
527
543
 
@@ -535,67 +551,77 @@ class MetaOrchestrator:
535
551
  code_snippet = example.get("code", "")[:300] # More context for premium
536
552
  quality_score = example.get("quality_score", 0)
537
553
 
538
- prompt_parts.append(f" <attempt number=\"{i}\" quality_score=\"{quality_score}\">")
554
+ prompt_parts.append(f' <attempt number="{i}" quality_score="{quality_score}">')
539
555
  prompt_parts.append(f" <error>{self._escape_xml(error)}</error>")
540
556
  if code_snippet:
541
- prompt_parts.append(f" <code_snippet>{self._escape_xml(code_snippet)}</code_snippet>")
557
+ prompt_parts.append(
558
+ f" <code_snippet>{self._escape_xml(code_snippet)}</code_snippet>"
559
+ )
542
560
  prompt_parts.append(" </attempt>")
543
561
 
544
562
  prompt_parts.append(" </capable_tier_attempts>")
545
563
  prompt_parts.append("")
546
564
 
547
- prompt_parts.extend([
548
- " </escalation_context>",
549
- "",
550
- " <expert_task>",
551
- " <critical_notice>",
552
- " You are the FINAL tier in the progressive escalation system.",
553
- " Previous tiers (cheap and capable) have attempted this task",
554
- " multiple times and could not achieve the required quality.",
555
- "",
556
- " This is the last automated attempt before human review.",
557
- " Excellence is not optional - it is required.",
558
- " </critical_notice>",
559
- "",
560
- " <expert_techniques>",
561
- " Apply sophisticated approaches:",
562
- " - Deep analysis of why previous attempts failed",
563
- " - Production-grade error handling and edge cases",
564
- " - Comprehensive documentation and clarity",
565
- " - Defensive programming against subtle bugs",
566
- ])
565
+ prompt_parts.extend(
566
+ [
567
+ " </escalation_context>",
568
+ "",
569
+ " <expert_task>",
570
+ " <critical_notice>",
571
+ " You are the FINAL tier in the progressive escalation system.",
572
+ " Previous tiers (cheap and capable) have attempted this task",
573
+ " multiple times and could not achieve the required quality.",
574
+ "",
575
+ " This is the last automated attempt before human review.",
576
+ " Excellence is not optional - it is required.",
577
+ " </critical_notice>",
578
+ "",
579
+ " <expert_techniques>",
580
+ " Apply sophisticated approaches:",
581
+ " - Deep analysis of why previous attempts failed",
582
+ " - Production-grade error handling and edge cases",
583
+ " - Comprehensive documentation and clarity",
584
+ " - Defensive programming against subtle bugs",
585
+ ]
586
+ )
567
587
 
568
588
  # Add specific techniques based on failure patterns
569
589
  if failure_patterns:
570
590
  error_types = failure_patterns.get("error_types", {})
571
591
  if "async_errors" in error_types:
572
- prompt_parts.append(" - Advanced async patterns (asyncio.gather, proper timeouts)")
592
+ prompt_parts.append(
593
+ " - Advanced async patterns (asyncio.gather, proper timeouts)"
594
+ )
573
595
  if "mocking_errors" in error_types:
574
- prompt_parts.append(" - Sophisticated mocking (pytest fixtures, proper lifecycle)")
596
+ prompt_parts.append(
597
+ " - Sophisticated mocking (pytest fixtures, proper lifecycle)"
598
+ )
575
599
  if "syntax_errors" in error_types:
576
600
  prompt_parts.append(" - Rigorous syntax validation before submission")
577
601
 
578
- prompt_parts.extend([
579
- " </expert_techniques>",
580
- "",
581
- " <quality_requirements>",
582
- " <pass_rate>95%+</pass_rate>",
583
- " <coverage>85%+</coverage>",
584
- " <quality_score>95+</quality_score>",
585
- " <zero_syntax_errors>MANDATORY</zero_syntax_errors>",
586
- " </quality_requirements>",
587
- "",
588
- " <success_criteria>",
589
- " Your implementation must:",
590
- " 1. Address ALL failure patterns identified above",
591
- " 2. Achieve exceptional quality scores (95+)",
592
- " 3. Have zero syntax errors or runtime failures",
593
- " 4. Include comprehensive edge case coverage",
594
- " 5. Be production-ready with proper documentation",
595
- " </success_criteria>",
596
- " </expert_task>",
597
- "</task>"
598
- ])
602
+ prompt_parts.extend(
603
+ [
604
+ " </expert_techniques>",
605
+ "",
606
+ " <quality_requirements>",
607
+ " <pass_rate>95%+</pass_rate>",
608
+ " <coverage>85%+</coverage>",
609
+ " <quality_score>95+</quality_score>",
610
+ " <zero_syntax_errors>MANDATORY</zero_syntax_errors>",
611
+ " </quality_requirements>",
612
+ "",
613
+ " <success_criteria>",
614
+ " Your implementation must:",
615
+ " 1. Address ALL failure patterns identified above",
616
+ " 2. Achieve exceptional quality scores (95+)",
617
+ " 3. Have zero syntax errors or runtime failures",
618
+ " 4. Include comprehensive edge case coverage",
619
+ " 5. Be production-ready with proper documentation",
620
+ " </success_criteria>",
621
+ " </expert_task>",
622
+ "</task>",
623
+ ]
624
+ )
599
625
 
600
626
  return "\n".join(prompt_parts)
601
627
 
@@ -613,8 +639,7 @@ class MetaOrchestrator:
613
639
  'Error: &lt;missing&gt;'
614
640
  """
615
641
  return (
616
- text
617
- .replace("&", "&amp;")
642
+ text.replace("&", "&amp;")
618
643
  .replace("<", "&lt;")
619
644
  .replace(">", "&gt;")
620
645
  .replace('"', "&quot;")
@@ -622,9 +647,7 @@ class MetaOrchestrator:
622
647
  )
623
648
 
624
649
  def create_agent_team(
625
- self,
626
- tier: Tier,
627
- failure_context: dict[str, Any] | None = None
650
+ self, tier: Tier, failure_context: dict[str, Any] | None = None
628
651
  ) -> list[str]:
629
652
  """Create specialized agent team for tier.
630
653
 
@@ -658,10 +681,7 @@ class MetaOrchestrator:
658
681
  else: # PREMIUM
659
682
  return ["generator", "analyzer", "reviewer"]
660
683
 
661
- def analyze_failure_patterns(
662
- self,
663
- failures: list[dict[str, Any]]
664
- ) -> dict[str, Any]:
684
+ def analyze_failure_patterns(self, failures: list[dict[str, Any]]) -> dict[str, Any]:
665
685
  """Analyze failure patterns to inform next tier.
666
686
 
667
687
  Groups failures by type and identifies common issues.
@@ -697,5 +717,7 @@ class MetaOrchestrator:
697
717
  return {
698
718
  "total_failures": len(failures),
699
719
  "error_types": error_types,
700
- "primary_issue": max(error_types.items(), key=lambda x: x[1])[0] if error_types else "unknown"
720
+ "primary_issue": (
721
+ max(error_types.items(), key=lambda x: x[1])[0] if error_types else "unknown"
722
+ ),
701
723
  }
@@ -13,10 +13,7 @@ from pathlib import Path
13
13
  from typing import Any
14
14
 
15
15
  from empathy_os.config import _validate_file_path
16
- from empathy_os.workflows.progressive.core import (
17
- ProgressiveWorkflowResult,
18
- Tier,
19
- )
16
+ from empathy_os.workflows.progressive.core import ProgressiveWorkflowResult, Tier
20
17
 
21
18
  logger = logging.getLogger(__name__)
22
19
 
@@ -61,7 +58,9 @@ def generate_progression_report(result: ProgressiveWorkflowResult) -> str:
61
58
 
62
59
  # Cost savings
63
60
  if result.cost_savings > 0:
64
- report.append(f"Cost Savings: ${result.cost_savings:.2f} ({result.cost_savings_percent:.0f}% vs all-Premium)")
61
+ report.append(
62
+ f"Cost Savings: ${result.cost_savings:.2f} ({result.cost_savings_percent:.0f}% vs all-Premium)"
63
+ )
65
64
  report.append("")
66
65
 
67
66
  report.append("TIER BREAKDOWN:")
@@ -69,11 +68,7 @@ def generate_progression_report(result: ProgressiveWorkflowResult) -> str:
69
68
 
70
69
  # Tier-by-tier breakdown
71
70
  for tier_result in result.tier_results:
72
- tier_emoji = {
73
- Tier.CHEAP: "💰",
74
- Tier.CAPABLE: "📊",
75
- Tier.PREMIUM: "💎"
76
- }[tier_result.tier]
71
+ tier_emoji = {Tier.CHEAP: "💰", Tier.CAPABLE: "📊", Tier.PREMIUM: "💎"}[tier_result.tier]
77
72
 
78
73
  report.append(f"{tier_emoji} {tier_result.tier.value.upper()} Tier ({tier_result.model})")
79
74
  report.append(f" • Items: {len(tier_result.generated_items)}")
@@ -147,14 +142,16 @@ def save_results_to_disk(result: ProgressiveWorkflowResult, storage_path: str) -
147
142
  summary = {
148
143
  "workflow": result.workflow_name,
149
144
  "task_id": result.task_id,
150
- "timestamp": result.tier_results[0].timestamp.isoformat() if result.tier_results else None,
145
+ "timestamp": (
146
+ result.tier_results[0].timestamp.isoformat() if result.tier_results else None
147
+ ),
151
148
  "total_cost": result.total_cost,
152
149
  "total_duration": result.total_duration,
153
150
  "cost_savings": result.cost_savings,
154
151
  "cost_savings_percent": result.cost_savings_percent,
155
152
  "success": result.success,
156
153
  "tier_count": len(result.tier_results),
157
- "final_cqs": result.final_result.quality_score if result.final_result else 0
154
+ "final_cqs": result.final_result.quality_score if result.final_result else 0,
158
155
  }
159
156
 
160
157
  summary_file = validated_dir / "summary.json"
@@ -179,9 +176,9 @@ def save_results_to_disk(result: ProgressiveWorkflowResult, storage_path: str) -
179
176
  "test_pass_rate": tier_result.failure_analysis.test_pass_rate,
180
177
  "coverage": tier_result.failure_analysis.coverage_percent,
181
178
  "assertion_depth": tier_result.failure_analysis.assertion_depth,
182
- "confidence": tier_result.failure_analysis.confidence_score
179
+ "confidence": tier_result.failure_analysis.confidence_score,
183
180
  },
184
- "item_count": len(tier_result.generated_items)
181
+ "item_count": len(tier_result.generated_items),
185
182
  }
186
183
 
187
184
  tier_file = validated_dir / f"tier_{i}_{tier_result.tier.value}.json"
@@ -222,7 +219,9 @@ def _format_duration(seconds: float) -> str:
222
219
  return f"{minutes}m {remaining_seconds}s"
223
220
 
224
221
 
225
- def load_result_from_disk(task_id: str, storage_path: str = ".empathy/progressive_runs") -> dict[str, Any]:
222
+ def load_result_from_disk(
223
+ task_id: str, storage_path: str = ".empathy/progressive_runs"
224
+ ) -> dict[str, Any]:
226
225
  """Load saved result from disk.
227
226
 
228
227
  Args:
@@ -262,11 +261,7 @@ def load_result_from_disk(task_id: str, storage_path: str = ".empathy/progressiv
262
261
  report_file = task_dir / "report.txt"
263
262
  report = report_file.read_text() if report_file.exists() else ""
264
263
 
265
- return {
266
- "summary": summary,
267
- "tier_results": tier_results,
268
- "report": report
269
- }
264
+ return {"summary": summary, "tier_results": tier_results, "report": report}
270
265
 
271
266
 
272
267
  def list_saved_results(storage_path: str = ".empathy/progressive_runs") -> list[dict[str, Any]]:
@@ -311,9 +306,7 @@ def list_saved_results(storage_path: str = ".empathy/progressive_runs") -> list[
311
306
 
312
307
 
313
308
  def cleanup_old_results(
314
- storage_path: str = ".empathy/progressive_runs",
315
- retention_days: int = 30,
316
- dry_run: bool = False
309
+ storage_path: str = ".empathy/progressive_runs", retention_days: int = 30, dry_run: bool = False
317
310
  ) -> tuple[int, int]:
318
311
  """Clean up old progressive workflow results.
319
312
 
@@ -363,6 +356,7 @@ def cleanup_old_results(
363
356
  # Old result, delete it
364
357
  if not dry_run:
365
358
  import shutil
359
+
366
360
  shutil.rmtree(task_dir)
367
361
  logger.info(f"Deleted old result: {task_dir.name}")
368
362
  else:
@@ -378,9 +372,7 @@ def cleanup_old_results(
378
372
  return (deleted_count, retained_count)
379
373
 
380
374
 
381
- def generate_cost_analytics(
382
- storage_path: str = ".empathy/progressive_runs"
383
- ) -> dict[str, Any]:
375
+ def generate_cost_analytics(storage_path: str = ".empathy/progressive_runs") -> dict[str, Any]:
384
376
  """Generate cost optimization analytics from saved results.
385
377
 
386
378
  Analyzes historical progressive workflow runs to provide insights:
@@ -408,7 +400,7 @@ def generate_cost_analytics(
408
400
  "total_runs": 0,
409
401
  "total_cost": 0.0,
410
402
  "total_savings": 0.0,
411
- "avg_savings_percent": 0.0
403
+ "avg_savings_percent": 0.0,
412
404
  }
413
405
 
414
406
  total_runs = len(results)
@@ -417,8 +409,7 @@ def generate_cost_analytics(
417
409
 
418
410
  # Calculate average savings percent (weighted by cost)
419
411
  weighted_savings = sum(
420
- r.get("cost_savings_percent", 0) * r.get("total_cost", 0)
421
- for r in results
412
+ r.get("cost_savings_percent", 0) * r.get("total_cost", 0) for r in results
422
413
  )
423
414
  avg_savings_percent = weighted_savings / total_cost if total_cost > 0 else 0
424
415
 
@@ -450,7 +441,7 @@ def generate_cost_analytics(
450
441
  "runs": 0,
451
442
  "total_cost": 0.0,
452
443
  "total_savings": 0.0,
453
- "successes": 0
444
+ "successes": 0,
454
445
  }
455
446
 
456
447
  stats = workflow_stats[workflow]
@@ -476,7 +467,7 @@ def generate_cost_analytics(
476
467
  "avg_final_cqs": round(avg_cqs, 1),
477
468
  "tier_usage": tier_usage,
478
469
  "tier_costs": tier_costs,
479
- "workflow_stats": workflow_stats
470
+ "workflow_stats": workflow_stats,
480
471
  }
481
472
 
482
473