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
@@ -1,9 +1,9 @@
1
- """CLI for wizard scaffolding.
1
+ """CLI for workflow scaffolding.
2
2
 
3
3
  Usage:
4
- python -m scaffolding create my_wizard --domain healthcare
5
- python -m scaffolding create my_wizard --methodology tdd --domain finance
6
- python -m scaffolding create my_wizard --interactive
4
+ python -m scaffolding create my_workflow --domain healthcare
5
+ python -m scaffolding create my_workflow --methodology tdd --domain finance
6
+ python -m scaffolding create my_workflow --interactive
7
7
 
8
8
  Copyright 2025 Smart AI Memory, LLC
9
9
  Licensed under Fair Source 0.9
@@ -26,29 +26,29 @@ logger = logging.getLogger(__name__)
26
26
 
27
27
 
28
28
  def cmd_create(args):
29
- """Create a new wizard using specified methodology.
29
+ """Create a new workflow using specified methodology.
30
30
 
31
31
  Args:
32
32
  args: Command line arguments
33
33
 
34
34
  """
35
- wizard_name = args.name
35
+ workflow_name = args.name
36
36
  domain = args.domain or "general"
37
- wizard_type = args.type or "domain"
37
+ workflow_type = args.type or "domain"
38
38
  methodology = args.methodology or "pattern"
39
39
 
40
40
  print(f"\n{'=' * 60}")
41
- print(f"Creating Wizard: {wizard_name}")
41
+ print(f"Creating Workflow: {workflow_name}")
42
42
  print(f"{'=' * 60}\n")
43
43
  print(f"Domain: {domain}")
44
- print(f"Type: {wizard_type}")
44
+ print(f"Type: {workflow_type}")
45
45
  print(f"Methodology: {methodology}")
46
46
  print()
47
47
 
48
48
  # Get pattern recommendations
49
49
  registry = get_pattern_registry()
50
- recommended = registry.recommend_for_wizard(
51
- wizard_type=wizard_type,
50
+ recommended = registry.recommend_for_workflow(
51
+ workflow_type=workflow_type,
52
52
  domain=domain,
53
53
  )
54
54
 
@@ -82,23 +82,23 @@ def cmd_create(args):
82
82
  for pid in selected_patterns:
83
83
  print(f" - {pid}")
84
84
 
85
- # Create wizard using selected methodology
86
- print(f"\nCreating wizard with {methodology} methodology...")
85
+ # Create workflow using selected methodology
86
+ print(f"\nCreating workflow with {methodology} methodology...")
87
87
 
88
88
  if methodology == "pattern":
89
89
  method = PatternCompose()
90
- result = method.create_wizard(
91
- name=wizard_name,
90
+ result = method.create_workflow(
91
+ name=workflow_name,
92
92
  domain=domain,
93
- wizard_type=wizard_type,
93
+ workflow_type=workflow_type,
94
94
  selected_patterns=selected_patterns,
95
95
  )
96
96
  elif methodology == "tdd":
97
97
  method = TDDFirst()
98
- result = method.create_wizard(
99
- name=wizard_name,
98
+ result = method.create_workflow(
99
+ name=workflow_name,
100
100
  domain=domain,
101
- wizard_type=wizard_type,
101
+ workflow_type=workflow_type,
102
102
  pattern_ids=selected_patterns,
103
103
  )
104
104
  else:
@@ -107,7 +107,7 @@ def cmd_create(args):
107
107
 
108
108
  # Display results
109
109
  print(f"\n{'=' * 60}")
110
- print("✅ Wizard Created Successfully!")
110
+ print("✅ Workflow Created Successfully!")
111
111
  print(f"{'=' * 60}\n")
112
112
 
113
113
  print("Generated Files:")
@@ -162,21 +162,21 @@ def cmd_list_patterns(args):
162
162
  def main():
163
163
  """Main CLI entry point."""
164
164
  parser = argparse.ArgumentParser(
165
- description="Wizard Scaffolding for Empathy Framework",
165
+ description="Workflow Scaffolding for Empathy Framework",
166
166
  formatter_class=argparse.RawDescriptionHelpFormatter,
167
167
  epilog="""
