empathy-framework 4.6.6__py3-none-any.whl → 4.7.1__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 (273) hide show
  1. empathy_framework-4.7.1.dist-info/METADATA +690 -0
  2. empathy_framework-4.7.1.dist-info/RECORD +379 -0
  3. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/top_level.txt +1 -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 2.py +173 -0
  130. empathy_os/vscode_bridge.py +173 -0
  131. empathy_os/workflows/__init__.py +212 -120
  132. empathy_os/workflows/batch_processing.py +8 -24
  133. empathy_os/workflows/bug_predict.py +1 -1
  134. empathy_os/workflows/code_review.py +20 -5
  135. empathy_os/workflows/code_review_pipeline.py +13 -8
  136. empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
  137. empathy_os/workflows/manage_documentation.py +1 -0
  138. empathy_os/workflows/orchestrated_health_check.py +6 -11
  139. empathy_os/workflows/orchestrated_release_prep.py +3 -3
  140. empathy_os/workflows/pr_review.py +18 -10
  141. empathy_os/workflows/progressive/README 2.md +454 -0
  142. empathy_os/workflows/progressive/__init__ 2.py +92 -0
  143. empathy_os/workflows/progressive/__init__.py +2 -12
  144. empathy_os/workflows/progressive/cli 2.py +242 -0
  145. empathy_os/workflows/progressive/cli.py +14 -37
  146. empathy_os/workflows/progressive/core 2.py +488 -0
  147. empathy_os/workflows/progressive/core.py +12 -12
  148. empathy_os/workflows/progressive/orchestrator 2.py +701 -0
  149. empathy_os/workflows/progressive/orchestrator.py +166 -144
  150. empathy_os/workflows/progressive/reports 2.py +528 -0
  151. empathy_os/workflows/progressive/reports.py +22 -31
  152. empathy_os/workflows/progressive/telemetry 2.py +280 -0
  153. empathy_os/workflows/progressive/telemetry.py +8 -14
  154. empathy_os/workflows/progressive/test_gen 2.py +514 -0
  155. empathy_os/workflows/progressive/test_gen.py +29 -48
  156. empathy_os/workflows/progressive/workflow 2.py +628 -0
  157. empathy_os/workflows/progressive/workflow.py +31 -70
  158. empathy_os/workflows/release_prep.py +21 -6
  159. empathy_os/workflows/release_prep_crew.py +1 -0
  160. empathy_os/workflows/secure_release.py +13 -6
  161. empathy_os/workflows/security_audit.py +8 -3
  162. empathy_os/workflows/test_coverage_boost_crew.py +3 -2
  163. empathy_os/workflows/test_maintenance_crew.py +1 -0
  164. empathy_os/workflows/test_runner.py +16 -12
  165. empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
  166. empathy_software_plugin/cli.py +0 -122
  167. patterns/README.md +119 -0
  168. patterns/__init__.py +95 -0
  169. patterns/behavior.py +298 -0
  170. patterns/code_review_memory.json +441 -0
  171. patterns/core.py +97 -0
  172. patterns/debugging.json +3763 -0
  173. patterns/empathy.py +268 -0
  174. patterns/health_check_memory.json +505 -0
  175. patterns/input.py +161 -0
  176. patterns/memory_graph.json +8 -0
  177. patterns/refactoring_memory.json +1113 -0
  178. patterns/registry.py +663 -0
  179. patterns/security_memory.json +8 -0
  180. patterns/structural.py +415 -0
  181. patterns/validation.py +194 -0
  182. coach_wizards/__init__.py +0 -45
  183. coach_wizards/accessibility_wizard.py +0 -91
  184. coach_wizards/api_wizard.py +0 -91
  185. coach_wizards/base_wizard.py +0 -209
  186. coach_wizards/cicd_wizard.py +0 -91
  187. coach_wizards/code_reviewer_README.md +0 -60
  188. coach_wizards/code_reviewer_wizard.py +0 -180
  189. coach_wizards/compliance_wizard.py +0 -91
  190. coach_wizards/database_wizard.py +0 -91
  191. coach_wizards/debugging_wizard.py +0 -91
  192. coach_wizards/documentation_wizard.py +0 -91
  193. coach_wizards/generate_wizards.py +0 -347
  194. coach_wizards/localization_wizard.py +0 -173
  195. coach_wizards/migration_wizard.py +0 -91
  196. coach_wizards/monitoring_wizard.py +0 -91
  197. coach_wizards/observability_wizard.py +0 -91
  198. coach_wizards/performance_wizard.py +0 -91
  199. coach_wizards/prompt_engineering_wizard.py +0 -661
  200. coach_wizards/refactoring_wizard.py +0 -91
  201. coach_wizards/scaling_wizard.py +0 -90
  202. coach_wizards/security_wizard.py +0 -92
  203. coach_wizards/testing_wizard.py +0 -91
  204. empathy_framework-4.6.6.dist-info/METADATA +0 -1597
  205. empathy_framework-4.6.6.dist-info/RECORD +0 -410
  206. empathy_llm_toolkit/wizards/__init__.py +0 -43
  207. empathy_llm_toolkit/wizards/base_wizard.py +0 -364
  208. empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
  209. empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
  210. empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
  211. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
  212. empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
  213. empathy_os/wizard_factory_cli.py +0 -170
  214. empathy_software_plugin/wizards/__init__.py +0 -42
  215. empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
  216. empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
  217. empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
  218. empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
  219. empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
  220. empathy_software_plugin/wizards/base_wizard.py +0 -288
  221. empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
  222. empathy_software_plugin/wizards/code_review_wizard.py +0 -604
  223. empathy_software_plugin/wizards/debugging/__init__.py +0 -50
  224. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
  225. empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
  226. empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
  227. empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
  228. empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
  229. empathy_software_plugin/wizards/debugging/verification.py +0 -369
  230. empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
  231. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
  232. empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
  233. empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
  234. empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
  235. empathy_software_plugin/wizards/performance/__init__.py +0 -9
  236. empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
  237. empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
  238. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
  239. empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
  240. empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
  241. empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
  242. empathy_software_plugin/wizards/security/__init__.py +0 -32
  243. empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
  244. empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
  245. empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
  246. empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
  247. empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
  248. empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
  249. empathy_software_plugin/wizards/testing/__init__.py +0 -27
  250. empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
  251. empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
  252. empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
  253. empathy_software_plugin/wizards/testing_wizard.py +0 -274
  254. wizards/__init__.py +0 -82
  255. wizards/admission_assessment_wizard.py +0 -644
  256. wizards/care_plan.py +0 -321
  257. wizards/clinical_assessment.py +0 -769
  258. wizards/discharge_planning.py +0 -77
  259. wizards/discharge_summary_wizard.py +0 -468
  260. wizards/dosage_calculation.py +0 -497
  261. wizards/incident_report_wizard.py +0 -454
  262. wizards/medication_reconciliation.py +0 -85
  263. wizards/nursing_assessment.py +0 -171
  264. wizards/patient_education.py +0 -654
  265. wizards/quality_improvement.py +0 -705
  266. wizards/sbar_report.py +0 -324
  267. wizards/sbar_wizard.py +0 -608
  268. wizards/shift_handoff_wizard.py +0 -535
  269. wizards/soap_note_wizard.py +0 -679
  270. wizards/treatment_plan.py +0 -15
  271. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/WHEEL +0 -0
  272. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/entry_points.txt +0 -0
  273. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/licenses/LICENSE +0 -0
