empathy-framework 2.4.0__py3-none-any.whl → 3.8.2__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 (329) hide show
  1. coach_wizards/__init__.py +13 -12
  2. coach_wizards/accessibility_wizard.py +12 -12
  3. coach_wizards/api_wizard.py +12 -12
  4. coach_wizards/base_wizard.py +26 -20
  5. coach_wizards/cicd_wizard.py +15 -13
  6. coach_wizards/code_reviewer_README.md +60 -0
  7. coach_wizards/code_reviewer_wizard.py +180 -0
  8. coach_wizards/compliance_wizard.py +12 -12
  9. coach_wizards/database_wizard.py +12 -12
  10. coach_wizards/debugging_wizard.py +12 -12
  11. coach_wizards/documentation_wizard.py +12 -12
  12. coach_wizards/generate_wizards.py +1 -2
  13. coach_wizards/localization_wizard.py +101 -19
  14. coach_wizards/migration_wizard.py +12 -12
  15. coach_wizards/monitoring_wizard.py +12 -12
  16. coach_wizards/observability_wizard.py +12 -12
  17. coach_wizards/performance_wizard.py +12 -12
  18. coach_wizards/prompt_engineering_wizard.py +661 -0
  19. coach_wizards/refactoring_wizard.py +12 -12
  20. coach_wizards/scaling_wizard.py +12 -12
  21. coach_wizards/security_wizard.py +12 -12
  22. coach_wizards/testing_wizard.py +12 -12
  23. empathy_framework-3.8.2.dist-info/METADATA +1176 -0
  24. empathy_framework-3.8.2.dist-info/RECORD +333 -0
  25. empathy_framework-3.8.2.dist-info/entry_points.txt +22 -0
  26. {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/top_level.txt +5 -1
  27. empathy_healthcare_plugin/__init__.py +1 -2
  28. empathy_healthcare_plugin/monitors/__init__.py +9 -0
  29. empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
  30. empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
  31. empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
  32. empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
  33. empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
  34. empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
  35. empathy_llm_toolkit/__init__.py +7 -7
  36. empathy_llm_toolkit/agent_factory/__init__.py +53 -0
  37. empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
  38. empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
  39. empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
  40. empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
  41. empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
  42. empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
  43. empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
  44. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
  45. empathy_llm_toolkit/agent_factory/base.py +305 -0
  46. empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
  47. empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
  48. empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
  49. empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
  50. empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
  51. empathy_llm_toolkit/agent_factory/decorators.py +286 -0
  52. empathy_llm_toolkit/agent_factory/factory.py +558 -0
  53. empathy_llm_toolkit/agent_factory/framework.py +192 -0
  54. empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
  55. empathy_llm_toolkit/agent_factory/resilient.py +320 -0
  56. empathy_llm_toolkit/claude_memory.py +14 -15
  57. empathy_llm_toolkit/cli/__init__.py +8 -0
  58. empathy_llm_toolkit/cli/sync_claude.py +487 -0
  59. empathy_llm_toolkit/code_health.py +186 -28
  60. empathy_llm_toolkit/config/__init__.py +29 -0
  61. empathy_llm_toolkit/config/unified.py +295 -0
  62. empathy_llm_toolkit/contextual_patterns.py +11 -12
  63. empathy_llm_toolkit/core.py +168 -53
  64. empathy_llm_toolkit/git_pattern_extractor.py +17 -13
  65. empathy_llm_toolkit/levels.py +6 -13
  66. empathy_llm_toolkit/pattern_confidence.py +14 -18
  67. empathy_llm_toolkit/pattern_resolver.py +10 -12
  68. empathy_llm_toolkit/pattern_summary.py +16 -14
  69. empathy_llm_toolkit/providers.py +194 -28
  70. empathy_llm_toolkit/routing/__init__.py +32 -0
  71. empathy_llm_toolkit/routing/model_router.py +362 -0
  72. empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
  73. empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
  74. empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
  75. empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
  76. empathy_llm_toolkit/security/README.md +262 -0
  77. empathy_llm_toolkit/security/__init__.py +62 -0
  78. empathy_llm_toolkit/security/audit_logger.py +929 -0
  79. empathy_llm_toolkit/security/audit_logger_example.py +152 -0
  80. empathy_llm_toolkit/security/pii_scrubber.py +640 -0
  81. empathy_llm_toolkit/security/secrets_detector.py +678 -0
  82. empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
  83. empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
  84. empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
  85. empathy_llm_toolkit/session_status.py +20 -22
  86. empathy_llm_toolkit/state.py +28 -21
  87. empathy_llm_toolkit/wizards/__init__.py +38 -0
  88. empathy_llm_toolkit/wizards/base_wizard.py +364 -0
  89. empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
  90. empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
  91. empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
  92. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
  93. empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
  94. empathy_os/__init__.py +125 -84
  95. empathy_os/adaptive/__init__.py +13 -0
  96. empathy_os/adaptive/task_complexity.py +127 -0
  97. empathy_os/{monitoring.py → agent_monitoring.py} +28 -28
  98. empathy_os/cache/__init__.py +117 -0
  99. empathy_os/cache/base.py +166 -0
  100. empathy_os/cache/dependency_manager.py +253 -0
  101. empathy_os/cache/hash_only.py +248 -0
  102. empathy_os/cache/hybrid.py +390 -0
  103. empathy_os/cache/storage.py +282 -0
  104. empathy_os/cli.py +1516 -70
  105. empathy_os/cli_unified.py +597 -0
  106. empathy_os/config/__init__.py +63 -0
  107. empathy_os/config/xml_config.py +239 -0
  108. empathy_os/config.py +95 -37
  109. empathy_os/coordination.py +72 -68
  110. empathy_os/core.py +94 -107
  111. empathy_os/cost_tracker.py +74 -55
  112. empathy_os/dashboard/__init__.py +15 -0
  113. empathy_os/dashboard/server.py +743 -0
  114. empathy_os/discovery.py +17 -14
  115. empathy_os/emergence.py +21 -22
  116. empathy_os/exceptions.py +18 -30
  117. empathy_os/feedback_loops.py +30 -33
  118. empathy_os/levels.py +32 -35
  119. empathy_os/leverage_points.py +31 -32
  120. empathy_os/logging_config.py +19 -16
  121. empathy_os/memory/__init__.py +195 -0
  122. empathy_os/memory/claude_memory.py +466 -0
  123. empathy_os/memory/config.py +224 -0
  124. empathy_os/memory/control_panel.py +1298 -0
  125. empathy_os/memory/edges.py +179 -0
  126. empathy_os/memory/graph.py +567 -0
  127. empathy_os/memory/long_term.py +1194 -0
  128. empathy_os/memory/nodes.py +179 -0
  129. empathy_os/memory/redis_bootstrap.py +540 -0
  130. empathy_os/memory/security/__init__.py +31 -0
  131. empathy_os/memory/security/audit_logger.py +930 -0
  132. empathy_os/memory/security/pii_scrubber.py +640 -0
  133. empathy_os/memory/security/secrets_detector.py +678 -0
  134. empathy_os/memory/short_term.py +2119 -0
  135. empathy_os/memory/storage/__init__.py +15 -0
  136. empathy_os/memory/summary_index.py +583 -0
  137. empathy_os/memory/unified.py +619 -0
  138. empathy_os/metrics/__init__.py +12 -0
  139. empathy_os/metrics/prompt_metrics.py +190 -0
  140. empathy_os/models/__init__.py +136 -0
  141. empathy_os/models/__main__.py +13 -0
  142. empathy_os/models/cli.py +655 -0
  143. empathy_os/models/empathy_executor.py +354 -0
  144. empathy_os/models/executor.py +252 -0
  145. empathy_os/models/fallback.py +671 -0
  146. empathy_os/models/provider_config.py +563 -0
  147. empathy_os/models/registry.py +382 -0
  148. empathy_os/models/tasks.py +302 -0
  149. empathy_os/models/telemetry.py +548 -0
  150. empathy_os/models/token_estimator.py +378 -0
  151. empathy_os/models/validation.py +274 -0
  152. empathy_os/monitoring/__init__.py +52 -0
  153. empathy_os/monitoring/alerts.py +23 -0
  154. empathy_os/monitoring/alerts_cli.py +268 -0
  155. empathy_os/monitoring/multi_backend.py +271 -0
  156. empathy_os/monitoring/otel_backend.py +363 -0
  157. empathy_os/optimization/__init__.py +19 -0
  158. empathy_os/optimization/context_optimizer.py +272 -0
  159. empathy_os/pattern_library.py +30 -29
  160. empathy_os/persistence.py +35 -37
  161. empathy_os/platform_utils.py +261 -0
  162. empathy_os/plugins/__init__.py +28 -0
  163. empathy_os/plugins/base.py +361 -0
  164. empathy_os/plugins/registry.py +268 -0
  165. empathy_os/project_index/__init__.py +30 -0
  166. empathy_os/project_index/cli.py +335 -0
  167. empathy_os/project_index/crew_integration.py +430 -0
  168. empathy_os/project_index/index.py +425 -0
  169. empathy_os/project_index/models.py +501 -0
  170. empathy_os/project_index/reports.py +473 -0
  171. empathy_os/project_index/scanner.py +538 -0
  172. empathy_os/prompts/__init__.py +61 -0
  173. empathy_os/prompts/config.py +77 -0
  174. empathy_os/prompts/context.py +177 -0
  175. empathy_os/prompts/parser.py +285 -0
  176. empathy_os/prompts/registry.py +313 -0
  177. empathy_os/prompts/templates.py +208 -0
  178. empathy_os/redis_config.py +144 -58
  179. empathy_os/redis_memory.py +79 -77
  180. empathy_os/resilience/__init__.py +56 -0
  181. empathy_os/resilience/circuit_breaker.py +256 -0
  182. empathy_os/resilience/fallback.py +179 -0
  183. empathy_os/resilience/health.py +300 -0
  184. empathy_os/resilience/retry.py +209 -0
  185. empathy_os/resilience/timeout.py +135 -0
  186. empathy_os/routing/__init__.py +43 -0
  187. empathy_os/routing/chain_executor.py +433 -0
  188. empathy_os/routing/classifier.py +217 -0
  189. empathy_os/routing/smart_router.py +234 -0
  190. empathy_os/routing/wizard_registry.py +307 -0
  191. empathy_os/templates.py +19 -14
  192. empathy_os/trust/__init__.py +28 -0
  193. empathy_os/trust/circuit_breaker.py +579 -0
  194. empathy_os/trust_building.py +67 -58
  195. empathy_os/validation/__init__.py +19 -0
  196. empathy_os/validation/xml_validator.py +281 -0
  197. empathy_os/wizard_factory_cli.py +170 -0
  198. empathy_os/{workflows.py → workflow_commands.py} +131 -37
  199. empathy_os/workflows/__init__.py +360 -0
  200. empathy_os/workflows/base.py +1660 -0
  201. empathy_os/workflows/bug_predict.py +962 -0
  202. empathy_os/workflows/code_review.py +960 -0
  203. empathy_os/workflows/code_review_adapters.py +310 -0
  204. empathy_os/workflows/code_review_pipeline.py +720 -0
  205. empathy_os/workflows/config.py +600 -0
  206. empathy_os/workflows/dependency_check.py +648 -0
  207. empathy_os/workflows/document_gen.py +1069 -0
  208. empathy_os/workflows/documentation_orchestrator.py +1205 -0
  209. empathy_os/workflows/health_check.py +679 -0
  210. empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
  211. empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
  212. empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
  213. empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
  214. empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
  215. empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
  216. empathy_os/workflows/manage_documentation.py +804 -0
  217. empathy_os/workflows/new_sample_workflow1.py +146 -0
  218. empathy_os/workflows/new_sample_workflow1_README.md +150 -0
  219. empathy_os/workflows/perf_audit.py +687 -0
  220. empathy_os/workflows/pr_review.py +748 -0
  221. empathy_os/workflows/progress.py +445 -0
  222. empathy_os/workflows/progress_server.py +322 -0
  223. empathy_os/workflows/refactor_plan.py +693 -0
  224. empathy_os/workflows/release_prep.py +808 -0
  225. empathy_os/workflows/research_synthesis.py +404 -0
  226. empathy_os/workflows/secure_release.py +585 -0
  227. empathy_os/workflows/security_adapters.py +297 -0
  228. empathy_os/workflows/security_audit.py +1046 -0
  229. empathy_os/workflows/step_config.py +234 -0
  230. empathy_os/workflows/test5.py +125 -0
  231. empathy_os/workflows/test5_README.md +158 -0
  232. empathy_os/workflows/test_gen.py +1855 -0
  233. empathy_os/workflows/test_lifecycle.py +526 -0
  234. empathy_os/workflows/test_maintenance.py +626 -0
  235. empathy_os/workflows/test_maintenance_cli.py +590 -0
  236. empathy_os/workflows/test_maintenance_crew.py +821 -0
  237. empathy_os/workflows/xml_enhanced_crew.py +285 -0
  238. empathy_software_plugin/__init__.py +1 -2
  239. empathy_software_plugin/cli/__init__.py +120 -0
  240. empathy_software_plugin/cli/inspect.py +362 -0
  241. empathy_software_plugin/cli.py +49 -27
  242. empathy_software_plugin/plugin.py +4 -8
  243. empathy_software_plugin/wizards/__init__.py +42 -0
  244. empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
  245. empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
  246. empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
  247. empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
  248. empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
  249. empathy_software_plugin/wizards/base_wizard.py +288 -0
  250. empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
  251. empathy_software_plugin/wizards/code_review_wizard.py +606 -0
  252. empathy_software_plugin/wizards/debugging/__init__.py +50 -0
  253. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
  254. empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
  255. empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
  256. empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
  257. empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
  258. empathy_software_plugin/wizards/debugging/verification.py +369 -0
  259. empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
  260. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
  261. empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
  262. empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
  263. empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
  264. empathy_software_plugin/wizards/performance/__init__.py +9 -0
  265. empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
  266. empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
  267. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
  268. empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
  269. empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
  270. empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
  271. empathy_software_plugin/wizards/security/__init__.py +32 -0
  272. empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
  273. empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
  274. empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
  275. empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
  276. empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
  277. empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
  278. empathy_software_plugin/wizards/testing/__init__.py +27 -0
  279. empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
  280. empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
  281. empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
  282. empathy_software_plugin/wizards/testing_wizard.py +274 -0
  283. hot_reload/README.md +473 -0
  284. hot_reload/__init__.py +62 -0
  285. hot_reload/config.py +84 -0
  286. hot_reload/integration.py +228 -0
  287. hot_reload/reloader.py +298 -0
  288. hot_reload/watcher.py +179 -0
  289. hot_reload/websocket.py +176 -0
  290. scaffolding/README.md +589 -0
  291. scaffolding/__init__.py +35 -0
  292. scaffolding/__main__.py +14 -0
  293. scaffolding/cli.py +240 -0
  294. test_generator/__init__.py +38 -0
  295. test_generator/__main__.py +14 -0
  296. test_generator/cli.py +226 -0
  297. test_generator/generator.py +325 -0
  298. test_generator/risk_analyzer.py +216 -0
  299. workflow_patterns/__init__.py +33 -0
  300. workflow_patterns/behavior.py +249 -0
  301. workflow_patterns/core.py +76 -0
  302. workflow_patterns/output.py +99 -0
  303. workflow_patterns/registry.py +255 -0
  304. workflow_patterns/structural.py +288 -0
  305. workflow_scaffolding/__init__.py +11 -0
  306. workflow_scaffolding/__main__.py +12 -0
  307. workflow_scaffolding/cli.py +206 -0
  308. workflow_scaffolding/generator.py +265 -0
  309. agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
  310. agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
  311. agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
  312. agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
  313. agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
  314. agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
  315. agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
  316. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
  317. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
  318. agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
  319. agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
  320. agents/compliance_anticipation_agent.py +0 -1427
  321. agents/epic_integration_wizard.py +0 -541
  322. agents/trust_building_behaviors.py +0 -891
  323. empathy_framework-2.4.0.dist-info/METADATA +0 -485
  324. empathy_framework-2.4.0.dist-info/RECORD +0 -102
  325. empathy_framework-2.4.0.dist-info/entry_points.txt +0 -6
  326. empathy_llm_toolkit/htmlcov/status.json +0 -1
  327. empathy_llm_toolkit/security/htmlcov/status.json +0 -1
  328. {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/WHEEL +0 -0
  329. {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,5 +1,4 @@
1
- """
2
- Trust-Building Behaviors for Anticipatory AI Agents
1
+ """Trust-Building Behaviors for Anticipatory AI Agents
3
2
 
4
3
  Implements behaviors that build trust through anticipatory actions:
5
4
  - Pre-format data for handoffs (reduce cognitive load)
@@ -29,8 +28,7 @@ logger = logging.getLogger(__name__)
29
28
 
30
29
  @dataclass
31
30
  class TrustSignal:
32
- """
33
- A signal that indicates trust is building or eroding
31
+ """A signal that indicates trust is building or eroding
34
32
 
35
33
  Trust signals help track how trust evolves over time based on
36
34
  observable behaviors and outcomes.
@@ -44,8 +42,7 @@ class TrustSignal:
44
42
 
45
43
 
46
44
  class TrustBuildingBehaviors:
47
- """
48
- Level 4 Anticipatory trust-building behaviors
45
+ """Level 4 Anticipatory trust-building behaviors
49
46
 
50
47
  Philosophy: Trust is earned through consistent, helpful actions that
51
48
  demonstrate understanding of collaboration dynamics and proactive
@@ -76,6 +73,7 @@ class TrustBuildingBehaviors:
76
73
  ... instruction=instruction,
77
74
  ... ambiguities=["which system?", "what changes?"]
78
75
  ... )
76
+
79
77
  """
80
78
 
81
79
  def __init__(self):
@@ -83,10 +81,12 @@ class TrustBuildingBehaviors:
83
81
  self.trust_signals: list[TrustSignal] = []
84
82
 
85
83
  def pre_format_for_handoff(
86
- self, data: dict[str, Any], recipient_role: str, context: str
84
+ self,
85
+ data: dict[str, Any],
86
+ recipient_role: str,
87
+ context: str,
87
88
  ) -> dict[str, Any]:
88
- """
89
- Pre-format data for handoff to reduce recipient's cognitive load
89
+ """Pre-format data for handoff to reduce recipient's cognitive load
90
90
 
91
91
  **Trust Built:**
92
92
  - "This AI understands my workflow"
@@ -109,6 +109,7 @@ class TrustBuildingBehaviors:
109
109
  ... context="board_meeting"
110
110
  ... )
111
111
  >>> # Returns: executive summary format with key highlights
112
+
112
113
  """
113
114
  logger.info(f"Pre-formatting data for handoff to {recipient_role} (context: {context})")
114
115
 
@@ -148,8 +149,7 @@ class TrustBuildingBehaviors:
148
149
  detected_ambiguities: list[str],
149
150
  context: dict[str, Any] | None = None,
150
151
  ) -> dict[str, Any]:
151
- """
152
- Clarify ambiguous instructions before execution to prevent wasted effort
152
+ """Clarify ambiguous instructions before execution to prevent wasted effort
153
153
 
154
154
  **Trust Built:**
155
155
  - "This AI doesn't make dangerous assumptions"
@@ -171,14 +171,16 @@ class TrustBuildingBehaviors:
171
171
  ... instruction=instruction,
172
172
  ... detected_ambiguities=ambiguities
173
173
  ... )