168
168
  Examples:
169
- # Create healthcare wizard (recommended approach)
169
+ # Create healthcare workflow (recommended approach)
170
170
  %(prog)s create patient_intake --domain healthcare
171
171
 
172
172
  # Create with TDD methodology
173
- %(prog)s create my_wizard --methodology tdd --domain finance
173
+ %(prog)s create my_workflow --methodology tdd --domain finance
174
174
 
175
175
  # Interactive pattern selection
176
- %(prog)s create my_wizard --interactive --domain legal
176
+ %(prog)s create my_workflow --interactive --domain legal
177
177
 
178
178
  # Specify patterns manually
179
- %(prog)s create my_wizard --patterns linear_flow,approval,structured_fields
179
+ %(prog)s create my_workflow --patterns linear_flow,approval,structured_fields
180
180
 
181
181
  # List available patterns
182
182
  %(prog)s list-patterns
@@ -186,8 +186,8 @@ Examples:
186
186
  subparsers = parser.add_subparsers(dest="command", help="Command to run")
187
187
 
188
188
  # Create command
189
- create_parser = subparsers.add_parser("create", help="Create a new wizard")
190
- create_parser.add_argument("name", help="Wizard name (e.g., patient_intake)")
189
+ create_parser = subparsers.add_parser("create", help="Create a new workflow")
190
+ create_parser.add_argument("name", help="Workflow name (e.g., patient_intake)")
191
191
  create_parser.add_argument(
192
192
  "--domain",
193
193
  "-d",
@@ -197,7 +197,7 @@ Examples:
197
197
  "--type",
198
198
  "-t",
199
199
  choices=["domain", "coach", "ai"],
200
- help="Wizard type (default: domain)",
200
+ help="Workflow type (default: domain)",
201
201
  )
202
202
  create_parser.add_argument(
203
203
  "--methodology",
@@ -43,12 +43,7 @@ from .ab_testing import (
43
43
  Variant,
44
44
  WorkflowABTester,
45
45
  )
46
- from .blueprint import (
47
- AgentBlueprint,
48
- AgentSpec,
49
- ToolSpec,
50
- WorkflowBlueprint,
51
- )
46
+ from .blueprint import AgentBlueprint, AgentSpec, ToolSpec, WorkflowBlueprint
52
47
 
53
48
  # CLI interface
54
49
  from .cli import Console
@@ -110,13 +105,7 @@ from .feedback import (
110
105
  FeedbackLoop,
111
106
  WorkflowPattern,
112
107
  )
113
- from .forms import (
114
- FieldType,
115
- Form,
116
- FormField,
117
- FormResponse,
118
- ValidationResult,
119
- )
108
+ from .forms import FieldType, Form, FormField, FormResponse, ValidationResult
120
109
  from .generator import AgentGenerator
121
110
 
122
111
  # LLM-powered analysis
@@ -133,12 +122,7 @@ from .mcp_server import SOCRATIC_TOOLS, SocraticMCPServer
133
122
  from .session import SessionState, SocraticSession
134
123
 
135
124
  # Persistent storage
136
- from .storage import (
137
- JSONFileStorage,
138
- SQLiteStorage,
139
- StorageBackend,
140
- StorageManager,
141
- )
125
+ from .storage import JSONFileStorage, SQLiteStorage, StorageBackend, StorageManager
142
126
  from .success import MetricType, SuccessCriteria, SuccessMetric
143
127
 
144
128
  # Visual editor
@@ -166,24 +166,16 @@ class Experiment:
166
166
  variants=[Variant.from_dict(v) for v in data["variants"]],
167
167
  domain_filter=data.get("domain_filter"),
168
168
  goal_filter=data.get("goal_filter"),
169
- allocation_strategy=AllocationStrategy(
170
- data.get("allocation_strategy", "fixed")
171
- ),
169
+ allocation_strategy=AllocationStrategy(data.get("allocation_strategy", "fixed")),
172
170
  min_sample_size=data.get("min_sample_size", 100),
173
171
  max_duration_days=data.get("max_duration_days", 30),
174
172
  confidence_level=data.get("confidence_level", 0.95),
175
173
  status=ExperimentStatus(data.get("status", "draft")),
176
174
  created_at=datetime.fromisoformat(data["created_at"]),
177
175
  started_at=(
178
- datetime.fromisoformat(data["started_at"])
179
- if data.get("started_at")
180
- else None
181
- ),
182
- ended_at=(
183
- datetime.fromisoformat(data["ended_at"])
184
- if data.get("ended_at")
185
- else None
176
+ datetime.fromisoformat(data["started_at"]) if data.get("started_at") else None
186
177
  ),
178
+ ended_at=(datetime.fromisoformat(data["ended_at"]) if data.get("ended_at") else None),
187
179
  )