@@ -65,16 +65,20 @@ class ReactFormSchema:
65
65
  "pattern": f.validation.pattern,
66
66
  },
67
67
  "showWhen": f.show_when,
68
- "options": [
69
- {
70
- "value": o.value,
71
- "label": o.label,
72
- "description": o.description,
73
- "icon": o.icon,
74
- "recommended": o.recommended,
75
- }
76
- for o in f.options
77
- ] if f.options else None,
68
+ "options": (
69
+ [
70
+ {
71
+ "value": o.value,
72
+ "label": o.label,
73
+ "description": o.description,
74
+ "icon": o.icon,
75
+ "recommended": o.recommended,
76
+ }
77
+ for o in f.options
78
+ ]
79
+ if f.options
80
+ else None
81
+ ),
78
82
  }
79
83
  fields.append(field_schema)
80
84
 
@@ -165,26 +169,34 @@ class ReactBlueprintSchema:
165
169
  """Create schema from a WorkflowBlueprint."""
166
170
  agents = []
167
171
  for agent in blueprint.agents:
168
- agents.append({
169
- "id": agent.spec.id,
170
- "name": agent.spec.name,
171
- "role": agent.spec.role.value,
172
- "goal": agent.spec.goal,
173
- "backstory": agent.spec.backstory[:200] + "..." if len(agent.spec.backstory) > 200 else agent.spec.backstory,
174
- "modelTier": agent.spec.model_tier,
175
- "tools": [t.name for t in agent.spec.tools],
176
- })
172
+ agents.append(
173
+ {
174
+ "id": agent.spec.id,
175
+ "name": agent.spec.name,
176
+ "role": agent.spec.role.value,
177
+ "goal": agent.spec.goal,
178
+ "backstory": (
179
+ agent.spec.backstory[:200] + "..."
180
+ if len(agent.spec.backstory) > 200
181
+ else agent.spec.backstory
182
+ ),
183
+ "modelTier": agent.spec.model_tier,
184
+ "tools": [t.name for t in agent.spec.tools],
185
+ }
186
+ )
177
187
 
