empathy-framework 3.7.0__py3-none-any.whl → 3.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 (267) hide show
  1. coach_wizards/code_reviewer_README.md +60 -0
  2. coach_wizards/code_reviewer_wizard.py +180 -0
  3. {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/METADATA +20 -2
  4. empathy_framework-3.7.1.dist-info/RECORD +327 -0
  5. {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/top_level.txt +5 -1
  6. empathy_healthcare_plugin/monitors/__init__.py +9 -0
  7. empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
  8. empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
  9. empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
  10. empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
  11. empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
  12. empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
  13. empathy_llm_toolkit/agent_factory/__init__.py +53 -0
  14. empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
  15. empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
  16. empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
  17. empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
  18. empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
  19. empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
  20. empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
  21. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
  22. empathy_llm_toolkit/agent_factory/base.py +305 -0
  23. empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
  24. empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
  25. empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
  26. empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
  27. empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
  28. empathy_llm_toolkit/agent_factory/decorators.py +286 -0
  29. empathy_llm_toolkit/agent_factory/factory.py +558 -0
  30. empathy_llm_toolkit/agent_factory/framework.py +192 -0
  31. empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
  32. empathy_llm_toolkit/agent_factory/resilient.py +320 -0
  33. empathy_llm_toolkit/cli/__init__.py +8 -0
  34. empathy_llm_toolkit/cli/sync_claude.py +487 -0
  35. empathy_llm_toolkit/code_health.py +150 -3
  36. empathy_llm_toolkit/config/__init__.py +29 -0
  37. empathy_llm_toolkit/config/unified.py +295 -0
  38. empathy_llm_toolkit/routing/__init__.py +32 -0
  39. empathy_llm_toolkit/routing/model_router.py +362 -0
  40. empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
  41. empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
  42. empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
  43. empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
  44. empathy_llm_toolkit/security/README.md +262 -0
  45. empathy_llm_toolkit/security/__init__.py +62 -0
  46. empathy_llm_toolkit/security/audit_logger.py +929 -0
  47. empathy_llm_toolkit/security/audit_logger_example.py +152 -0
  48. empathy_llm_toolkit/security/pii_scrubber.py +640 -0
  49. empathy_llm_toolkit/security/secrets_detector.py +678 -0
  50. empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
  51. empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
  52. empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
  53. empathy_llm_toolkit/wizards/__init__.py +38 -0
  54. empathy_llm_toolkit/wizards/base_wizard.py +364 -0
  55. empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
  56. empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
  57. empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
  58. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
  59. empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
  60. empathy_os/__init__.py +52 -52
  61. empathy_os/adaptive/__init__.py +13 -0
  62. empathy_os/adaptive/task_complexity.py +127 -0
  63. empathy_os/cli.py +118 -8
  64. empathy_os/cli_unified.py +121 -1
  65. empathy_os/config/__init__.py +63 -0
  66. empathy_os/config/xml_config.py +239 -0
  67. empathy_os/dashboard/__init__.py +15 -0
  68. empathy_os/dashboard/server.py +743 -0
  69. empathy_os/memory/__init__.py +195 -0
  70. empathy_os/memory/claude_memory.py +466 -0
  71. empathy_os/memory/config.py +224 -0
  72. empathy_os/memory/control_panel.py +1298 -0
  73. empathy_os/memory/edges.py +179 -0
  74. empathy_os/memory/graph.py +567 -0
  75. empathy_os/memory/long_term.py +1193 -0
  76. empathy_os/memory/nodes.py +179 -0
  77. empathy_os/memory/redis_bootstrap.py +540 -0
  78. empathy_os/memory/security/__init__.py +31 -0
  79. empathy_os/memory/security/audit_logger.py +930 -0
  80. empathy_os/memory/security/pii_scrubber.py +640 -0
  81. empathy_os/memory/security/secrets_detector.py +678 -0
  82. empathy_os/memory/short_term.py +2119 -0
  83. empathy_os/memory/storage/__init__.py +15 -0
  84. empathy_os/memory/summary_index.py +583 -0
  85. empathy_os/memory/unified.py +619 -0
  86. empathy_os/metrics/__init__.py +12 -0
  87. empathy_os/metrics/prompt_metrics.py +190 -0
  88. empathy_os/models/__init__.py +136 -0
  89. empathy_os/models/__main__.py +13 -0
  90. empathy_os/models/cli.py +655 -0
  91. empathy_os/models/empathy_executor.py +354 -0
  92. empathy_os/models/executor.py +252 -0
  93. empathy_os/models/fallback.py +671 -0
  94. empathy_os/models/provider_config.py +563 -0
  95. empathy_os/models/registry.py +382 -0
  96. empathy_os/models/tasks.py +302 -0
  97. empathy_os/models/telemetry.py +548 -0
  98. empathy_os/models/token_estimator.py +378 -0
  99. empathy_os/models/validation.py +274 -0
  100. empathy_os/monitoring/__init__.py +52 -0
  101. empathy_os/monitoring/alerts.py +23 -0
  102. empathy_os/monitoring/alerts_cli.py +268 -0
  103. empathy_os/monitoring/multi_backend.py +271 -0
  104. empathy_os/monitoring/otel_backend.py +363 -0
  105. empathy_os/optimization/__init__.py +19 -0
  106. empathy_os/optimization/context_optimizer.py +272 -0
  107. empathy_os/plugins/__init__.py +28 -0
  108. empathy_os/plugins/base.py +361 -0
  109. empathy_os/plugins/registry.py +268 -0
  110. empathy_os/project_index/__init__.py +30 -0
  111. empathy_os/project_index/cli.py +335 -0
  112. empathy_os/project_index/crew_integration.py +430 -0
  113. empathy_os/project_index/index.py +425 -0
  114. empathy_os/project_index/models.py +501 -0
  115. empathy_os/project_index/reports.py +473 -0
  116. empathy_os/project_index/scanner.py +538 -0
  117. empathy_os/prompts/__init__.py +61 -0
  118. empathy_os/prompts/config.py +77 -0
  119. empathy_os/prompts/context.py +177 -0
  120. empathy_os/prompts/parser.py +285 -0
  121. empathy_os/prompts/registry.py +313 -0
  122. empathy_os/prompts/templates.py +208 -0
  123. empathy_os/resilience/__init__.py +56 -0
  124. empathy_os/resilience/circuit_breaker.py +256 -0
  125. empathy_os/resilience/fallback.py +179 -0
  126. empathy_os/resilience/health.py +300 -0
  127. empathy_os/resilience/retry.py +209 -0
  128. empathy_os/resilience/timeout.py +135 -0
  129. empathy_os/routing/__init__.py +43 -0
  130. empathy_os/routing/chain_executor.py +433 -0
  131. empathy_os/routing/classifier.py +217 -0
  132. empathy_os/routing/smart_router.py +234 -0
  133. empathy_os/routing/wizard_registry.py +307 -0
  134. empathy_os/trust/__init__.py +28 -0
  135. empathy_os/trust/circuit_breaker.py +579 -0
  136. empathy_os/validation/__init__.py +19 -0
  137. empathy_os/validation/xml_validator.py +281 -0
  138. empathy_os/wizard_factory_cli.py +170 -0
  139. empathy_os/workflows/__init__.py +360 -0
  140. empathy_os/workflows/base.py +1530 -0
  141. empathy_os/workflows/bug_predict.py +962 -0
  142. empathy_os/workflows/code_review.py +960 -0
  143. empathy_os/workflows/code_review_adapters.py +310 -0
  144. empathy_os/workflows/code_review_pipeline.py +720 -0
  145. empathy_os/workflows/config.py +600 -0
  146. empathy_os/workflows/dependency_check.py +648 -0
  147. empathy_os/workflows/document_gen.py +1069 -0
  148. empathy_os/workflows/documentation_orchestrator.py +1205 -0
  149. empathy_os/workflows/health_check.py +679 -0
  150. empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
  151. empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
  152. empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
  153. empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
  154. empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
  155. empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
  156. empathy_os/workflows/manage_documentation.py +804 -0
  157. empathy_os/workflows/new_sample_workflow1.py +146 -0
  158. empathy_os/workflows/new_sample_workflow1_README.md +150 -0
  159. empathy_os/workflows/perf_audit.py +687 -0
  160. empathy_os/workflows/pr_review.py +748 -0
  161. empathy_os/workflows/progress.py +445 -0
  162. empathy_os/workflows/progress_server.py +322 -0
  163. empathy_os/workflows/refactor_plan.py +691 -0
  164. empathy_os/workflows/release_prep.py +808 -0
  165. empathy_os/workflows/research_synthesis.py +404 -0
  166. empathy_os/workflows/secure_release.py +585 -0
  167. empathy_os/workflows/security_adapters.py +297 -0
  168. empathy_os/workflows/security_audit.py +1050 -0
  169. empathy_os/workflows/step_config.py +234 -0
  170. empathy_os/workflows/test5.py +125 -0
  171. empathy_os/workflows/test5_README.md +158 -0
  172. empathy_os/workflows/test_gen.py +1855 -0
  173. empathy_os/workflows/test_lifecycle.py +526 -0
  174. empathy_os/workflows/test_maintenance.py +626 -0
  175. empathy_os/workflows/test_maintenance_cli.py +590 -0
  176. empathy_os/workflows/test_maintenance_crew.py +821 -0
  177. empathy_os/workflows/xml_enhanced_crew.py +285 -0
  178. empathy_software_plugin/cli/__init__.py +120 -0
  179. empathy_software_plugin/cli/inspect.py +362 -0
  180. empathy_software_plugin/cli.py +3 -1
  181. empathy_software_plugin/wizards/__init__.py +42 -0
  182. empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
  183. empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
  184. empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
  185. empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
  186. empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
  187. empathy_software_plugin/wizards/base_wizard.py +288 -0
  188. empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
  189. empathy_software_plugin/wizards/code_review_wizard.py +606 -0
  190. empathy_software_plugin/wizards/debugging/__init__.py +50 -0
  191. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
  192. empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
  193. empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
  194. empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
  195. empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
  196. empathy_software_plugin/wizards/debugging/verification.py +369 -0
  197. empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
  198. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
  199. empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
  200. empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
  201. empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
  202. empathy_software_plugin/wizards/performance/__init__.py +9 -0
  203. empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
  204. empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
  205. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
  206. empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
  207. empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
  208. empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
  209. empathy_software_plugin/wizards/security/__init__.py +32 -0
  210. empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
  211. empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
  212. empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
  213. empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
  214. empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
  215. empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
  216. empathy_software_plugin/wizards/testing/__init__.py +27 -0
  217. empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
  218. empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
  219. empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
  220. empathy_software_plugin/wizards/testing_wizard.py +274 -0
  221. hot_reload/README.md +473 -0
  222. hot_reload/__init__.py +62 -0
  223. hot_reload/config.py +84 -0
  224. hot_reload/integration.py +228 -0
  225. hot_reload/reloader.py +298 -0
  226. hot_reload/watcher.py +179 -0
  227. hot_reload/websocket.py +176 -0
  228. scaffolding/README.md +589 -0
  229. scaffolding/__init__.py +35 -0
  230. scaffolding/__main__.py +14 -0
  231. scaffolding/cli.py +240 -0
  232. test_generator/__init__.py +38 -0
  233. test_generator/__main__.py +14 -0
  234. test_generator/cli.py +226 -0
  235. test_generator/generator.py +325 -0
  236. test_generator/risk_analyzer.py +216 -0
  237. workflow_patterns/__init__.py +33 -0
  238. workflow_patterns/behavior.py +249 -0
  239. workflow_patterns/core.py +76 -0
  240. workflow_patterns/output.py +99 -0
  241. workflow_patterns/registry.py +255 -0
  242. workflow_patterns/structural.py +288 -0
  243. workflow_scaffolding/__init__.py +11 -0
  244. workflow_scaffolding/__main__.py +12 -0
  245. workflow_scaffolding/cli.py +206 -0
  246. workflow_scaffolding/generator.py +265 -0
  247. agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
  248. agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
  249. agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
  250. agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
  251. agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
  252. agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
  253. agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
  254. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
  255. agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
  256. agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
  257. agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
  258. agents/compliance_anticipation_agent.py +0 -1422
  259. agents/compliance_db.py +0 -339
  260. agents/epic_integration_wizard.py +0 -530
  261. agents/notifications.py +0 -291
  262. agents/trust_building_behaviors.py +0 -872
  263. empathy_framework-3.7.0.dist-info/RECORD +0 -105
  264. {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/WHEEL +0 -0
  265. {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/entry_points.txt +0 -0
  266. {empathy_framework-3.7.0.dist-info → empathy_framework-3.7.1.dist-info}/licenses/LICENSE +0 -0
  267. /empathy_os/{monitoring.py → agent_monitoring.py} +0 -0
@@ -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)
@@ -0,0 +1,170 @@
1
+ """Wizard Factory CLI integration for Empathy Framework.
2
+
3
+ Provides wizard-factory commands integrated into the main empathy CLI:
4
+ - empathy wizard-factory create
5
+ - empathy wizard-factory list-patterns
6
+ - empathy wizard-factory generate-tests
7
+ - empathy wizard-factory analyze
8
+
9
+ Copyright 2025 Smart AI Memory, LLC
10
+ Licensed under Fair Source 0.9
11
+ """
12
+
13
+ import subprocess
14
+ import sys
15
+
16
+
17
+ def cmd_wizard_factory_create(args):
18
+ """Create a new wizard using scaffolding."""
19
+ # Build command
20
+ cmd = ["python", "-m", "scaffolding", "create", args.name]
21
+
22
+ if args.domain:
23
+ cmd.extend(["--domain", args.domain])
24
+
25
+ if args.type:
26
+ cmd.extend(["--type", args.type])
27
+
28
+ if args.methodology:
29
+ cmd.extend(["--methodology", args.methodology])
30
+
31
+ if args.patterns:
32
+ cmd.extend(["--patterns", args.patterns])
33
+
34
+ if args.interactive:
35
+ cmd.append("--interactive")
36
+
37
+ # Run scaffolding
38
+ result = subprocess.run(cmd)
39
+ sys.exit(result.returncode)
40
+
41
+
42
+ def cmd_wizard_factory_list_patterns(args):
43
+ """List available patterns."""
44
+ result = subprocess.run(["python", "-m", "scaffolding", "list-patterns"])
45
+ sys.exit(result.returncode)
46
+
47
+
48
+ def cmd_wizard_factory_generate_tests(args):
49
+ """Generate tests for a wizard."""
50
+ cmd = ["python", "-m", "test_generator", "generate", args.wizard_id]
51
+
52
+ if args.patterns:
53
+ cmd.extend(["--patterns", args.patterns])
54
+
55
+ if args.output:
56
+ cmd.extend(["--output", args.output])
57
+
58
+ result = subprocess.run(cmd)
59
+ sys.exit(result.returncode)
60
+
61
+
62
+ def cmd_wizard_factory_analyze(args):
63
+ """Analyze wizard risk."""
64
+ cmd = ["python", "-m", "test_generator", "analyze", args.wizard_id]
65
+
66
+ if args.patterns:
67
+ cmd.extend(["--patterns", args.patterns])
68
+
69
+ if args.json:
70
+ cmd.append("--json")
71
+
72
+ result = subprocess.run(cmd)
73
+ sys.exit(result.returncode)
74
+
75
+
76
+ def add_wizard_factory_commands(subparsers):
77
+ """Add wizard-factory commands to main CLI.
78
+
79
+ Args:
80
+ subparsers: ArgumentParser subparsers object
81
+ """
82
+ # Main wizard-factory command
83
+ parser_wf = subparsers.add_parser(
84
+ "wizard-factory",
85
+ help="Wizard Factory - create wizards 12x faster",
86
+ )
87
+ wf_subparsers = parser_wf.add_subparsers(dest="wizard_factory_command")
88
+
89
+ # wizard-factory create
90
+ parser_wf_create = wf_subparsers.add_parser(
91
+ "create",
92
+ help="Create a new wizard",
93
+ )
94
+ parser_wf_create.add_argument("name", help="Wizard name (snake_case)")
95
+ parser_wf_create.add_argument(
96
+ "--domain",
97
+ "-d",
98
+ help="Domain (healthcare, finance, software, legal, etc.)",
99
+ )
100
+ parser_wf_create.add_argument(
101
+ "--type",
102
+ "-t",
103
+ choices=["domain", "coach", "ai"],
104
+ default="domain",
105
+ help="Wizard type (default: domain)",
106
+ )
107
+ parser_wf_create.add_argument(
108
+ "--methodology",
109
+ "-m",
110
+ choices=["pattern", "tdd"],
111
+ default="pattern",
112
+ help="Methodology (pattern-compose or tdd-first, default: pattern)",
113
+ )
114
+ parser_wf_create.add_argument(
115
+ "--patterns",
116
+ "-p",
117
+ help="Comma-separated pattern IDs (e.g. linear_flow,approval)",
118
+ )
119
+ parser_wf_create.add_argument(
120
+ "--interactive",
121
+ "-i",
122
+ action="store_true",
123
+ help="Interactive pattern selection",
124
+ )
125
+ parser_wf_create.set_defaults(func=cmd_wizard_factory_create)
126
+
127
+ # wizard-factory list-patterns
128
+ parser_wf_list = wf_subparsers.add_parser(
129
+ "list-patterns",
130
+ help="List available patterns",
131
+ )
132
+ parser_wf_list.set_defaults(func=cmd_wizard_factory_list_patterns)
133
+
134
+ # wizard-factory generate-tests
135
+ parser_wf_gen = wf_subparsers.add_parser(
136
+ "generate-tests",
137
+ help="Generate tests for a wizard",
138
+ )
139
+ parser_wf_gen.add_argument("wizard_id", help="Wizard ID")
140
+ parser_wf_gen.add_argument(
141
+ "--patterns",
142
+ "-p",
143
+ required=True,
144
+ help="Comma-separated pattern IDs",
145
+ )
146
+ parser_wf_gen.add_argument(
147
+ "--output",
148
+ "-o",
149
+ help="Output directory for tests",
150
+ )
151
+ parser_wf_gen.set_defaults(func=cmd_wizard_factory_generate_tests)
152
+
153
+ # wizard-factory analyze
154
+ parser_wf_analyze = wf_subparsers.add_parser(
155
+ "analyze",
156
+ help="Analyze wizard risk and get coverage recommendations",
157
+ )
158
+ parser_wf_analyze.add_argument("wizard_id", help="Wizard ID")
159
+ parser_wf_analyze.add_argument(
160
+ "--patterns",
161
+ "-p",
162
+ required=True,
163
+ help="Comma-separated pattern IDs",
164
+ )
165
+ parser_wf_analyze.add_argument(
166
+ "--json",
167
+ action="store_true",
168
+ help="Output JSON format",
169
+ )
170
+ parser_wf_analyze.set_defaults(func=cmd_wizard_factory_analyze)