188
180
 
189
181
  @property
@@ -360,7 +352,7 @@ class StatisticalAnalyzer:
360
352
  # Continued fraction approximation (simplified)
361
353
  result = 0.0
362
354
  for k in range(100):
363
- term = (x ** k) * math.gamma(a + k) / (math.gamma(k + 1) * math.gamma(a))
355
+ term = (x**k) * math.gamma(a + k) / (math.gamma(k + 1) * math.gamma(a))
364
356
  result += term * ((1 - x) ** b) / (a + k)
365
357
  if abs(term) < 1e-10:
366
358
  break
@@ -421,10 +413,12 @@ class TrafficAllocator:
421
413
  def _fixed_allocation(self, user_id: str) -> Variant:
422
414
  """Deterministic allocation based on user ID hash."""
423
415
  # Hash user ID for consistent assignment (not for security)
424
- hash_val = int(hashlib.md5(
425
- f"{self.experiment.experiment_id}:{user_id}".encode(),
426
- usedforsecurity=False
427
- ).hexdigest(), 16)
416
+ hash_val = int(
417
+ hashlib.md5(
418
+ f"{self.experiment.experiment_id}:{user_id}".encode(), usedforsecurity=False
419
+ ).hexdigest(),
420
+ 16,
421
+ )
428
422
  bucket = hash_val % 100
429
423
 
430
424
  cumulative = 0.0
@@ -471,12 +465,10 @@ class TrafficAllocator:
471
465
  for variant in self.experiment.variants:
472
466
  if variant.impressions == 0:
473
467
  # Give unvisited variants high priority
474
- ucb_scores.append((float('inf'), variant))
468
+ ucb_scores.append((float("inf"), variant))
475
469
  else:
476
470
  mean = variant.avg_success_score
477
- exploration = math.sqrt(
478
- 2 * math.log(total_impressions) / variant.impressions
479
- )
471
+ exploration = math.sqrt(2 * math.log(total_impressions) / variant.impressions)
480
472
  ucb = mean + exploration
481
473
  ucb_scores.append((ucb, variant))
482
474
 
@@ -532,9 +524,7 @@ class ExperimentManager:
532
524
  Returns:
533
525
  Created experiment