174
+
174
175
  """
175
176
  logger.info(f"Clarifying ambiguous instruction: {instruction}")
176
177
 
177
- clarification = {
178
+ clarifying_questions: list[dict[str, str]] = []
179
+ clarification: dict[str, Any] = {
178
180
  "original_instruction": instruction,
179
181
  "status": "needs_clarification",
180
182
  "ambiguities_detected": detected_ambiguities,
181
- "clarifying_questions": [],
183
+ "clarifying_questions": clarifying_questions,
182
184
  "reasoning": (
183
185
  "Detected ambiguities in instruction. Clarifying before acting "
184
186
  "to prevent wasted effort or incorrect execution."
@@ -189,7 +191,7 @@ class TrustBuildingBehaviors:
189
191
  # Generate specific clarifying questions
190
192
  for ambiguity in detected_ambiguities:
191
193
  question = self._generate_clarifying_question(instruction, ambiguity, context)
192
- clarification["clarifying_questions"].append(question)
194
+ clarifying_questions.append(question)
193
195
 
194
196
  # Record trust signal
195
197
  self._record_trust_signal(
@@ -201,10 +203,11 @@ class TrustBuildingBehaviors:
201
203
  return clarification
202
204
 
203
205
  def volunteer_structure_during_stress(
204
- self, stress_indicators: dict[str, Any], available_scaffolding: list[str]
206
+ self,
207
+ stress_indicators: dict[str, Any],
208
+ available_scaffolding: list[str],
205
209
  ) -> dict[str, Any]:
206
- """
207
- Volunteer structure/scaffolding during stressful situations
210
+ """Volunteer structure/scaffolding during stressful situations
208
211
 
209
212
  **Not pep talks, actual structural help:**
210
213
  - Break down overwhelming tasks
@@ -231,14 +234,16 @@ class TrustBuildingBehaviors:
231
234
  ... stress_indicators=stress,
232
235
  ... available_scaffolding=scaffolding
233
236
  ... )
237
+
234
238
  """
