empathy-framework 3.7.0__py3-none-any.whl → 3.8.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.
- coach_wizards/code_reviewer_README.md +60 -0
- coach_wizards/code_reviewer_wizard.py +180 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/METADATA +148 -11
- empathy_framework-3.8.0.dist-info/RECORD +333 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/top_level.txt +5 -1
- empathy_healthcare_plugin/monitors/__init__.py +9 -0
- empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
- empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
- empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
- empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
- empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
- empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
- empathy_llm_toolkit/agent_factory/__init__.py +53 -0
- empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
- empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
- empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
- empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
- empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
- empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
- empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
- empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
- empathy_llm_toolkit/agent_factory/base.py +305 -0
- empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
- empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
- empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
- empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
- empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
- empathy_llm_toolkit/agent_factory/decorators.py +286 -0
- empathy_llm_toolkit/agent_factory/factory.py +558 -0
- empathy_llm_toolkit/agent_factory/framework.py +192 -0
- empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
- empathy_llm_toolkit/agent_factory/resilient.py +320 -0
- empathy_llm_toolkit/cli/__init__.py +8 -0
- empathy_llm_toolkit/cli/sync_claude.py +487 -0
- empathy_llm_toolkit/code_health.py +150 -3
- empathy_llm_toolkit/config/__init__.py +29 -0
- empathy_llm_toolkit/config/unified.py +295 -0
- empathy_llm_toolkit/routing/__init__.py +32 -0
- empathy_llm_toolkit/routing/model_router.py +362 -0
- empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
- empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
- empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
- empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
- empathy_llm_toolkit/security/README.md +262 -0
- empathy_llm_toolkit/security/__init__.py +62 -0
- empathy_llm_toolkit/security/audit_logger.py +929 -0
- empathy_llm_toolkit/security/audit_logger_example.py +152 -0
- empathy_llm_toolkit/security/pii_scrubber.py +640 -0
- empathy_llm_toolkit/security/secrets_detector.py +678 -0
- empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
- empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
- empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
- empathy_llm_toolkit/wizards/__init__.py +38 -0
- empathy_llm_toolkit/wizards/base_wizard.py +364 -0
- empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
- empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
- empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
- empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
- empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
- empathy_os/__init__.py +52 -52
- empathy_os/adaptive/__init__.py +13 -0
- empathy_os/adaptive/task_complexity.py +127 -0
- empathy_os/cache/__init__.py +117 -0
- empathy_os/cache/base.py +166 -0
- empathy_os/cache/dependency_manager.py +253 -0
- empathy_os/cache/hash_only.py +248 -0
- empathy_os/cache/hybrid.py +390 -0
- empathy_os/cache/storage.py +282 -0
- empathy_os/cli.py +118 -8
- empathy_os/cli_unified.py +121 -1
- empathy_os/config/__init__.py +63 -0
- empathy_os/config/xml_config.py +239 -0
- empathy_os/config.py +2 -1
- empathy_os/dashboard/__init__.py +15 -0
- empathy_os/dashboard/server.py +743 -0
- empathy_os/memory/__init__.py +195 -0
- empathy_os/memory/claude_memory.py +466 -0
- empathy_os/memory/config.py +224 -0
- empathy_os/memory/control_panel.py +1298 -0
- empathy_os/memory/edges.py +179 -0
- empathy_os/memory/graph.py +567 -0
- empathy_os/memory/long_term.py +1194 -0
- empathy_os/memory/nodes.py +179 -0
- empathy_os/memory/redis_bootstrap.py +540 -0
- empathy_os/memory/security/__init__.py +31 -0
- empathy_os/memory/security/audit_logger.py +930 -0
- empathy_os/memory/security/pii_scrubber.py +640 -0
- empathy_os/memory/security/secrets_detector.py +678 -0
- empathy_os/memory/short_term.py +2119 -0
- empathy_os/memory/storage/__init__.py +15 -0
- empathy_os/memory/summary_index.py +583 -0
- empathy_os/memory/unified.py +619 -0
- empathy_os/metrics/__init__.py +12 -0
- empathy_os/metrics/prompt_metrics.py +190 -0
- empathy_os/models/__init__.py +136 -0
- empathy_os/models/__main__.py +13 -0
- empathy_os/models/cli.py +655 -0
- empathy_os/models/empathy_executor.py +354 -0
- empathy_os/models/executor.py +252 -0
- empathy_os/models/fallback.py +671 -0
- empathy_os/models/provider_config.py +563 -0
- empathy_os/models/registry.py +382 -0
- empathy_os/models/tasks.py +302 -0
- empathy_os/models/telemetry.py +548 -0
- empathy_os/models/token_estimator.py +378 -0
- empathy_os/models/validation.py +274 -0
- empathy_os/monitoring/__init__.py +52 -0
- empathy_os/monitoring/alerts.py +23 -0
- empathy_os/monitoring/alerts_cli.py +268 -0
- empathy_os/monitoring/multi_backend.py +271 -0
- empathy_os/monitoring/otel_backend.py +363 -0
- empathy_os/optimization/__init__.py +19 -0
- empathy_os/optimization/context_optimizer.py +272 -0
- empathy_os/plugins/__init__.py +28 -0
- empathy_os/plugins/base.py +361 -0
- empathy_os/plugins/registry.py +268 -0
- empathy_os/project_index/__init__.py +30 -0
- empathy_os/project_index/cli.py +335 -0
- empathy_os/project_index/crew_integration.py +430 -0
- empathy_os/project_index/index.py +425 -0
- empathy_os/project_index/models.py +501 -0
- empathy_os/project_index/reports.py +473 -0
- empathy_os/project_index/scanner.py +538 -0
- empathy_os/prompts/__init__.py +61 -0
- empathy_os/prompts/config.py +77 -0
- empathy_os/prompts/context.py +177 -0
- empathy_os/prompts/parser.py +285 -0
- empathy_os/prompts/registry.py +313 -0
- empathy_os/prompts/templates.py +208 -0
- empathy_os/resilience/__init__.py +56 -0
- empathy_os/resilience/circuit_breaker.py +256 -0
- empathy_os/resilience/fallback.py +179 -0
- empathy_os/resilience/health.py +300 -0
- empathy_os/resilience/retry.py +209 -0
- empathy_os/resilience/timeout.py +135 -0
- empathy_os/routing/__init__.py +43 -0
- empathy_os/routing/chain_executor.py +433 -0
- empathy_os/routing/classifier.py +217 -0
- empathy_os/routing/smart_router.py +234 -0
- empathy_os/routing/wizard_registry.py +307 -0
- empathy_os/trust/__init__.py +28 -0
- empathy_os/trust/circuit_breaker.py +579 -0
- empathy_os/validation/__init__.py +19 -0
- empathy_os/validation/xml_validator.py +281 -0
- empathy_os/wizard_factory_cli.py +170 -0
- empathy_os/workflows/__init__.py +360 -0
- empathy_os/workflows/base.py +1660 -0
- empathy_os/workflows/bug_predict.py +962 -0
- empathy_os/workflows/code_review.py +960 -0
- empathy_os/workflows/code_review_adapters.py +310 -0
- empathy_os/workflows/code_review_pipeline.py +720 -0
- empathy_os/workflows/config.py +600 -0
- empathy_os/workflows/dependency_check.py +648 -0
- empathy_os/workflows/document_gen.py +1069 -0
- empathy_os/workflows/documentation_orchestrator.py +1205 -0
- empathy_os/workflows/health_check.py +679 -0
- empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
- empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
- empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
- empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
- empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
- empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
- empathy_os/workflows/manage_documentation.py +804 -0
- empathy_os/workflows/new_sample_workflow1.py +146 -0
- empathy_os/workflows/new_sample_workflow1_README.md +150 -0
- empathy_os/workflows/perf_audit.py +687 -0
- empathy_os/workflows/pr_review.py +748 -0
- empathy_os/workflows/progress.py +445 -0
- empathy_os/workflows/progress_server.py +322 -0
- empathy_os/workflows/refactor_plan.py +693 -0
- empathy_os/workflows/release_prep.py +808 -0
- empathy_os/workflows/research_synthesis.py +404 -0
- empathy_os/workflows/secure_release.py +585 -0
- empathy_os/workflows/security_adapters.py +297 -0
- empathy_os/workflows/security_audit.py +1046 -0
- empathy_os/workflows/step_config.py +234 -0
- empathy_os/workflows/test5.py +125 -0
- empathy_os/workflows/test5_README.md +158 -0
- empathy_os/workflows/test_gen.py +1855 -0
- empathy_os/workflows/test_lifecycle.py +526 -0
- empathy_os/workflows/test_maintenance.py +626 -0
- empathy_os/workflows/test_maintenance_cli.py +590 -0
- empathy_os/workflows/test_maintenance_crew.py +821 -0
- empathy_os/workflows/xml_enhanced_crew.py +285 -0
- empathy_software_plugin/cli/__init__.py +120 -0
- empathy_software_plugin/cli/inspect.py +362 -0
- empathy_software_plugin/cli.py +3 -1
- empathy_software_plugin/wizards/__init__.py +42 -0
- empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
- empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
- empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
- empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
- empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
- empathy_software_plugin/wizards/base_wizard.py +288 -0
- empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
- empathy_software_plugin/wizards/code_review_wizard.py +606 -0
- empathy_software_plugin/wizards/debugging/__init__.py +50 -0
- empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
- empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
- empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
- empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
- empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
- empathy_software_plugin/wizards/debugging/verification.py +369 -0
- empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
- empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
- empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
- empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
- empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
- empathy_software_plugin/wizards/performance/__init__.py +9 -0
- empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
- empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
- empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
- empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
- empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
- empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
- empathy_software_plugin/wizards/security/__init__.py +32 -0
- empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
- empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
- empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
- empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
- empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
- empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
- empathy_software_plugin/wizards/testing/__init__.py +27 -0
- empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
- empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
- empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
- empathy_software_plugin/wizards/testing_wizard.py +274 -0
- hot_reload/README.md +473 -0
- hot_reload/__init__.py +62 -0
- hot_reload/config.py +84 -0
- hot_reload/integration.py +228 -0
- hot_reload/reloader.py +298 -0
- hot_reload/watcher.py +179 -0
- hot_reload/websocket.py +176 -0
- scaffolding/README.md +589 -0
- scaffolding/__init__.py +35 -0
- scaffolding/__main__.py +14 -0
- scaffolding/cli.py +240 -0
- test_generator/__init__.py +38 -0
- test_generator/__main__.py +14 -0
- test_generator/cli.py +226 -0
- test_generator/generator.py +325 -0
- test_generator/risk_analyzer.py +216 -0
- workflow_patterns/__init__.py +33 -0
- workflow_patterns/behavior.py +249 -0
- workflow_patterns/core.py +76 -0
- workflow_patterns/output.py +99 -0
- workflow_patterns/registry.py +255 -0
- workflow_patterns/structural.py +288 -0
- workflow_scaffolding/__init__.py +11 -0
- workflow_scaffolding/__main__.py +12 -0
- workflow_scaffolding/cli.py +206 -0
- workflow_scaffolding/generator.py +265 -0
- agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
- agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
- agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
- agents/compliance_anticipation_agent.py +0 -1422
- agents/compliance_db.py +0 -339
- agents/epic_integration_wizard.py +0 -530
- agents/notifications.py +0 -291
- agents/trust_building_behaviors.py +0 -872
- empathy_framework-3.7.0.dist-info/RECORD +0 -105
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/WHEEL +0 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/entry_points.txt +0 -0
- {empathy_framework-3.7.0.dist-info → empathy_framework-3.8.0.dist-info}/licenses/LICENSE +0 -0
- /empathy_os/{monitoring.py → agent_monitoring.py} +0 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"""Secure MemDocs Integration - Example Usage
|
|
2
|
+
|
|
3
|
+
Demonstrates Phase 2 enterprise privacy integration with:
|
|
4
|
+
- PII scrubbing
|
|
5
|
+
- Secrets detection
|
|
6
|
+
- Three-tier classification
|
|
7
|
+
- Encryption for SENSITIVE patterns
|
|
8
|
+
- Audit logging
|
|
9
|
+
|
|
10
|
+
Author: Empathy Framework Team
|
|
11
|
+
Version: 1.8.0-beta
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
# Add parent directory to path for imports
|
|
18
|
+
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
|
19
|
+
|
|
20
|
+
from empathy_llm_toolkit.security import SecureMemDocsIntegration, SecurityError
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def example_basic_usage():
|
|
24
|
+
"""Example 1: Basic pattern storage with auto-classification"""
|
|
25
|
+
print("\n=== Example 1: Basic Pattern Storage ===\n")
|
|
26
|
+
|
|
27
|
+
# Initialize secure integration
|
|
28
|
+
integration = SecureMemDocsIntegration(
|
|
29
|
+
storage_dir="./example_memdocs",
|
|
30
|
+
audit_log_dir="./example_logs",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# Store a simple pattern
|
|
34
|
+
content = """
|
|
35
|
+
Standard Python sorting algorithm implementation:
|
|
36
|
+
|
|
37
|
+
def quick_sort(arr):
|
|
38
|
+
if len(arr) <= 1:
|
|
39
|
+
return arr
|
|
40
|
+
pivot = arr[len(arr) // 2]
|
|
41
|
+
left = [x for x in arr if x < pivot]
|
|
42
|
+
middle = [x for x in arr if x == pivot]
|
|
43
|
+
right = [x for x in arr if x > pivot]
|
|
44
|
+
return quick_sort(left) + middle + quick_sort(right)
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
result = integration.store_pattern(
|
|
48
|
+
content=content,
|
|
49
|
+
pattern_type="algorithm",
|
|
50
|
+
user_id="developer@company.com",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
print("Pattern stored successfully!")
|
|
54
|
+
print(f" Pattern ID: {result['pattern_id']}")
|
|
55
|
+
print(f" Classification: {result['classification']}")
|
|
56
|
+
print(f" PII removed: {result['sanitization_report']['pii_count']}")
|
|
57
|
+
print(f" Encrypted: {result['metadata']['encrypted']}")
|
|
58
|
+
print(f" Retention: {result['metadata']['retention_days']} days")
|
|
59
|
+
|
|
60
|
+
return result["pattern_id"]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def example_pii_scrubbing():
|
|
64
|
+
"""Example 2: PII scrubbing in action"""
|
|
65
|
+
print("\n=== Example 2: PII Scrubbing ===\n")
|
|
66
|
+
|
|
67
|
+
integration = SecureMemDocsIntegration(
|
|
68
|
+
storage_dir="./example_memdocs",
|
|
69
|
+
audit_log_dir="./example_logs",
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Content with PII
|
|
73
|
+
content = """
|
|
74
|
+
Contact Information:
|
|
75
|
+
- Email: john.doe@example.com
|
|
76
|
+
- Phone: 555-123-4567
|
|
77
|
+
- SSN: 123-45-6789
|
|
78
|
+
|
|
79
|
+
For support, call our team at support@company.com
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
result = integration.store_pattern(
|
|
83
|
+
content=content,
|
|
84
|
+
pattern_type="contact_info",
|
|
85
|
+
user_id="hr@company.com",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
print("Pattern stored with PII scrubbing:")
|
|
89
|
+
print(f" Pattern ID: {result['pattern_id']}")
|
|
90
|
+
print(f" PII removed: {result['sanitization_report']['pii_count']} items")
|
|
91
|
+
for pii_item in result["sanitization_report"]["pii_removed"]:
|
|
92
|
+
print(f" - {pii_item['type']}")
|
|
93
|
+
|
|
94
|
+
# Retrieve to see scrubbed content
|
|
95
|
+
pattern = integration.retrieve_pattern(
|
|
96
|
+
pattern_id=result["pattern_id"],
|
|
97
|
+
user_id="hr@company.com",
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
print("\nRetrieved content (PII scrubbed):")
|
|
101
|
+
print(pattern["content"][:200] + "...")
|
|
102
|
+
|
|
103
|
+
return result["pattern_id"]
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def example_secrets_blocking():
|
|
107
|
+
"""Example 3: Secrets detection blocks storage"""
|
|
108
|
+
print("\n=== Example 3: Secrets Detection ===\n")
|
|
109
|
+
|
|
110
|
+
integration = SecureMemDocsIntegration(
|
|
111
|
+
storage_dir="./example_memdocs",
|
|
112
|
+
audit_log_dir="./example_logs",
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# Content with secrets (WILL BE BLOCKED)
|
|
116
|
+
content = """
|
|
117
|
+
# Configuration
|
|
118
|
+
ANTHROPIC_API_KEY = "sk-ant-api03-abc123xyz789..."
|
|
119
|
+
OPENAI_API_KEY = "sk-proj-abc123xyz789..."
|
|
120
|
+
DATABASE_URL = "postgres://user:password@localhost:5432/db"
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
try:
|
|
124
|
+
integration.store_pattern(
|
|
125
|
+
content=content,
|
|
126
|
+
pattern_type="config",
|
|
127
|
+
user_id="developer@company.com",
|
|
128
|
+
)
|
|
129
|
+
print("ERROR: Secrets should have been blocked!")
|
|
130
|
+
except SecurityError as e:
|
|
131
|
+
print("Storage blocked (as expected):")
|
|
132
|
+
print(f" Reason: {e!s}")
|
|
133
|
+
print(" Action: Secrets detected and storage prevented")
|
|
134
|
+
print(" Audit: Security violation logged")
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def example_healthcare_sensitive():
|
|
138
|
+
"""Example 4: Healthcare pattern with SENSITIVE classification"""
|
|
139
|
+
print("\n=== Example 4: Healthcare Pattern (SENSITIVE) ===\n")
|
|
140
|
+
|
|
141
|
+
integration = SecureMemDocsIntegration(
|
|
142
|
+
storage_dir="./example_memdocs",
|
|
143
|
+
audit_log_dir="./example_logs",
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# Healthcare content (auto-classified as SENSITIVE)
|
|
147
|
+
content = """
|
|
148
|
+
# Patient Vital Signs Monitoring Protocol
|
|
149
|
+
|
|
150
|
+
Normal ranges:
|
|
151
|
+
- Heart rate: 60-100 bpm
|
|
152
|
+
- Blood pressure: 90/60 to 120/80 mmHg
|
|
153
|
+
- Respiratory rate: 12-20 breaths/min
|
|
154
|
+
- Temperature: 97-99°F (36.1-37.2°C)
|
|
155
|
+
- Oxygen saturation: 95-100%
|
|
156
|
+
|
|
157
|
+
Alert thresholds:
|
|
158
|
+
- Heart rate < 50 or > 120 bpm
|
|
159
|
+
- Systolic BP < 90 or > 180 mmHg
|
|
160
|
+
- Oxygen saturation < 92%
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
result = integration.store_pattern(
|
|
164
|
+
content=content,
|
|
165
|
+
pattern_type="clinical_protocol",
|
|
166
|
+
user_id="nurse@hospital.com",
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
print("Healthcare pattern stored:")
|
|
170
|
+
print(f" Pattern ID: {result['pattern_id']}")
|
|
171
|
+
print(f" Classification: {result['classification']} (auto-detected)")
|
|
172
|
+
print(f" Encrypted: {result['metadata']['encrypted']} (HIPAA compliance)")
|
|
173
|
+
print(f" Retention: {result['metadata']['retention_days']} days (HIPAA minimum)")
|
|
174
|
+
print(" Access: Creator only (explicit permission required)")
|
|
175
|
+
|
|
176
|
+
# Retrieve (only creator can access)
|
|
177
|
+
pattern = integration.retrieve_pattern(
|
|
178
|
+
pattern_id=result["pattern_id"],
|
|
179
|
+
user_id="nurse@hospital.com",
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
print("\nPattern retrieved and decrypted successfully")
|
|
183
|
+
print(f" Content length: {len(pattern['content'])} chars")
|
|
184
|
+
|
|
185
|
+
# Try to retrieve as different user (will be blocked)
|
|
186
|
+
try:
|
|
187
|
+
pattern = integration.retrieve_pattern(
|
|
188
|
+
pattern_id=result["pattern_id"],
|
|
189
|
+
user_id="other_user@hospital.com",
|
|
190
|
+
)
|
|
191
|
+
print("ERROR: Access should have been denied!")
|
|
192
|
+
except Exception:
|
|
193
|
+
print("\nAccess denied for different user (as expected):")
|
|
194
|
+
print(" Reason: SENSITIVE patterns require explicit permission")
|
|
195
|
+
|
|
196
|
+
return result["pattern_id"]
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def example_list_patterns():
|
|
200
|
+
"""Example 5: List accessible patterns"""
|
|
201
|
+
print("\n=== Example 5: List Patterns ===\n")
|
|
202
|
+
|
|
203
|
+
integration = SecureMemDocsIntegration(
|
|
204
|
+
storage_dir="./example_memdocs",
|
|
205
|
+
audit_log_dir="./example_logs",
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
# List patterns for user
|
|
209
|
+
patterns = integration.list_patterns(user_id="developer@company.com")
|
|
210
|
+
|
|
211
|
+
print(f"Accessible patterns: {len(patterns)}")
|
|
212
|
+
for pattern in patterns:
|
|
213
|
+
print(f"\n Pattern: {pattern['pattern_id']}")
|
|
214
|
+
print(f" Type: {pattern['pattern_type']}")
|
|
215
|
+
print(f" Classification: {pattern['classification']}")
|
|
216
|
+
print(f" Created: {pattern['created_at']}")
|
|
217
|
+
print(f" Encrypted: {pattern['encrypted']}")
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def example_statistics():
|
|
221
|
+
"""Example 6: Get storage statistics"""
|
|
222
|
+
print("\n=== Example 6: Storage Statistics ===\n")
|
|
223
|
+
|
|
224
|
+
integration = SecureMemDocsIntegration(
|
|
225
|
+
storage_dir="./example_memdocs",
|
|
226
|
+
audit_log_dir="./example_logs",
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
stats = integration.get_statistics()
|
|
230
|
+
|
|
231
|
+
print("MemDocs Statistics:")
|
|
232
|
+
print(f" Total patterns: {stats['total_patterns']}")
|
|
233
|
+
print(" By classification:")
|
|
234
|
+
for classification, count in stats["by_classification"].items():
|
|
235
|
+
print(f" - {classification}: {count}")
|
|
236
|
+
print(f" Encrypted patterns: {stats['encrypted_count']}")
|
|
237
|
+
print(f" With PII scrubbed: {stats['with_pii_scrubbed']}")
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def main():
|
|
241
|
+
"""Run all examples"""
|
|
242
|
+
print("=" * 70)
|
|
243
|
+
print("Secure MemDocs Integration - Example Usage")
|
|
244
|
+
print("Phase 2: Enterprise Privacy Integration")
|
|
245
|
+
print("=" * 70)
|
|
246
|
+
|
|
247
|
+
try:
|
|
248
|
+
# Example 1: Basic usage
|
|
249
|
+
example_basic_usage()
|
|
250
|
+
|
|
251
|
+
# Example 2: PII scrubbing
|
|
252
|
+
example_pii_scrubbing()
|
|
253
|
+
|
|
254
|
+
# Example 3: Secrets blocking
|
|
255
|
+
example_secrets_blocking()
|
|
256
|
+
|
|
257
|
+
# Example 4: Healthcare (SENSITIVE)
|
|
258
|
+
example_healthcare_sensitive()
|
|
259
|
+
|
|
260
|
+
# Example 5: List patterns
|
|
261
|
+
example_list_patterns()
|
|
262
|
+
|
|
263
|
+
# Example 6: Statistics
|
|
264
|
+
example_statistics()
|
|
265
|
+
|
|
266
|
+
print("\n" + "=" * 70)
|
|
267
|
+
print("All examples completed successfully!")
|
|
268
|
+
print("=" * 70)
|
|
269
|
+
|
|
270
|
+
except Exception as e:
|
|
271
|
+
print(f"\n\nError running examples: {e}")
|
|
272
|
+
import traceback
|
|
273
|
+
|
|
274
|
+
traceback.print_exc()
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
if __name__ == "__main__":
|
|
278
|
+
main()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Empathy LLM Wizards - Canonical Examples
|
|
2
|
+
|
|
3
|
+
Core wizard base class and canonical domain examples demonstrating
|
|
4
|
+
the Empathy Framework's capabilities across different use cases.
|
|
5
|
+
|
|
6
|
+
Included Wizards (3 canonical examples):
|
|
7
|
+
1. HealthcareWizard - HIPAA-compliant medical assistant
|
|
8
|
+
2. CustomerSupportWizard - Customer service and help desk
|
|
9
|
+
3. TechnologyWizard - IT and software development operations
|
|
10
|
+
|
|
11
|
+
Additional Wizards Available:
|
|
12
|
+
For specialized domain wizards, install separate packages:
|
|
13
|
+
- Healthcare (23 wizards): pip install empathy-healthcare-wizards
|
|
14
|
+
- Tech & AI (16 wizards): pip install empathy-software-wizards
|
|
15
|
+
- Business (12+ wizards): pip install empathy-business-wizards
|
|
16
|
+
|
|
17
|
+
Or try the live dashboards:
|
|
18
|
+
- Healthcare: https://healthcare.smartaimemory.com/static/dashboard.html
|
|
19
|
+
- Tech & AI: https://wizards.smartaimemory.com/
|
|
20
|
+
|
|
21
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
22
|
+
Licensed under Fair Source 0.9
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from .base_wizard import BaseWizard, WizardConfig
|
|
26
|
+
from .customer_support_wizard import CustomerSupportWizard
|
|
27
|
+
from .healthcare_wizard import HealthcareWizard
|
|
28
|
+
from .technology_wizard import TechnologyWizard
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
# Base classes
|
|
32
|
+
"BaseWizard",
|
|
33
|
+
# Canonical domain examples
|
|
34
|
+
"CustomerSupportWizard",
|
|
35
|
+
"HealthcareWizard",
|
|
36
|
+
"TechnologyWizard",
|
|
37
|
+
"WizardConfig",
|
|
38
|
+
]
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"""Base Wizard - Foundation for all EmpathyLLM wizards
|
|
2
|
+
|
|
3
|
+
Provides common functionality for security-aware AI assistants with domain-specific
|
|
4
|
+
configurations and integrated privacy controls.
|
|
5
|
+
|
|
6
|
+
Copyright 2025 Smart AI Memory, LLC
|
|
7
|
+
Licensed under Fair Source 0.9
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from empathy_llm_toolkit import EmpathyLLM
|
|
15
|
+
from empathy_llm_toolkit.claude_memory import ClaudeMemoryConfig
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class WizardConfig:
|
|
22
|
+
"""Configuration for an Empathy wizard"""
|
|
23
|
+
|
|
24
|
+
# Wizard identity
|
|
25
|
+
name: str
|
|
26
|
+
description: str
|
|
27
|
+
domain: str # healthcare, finance, legal, general, etc.
|
|
28
|
+
|
|
29
|
+
# Empathy level (0-4)
|
|
30
|
+
default_empathy_level: int = 2
|
|
31
|
+
|
|
32
|
+
# Security configuration
|
|
33
|
+
enable_security: bool = False
|
|
34
|
+
pii_patterns: list[str] = field(default_factory=list)
|
|
35
|
+
enable_secrets_detection: bool = False
|
|
36
|
+
block_on_secrets: bool = True
|
|
37
|
+
|
|
38
|
+
# Audit configuration
|
|
39
|
+
audit_all_access: bool = False
|
|
40
|
+
retention_days: int = 180
|
|
41
|
+
|
|
42
|
+
# Classification
|
|
43
|
+
default_classification: str = "INTERNAL" # PUBLIC, INTERNAL, SENSITIVE
|
|
44
|
+
auto_classify: bool = True
|
|
45
|
+
|
|
46
|
+
# Memory configuration
|
|
47
|
+
enable_memory: bool = False
|
|
48
|
+
memory_config: ClaudeMemoryConfig | None = None
|
|
49
|
+
|
|
50
|
+
# XML-enhanced prompts (Phase 4)
|
|
51
|
+
xml_prompts_enabled: bool = True # Enable by default for better Claude API performance
|
|
52
|
+
xml_schema_version: str = "1.0"
|
|
53
|
+
enforce_xml_response: bool = False # Require XML-structured responses
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class BaseWizard:
|
|
57
|
+
"""Base class for all Empathy LLM wizards
|
|
58
|
+
|
|
59
|
+
Provides:
|
|
60
|
+
- Integration with EmpathyLLM
|
|
61
|
+
- Security pipeline configuration
|
|
62
|
+
- Domain-specific prompting
|
|
63
|
+
- Audit logging
|
|
64
|
+
- Session management
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
def __init__(
|
|
68
|
+
self,
|
|
69
|
+
llm: EmpathyLLM,
|
|
70
|
+
config: WizardConfig,
|
|
71
|
+
):
|
|
72
|
+
"""Initialize wizard with LLM and configuration
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
llm: EmpathyLLM instance (with or without security enabled)
|
|
76
|
+
config: Wizard configuration
|
|
77
|
+
|
|
78
|
+
"""
|
|
79
|
+
self.llm = llm
|
|
80
|
+
self.config = config
|
|
81
|
+
self.logger = logging.getLogger(f"wizard.{config.name}")
|
|
82
|
+
|
|
83
|
+
# Validate configuration
|
|
84
|
+
self._validate_config()
|
|
85
|
+
|
|
86
|
+
def _validate_config(self):
|
|
87
|
+
"""Validate wizard configuration"""
|
|
88
|
+
if not 0 <= self.config.default_empathy_level <= 4:
|
|
89
|
+
raise ValueError(f"Empathy level must be 0-4, got {self.config.default_empathy_level}")
|
|
90
|
+
|
|
91
|
+
if self.config.default_classification not in ["PUBLIC", "INTERNAL", "SENSITIVE"]:
|
|
92
|
+
raise ValueError(f"Invalid classification: {self.config.default_classification}")
|
|
93
|
+
|
|
94
|
+
async def process(
|
|
95
|
+
self,
|
|
96
|
+
user_input: str,
|
|
97
|
+
user_id: str,
|
|
98
|
+
empathy_level: int | None = None,
|
|
99
|
+
session_context: dict[str, Any] | None = None,
|
|
100
|
+
) -> dict[str, Any]:
|
|
101
|
+
"""Process user input through the wizard
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
user_input: User's message or request
|
|
105
|
+
user_id: Identifier for the user
|
|
106
|
+
empathy_level: Override default empathy level (optional)
|
|
107
|
+
session_context: Additional context for the conversation
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
Dictionary containing:
|
|
111
|
+
- response: AI response
|
|
112
|
+
- empathy_level: Level used
|
|
113
|
+
- security_report: Security scan results (if enabled)
|
|
114
|
+
- metadata: Additional wizard metadata
|
|
115
|
+
|
|
116
|
+
"""
|
|
117
|
+
level = empathy_level if empathy_level is not None else self.config.default_empathy_level
|
|
118
|
+
|
|
119
|
+
self.logger.info(
|
|
120
|
+
"processing_request: wizard=%s user_id=%s empathy_level=%s",
|
|
121
|
+
self.config.name,
|
|
122
|
+
user_id,
|
|
123
|
+
level,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# Build system prompt with domain knowledge
|
|
127
|
+
system_prompt = self._build_system_prompt()
|
|
128
|
+
|
|
129
|
+
# Add session context if provided
|
|
130
|
+
if session_context:
|
|
131
|
+
context_str = self._format_context(session_context)
|
|
132
|
+
user_input = f"{context_str}\n\n{user_input}"
|
|
133
|
+
|
|
134
|
+
# Process through EmpathyLLM (with security if enabled)
|
|
135
|
+
# Note: EmpathyLLM uses 'force_level' and 'context' parameters
|
|
136
|
+
context_dict = session_context.copy() if session_context else {}
|
|
137
|
+
context_dict["system_prompt"] = system_prompt
|
|
138
|
+
|
|
139
|
+
result = await self.llm.interact(
|
|
140
|
+
user_id=user_id,
|
|
141
|
+
user_input=user_input,
|
|
142
|
+
force_level=level,
|
|
143
|
+
context=context_dict,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
# Enhance result with wizard metadata
|
|
147
|
+
result["wizard"] = {
|
|
148
|
+
"name": self.config.name,
|
|
149
|
+
"domain": self.config.domain,
|
|
150
|
+
"empathy_level": level,
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return result
|
|
154
|
+
|
|
155
|
+
def _build_system_prompt(self) -> str:
|
|
156
|
+
"""Build domain-specific system prompt
|
|
157
|
+
|
|
158
|
+
Override in subclasses to add domain knowledge
|
|
159
|
+
"""
|
|
160
|
+
return f"""You are an AI assistant specialized in {self.config.domain}.
|
|
161
|
+
|
|
162
|
+
Description: {self.config.description}
|
|
163
|
+
|
|
164
|
+
Guidelines:
|
|
165
|
+
- Provide accurate, helpful responses
|
|
166
|
+
- Be empathetic and understanding
|
|
167
|
+
- Follow domain best practices
|
|
168
|
+
- Maintain user privacy and confidentiality
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
def _format_context(self, context: dict[str, Any]) -> str:
|
|
172
|
+
"""Format session context for inclusion in prompt"""
|
|
173
|
+
lines = ["Context:"]
|
|
174
|
+
for key, value in context.items():
|
|
175
|
+
lines.append(f"- {key}: {value}")
|
|
176
|
+
return "\n".join(lines)
|
|
177
|
+
|
|
178
|
+
# =========================================================================
|
|
179
|
+
# XML-Enhanced Prompt Support (Phase 4)
|
|
180
|
+
# =========================================================================
|
|
181
|
+
|
|
182
|
+
def _is_xml_enabled(self) -> bool:
|
|
183
|
+
"""Check if XML prompts are enabled for this wizard."""
|
|
184
|
+
return self.config.xml_prompts_enabled
|
|
185
|
+
|
|
186
|
+
def _render_xml_prompt(
|
|
187
|
+
self,
|
|
188
|
+
role: str,
|
|
189
|
+
goal: str,
|
|
190
|
+
instructions: list[str],
|
|
191
|
+
constraints: list[str],
|
|
192
|
+
input_type: str,
|
|
193
|
+
input_payload: str,
|
|
194
|
+
extra: dict[str, Any] | None = None,
|
|
195
|
+
) -> str:
|
|
196
|
+
"""Render a wizard prompt using XML structure.
|
|
197
|
+
|
|
198
|
+
This method follows Claude API best practices for XML-enhanced prompts,
|
|
199
|
+
providing clearer structure and better performance.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
role: The role/expertise for the AI (e.g., "registered nurse")
|
|
203
|
+
goal: The primary objective of the task
|
|
204
|
+
instructions: Step-by-step instructions list
|
|
205
|
+
constraints: Guidelines and boundaries list
|
|
206
|
+
input_type: Type of input data (e.g., "patient_data", "code", "document")
|
|
207
|
+
input_payload: The actual input content
|
|
208
|
+
extra: Additional context fields (optional)
|
|
209
|
+
|
|
210
|
+
Returns:
|
|
211
|
+
XML-formatted prompt string
|
|
212
|
+
|
|
213
|
+
Example:
|
|
214
|
+
prompt = self._render_xml_prompt(
|
|
215
|
+
role="HIPAA compliance specialist",
|
|
216
|
+
goal="Review patient handoff for completeness",
|
|
217
|
+
instructions=[
|
|
218
|
+
"Check for required SBAR elements",
|
|
219
|
+
"Verify patient identifiers present",
|
|
220
|
+
"Confirm allergies documented",
|
|
221
|
+
],
|
|
222
|
+
constraints=[
|
|
223
|
+
"Follow Joint Commission standards",
|
|
224
|
+
"Maintain professional medical terminology",
|
|
225
|
+
],
|
|
226
|
+
input_type="shift_handoff",
|
|
227
|
+
input_payload=json.dumps(handoff_data),
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
"""
|
|
231
|
+
if not self._is_xml_enabled():
|
|
232
|
+
# Fallback to plain text if XML disabled
|
|
233
|
+
return self._render_plain_prompt(
|
|
234
|
+
role,
|
|
235
|
+
goal,
|
|
236
|
+
instructions,
|
|
237
|
+
constraints,
|
|
238
|
+
input_payload,
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
parts = [f'<task role="{role}" version="{self.config.xml_schema_version}">']
|
|
242
|
+
parts.append(f" <goal>{goal}</goal>")
|
|
243
|
+
parts.append("")
|
|
244
|
+
|
|
245
|
+
if instructions:
|
|
246
|
+
parts.append(" <instructions>")
|
|
247
|
+
for i, inst in enumerate(instructions, 1):
|
|
248
|
+
parts.append(f" {i}. {inst}")
|
|
249
|
+
parts.append(" </instructions>")
|
|
250
|
+
parts.append("")
|
|
251
|
+
|
|
252
|
+
if constraints:
|
|
253
|
+
parts.append(" <constraints>")
|
|
254
|
+
for constraint in constraints:
|
|
255
|
+
parts.append(f" - {constraint}")
|
|
256
|
+
parts.append(" </constraints>")
|
|
257
|
+
parts.append("")
|
|
258
|
+
|
|
259
|
+
# Add extra context if provided
|
|
260
|
+
if extra:
|
|
261
|
+
parts.append(" <context>")
|
|
262
|
+
for key, value in extra.items():
|
|
263
|
+
parts.append(f" <{key}>{value}</{key}>")
|
|
264
|
+
parts.append(" </context>")
|
|
265
|
+
parts.append("")
|
|
266
|
+
|
|
267
|
+
parts.append(f' <input type="{input_type}">')
|
|
268
|
+
parts.append(f" {input_payload}")
|
|
269
|
+
parts.append(" </input>")
|
|
270
|
+
parts.append("</task>")
|
|
271
|
+
|
|
272
|
+
return "\n".join(parts)
|
|
273
|
+
|
|
274
|
+
def _render_plain_prompt(
|
|
275
|
+
self,
|
|
276
|
+
role: str,
|
|
277
|
+
goal: str,
|
|
278
|
+
instructions: list[str],
|
|
279
|
+
constraints: list[str],
|
|
280
|
+
input_payload: str,
|
|
281
|
+
) -> str:
|
|
282
|
+
"""Render plain text prompt (fallback for non-XML mode).
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
role: The role/expertise for the AI
|
|
286
|
+
goal: The primary objective
|
|
287
|
+
instructions: Step-by-step instructions
|
|
288
|
+
constraints: Guidelines and boundaries
|
|
289
|
+
input_payload: The input content
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
Plain text formatted prompt
|
|
293
|
+
|
|
294
|
+
"""
|
|
295
|
+
parts = [f"Role: {role}"]
|
|
296
|
+
parts.append(f"Goal: {goal}")
|
|
297
|
+
parts.append("")
|
|
298
|
+
|
|
299
|
+
if instructions:
|
|
300
|
+
parts.append("Instructions:")
|
|
301
|
+
for i, inst in enumerate(instructions, 1):
|
|
302
|
+
parts.append(f"{i}. {inst}")
|
|
303
|
+
parts.append("")
|
|
304
|
+
|
|
305
|
+
if constraints:
|
|
306
|
+
parts.append("Guidelines:")
|
|
307
|
+
for constraint in constraints:
|
|
308
|
+
parts.append(f"- {constraint}")
|
|
309
|
+
parts.append("")
|
|
310
|
+
|
|
311
|
+
parts.append("Input:")
|
|
312
|
+
parts.append(input_payload)
|
|
313
|
+
|
|
314
|
+
return "\n".join(parts)
|
|
315
|
+
|
|
316
|
+
def _parse_xml_response(self, response: str) -> dict[str, Any]:
|
|
317
|
+
"""Parse XML-structured response if enforcement is enabled.
|
|
318
|
+
|
|
319
|
+
Args:
|
|
320
|
+
response: The LLM response text
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
Dictionary with parsed fields or raw response
|
|
324
|
+
|
|
325
|
+
Note:
|
|
326
|
+
This is a basic parser. For production use, consider
|
|
327
|
+
using the full XmlResponseParser from empathy_os.prompts.
|
|
328
|
+
|
|
329
|
+
"""
|
|
330
|
+
if not self.config.enforce_xml_response:
|
|
331
|
+
return {"xml_parsed": False, "content": response}
|
|
332
|
+
|
|
333
|
+
# Basic XML parsing - extract common tags
|
|
334
|
+
import re
|
|
335
|
+
|
|
336
|
+
result: dict[str, Any] = {"xml_parsed": True}
|
|
337
|
+
|
|
338
|
+
# Extract <summary> tag
|
|
339
|
+
summary_match = re.search(r"<summary>(.*?)</summary>", response, re.DOTALL)
|
|
340
|
+
if summary_match:
|
|
341
|
+
result["summary"] = summary_match.group(1).strip()
|
|
342
|
+
|
|
343
|
+
# Extract <recommendation> tags
|
|
344
|
+
recommendations = re.findall(r"<recommendation>(.*?)</recommendation>", response, re.DOTALL)
|
|
345
|
+
if recommendations:
|
|
346
|
+
result["recommendations"] = [r.strip() for r in recommendations]
|
|
347
|
+
|
|
348
|
+
# Extract <finding> tags
|
|
349
|
+
findings = re.findall(r"<finding>(.*?)</finding>", response, re.DOTALL)
|
|
350
|
+
if findings:
|
|
351
|
+
result["findings"] = [f.strip() for f in findings]
|
|
352
|
+
|
|
353
|
+
# Always include raw content
|
|
354
|
+
result["content"] = response
|
|
355
|
+
|
|
356
|
+
return result
|
|
357
|
+
|
|
358
|
+
def get_config(self) -> WizardConfig:
|
|
359
|
+
"""Get wizard configuration"""
|
|
360
|
+
return self.config
|
|
361
|
+
|
|
362
|
+
def get_name(self) -> str:
|
|
363
|
+
"""Get wizard name"""
|
|
364
|
+
return self.config.name
|