534
526
  """
535
- experiment_id = hashlib.sha256(
536
- f"{name}:{time.time()}".encode()
537
- ).hexdigest()[:12]
527
+ experiment_id = hashlib.sha256(f"{name}:{time.time()}".encode()).hexdigest()[:12]
538
528
 
539
529
  # Create variants
540
530
  num_variants = 1 + len(treatment_configs)
@@ -552,14 +542,16 @@ class ExperimentManager:
552
542
  ]
553
543
 
554
544
  for i, config in enumerate(treatment_configs):
555
- variants.append(Variant(
556
- variant_id=f"{experiment_id}_treatment_{i}",
557
- name=config.get("name", f"Treatment {i + 1}"),
558
- description=config.get("description", ""),
559
- config=config.get("config", config),
560
- is_control=False,
561
- traffic_percentage=traffic_each,
562
- ))
545
+ variants.append(
546
+ Variant(
547
+ variant_id=f"{experiment_id}_treatment_{i}",
548
+ name=config.get("name", f"Treatment {i + 1}"),
549
+ description=config.get("description", ""),
550
+ config=config.get("config", config),
551
+ is_control=False,
552
+ traffic_percentage=traffic_each,
553
+ )
554
+ )
563
555
 
564
556
  experiment = Experiment(
565
557
  experiment_id=experiment_id,
@@ -724,8 +716,7 @@ class ExperimentManager:
724
716
  # Calculate lift
725
717
  if control.conversion_rate > 0:
726
718
  lift = (
727
- (best_treatment.conversion_rate - control.conversion_rate)
728
- / control.conversion_rate
719
+ (best_treatment.conversion_rate - control.conversion_rate) / control.conversion_rate
729
720
  ) * 100
730
721
  else:
731
722
  lift = 0.0
@@ -750,9 +741,7 @@ class ExperimentManager:
750
741
  )
751
742
  else:
752
743
  winner = control
753
- recommendation = (
754
- "Keep control. Treatment did not show improvement."
755
- )
744
+ recommendation = "Keep control. Treatment did not show improvement."
756
745
  else:
757
746
  recommendation = (
758
747
  f"No significant difference detected (p={p_value:.4f}). "
@@ -404,27 +404,21 @@ class WorkflowBlueprint:
404
404
  # Validate all agents
405
405
  for agent in self.agents:
406
406
  if not agent.validate():
407
- errors.extend(
408
- f"Agent '{agent.spec.id}': {e}" for e in agent.validation_errors
409
- )
407
+ errors.extend(f"Agent '{agent.spec.id}': {e}" for e in agent.validation_errors)
410
408
 
411
409
  # Validate stages reference valid agents
412
410
  agent_ids = {a.spec.id for a in self.agents}
413
411
  for stage in self.stages:
414
412
  for agent_id in stage.agent_ids:
415
413
  if agent_id not in agent_ids:
416
- errors.append(
417
- f"Stage '{stage.id}' references unknown agent '{agent_id}'"
418
- )
414
+ errors.append(f"Stage '{stage.id}' references unknown agent '{agent_id}'")
419
415
 
420
416
  # Validate stage dependencies
421
417
  stage_ids = {s.id for s in self.stages}
422
418
  for stage in self.stages:
423
419
  for dep in stage.depends_on:
424
420
  if dep not in stage_ids:
425
- errors.append(
426
- f"Stage '{stage.id}' depends on unknown stage '{dep}'"
427
- )
421
+ errors.append(f"Stage '{stage.id}' depends on unknown stage '{dep}'")
428
422
 
429
423
  return len(errors) == 0, errors
430
424
 
@@ -497,37 +491,43 @@ class WorkflowBlueprint:
497
491
 
498
492
  # Parse tools
499
493
  for tool_data in spec_data.get("tools", []):
500
- spec.tools.append(ToolSpec(
501
- id=tool_data.get("id", ""),
502
- name=tool_data.get("name", ""),
503
- category=ToolCategory(tool_data.get("category", "code_analysis")),
504
- description=tool_data.get("description", ""),
505
- parameters=tool_data.get("parameters", {}),
506
- requires_confirmation=tool_data.get("requires_confirmation", False),
507
- is_mutating=tool_data.get("is_mutating", False),
508
- cost_tier=tool_data.get("cost_tier", "cheap"),
509
- ))
510
-
511
- blueprint.agents.append(AgentBlueprint(
512
- spec=spec,
513
- generated_from=agent_data.get("generated_from", "socratic"),
514
- template_id=agent_data.get("template_id"),
515
- customizations=agent_data.get("customizations", {}),
516
- ))
494
+ spec.tools.append(
495
+ ToolSpec(
496
+ id=tool_data.get("id", ""),
497
+ name=tool_data.get("name", ""),
498
+ category=ToolCategory(tool_data.get("category", "code_analysis")),
499
+ description=tool_data.get("description", ""),
500
+ parameters=tool_data.get("parameters", {}),
501
+ requires_confirmation=tool_data.get("requires_confirmation", False),
502
+ is_mutating=tool_data.get("is_mutating", False),
503
+ cost_tier=tool_data.get("cost_tier", "cheap"),
504
+ )
505
+ )
506
+
507
+ blueprint.agents.append(
508
+ AgentBlueprint(
509
+ spec=spec,
510
+ generated_from=agent_data.get("generated_from", "socratic"),
511
+ template_id=agent_data.get("template_id"),
512
+ customizations=agent_data.get("customizations", {}),
513
+ )
514
+ )
517
515
 
518
516
  # Parse stages
519
517
  for stage_data in data.get("stages", []):
520
- blueprint.stages.append(StageSpec(
521
- id=stage_data.get("id", ""),
522
- name=stage_data.get("name", ""),
523
- description=stage_data.get("description", ""),
524
- agent_ids=stage_data.get("agent_ids", []),
525
- parallel=stage_data.get("parallel", False),
526
- run_when=stage_data.get("run_when"),
527
- depends_on=stage_data.get("depends_on", []),
528
- input_mapping=stage_data.get("input_mapping", {}),
529
- output_aggregation=stage_data.get("output_aggregation", "merge"),
530
- timeout=stage_data.get("timeout", 300),
531
- ))
518
+ blueprint.stages.append(
519
+ StageSpec(
520
+ id=stage_data.get("id", ""),
521
+ name=stage_data.get("name", ""),
522
+ description=stage_data.get("description", ""),
523
+ agent_ids=stage_data.get("agent_ids", []),
524
+ parallel=stage_data.get("parallel", False),
525
+ run_when=stage_data.get("run_when"),
526
+ depends_on=stage_data.get("depends_on", []),
527
+ input_mapping=stage_data.get("input_mapping", {}),
528
+ output_aggregation=stage_data.get("output_aggregation", "merge"),
529
+ timeout=stage_data.get("timeout", 300),
530
+ )
531
+ )
532
532
 
533
533
  return blueprint
@@ -109,17 +109,13 @@ class Console:
109
109
  widths[i] = max(widths[i], len(str(cell)))
110
110
 
111
111
  # Print header
112
- header_line = " | ".join(
113
- self._c("bold", h.ljust(widths[i])) for i, h in enumerate(headers)
114
- )
112
+ header_line = " | ".join(self._c("bold", h.ljust(widths[i])) for i, h in enumerate(headers))
115
113
  print(header_line)
116
114
  print("-" * (sum(widths) + len(widths) * 3 - 1))
117
115
 
118
116
  # Print rows
119
117
  for row in rows:
120
- row_line = " | ".join(
121
- str(cell).ljust(widths[i]) for i, cell in enumerate(row)
122
- )
118
+ row_line = " | ".join(str(cell).ljust(widths[i]) for i, cell in enumerate(row))
123
119
  print(row_line)
124
120
 
125
121
 
@@ -469,12 +465,18 @@ def cmd_list(args: argparse.Namespace) -> int:
469
465
  headers = ["ID", "State", "Goal", "Updated"]
470
466
  rows = []
471
467
  for s in sessions:
472
- rows.append([
473
- s["session_id"][:8],
474
- s["state"],
475
- (s.get("goal") or "")[:40] + "..." if len(s.get("goal") or "") > 40 else s.get("goal") or "",
476
- s.get("updated_at", "")[:16],
477
- ])
468
+ rows.append(
469
+ [
470
+ s["session_id"][:8],
471
+ s["state"],
472
+ (
473
+ (s.get("goal") or "")[:40] + "..."
474
+ if len(s.get("goal") or "") > 40
475
+ else s.get("goal") or ""
476
+ ),
477
+ s.get("updated_at", "")[:16],
478
+ ]
479
+ )
478
480
 
479
481
  console.table(headers, rows)
480
482
  return 0
@@ -495,13 +497,15 @@ def cmd_blueprints(args: argparse.Namespace) -> int:
495
497
  headers = ["ID", "Name", "Domain", "Agents", "Generated"]
496
498
  rows = []
497
499
  for b in blueprints:
498
- rows.append([
499
- b["id"][:8] if b.get("id") else "?",
500
- b.get("name", "")[:30],
501
- b.get("domain", ""),
502
- str(b.get("agents_count", 0)),
503
- (b.get("generated_at") or "")[:16],
504
- ])
500
+ rows.append(
501
+ [
502
+ b["id"][:8] if b.get("id") else "?",
503
+ b.get("name", "")[:30],
504
+ b.get("domain", ""),
505
+ str(b.get("agents_count", 0)),
506
+ (b.get("generated_at") or "")[:16],
507
+ ]
508
+ )
505
509
 
506
510
  console.table(headers, rows)
507
511
  return 0
@@ -625,7 +629,17 @@ def create_parser() -> argparse.ArgumentParser:
625
629
 
626
630
  # list
627
631
  list_parser = subparsers.add_parser("list", help="List sessions")
628
- list_parser.add_argument("--state", "-s", choices=["awaiting_goal", "awaiting_answers", "ready_to_generate", "completed", "cancelled"])
632
+ list_parser.add_argument(
633
+ "--state",
634
+ "-s",
635
+ choices=[
636
+ "awaiting_goal",
637
+ "awaiting_answers",
638
+ "ready_to_generate",
639
+ "completed",
640
+ "cancelled",
641
+ ],
642
+ )
629
643
  list_parser.add_argument("--limit", "-n", type=int, default=20)
630
644
 
631
645
  # blueprints
@@ -348,9 +348,7 @@ class CollaborationManager:
348
348
  Returns:
349
349
  The created session
350
350
  """