235
239
  logger.info("Volunteering structure during detected stress")
236
240
 
237
241
  stress_level = self._assess_stress_level(stress_indicators)
238
242
 
239
- support = {
243
+ offered_support: list[dict[str, Any]] = []
244
+ support: dict[str, Any] = {
240
245
  "stress_assessment": {"level": stress_level, "indicators": stress_indicators},
241
- "offered_support": [],
246
+ "offered_support": offered_support,
242
247
  "reasoning": (
243
248
  f"Detected {stress_level} stress. Volunteering structural support "
244
249
  "to reduce cognitive load and provide actionable scaffolding."
@@ -249,30 +254,30 @@ class TrustBuildingBehaviors:
249
254
  # Offer appropriate scaffolding based on stress level
250
255
  if stress_level in ["high", "critical"]:
251
256
  if "prioritization" in available_scaffolding:
252
- support["offered_support"].append(
257
+ offered_support.append(
253
258
  {
254
259
  "type": "prioritization",
255
260
  "description": "Help prioritize tasks using urgency-importance matrix",
256
261
  "immediate": True,
257
- }
262
+ },
258
263
  )
259
264
 
260
265
  if "breakdown" in available_scaffolding:
261
- support["offered_support"].append(
266
+ offered_support.append(
262
267
  {
263
268
  "type": "task_breakdown",
264
269
  "description": "Break overwhelming tasks into smaller, manageable steps",
265
270
  "immediate": True,
266
- }
271
+ },
267
272
  )
268
273
 
269
274
  if "templates" in available_scaffolding:
270
- support["offered_support"].append(
275
+ offered_support.append(
271
276
  {
272
277
  "type": "templates",
273
278
  "description": "Provide templates to reduce creation effort",
274
279
  "immediate": False,
275
- }
280
+ },
276
281
  )
277
282
 
278
283
  # Record trust signal
@@ -285,10 +290,11 @@ class TrustBuildingBehaviors:
285
290
  return support
286
291
 
287
292
  def offer_proactive_help(
288
- self, struggle_indicators: dict[str, Any], available_help: list[str]
293
+ self,
294
+ struggle_indicators: dict[str, Any],
295
+ available_help: list[str],
289
296
  ) -> dict[str, Any]:
290
- """
291
- Proactively offer help when collaborator is struggling
297
+ """Proactively offer help when collaborator is struggling
292
298
 
293
299
  **Trust Built:**
294
300
  - "This AI notices when I'm stuck"
@@ -309,14 +315,16 @@ class TrustBuildingBehaviors:
309
315
  ... struggle_indicators=indicators,
310
316
  ... available_help=help_types
311
317
  ... )
318
+
312
319
  """
313
320
  logger.info("Offering proactive help based on struggle indicators")
314
321
 
315
322
  struggle_type = self._classify_struggle(struggle_indicators)
316
323
 
317
- offer = {
324
+ help_offered: list[dict[str, str]] = []
325
+ offer: dict[str, Any] = {
318
326
  "struggle_assessment": {"type": struggle_type, "indicators": struggle_indicators},
319
- "help_offered": [],
327
+ "help_offered": help_offered,
320
328
  "tone": "supportive_not_condescending",
321
329
  "reasoning": (
322
330
  f"Detected {struggle_type} struggle pattern. Offering relevant help "
@@ -328,22 +336,21 @@ class TrustBuildingBehaviors:
328
336
  # Offer appropriate help based on struggle type
329
337
  if struggle_type == "comprehension":
330
338
  if "explanation" in available_help:
331
- offer["help_offered"].append(
332
- {"type": "explanation", "description": "Provide clearer explanation of concept"}
339
+ help_offered.append(
340
+ {
341
+ "type": "explanation",
342
+ "description": "Provide clearer explanation of concept",
343
+ },
333
344
  )
334
345
  if "examples" in available_help:
335
- offer["help_offered"].append(
336
- {"type": "examples", "description": "Show concrete examples"}
337
- )
346
+ help_offered.append({"type": "examples", "description": "Show concrete examples"})
338
347
 
339
348
  elif struggle_type == "execution":
340
349
  if "debugging" in available_help:
341
- offer["help_offered"].append(
342
- {"type": "debugging", "description": "Help debug the issue"}
343
- )
350
+ help_offered.append({"type": "debugging", "description": "Help debug the issue"})
344
351
  if "guidance" in available_help:
345
- offer["help_offered"].append(
346
- {"type": "step_by_step", "description": "Provide step-by-step guidance"}
352
+ help_offered.append(
353
+ {"type": "step_by_step", "description": "Provide step-by-step guidance"},
347
354
  )
348
355
 
349
356
  # Record trust signal
@@ -356,11 +363,11 @@ class TrustBuildingBehaviors:
356
363
  return offer
357
364
 
358
365
  def get_trust_trajectory(self) -> dict[str, Any]:
359
- """
360
- Get trust trajectory based on recorded signals
366
+ """Get trust trajectory based on recorded signals
361
367
 
362
368
  Returns:
363
369
  Analysis of trust evolution over time
370
+
364
371
  """
365
372
  if not self.trust_signals:
366
373
  return {"status": "insufficient_data", "trajectory": "unknown", "signal_count": 0}
@@ -396,12 +403,11 @@ class TrustBuildingBehaviors:
396
403
  """Determine appropriate format based on role and context"""
397
404
  if role in ["executive", "manager", "director"]:
398
405
  return "executive_summary"
399
- elif role in ["developer", "engineer", "analyst"]:
406
+ if role in ["developer", "engineer", "analyst"]:
400
407
  return "technical_detail"
401
- elif role in ["team_lead", "coordinator"]:
408
+ if role in ["team_lead", "coordinator"]:
402
409
  return "action_oriented"
403
- else:
404
- return "general"
410
+ return "general"
405
411
 
406
412
  def _create_executive_summary(self, data: dict, context: str) -> dict:
407
413
  """Create executive summary format"""
@@ -455,20 +461,25 @@ class TrustBuildingBehaviors:
455
461
  """Extract technical notes"""
456
462
  return [f"Data structure: {type(data).__name__}"]
457
463
 
458
- def _extract_immediate_actions(self, data: dict) -> list[str]:
464
+ def _extract_immediate_actions(self, data: dict[str, Any]) -> list[str]:
459
465
  """Extract immediate actions"""
460
466
  if "actions" in data:
461
- return data["actions"][:5]
467
+ actions: list[str] = data["actions"][:5]
468
+ return actions
462
469
  return ["Review data and determine next steps"]
463
470
 
464
- def _extract_priorities(self, data: dict) -> list[str]:
471
+ def _extract_priorities(self, data: dict[str, Any]) -> list[str]:
465
472
  """Extract priorities"""
466
473
  if "priorities" in data:
467
- return data["priorities"]
474
+ priorities: list[str] = data["priorities"]
475
+ return priorities
468
476
  return []
469
477
 
470
478
  def _generate_clarifying_question(
471
- self, instruction: str, ambiguity: str, context: dict | None
479
+ self,
480
+ instruction: str,
481
+ ambiguity: str,
482
+ context: dict | None,
472
483
  ) -> dict[str, str]:
473
484
  """Generate a specific clarifying question"""
474
485
  return {
@@ -484,21 +495,19 @@ class TrustBuildingBehaviors:
484
495
 
485
496
  if stress_score >= 4:
486
497
  return "critical"
487
- elif stress_score >= 3:
498
+ if stress_score >= 3:
488
499
  return "high"
489
- elif stress_score >= 2:
500
+ if stress_score >= 2:
490
501
  return "moderate"
491
- else:
492
- return "low"
502
+ return "low"
493
503
 
494
504
  def _classify_struggle(self, indicators: dict) -> str:
495
505
  """Classify type of struggle"""
496
506
  if "repeated_errors" in indicators:
497
507
  return "execution"
498
- elif "time_on_task" in indicators:
508
+ if "time_on_task" in indicators:
499
509
  return "comprehension"
500
- else:
501
- return "general"
510
+ return "general"
502
511
 
503
512
  def _record_trust_signal(self, signal_type: str, behavior: str, evidence: str | None = None):
504
513
  """Record a trust signal"""
@@ -0,0 +1,19 @@
1
+ """XML validation for XML-enhanced prompts.
2
+
3
+ Provides schema validation and graceful fallbacks.
4
+
5
+ Copyright 2026 Smart-AI-Memory
6
+ Licensed under Fair Source License 0.9
7
+ """
8
+
9
+ from empathy_os.validation.xml_validator import (
10
+ ValidationResult,
11
+ XMLValidator,
12
+ validate_xml_response,
13
+ )
14
+
15
+ __all__ = [
16
+ "XMLValidator",
17
+ "ValidationResult",
18
+ "validate_xml_response",
19
+ ]
@@ -0,0 +1,281 @@
1
+ """XML validation for response verification.
2
+
3
+ Validates XML-structured responses with graceful fallbacks.
4
+
5
+ Copyright 2026 Smart-AI-Memory
6
+ Licensed under Fair Source License 0.9
7
+ """
8
+
9
+ import xml.etree.ElementTree as ET
10
+ from dataclasses import dataclass
11
+ from pathlib import Path
12
+ from typing import Any
13
+
14
+
15
+ @dataclass
16
+ class ValidationResult:
17
+ """Result of XML validation.
18
+
19
+ Attributes:
20
+ is_valid: Whether XML is valid
21
+ error_message: Error message if invalid
22
+ parsed_data: Parsed data if valid
23
+ fallback_used: Whether fallback parsing was used
24
+ """
25
+
26
+ is_valid: bool
27
+ error_message: str | None = None
28
+ parsed_data: dict[str, Any] | None = None
29
+ fallback_used: bool = False
30
+
31
+
32
+ class XMLValidator:
33
+ """Validates XML responses with graceful fallbacks.
34
+
35
+ Supports:
36
+ - Well-formedness validation
37
+ - XSD schema validation (optional)
38
+ - Graceful fallback on validation errors
39
+ - Schema caching for performance
40
+
41
+ Usage:
42
+ validator = XMLValidator()
43
+ result = validator.validate("<thinking>...</thinking>")
44
+
45
+ if result.is_valid:
46
+ data = result.parsed_data
47
+ else:
48
+ # Use fallback parsing
49
+ data = fallback_parse(response)
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ schema_dir: str = ".empathy/schemas",
55
+ strict: bool = False,
56
+ enable_xsd: bool = False,
57
+ ):
58
+ """Initialize validator.
59
+
60
+ Args:
61
+ schema_dir: Directory containing XSD schemas
62
+ strict: If True, fail on validation errors. If False, use fallback.
63
+ enable_xsd: Enable XSD schema validation (requires lxml)
64
+ """
65
+ self.schema_dir = Path(schema_dir)
66
+ self.strict = strict
67
+ self.enable_xsd = enable_xsd
68
+ self._schema_cache: dict[str, Any] = {}
69
+
70
+ # Try to import lxml for XSD validation
71
+ self._lxml_available = False
72
+ if enable_xsd:
73
+ try:
74
+ from lxml import etree as lxml_etree # noqa: F401
75
+
76
+ self._lxml_available = True
77
+ except ImportError:
78
+ pass
79
+
80
+ def validate(self, xml_string: str, schema_name: str | None = None) -> ValidationResult:
81
+ """Validate XML string.
82
+
83
+ Args:
84
+ xml_string: XML content to validate
85
+ schema_name: Optional XSD schema name (e.g., "agent_response")
86
+
87
+ Returns:
88
+ ValidationResult with validation status and parsed data
89
+ """
90
+ # Step 1: Well-formedness validation
91
+ try:
92
+ root = ET.fromstring(xml_string) # nosec B314 - parsing trusted LLM responses
93
+ except ET.ParseError as e:
94
+ if self.strict:
95
+ return ValidationResult(
96
+ is_valid=False,
97
+ error_message=f"XML parsing failed: {e}",
98
+ fallback_used=False,
99
+ )
100
+ # Try fallback parsing
101
+ return self._fallback_parse(xml_string, str(e))
102
+
103
+ # Step 2: XSD schema validation (optional)
104
+ if schema_name and self.enable_xsd and self._lxml_available:
105
+ schema_result = self._validate_with_xsd(xml_string, schema_name)
106
+ if not schema_result.is_valid:
107
+ if self.strict:
108
+ return schema_result
109
+ # Continue with parsed data despite schema error
110
+ return ValidationResult(
111
+ is_valid=True,
112
+ parsed_data=self._extract_data(root),
113
+ fallback_used=True,
114
+ error_message=f"Schema validation failed: {schema_result.error_message}",
115
+ )
116
+
117
+ # Step 3: Extract structured data
118
+ parsed_data = self._extract_data(root)
119
+
120
+ return ValidationResult(
121
+ is_valid=True,
122
+ parsed_data=parsed_data,
123
+ fallback_used=False,
124
+ )
125
+
126
+ def _validate_with_xsd(self, xml_string: str, schema_name: str) -> ValidationResult:
127
+ """Validate XML against XSD schema.
128
+
129
+ Args:
130
+ xml_string: XML content
131
+ schema_name: Schema file name (without .xsd extension)
132
+
133
+ Returns:
134
+ ValidationResult
135
+ """
136
+ if not self._lxml_available:
137
+ return ValidationResult(
138
+ is_valid=False,
139
+ error_message="lxml not available for XSD validation",
140
+ )
141
+
142
+ try:
143
+ from lxml import etree as lxml_etree
144
+ except ImportError:
145
+ return ValidationResult(
146
+ is_valid=False,
147
+ error_message="lxml import failed",
148
+ )
149
+
150
+ # Load schema
151
+ schema_path = self.schema_dir / f"{schema_name}.xsd"
152
+ if not schema_path.exists():
153
+ return ValidationResult(
154
+ is_valid=False,
155
+ error_message=f"Schema not found: {schema_path}",
156
+ )
157
+
158
+ # Check cache
159
+ if schema_name not in self._schema_cache:
160
+ try:
161
+ schema_doc = lxml_etree.parse(str(schema_path))
162
+ self._schema_cache[schema_name] = lxml_etree.XMLSchema(schema_doc)
163
+ except Exception as e:
164
+ return ValidationResult(
165
+ is_valid=False,
166
+ error_message=f"Schema loading failed: {e}",
167
+ )
168
+
169
+ schema = self._schema_cache[schema_name]
170
+
171
+ # Validate
172
+ try:
173
+ xml_doc = lxml_etree.fromstring(xml_string.encode("utf-8"))
174
+ is_valid = schema.validate(xml_doc)
175
+
176
+ if not is_valid:
177
+ error_log = schema.error_log
178
+ return ValidationResult(
179
+ is_valid=False,
180
+ error_message=f"Schema validation failed: {error_log}",
181
+ )
182
+
183
+ return ValidationResult(is_valid=True)
184
+
185
+ except Exception as e:
186
+ return ValidationResult(
187
+ is_valid=False,
188
+ error_message=f"Validation error: {e}",
189
+ )
190
+
191
+ def _fallback_parse(self, xml_string: str, error: str) -> ValidationResult:
192
+ """Attempt fallback parsing of malformed XML.
193
+
194
+ Args:
195
+ xml_string: XML string that failed to parse
196
+ error: Parse error message
197
+
198
+ Returns:
199
+ ValidationResult with fallback data
200
+ """
201
+ # Try to extract data using regex patterns
202
+ import re
203
+
204
+ data: dict[str, Any] = {}
205
+
206
+ # Extract thinking content
207
+ thinking_match = re.search(r"<thinking[^>]*>(.*?)</thinking>", xml_string, re.DOTALL)
208
+ if thinking_match:
209
+ data["thinking"] = thinking_match.group(1).strip()
210
+
211
+ # Extract answer content
212
+ answer_match = re.search(r"<answer[^>]*>(.*?)</answer>", xml_string, re.DOTALL)
213
+ if answer_match:
214
+ data["answer"] = answer_match.group(1).strip()
215
+
216
+ # If we extracted something, consider it a partial success
217
+ if data:
218
+ return ValidationResult(
219
+ is_valid=True,
220
+ parsed_data=data,
221
+ fallback_used=True,
222
+ error_message=f"XML parsing failed, used fallback: {error}",
223
+ )
224
+
225
+ # Complete failure
226
+ return ValidationResult(
227
+ is_valid=False,
228
+ error_message=f"XML parsing and fallback failed: {error}",
229
+ fallback_used=True,
230
+ )
231
+
232
+ def _extract_data(self, root: ET.Element) -> dict[str, Any]:
233
+ """Extract structured data from parsed XML.
234
+
235
+ Args:
236
+ root: Parsed XML root element
237
+
238
+ Returns:
239
+ Dictionary with extracted data
240
+ """
241
+ data: dict[str, Any] = {}
242
+
243
+ # Extract all child elements
244
+ for child in root:
245
+ # Handle nested elements
246
+ if len(child):
247
+ data[child.tag] = self._extract_data(child)
248
+ else:
249
+ # Leaf node - get text content
250
+ data[child.tag] = child.text if child.text else ""
251
+
252
+ # Also store root attributes
253
+ if root.attrib:
254
+ data["_attributes"] = dict(root.attrib)
255
+
256
+ return data
257
+
258
+
259
+ def validate_xml_response(
260
+ response: str,
261
+ schema_name: str | None = None,
262
+ strict: bool = False,
263
+ ) -> ValidationResult:
264
+ """Convenience function to validate XML response.
265
+
266
+ Args:
267
+ response: XML response string
268
+ schema_name: Optional XSD schema name
269
+ strict: If True, fail on validation errors
270
+
271
+ Returns:
272
+ ValidationResult
273
+
274
+ Example:
275
+ >>> response = "<thinking>Analysis</thinking><answer>Result</answer>"
276
+ >>> result = validate_xml_response(response)
277
+ >>> if result.is_valid:
278
+ ... print(result.parsed_data)
279
+ """
280
+ validator = XMLValidator(strict=strict)
281
+ return validator.validate(response, schema_name)