178
188
  stages = []
179
189
  for stage in blueprint.stages:
180
- stages.append({
181
- "id": stage.id,
182
- "name": stage.name,
183
- "description": stage.description,
184
- "agents": stage.agent_ids,
185
- "parallel": stage.parallel,
186
- "dependsOn": stage.depends_on,
187
- })
190
+ stages.append(
191
+ {
192
+ "id": stage.id,
193
+ "name": stage.name,
194
+ "description": stage.description,
195
+ "agents": stage.agent_ids,
196
+ "parallel": stage.parallel,
197
+ "dependsOn": stage.depends_on,
198
+ }
199
+ )
188
200
 
189
201
  success_criteria = None
190
202
  if blueprint.success_criteria:
@@ -226,13 +238,13 @@ def render_form_html(form: Form, action_url: str = "/api/socratic/submit") -> st
226
238
  html_parts = [
227
239
  f'<form id="{form.id}" action="{action_url}" method="POST" class="socratic-form">',
228
240
  ' <div class="form-header">',
229
- f' <h2>{_escape_html(form.title)}</h2>',
241
+ f" <h2>{_escape_html(form.title)}</h2>",
230
242
  f' <p class="form-description">{_escape_html(form.description)}</p>',
231
243
  ' <div class="progress-bar">',
232
244
  f' <div class="progress-fill" style="width: {form.progress * 100}%"></div>',
233
245
  f' <span class="progress-text">{form.progress:.0%}</span>',
234
- ' </div>',
235
- ' </div>',
246
+ " </div>",
247
+ " </div>",
236
248
  ' <div class="form-fields">',
237
249
  ]
238
250
 
@@ -242,34 +254,36 @@ def render_form_html(form: Form, action_url: str = "/api/socratic/submit") -> st
242
254
  for category, fields in fields_by_category.items():
243
255
  if len(fields_by_category) > 1:
244
256
  html_parts.append(f' <fieldset class="field-category" data-category="{category}">')
245
- html_parts.append(f' <legend>{category.title()}</legend>')
257
+ html_parts.append(f" <legend>{category.title()}</legend>")
246
258
 
247
259
  for field in fields:
248
260
  html_parts.append(_render_field_html(field))
249
261
 
250
262
  if len(fields_by_category) > 1:
251
- html_parts.append(' </fieldset>')
252
-
253
- html_parts.extend([
254
- ' </div>',
255
- ' <div class="form-actions">',
256
- ' <button type="submit" class="btn-primary">Continue</button>',
257
- ' </div>',
258
- '</form>',
259
- ])
263
+ html_parts.append(" </fieldset>")
264
+
265
+ html_parts.extend(
266
+ [
267
+ " </div>",
268
+ ' <div class="form-actions">',
269
+ ' <button type="submit" class="btn-primary">Continue</button>',
270
+ " </div>",
271
+ "</form>",
272
+ ]
273
+ )
260
274
 
261
275
  return "\n".join(html_parts)
262
276
 
263
277
 
264
278
  def _render_field_html(field: FormField) -> str:
265
279
  """Render a single field as HTML."""
266
- required = 'required' if field.validation.required else ''
267
- required_indicator = '<span class="required">*</span>' if field.validation.required else ''
280
+ required = "required" if field.validation.required else ""
281
+ required_indicator = '<span class="required">*</span>' if field.validation.required else ""
268
282
 
269
283
  # Show when data attribute
270
284
  show_when = ""
271
285
  if field.show_when:
272
- show_when = f' data-show-when=\'{json.dumps(field.show_when)}\''
286
+ show_when = f" data-show-when='{json.dumps(field.show_when)}'"
273
287
 
274
288
  parts = [
275
289
  f' <div class="form-field" data-field-id="{field.id}"{show_when}>',
@@ -283,65 +297,84 @@ def _render_field_html(field: FormField) -> str:
283
297
  if field.field_type == FieldType.SINGLE_SELECT:
284
298
  parts.append(' <div class="radio-group">')
285
299
  for opt in field.options:
286
- rec_class = ' recommended' if opt.recommended else ''
300
+ rec_class = " recommended" if opt.recommended else ""
287
301
  parts.append(f' <label class="radio-option{rec_class}">')
288
- parts.append(f' <input type="radio" name="{field.id}" value="{opt.value}" {required}>')
302
+ parts.append(
303
+ f' <input type="radio" name="{field.id}" value="{opt.value}" {required}>'
304
+ )
289
305
  parts.append(f' <span class="option-label">{_escape_html(opt.label)}</span>')
290
306
  if opt.description:
291
- parts.append(f' <span class="option-desc">{_escape_html(opt.description)}</span>')
292
- parts.append(' </label>')
293
- parts.append(' </div>')
307
+ parts.append(
308
+ f' <span class="option-desc">{_escape_html(opt.description)}</span>'
309
+ )
310
+ parts.append(" </label>")
311
+ parts.append(" </div>")
294
312
 
295
313
  elif field.field_type == FieldType.MULTI_SELECT:
296
314
  parts.append(' <div class="checkbox-group">')
297
315
  for opt in field.options:
298
- rec_class = ' recommended' if opt.recommended else ''
316
+ rec_class = " recommended" if opt.recommended else ""
299
317
  parts.append(f' <label class="checkbox-option{rec_class}">')
300
318
  parts.append(f' <input type="checkbox" name="{field.id}" value="{opt.value}">')
301
319
  parts.append(f' <span class="option-label">{_escape_html(opt.label)}</span>')
302
320
  if opt.description:
303
- parts.append(f' <span class="option-desc">{_escape_html(opt.description)}</span>')
304
- parts.append(' </label>')
305
- parts.append(' </div>')
321
+ parts.append(
322
+ f' <span class="option-desc">{_escape_html(opt.description)}</span>'
323
+ )
324
+ parts.append(" </label>")
325
+ parts.append(" </div>")
306
326
 
307
327
  elif field.field_type == FieldType.TEXT_AREA:
308
- max_len = f' maxlength="{field.validation.max_length}"' if field.validation.max_length else ''
309
- parts.append(f' <textarea id="{field.id}" name="{field.id}" placeholder="{_escape_html(field.placeholder)}"{max_len} {required}></textarea>')
328
+ max_len = (
329
+ f' maxlength="{field.validation.max_length}"' if field.validation.max_length else ""
330
+ )
331
+ parts.append(
332
+ f' <textarea id="{field.id}" name="{field.id}" placeholder="{_escape_html(field.placeholder)}"{max_len} {required}></textarea>'
333
+ )
310
334
 
311
335
  elif field.field_type == FieldType.BOOLEAN:
312
336
  parts.append(' <div class="switch-container">')
313
337
  parts.append(' <label class="switch">')
314
- parts.append(f' <input type="checkbox" id="{field.id}" name="{field.id}" value="true">')
338
+ parts.append(
339
+ f' <input type="checkbox" id="{field.id}" name="{field.id}" value="true">'
340
+ )
315
341
  parts.append(' <span class="slider"></span>')
316
- parts.append(' </label>')
317
- parts.append(' </div>')
342
+ parts.append(" </label>")
343
+ parts.append(" </div>")
318
344
 
319
345
  elif field.field_type == FieldType.SLIDER:
320
346
  min_val = field.validation.min_value or 0
321
347
  max_val = field.validation.max_value or 100
322
348
  parts.append(' <div class="slider-container">')
323
- parts.append(f' <input type="range" id="{field.id}" name="{field.id}" min="{min_val}" max="{max_val}">')
349
+ parts.append(
350
+ f' <input type="range" id="{field.id}" name="{field.id}" min="{min_val}" max="{max_val}">'
351
+ )
324
352
  parts.append(f' <output for="{field.id}"></output>')
325
- parts.append(' </div>')
353
+ parts.append(" </div>")
326
354
 
327
355
  else: # TEXT, NUMBER
328
356
  input_type = "number" if field.field_type == FieldType.NUMBER else "text"
329
- max_len = f' maxlength="{field.validation.max_length}"' if field.validation.max_length else ''
330
- parts.append(f' <input type="{input_type}" id="{field.id}" name="{field.id}" placeholder="{_escape_html(field.placeholder)}"{max_len} {required}>')
357
+ max_len = (
358
+ f' maxlength="{field.validation.max_length}"' if field.validation.max_length else ""
359
+ )
360
+ parts.append(
361
+ f' <input type="{input_type}" id="{field.id}" name="{field.id}" placeholder="{_escape_html(field.placeholder)}"{max_len} {required}>'
362
+ )
331
363
 
332
- parts.append(' </div>')
364
+ parts.append(" </div>")
333
365
 
334
366
  return "\n".join(parts)
335
367
 
336
368
 
337
369
  def _escape_html(text: str) -> str:
338
370
  """Escape HTML special characters."""
339
- return (text
340
- .replace("&", "&amp;")
371
+ return (
372
+ text.replace("&", "&amp;")
341
373
  .replace("<", "&lt;")
342
374
  .replace(">", "&gt;")
343
375
  .replace('"', "&quot;")
344
- .replace("'", "&#x27;"))
376
+ .replace("'", "&#x27;")
377
+ )
345
378
 
346
379
 
347
380
  # =============================================================================
@@ -908,7 +941,7 @@ def render_complete_page(form: Form, session: SocraticSession) -> str:
908
941
  <body>
909
942
  <div class="container">
910
943
  <div class="session-info">
911
- <span class="domain-badge">{session_data.domain or 'General'}</span>
944
+ <span class="domain-badge">{session_data.domain or "General"}</span>
912
945
  <span class="confidence">Confidence: {session_data.confidence:.0%}</span>
913
946
  </div>
914
947
 
@@ -1493,7 +1493,9 @@ def cmd_file_test_status(args: Any) -> int:
1493
1493
  stale_marker = " [STALE]" if record.is_stale else ""
1494
1494
  print(f"\n{record.file_path}")
1495
1495
  print(f" Status: {status}{stale_marker}")
1496
- print(f" Tests: {record.test_count} (passed: {record.passed}, failed: {record.failed})")
1496
+ print(
1497
+ f" Tests: {record.test_count} (passed: {record.passed}, failed: {record.failed})"
1498
+ )
1497
1499
  if record.duration_seconds:
1498
1500
  print(f" Duration: {record.duration_seconds:.1f}s")
1499
1501
  print(f" Last Run: {record.timestamp[:19]}")
@@ -566,9 +566,7 @@ class UsageTracker:
566
566
  # Calculate hit rates for workflows
567
567
  for wf_stats in by_workflow.values():
568
568
  wf_requests = wf_stats["requests"]
569
- wf_stats["hit_rate"] = (
570
- (wf_stats["hits"] / wf_requests) if wf_requests > 0 else 0.0
571
- )
569
+ wf_stats["hit_rate"] = (wf_stats["hits"] / wf_requests) if wf_requests > 0 else 0.0
572
570
 
573
571
  return {
574
572
  "hit_rate": round(hit_rate, 4),
@@ -1,6 +1,6 @@
1
- """Risk-Driven Test Generator for Wizard Factory.
1
+ """Risk-Driven Test Generator for Workflow Factory.
2
2
 
3
- Generates comprehensive tests for wizards based on risk analysis and patterns.
3
+ Generates comprehensive tests for workflows based on risk analysis and patterns.
4
4
 
5
5
  Features:
6
6
  - Risk-based test prioritization
@@ -14,7 +14,7 @@ Usage:
14
14
 
15
15
  generator = TestGenerator()
16
16
  tests = generator.generate_tests(
17
- wizard_id="soap_note",
17
+ workflow_id="soap_note",
18
18
  pattern_ids=["linear_flow", "approval", "structured_fields"]
19
19
  )
20
20
 
@@ -28,33 +28,33 @@ logger = logging.getLogger(__name__)
28
28
 
29
29
 
30
30
  def cmd_generate(args):
31
- """Generate tests for a wizard.
31
+ """Generate tests for a workflow.
32
32
 
33
33
  Args:
34
34
  args: Command line arguments
35
35
 
36
36
  """
37
- wizard_id = args.wizard_id
37
+ workflow_id = args.workflow_id
38
38
  pattern_ids = args.patterns.split(",") if args.patterns else []
39
39
 
40
- logger.info(f"Generating tests for wizard: {wizard_id}")
40
+ logger.info(f"Generating tests for workflow: {workflow_id}")
41
41
  logger.info(f"Patterns: {', '.join(pattern_ids)}")
42
42
 
43
43
  # Generate tests
44
44
  generator = TestGenerator()
45
45
  tests = generator.generate_tests(
46
- wizard_id=wizard_id,
46
+ workflow_id=workflow_id,
47
47
  pattern_ids=pattern_ids,
48
- wizard_module=args.module,
49
- wizard_class=args.wizard_class,
48
+ workflow_module=args.module,
49
+ workflow_class=args.workflow_class,
50
50
  )
51
51
 
52
52
  # Determine output directory
53
- output_dir = Path(args.output) if args.output else Path("tests/unit/wizards")
53
+ output_dir = Path(args.output) if args.output else Path("tests/unit/workflows")
54
54
  output_dir.mkdir(parents=True, exist_ok=True)
55
55
 
56
56
  # Write unit tests
57
- unit_test_file = output_dir / f"test_{wizard_id}_wizard.py"
57
+ unit_test_file = output_dir / f"test_{workflow_id}_workflow.py"
58
58
  validated_unit_test = _validate_file_path(str(unit_test_file))
59
59
  with open(validated_unit_test, "w") as f:
60
60
  f.write(tests["unit"])
@@ -63,7 +63,7 @@ def cmd_generate(args):
63
63
  # Write integration tests (if generated)
64
64
  if tests["integration"]:
65
65
  integration_test_file = (
66
- output_dir.parent.parent / "integration" / f"test_{wizard_id}_integration.py"
66
+ output_dir.parent.parent / "integration" / f"test_{workflow_id}_integration.py"
67
67
  )
68
68
  integration_test_file.parent.mkdir(parents=True, exist_ok=True)
69
69
  validated_integration = _validate_file_path(str(integration_test_file))
@@ -72,7 +72,7 @@ def cmd_generate(args):
72
72
  logger.info(f"✓ Integration tests written to: {validated_integration}")
73
73
 
74
74
  # Write fixtures
75
- fixtures_file = output_dir / f"fixtures_{wizard_id}.py"
75
+ fixtures_file = output_dir / f"fixtures_{workflow_id}.py"
76
76
  validated_fixtures = _validate_file_path(str(fixtures_file))
77
77
  with open(validated_fixtures, "w") as f:
78
78
  f.write(tests["fixtures"])
@@ -92,24 +92,24 @@ def cmd_generate(args):
92
92
 
93
93
 
94
94
  def cmd_analyze(args):
95
- """Analyze wizard risk and show recommendations.
95
+ """Analyze workflow risk and show recommendations.
96
96
 
97
97
  Args:
98
98
  args: Command line arguments
99
99
 
100
100
  """
101
- wizard_id = args.wizard_id
101
+ workflow_id = args.workflow_id
102
102
  pattern_ids = args.patterns.split(",") if args.patterns else []
103
103
 
104
- logger.info(f"Analyzing wizard: {wizard_id}")
104
+ logger.info(f"Analyzing workflow: {workflow_id}")
105
105
 
106
106
  # Perform risk analysis
107
107
  analyzer = RiskAnalyzer()
108
- analysis = analyzer.analyze(wizard_id, pattern_ids)
108
+ analysis = analyzer.analyze(workflow_id, pattern_ids)
109
109
 
110
110
  # Display results
111
111
  print(f"\n{'=' * 60}")
112
- print(f"Risk Analysis: {wizard_id}")
112
+ print(f"Risk Analysis: {workflow_id}")
113
113
  print(f"{'=' * 60}\n")
114
114
 
115
115
  print(f"Patterns Used: {len(analysis.pattern_ids)}")
@@ -148,7 +148,7 @@ def cmd_analyze(args):
148
148
  # JSON output if requested
149
149
  if args.json:
150
150
  json_output = analysis.to_dict()
151
- json_file = Path(f"{wizard_id}_risk_analysis.json")
151
+ json_file = Path(f"{workflow_id}_risk_analysis.json")
152
152
  with open(json_file, "w") as f:
153
153
  json.dump(json_output, f, indent=2)
154
154
  print(f"\n✓ JSON output written to: {json_file}")
@@ -157,18 +157,18 @@ def cmd_analyze(args):
157
157
  def main():
158
158
  """Main CLI entry point."""
159
159
  parser = argparse.ArgumentParser(
160
- description="Test Generator for Empathy Wizard Factory",
160
+ description="Test Generator for Empathy Workflow Factory",
161
161
  formatter_class=argparse.RawDescriptionHelpFormatter,
162
162
  epilog="""
163
163
  Examples:
164
- # Generate tests for SOAP Note wizard
164
+ # Generate tests for SOAP Note workflow
165
165
  %(prog)s generate soap_note --patterns linear_flow,approval,structured_fields
166
166
 
167
- # Analyze risk for debugging wizard
167
+ # Analyze risk for debugging workflow
168
168
  %(prog)s analyze debugging --patterns code_analysis_input,risk_assessment
169
169
 
170
170
  # Generate with custom module/class
171
- %(prog)s generate my_wizard --patterns linear_flow --module wizards.my_wizard --class MyWizard
171
+ %(prog)s generate my_workflow --patterns linear_flow --module workflows.my_workflow --class MyWorkflow
172
172
 
173
173
  # Output to custom directory
174
174
  %(prog)s generate soap_note --patterns linear_flow --output tests/custom/
@@ -178,8 +178,8 @@ Examples:
178
178
  subparsers = parser.add_subparsers(dest="command", help="Command to run")
179
179
 
180
180
  # Generate command
181
- gen_parser = subparsers.add_parser("generate", help="Generate tests for a wizard")
182
- gen_parser.add_argument("wizard_id", help="Wizard identifier (e.g., soap_note)")
181
+ gen_parser = subparsers.add_parser("generate", help="Generate tests for a workflow")
182
+ gen_parser.add_argument("workflow_id", help="Workflow identifier (e.g., soap_note)")
183
183
  gen_parser.add_argument(
184
184
  "--patterns",
185
185
  required=True,
@@ -187,22 +187,22 @@ Examples:
187
187
  )
188
188
  gen_parser.add_argument(
189
189
  "--module",
190
- help="Python module path (e.g., wizards.soap_note)",
190
+ help="Python module path (e.g., workflows.soap_note)",
191
191
  )
192
192
  gen_parser.add_argument(
193
193
  "--class",
194
- dest="wizard_class",
195
- help="Wizard class name (e.g., SOAPNoteWizard)",
194
+ dest="workflow_class",
195
+ help="Workflow class name (e.g., SOAPNoteWorkflow)",
196
196
  )
197
197
  gen_parser.add_argument(
198
198
  "--output",
199
199
  "-o",
200
- help="Output directory (default: tests/unit/wizards/)",
200
+ help="Output directory (default: tests/unit/workflows/)",
201
201
  )
202
202
 
203
203
  # Analyze command
204
- analyze_parser = subparsers.add_parser("analyze", help="Analyze wizard risk")
205
- analyze_parser.add_argument("wizard_id", help="Wizard identifier")
204
+ analyze_parser = subparsers.add_parser("analyze", help="Analyze workflow risk")
205
+ analyze_parser.add_argument("workflow_id", help="Workflow identifier")
206
206
  analyze_parser.add_argument(
207
207
  "--patterns",
208
208
  required=True,