351
- session_id = hashlib.sha256(
352
- f"{base_session_id}:{time.time()}".encode()
353
- ).hexdigest()[:12]
351
+ session_id = hashlib.sha256(f"{base_session_id}:{time.time()}".encode()).hexdigest()[:12]
354
352
 
355
353
  owner = Participant(
356
354
  user_id=owner_id,
@@ -485,9 +483,9 @@ class CollaborationManager:
485
483
  if not author:
486
484
  return None
487
485
 
488
- comment_id = hashlib.sha256(
489
- f"{session_id}:{author_id}:{time.time()}".encode()
490
- ).hexdigest()[:12]
486
+ comment_id = hashlib.sha256(f"{session_id}:{author_id}:{time.time()}".encode()).hexdigest()[
487
+ :12
488
+ ]
491
489
 
492
490
  comment = Comment(
493
491
  comment_id=comment_id,
@@ -614,9 +612,14 @@ class CollaborationManager:
614
612
 
615
613
  # Check if already voted
616
614
  existing = next(
617
- (v for v in session.votes
618
- if v.voter_id == voter_id and v.target_type == target_type and v.target_id == target_id),
619
- None
615
+ (
616
+ v
617
+ for v in session.votes
618
+ if v.voter_id == voter_id
619
+ and v.target_type == target_type
620
+ and v.target_id == target_id
621
+ ),
622
+ None,
620
623
  )
621
624
  if existing:
622
625
  # Update existing vote
@@ -676,8 +679,7 @@ class CollaborationManager:
676
679
 
677
680
  # Get votes for this target
678
681
  votes = [
679
- v for v in session.votes
680
- if v.target_type == target_type and v.target_id == target_id
682
+ v for v in session.votes if v.target_type == target_type and v.target_id == target_id
681
683
  ]
682
684
 
683
685
  # Count by type
@@ -686,10 +688,7 @@ class CollaborationManager:
686
688
  abstentions = sum(1 for v in votes if v.vote_type == VoteType.ABSTAIN)
687
689
 
688
690
  # Calculate quorum
689
- eligible_voters = [
690
- p for p in session.participants
691
- if p.role != ParticipantRole.VIEWER
692
- ]
691
+ eligible_voters = [p for p in session.participants if p.role != ParticipantRole.VIEWER]
693
692
  participation_rate = len(votes) / len(eligible_voters) if eligible_voters else 0
694
693
  quorum_reached = participation_rate >= session.quorum
695
694
 
@@ -731,8 +730,7 @@ class CollaborationManager:
731
730
  return []
732
731
 
733
732
  comments = [
734
- c for c in session.comments
735
- if c.target_type == target_type and c.target_id == target_id
733
+ c for c in session.comments if c.target_type == target_type and c.target_id == target_id
736
734
  ]
737
735
 
738
736
  if not include_resolved:
@@ -786,8 +784,7 @@ class CollaborationManager:
786
784
  session = self._sessions.get(session_id)
787
785
  if session:
788
786
  self._track_change(
789
- session, change_type, author_id, description,
790
- before_value, after_value
787
+ session, change_type, author_id, description, before_value, after_value
791
788
  )
792
789
  self._save_session(session)
793
790
 
@@ -818,9 +815,7 @@ class CollaborationManager:
818
815
  after_value: Any = None,
819
816
  ):
820
817
  """Internal method to track a change."""
821
- change_id = hashlib.sha256(
822
- f"{session.session_id}:{time.time()}".encode()
823
- ).hexdigest()[:12]
818
+ change_id = hashlib.sha256(f"{session.session_id}:{time.time()}".encode()).hexdigest()[:12]
824
819
 
825
820
  change = Change(
826
821
  change_id=change_id,
@@ -836,7 +831,9 @@ class CollaborationManager:
836
831
  for listener in self._change_listeners:
837
832
  try:
838
833
  listener(change)
839
- except Exception:
834
+ except Exception: # noqa: BLE001
835
+ # INTENTIONAL: Listener failure should not break change tracking.
836
+ # One bad listener shouldn't prevent others from executing.
840
837
  pass
841
838
 
842
839
  def _save_session(self, session: CollaborativeSession):
@@ -853,7 +850,9 @@ class CollaborationManager:
853
850
  data = json.load(f)
854
851
  session = CollaborativeSession.from_dict(data)
855
852
  self._sessions[session.session_id] = session
856
- except Exception:
853
+ except Exception: # noqa: BLE001
854
+ # INTENTIONAL: Skip corrupted session files gracefully.
855
+ # Loading should not fail due to one malformed file.
857
856
  pass
858
857
 
859
858
  def list_sessions(self) -> list[CollaborativeSession]:
@@ -874,8 +873,7 @@ class CollaborationManager:
874
873
  List of sessions the user participates in
875
874
  """
876
875
  return [
877
- s for s in self._sessions.values()
878
- if any(p.user_id == user_id for p in s.participants)
876
+ s for s in self._sessions.values() if any(p.user_id == user_id for p in s.participants)
879
877
  ]
880
878
 
881
879
 
@@ -930,7 +928,9 @@ class SyncAdapter:
930
928
  for handler in self._event_handlers:
931
929
  try:
932
930
  handler(event)
933
- except Exception:
931
+ except Exception: # noqa: BLE001
932
+ # INTENTIONAL: Handler failure should not prevent other handlers.
933
+ # Event propagation must continue for sync reliability.
934
934
  pass
935
935
 
936
936
  def on_event(self, handler: Callable[[SyncEvent], None]):
@@ -1038,6 +1038,7 @@ class InvitationManager:
1038
1038
  ).hexdigest()[:16]
1039
1039
 
1040
1040
  from datetime import timedelta
1041
+
1041
1042
  expires = datetime.now() + timedelta(hours=expires_hours)
1042
1043
 
1043
1044
  invitation = Invitation(
@@ -1105,7 +1106,8 @@ class InvitationManager:
1105
1106
  """
1106
1107
  now = datetime.now()
1107
1108
  return [
1108
- inv for inv in self._invitations.values()
1109
+ inv
1110
+ for inv in self._invitations.values()
1109
1111
  if inv.session_id == session_id
1110
1112
  and not inv.accepted
1111
1113
  and (inv.expires_at is None or inv.expires_at > now)
@@ -777,7 +777,15 @@ class DomainTemplateRegistry:
777
777
  agents=[SECURITY_SCANNER, COMPLIANCE_AUDITOR, RESULT_SYNTHESIZER],
778
778
  workflows=[SECURITY_AUDIT_WORKFLOW],
779
779
  default_workflow="security_audit_comprehensive",
780
- keywords=["security", "vulnerability", "audit", "compliance", "penetration", "CVE", "OWASP"],
780
+ keywords=[
781
+ "security",
782
+ "vulnerability",
783
+ "audit",
784
+ "compliance",
785
+ "penetration",
786
+ "CVE",
787
+ "OWASP",
788
+ ],
781
789
  required_tools=["read_file", "security_scan"],
782
790
  optional_tools=["grep_code", "analyze_ast"],
783
791
  )