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
@@ -1,530 +0,0 @@
1
- """Epic Integration Wizard - LangChain Agent
2
- Multi-step wizard for configuring and testing Epic FHIR integration
3
-
4
- Copyright 2025 Smart AI Memory, LLC
5
-
6
- Licensed under Fair Source 0.9 (the "License");
7
- you may not use this file except in compliance with the License.
8
- """
9
-
10
- import logging
11
- import operator
12
- from collections.abc import Sequence
13
- from datetime import datetime
14
- from typing import Annotated, TypedDict
15
-
16
- from langchain_core.messages import AIMessage, BaseMessage
17
- from langgraph.graph import END, StateGraph
18
-
19
- logger = logging.getLogger(__name__)
20
-
21
-
22
- # =============================================================================
23
- # Wizard State Management
24
- # =============================================================================
25
-
26
-
27
- class WizardState(TypedDict):
28
- """State for Epic Integration Wizard
29
-
30
- Tracks all wizard steps, user inputs, validation results, and progress.
31
- Microsoft-style linear progression with validation at each step.
32
- """
33
-
34
- # Wizard Progress
35
- current_step: int # 1-7
36
- completed_steps: list[int]
37
- messages: Annotated[Sequence[BaseMessage], operator.add]
38
-
39
- # Step 1: Prerequisites
40
- prerequisites_checked: bool
41
- prerequisites_passed: bool
42
- missing_prerequisites: list[str]
43
-
44
- # Step 2: Epic Credentials
45
- epic_client_id: str
46
- epic_client_secret: str
47
- epic_fhir_base_url: str
48
- epic_oauth_token_url: str
49
- epic_sandbox_mode: bool
50
-
51
- # Step 3: Connection Test
52
- connection_test_passed: bool
53
- connection_test_error: str
54
- oauth_token_obtained: bool
55
-
56
- # Step 4: Resource Permissions
57
- selected_resources: list[str] # Patient, Condition, MedicationRequest, etc.
58
- resource_scopes: list[str] # Patient.Read, Condition.Read, etc.
59
-
60
- # Step 5: Test Patient Lookup
61
- test_mrn: str
62
- patient_data_retrieved: bool
63
- patient_test_error: str
64
- retrieved_patient_name: str
65
-
66
- # Step 6: Review & Confirm
67
- configuration_confirmed: bool
68
-
69
- # Step 7: Complete
70
- integration_activated: bool
71
- activation_timestamp: str
72
-
73
- # Error Handling
74
- errors: list[str]
75
- warnings: list[str]
76
-
77
-
78
- def create_initial_state() -> WizardState:
79
- """Create initial wizard state"""
80
- return WizardState(
81
- current_step=1,
82
- completed_steps=[],
83
- messages=[],
84
- prerequisites_checked=False,
85
- prerequisites_passed=False,
86
- missing_prerequisites=[],
87
- epic_client_id="",
88
- epic_client_secret="",
89
- epic_fhir_base_url="",
90
- epic_oauth_token_url="",
91
- epic_sandbox_mode=True,
92
- connection_test_passed=False,
93
- connection_test_error="",
94
- oauth_token_obtained=False,
95
- selected_resources=[],
96
- resource_scopes=[],
97
- test_mrn="",
98
- patient_data_retrieved=False,
99
- patient_test_error="",
100
- retrieved_patient_name="",
101
- configuration_confirmed=False,
102
- integration_activated=False,
103
- activation_timestamp="",
104
- errors=[],
105
- warnings=[],
106
- )
107
-
108
-
109
- # =============================================================================
110
- # Wizard Nodes (Step Handlers)
111
- # =============================================================================
112
-
113
-
114
- async def step_1_prerequisites(state: WizardState) -> WizardState:
115
- """Step 1: Check Prerequisites
116
-
117
- Validates system readiness:
118
- - Python version
119
- - Required packages installed
120
- - Environment variables configured
121
- - Database connectivity
122
- """
123
- logger.info("Step 1: Checking prerequisites")
124
-
125
- missing = []
126
-
127
- # Check required environment variables
128
- import os
129
-
130
- required_env_vars = ["OPENAI_API_KEY", "SECRET_KEY"]
131
- for var in required_env_vars:
132
- if not os.getenv(var):
133
- missing.append(f"Environment variable: {var}")
134
-
135
- # Check database (simplified for now)
136
- try:
137
- from src.config import settings
138
-
139
- if not settings.database_url:
140
- missing.append("Database configuration")
141
- except Exception as e:
142
- missing.append(f"Configuration error: {e!s}")
143
-
144
- state["prerequisites_checked"] = True
145
- state["prerequisites_passed"] = len(missing) == 0
146
- state["missing_prerequisites"] = missing
147
- state["completed_steps"].append(1)
148
-
149
- # Always allow proceeding to Step 2 for manual credential entry
150
- # Even if automated prerequisites fail, user can still configure Epic manually
151
- if state["prerequisites_passed"]:
152
- state["messages"].append(
153
- AIMessage(content="✅ All prerequisites met. Ready to configure Epic integration."),
154
- )
155
- else:
156
- # Don't block progression - just warn user
157
- state["warnings"].append(f"Some automated prerequisites missing: {', '.join(missing)}")
158
- state["messages"].append(AIMessage(content=f"⚠️ Manual entry mode: {', '.join(missing)}"))
159
-
160
- return state
161
-
162
-
163
- async def step_2_credentials(state: WizardState) -> WizardState:
164
- """Step 2: Epic Credentials Input
165
-
166
- Collects and validates:
167
- - Epic Client ID
168
- - Epic Client Secret
169
- - FHIR Base URL
170
- - OAuth Token URL
171
- - Sandbox mode flag
172
- """
173
- logger.info("Step 2: Collecting Epic credentials")
174
-
175
- # Validate credentials are provided
176
- if not state.get("epic_client_id") or not state.get("epic_client_secret"):
177
- state["errors"].append("Epic credentials required")
178
- return state
179
-
180
- if not state.get("epic_fhir_base_url"):
181
- state["errors"].append("Epic FHIR base URL required")
182
- return state
183
-
184
- # Validate URL format
185
- if not state["epic_fhir_base_url"].startswith("https://"):
186
- state["warnings"].append("Epic FHIR URL should use HTTPS for security")
187
-
188
- state["completed_steps"].append(2)
189
- state["current_step"] = 3
190
- state["messages"].append(
191
- AIMessage(content="✅ Epic credentials collected. Ready to test connection."),
192
- )
193
-
194
- return state
195
-
196
-
197
- async def step_3_connection_test(state: WizardState) -> WizardState:
198
- """Step 3: Test Epic FHIR Connection
199
-
200
- Validates:
201
- - OAuth token can be obtained
202
- - FHIR endpoint is reachable
203
- - Credentials are valid
204
- """
205
- logger.info("Step 3: Testing Epic FHIR connection")
206
-
207
- try:
208
- # Import Epic client
209
- from src.integrations.epic_fhir_client import OAuthManager
210
-
211
- # Create OAuth manager
212
- oauth_manager = OAuthManager(
213
- token_url=state["epic_oauth_token_url"],
214
- client_id=state["epic_client_id"],
215
- client_secret=state["epic_client_secret"],
216
- )
217
-
218
- # Attempt to get token
219
- try:
220
- await oauth_manager.get_access_token()
221
- state["oauth_token_obtained"] = True
222
- state["connection_test_passed"] = True
223
- state["messages"].append(
224
- AIMessage(content="✅ Successfully connected to Epic FHIR API"),
225
- )
226
- except Exception as e:
227
- state["connection_test_error"] = str(e)
228
- state["connection_test_passed"] = False
229
- state["errors"].append(f"OAuth token request failed: {e!s}")
230
- state["messages"].append(AIMessage(content=f"❌ Connection failed: {e!s}"))
231
- return state
232
-
233
- state["completed_steps"].append(3)
234
- state["current_step"] = 4
235
-
236
- except Exception as e:
237
- logger.error(f"Connection test failed: {e}", exc_info=True)
238
- state["connection_test_error"] = str(e)
239
- state["connection_test_passed"] = False
240
- state["errors"].append(f"Connection test error: {e!s}")
241
-
242
- return state
243
-
244
-
245
- async def step_4_resource_permissions(state: WizardState) -> WizardState:
246
- """Step 4: Select FHIR Resources and Scopes
247
-
248
- User selects which FHIR resources to enable:
249
- - Patient (demographics)
250
- - Condition (diagnoses)
251
- - MedicationRequest (medications)
252
- - Observation (vitals, labs)
253
- - DocumentReference (clinical notes)
254
- """
255
- logger.info("Step 4: Configuring resource permissions")
256
-
257
- # Validate at least one resource is selected
258
- if not state.get("selected_resources"):
259
- state["errors"].append("At least one FHIR resource must be selected")
260
- return state
261
-
262
- # Map resources to OAuth scopes
263
- resource_scope_map = {
264
- "Patient": "Patient.Read",
265
- "Condition": "Condition.Read",
266
- "MedicationRequest": "MedicationRequest.Read",
267
- "Observation": "Observation.Read",
268
- "DocumentReference": "DocumentReference.Write",
269
- }
270
-
271
- scopes = [
272
- resource_scope_map[resource]
273
- for resource in state["selected_resources"]
274
- if resource in resource_scope_map
275
- ]
276
-
277
- state["resource_scopes"] = scopes
278
- state["completed_steps"].append(4)
279
- state["current_step"] = 5
280
- state["messages"].append(
281
- AIMessage(content=f"✅ Configured {len(scopes)} resource permissions: {', '.join(scopes)}"),
282
- )
283
-
284
- return state
285
-
286
-
287
- async def step_5_test_patient_lookup(state: WizardState) -> WizardState:
288
- """Step 5: Test Patient Lookup
289
-
290
- Validates end-to-end functionality:
291
- - Search patient by MRN
292
- - Retrieve patient demographics
293
- - Fetch related resources (conditions, medications)
294
- """
295
- logger.info("Step 5: Testing patient lookup")
296
-
297
- if not state.get("test_mrn"):
298
- state["errors"].append("Test MRN required for patient lookup")
299
- return state
300
-
301
- try:
302
- from src.integrations.epic_fhir_client import EpicFHIRClient, OAuthManager
303
-
304
- # Create Epic client
305
- oauth_manager = OAuthManager(
306
- token_url=state["epic_oauth_token_url"],
307
- client_id=state["epic_client_id"],
308
- client_secret=state["epic_client_secret"],
309
- )
310
-
311
- epic_client = EpicFHIRClient(
312
- base_url=state["epic_fhir_base_url"],
313
- oauth_manager=oauth_manager,
314
- )
315
-
316
- # Search for patient
317
- search_result = await epic_client.get(
318
- "/Patient",
319
- params={"identifier": f"urn:oid:1.2.840.114350|{state['test_mrn']}"},
320
- )
321
-
322
- if search_result.get("total", 0) > 0:
323
- patient = search_result["entry"][0]["resource"]
324
- patient_name = f"{patient['name'][0]['given'][0]} {patient['name'][0]['family']}"
325
-
326
- state["patient_data_retrieved"] = True
327
- state["retrieved_patient_name"] = patient_name
328
- state["messages"].append(
329
- AIMessage(content=f"✅ Successfully retrieved patient: {patient_name}"),
330
- )
331
- else:
332
- state["patient_test_error"] = "Patient not found"
333
- state["errors"].append(f"Patient with MRN {state['test_mrn']} not found")
334
- state["messages"].append(
335
- AIMessage(content=f"❌ Patient not found: MRN {state['test_mrn']}"),
336
- )
337
- return state
338
-
339
- state["completed_steps"].append(5)
340
- state["current_step"] = 6
341
-
342
- except Exception as e:
343
- logger.error(f"Patient lookup failed: {e}", exc_info=True)
344
- state["patient_test_error"] = str(e)
345
- state["errors"].append(f"Patient lookup error: {e!s}")
346
- state["messages"].append(AIMessage(content=f"❌ Patient lookup failed: {e!s}"))
347
-
348
- return state
349
-
350
-
351
- async def step_6_review_confirm(state: WizardState) -> WizardState:
352
- """Step 6: Review and Confirm Configuration
353
-
354
- Shows summary of all settings for final review:
355
- - Epic endpoint and credentials
356
- - Enabled resources
357
- - Test results
358
- """
359
- logger.info("Step 6: Review and confirm configuration")
360
-
361
- if not state.get("configuration_confirmed"):
362
- # User hasn't confirmed yet - show summary
363
- summary = f"""
364
- **Epic Integration Configuration Summary**
365
-
366
- **Connection:**
367
- - FHIR Endpoint: {state["epic_fhir_base_url"]}
368
- - Sandbox Mode: {"Yes" if state["epic_sandbox_mode"] else "No"}
369
- - Connection Test: {"✅ Passed" if state["connection_test_passed"] else "❌ Failed"}
370
-
371
- **Resources Enabled:**
372
- {chr(10).join(f"- {resource}" for resource in state["selected_resources"])}
373
-
374
- **Test Results:**
375
- - Patient Lookup: {"✅ Passed" if state["patient_data_retrieved"] else "❌ Failed"}
376
- - Test Patient: {state.get("retrieved_patient_name", "N/A")}
377
-
378
- Please confirm to activate integration.
379
- """
380
- state["messages"].append(AIMessage(content=summary))
381
- return state
382
-
383
- state["completed_steps"].append(6)
384
- state["current_step"] = 7
385
- state["messages"].append(
386
- AIMessage(content="✅ Configuration confirmed. Activating integration..."),
387
- )
388
-
389
- return state
390
-
391
-
392
- async def step_7_complete(state: WizardState) -> WizardState:
393
- """Step 7: Complete Integration Setup
394
-
395
- Finalizes configuration:
396
- - Saves settings to database/config
397
- - Activates Epic integration mode
398
- - Generates setup report
399
- """
400
- logger.info("Step 7: Completing Epic integration setup")
401
-
402
- # Save configuration (simplified - would save to database in production)
403
- try:
404
- import os
405
-
406
- # In production, save to database or config file
407
- # For now, just set environment variables
408
- os.environ["EPIC_FHIR_BASE_URL"] = state["epic_fhir_base_url"]
409
- os.environ["EPIC_CLIENT_ID"] = state["epic_client_id"]
410
- os.environ["EPIC_CLIENT_SECRET"] = state["epic_client_secret"]
411
- os.environ["EPIC_OAUTH_TOKEN_URL"] = state["epic_oauth_token_url"]
412
-
413
- state["integration_activated"] = True
414
- state["activation_timestamp"] = datetime.utcnow().isoformat()
415
- state["completed_steps"].append(7)
416
-
417
- state["messages"].append(
418
- AIMessage(
419
- content=f"""
420
- 🎉 **Epic Integration Activated!**
421
-
422
- Your AI Nurse Florence instance is now connected to Epic EHR.
423
-
424
- **Activated at:** {state["activation_timestamp"]}
425
- **Endpoint:** {state["epic_fhir_base_url"]}
426
- **Resources:** {", ".join(state["selected_resources"])}
427
-
428
- You can now:
429
- - Scan patient MRN barcodes
430
- - Auto-populate SBAR reports with Epic data
431
- - Generate AI-enhanced care plans using live patient data
432
-
433
- Next steps:
434
- 1. Train your staff on the Epic integration workflow
435
- 2. Review HIPAA compliance documentation
436
- 3. Monitor integration logs for any issues
437
- """,
438
- ),
439
- )
440
-
441
- except Exception as e:
442
- logger.error(f"Integration activation failed: {e}", exc_info=True)
443
- state["errors"].append(f"Activation error: {e!s}")
444
- state["messages"].append(AIMessage(content=f"❌ Activation failed: {e!s}"))
445
-
446
- return state
447
-
448
-
449
- # =============================================================================
450
- # Workflow Routing
451
- # =============================================================================
452
-
453
-
454
- def should_continue(state: WizardState) -> str:
455
- """Determine next step based on current state
456
-
457
- Microsoft wizard pattern: linear progression with error handling
458
- """
459
- # Check for blocking errors
460
- if state.get("errors") and len(state["errors"]) > 0:
461
- last_error = state["errors"][-1]
462
-
463
- # Some errors are blocking
464
- if "prerequisites" in last_error.lower():
465
- return "prerequisites"
466
- if "credentials" in last_error.lower():
467
- return "credentials"
468
- if "connection" in last_error.lower():
469
- return "connection_test"
470
-
471
- # Normal progression
472
- current_step = state.get("current_step", 1)
473
-
474
- if current_step == 1:
475
- return "prerequisites"
476
- if current_step == 2:
477
- return "credentials"
478
- if current_step == 3:
479
- return "connection_test"
480
- if current_step == 4:
481
- return "resource_permissions"
482
- if current_step == 5:
483
- return "test_patient_lookup"
484
- if current_step == 6:
485
- return "review_confirm"
486
- if current_step == 7:
487
- return "complete"
488
- return END
489
-
490
-
491
- # =============================================================================
492
- # LangGraph Workflow
493
- # =============================================================================
494
-
495
-
496
- def create_epic_wizard_graph():
497
- """Create LangGraph workflow for Epic Integration Wizard
498
-
499
- Microsoft-style multi-step wizard:
500
- Prerequisites → Credentials → Connection Test → Permissions → Patient Test → Review → Complete
501
- """
502
- workflow = StateGraph(WizardState)
503
-
504
- # Add nodes for each wizard step
505
- workflow.add_node("prerequisites", step_1_prerequisites)
506
- workflow.add_node("credentials", step_2_credentials)
507
- workflow.add_node("connection_test", step_3_connection_test)
508
- workflow.add_node("resource_permissions", step_4_resource_permissions)
509
- workflow.add_node("test_patient_lookup", step_5_test_patient_lookup)
510
- workflow.add_node("review_confirm", step_6_review_confirm)
511
- workflow.add_node("complete", step_7_complete)
512
-
513
- # Set entry point
514
- workflow.set_entry_point("prerequisites")
515
-
516
- # Add edges - linear progression (Microsoft wizard pattern)
517
- # Prerequisites → Credentials → Connection Test → Permissions → Patient Test → Review → Complete
518
- workflow.add_edge("prerequisites", "credentials")
519
- workflow.add_edge("credentials", "connection_test")
520
- workflow.add_edge("connection_test", "resource_permissions")
521
- workflow.add_edge("resource_permissions", "test_patient_lookup")
522
- workflow.add_edge("test_patient_lookup", "review_confirm")
523
- workflow.add_edge("review_confirm", "complete")
524
- workflow.add_edge("complete", END)
525
-
526
- return workflow.compile()
527
-
528
-
529
- # Create the compiled graph
530
- epic_wizard_graph = create_epic_wizard_graph()