empathy-framework 4.6.6__py3-none-any.whl → 4.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/METADATA +7 -6
  2. empathy_framework-4.7.0.dist-info/RECORD +354 -0
  3. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/top_level.txt +0 -2
  4. empathy_healthcare_plugin/monitors/monitoring/__init__.py +9 -9
  5. empathy_llm_toolkit/agent_factory/__init__.py +6 -6
  6. empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +7 -10
  7. empathy_llm_toolkit/agents_md/__init__.py +22 -0
  8. empathy_llm_toolkit/agents_md/loader.py +218 -0
  9. empathy_llm_toolkit/agents_md/parser.py +271 -0
  10. empathy_llm_toolkit/agents_md/registry.py +307 -0
  11. empathy_llm_toolkit/commands/__init__.py +51 -0
  12. empathy_llm_toolkit/commands/context.py +375 -0
  13. empathy_llm_toolkit/commands/loader.py +301 -0
  14. empathy_llm_toolkit/commands/models.py +231 -0
  15. empathy_llm_toolkit/commands/parser.py +371 -0
  16. empathy_llm_toolkit/commands/registry.py +429 -0
  17. empathy_llm_toolkit/config/__init__.py +8 -8
  18. empathy_llm_toolkit/config/unified.py +3 -7
  19. empathy_llm_toolkit/context/__init__.py +22 -0
  20. empathy_llm_toolkit/context/compaction.py +455 -0
  21. empathy_llm_toolkit/context/manager.py +434 -0
  22. empathy_llm_toolkit/hooks/__init__.py +24 -0
  23. empathy_llm_toolkit/hooks/config.py +306 -0
  24. empathy_llm_toolkit/hooks/executor.py +289 -0
  25. empathy_llm_toolkit/hooks/registry.py +302 -0
  26. empathy_llm_toolkit/hooks/scripts/__init__.py +39 -0
  27. empathy_llm_toolkit/hooks/scripts/evaluate_session.py +201 -0
  28. empathy_llm_toolkit/hooks/scripts/first_time_init.py +285 -0
  29. empathy_llm_toolkit/hooks/scripts/pre_compact.py +207 -0
  30. empathy_llm_toolkit/hooks/scripts/session_end.py +183 -0
  31. empathy_llm_toolkit/hooks/scripts/session_start.py +163 -0
  32. empathy_llm_toolkit/hooks/scripts/suggest_compact.py +225 -0
  33. empathy_llm_toolkit/learning/__init__.py +30 -0
  34. empathy_llm_toolkit/learning/evaluator.py +438 -0
  35. empathy_llm_toolkit/learning/extractor.py +514 -0
  36. empathy_llm_toolkit/learning/storage.py +560 -0
  37. empathy_llm_toolkit/providers.py +4 -11
  38. empathy_llm_toolkit/security/__init__.py +17 -17
  39. empathy_llm_toolkit/utils/tokens.py +2 -5
  40. empathy_os/__init__.py +202 -70
  41. empathy_os/cache_monitor.py +5 -3
  42. empathy_os/cli/__init__.py +11 -55
  43. empathy_os/cli/__main__.py +29 -15
  44. empathy_os/cli/commands/inspection.py +21 -12
  45. empathy_os/cli/commands/memory.py +4 -12
  46. empathy_os/cli/commands/profiling.py +198 -0
  47. empathy_os/cli/commands/utilities.py +27 -7
  48. empathy_os/cli.py +28 -57
  49. empathy_os/cli_unified.py +525 -1164
  50. empathy_os/cost_tracker.py +9 -3
  51. empathy_os/dashboard/server.py +200 -2
  52. empathy_os/hot_reload/__init__.py +7 -7
  53. empathy_os/hot_reload/config.py +6 -7
  54. empathy_os/hot_reload/integration.py +35 -35
  55. empathy_os/hot_reload/reloader.py +57 -57
  56. empathy_os/hot_reload/watcher.py +28 -28
  57. empathy_os/hot_reload/websocket.py +2 -2
  58. empathy_os/memory/__init__.py +11 -4
  59. empathy_os/memory/claude_memory.py +1 -1
  60. empathy_os/memory/cross_session.py +8 -12
  61. empathy_os/memory/edges.py +6 -6
  62. empathy_os/memory/file_session.py +770 -0
  63. empathy_os/memory/graph.py +30 -30
  64. empathy_os/memory/nodes.py +6 -6
  65. empathy_os/memory/short_term.py +15 -9
  66. empathy_os/memory/unified.py +606 -140
  67. empathy_os/meta_workflows/agent_creator.py +3 -9
  68. empathy_os/meta_workflows/cli_meta_workflows.py +113 -53
  69. empathy_os/meta_workflows/form_engine.py +6 -18
  70. empathy_os/meta_workflows/intent_detector.py +64 -24
  71. empathy_os/meta_workflows/models.py +3 -1
  72. empathy_os/meta_workflows/pattern_learner.py +13 -31
  73. empathy_os/meta_workflows/plan_generator.py +55 -47
  74. empathy_os/meta_workflows/session_context.py +2 -3
  75. empathy_os/meta_workflows/workflow.py +20 -51
  76. empathy_os/models/cli.py +2 -2
  77. empathy_os/models/tasks.py +1 -2
  78. empathy_os/models/telemetry.py +4 -1
  79. empathy_os/models/token_estimator.py +3 -1
  80. empathy_os/monitoring/alerts.py +938 -9
  81. empathy_os/monitoring/alerts_cli.py +346 -183
  82. empathy_os/orchestration/execution_strategies.py +12 -29
  83. empathy_os/orchestration/pattern_learner.py +20 -26
  84. empathy_os/orchestration/real_tools.py +6 -15
  85. empathy_os/platform_utils.py +2 -1
  86. empathy_os/plugins/__init__.py +2 -2
  87. empathy_os/plugins/base.py +64 -64
  88. empathy_os/plugins/registry.py +32 -32
  89. empathy_os/project_index/index.py +49 -15
  90. empathy_os/project_index/models.py +1 -2
  91. empathy_os/project_index/reports.py +1 -1
  92. empathy_os/project_index/scanner.py +1 -0
  93. empathy_os/redis_memory.py +10 -7
  94. empathy_os/resilience/__init__.py +1 -1
  95. empathy_os/resilience/health.py +10 -10
  96. empathy_os/routing/__init__.py +7 -7
  97. empathy_os/routing/chain_executor.py +37 -37
  98. empathy_os/routing/classifier.py +36 -36
  99. empathy_os/routing/smart_router.py +40 -40
  100. empathy_os/routing/{wizard_registry.py → workflow_registry.py} +47 -47
  101. empathy_os/scaffolding/__init__.py +8 -8
  102. empathy_os/scaffolding/__main__.py +1 -1
  103. empathy_os/scaffolding/cli.py +28 -28
  104. empathy_os/socratic/__init__.py +3 -19
  105. empathy_os/socratic/ab_testing.py +25 -36
  106. empathy_os/socratic/blueprint.py +38 -38
  107. empathy_os/socratic/cli.py +34 -20
  108. empathy_os/socratic/collaboration.py +30 -28
  109. empathy_os/socratic/domain_templates.py +9 -1
  110. empathy_os/socratic/embeddings.py +17 -13
  111. empathy_os/socratic/engine.py +135 -70
  112. empathy_os/socratic/explainer.py +70 -60
  113. empathy_os/socratic/feedback.py +24 -19
  114. empathy_os/socratic/forms.py +15 -10
  115. empathy_os/socratic/generator.py +51 -35
  116. empathy_os/socratic/llm_analyzer.py +25 -23
  117. empathy_os/socratic/mcp_server.py +99 -159
  118. empathy_os/socratic/session.py +19 -13
  119. empathy_os/socratic/storage.py +98 -67
  120. empathy_os/socratic/success.py +38 -27
  121. empathy_os/socratic/visual_editor.py +51 -39
  122. empathy_os/socratic/web_ui.py +99 -66
  123. empathy_os/telemetry/cli.py +3 -1
  124. empathy_os/telemetry/usage_tracker.py +1 -3
  125. empathy_os/test_generator/__init__.py +3 -3
  126. empathy_os/test_generator/cli.py +28 -28
  127. empathy_os/test_generator/generator.py +64 -66
  128. empathy_os/test_generator/risk_analyzer.py +11 -11
  129. empathy_os/vscode_bridge.py +173 -0
  130. empathy_os/workflows/__init__.py +212 -120
  131. empathy_os/workflows/batch_processing.py +8 -24
  132. empathy_os/workflows/bug_predict.py +1 -1
  133. empathy_os/workflows/code_review.py +20 -5
  134. empathy_os/workflows/code_review_pipeline.py +13 -8
  135. empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
  136. empathy_os/workflows/manage_documentation.py +1 -0
  137. empathy_os/workflows/orchestrated_health_check.py +6 -11
  138. empathy_os/workflows/orchestrated_release_prep.py +3 -3
  139. empathy_os/workflows/pr_review.py +18 -10
  140. empathy_os/workflows/progressive/__init__.py +2 -12
  141. empathy_os/workflows/progressive/cli.py +14 -37
  142. empathy_os/workflows/progressive/core.py +12 -12
  143. empathy_os/workflows/progressive/orchestrator.py +166 -144
  144. empathy_os/workflows/progressive/reports.py +22 -31
  145. empathy_os/workflows/progressive/telemetry.py +8 -14
  146. empathy_os/workflows/progressive/test_gen.py +29 -48
  147. empathy_os/workflows/progressive/workflow.py +31 -70
  148. empathy_os/workflows/release_prep.py +21 -6
  149. empathy_os/workflows/release_prep_crew.py +1 -0
  150. empathy_os/workflows/secure_release.py +13 -6
  151. empathy_os/workflows/security_audit.py +8 -3
  152. empathy_os/workflows/test_coverage_boost_crew.py +3 -2
  153. empathy_os/workflows/test_maintenance_crew.py +1 -0
  154. empathy_os/workflows/test_runner.py +16 -12
  155. empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
  156. empathy_software_plugin/cli.py +0 -122
  157. coach_wizards/__init__.py +0 -45
  158. coach_wizards/accessibility_wizard.py +0 -91
  159. coach_wizards/api_wizard.py +0 -91
  160. coach_wizards/base_wizard.py +0 -209
  161. coach_wizards/cicd_wizard.py +0 -91
  162. coach_wizards/code_reviewer_README.md +0 -60
  163. coach_wizards/code_reviewer_wizard.py +0 -180
  164. coach_wizards/compliance_wizard.py +0 -91
  165. coach_wizards/database_wizard.py +0 -91
  166. coach_wizards/debugging_wizard.py +0 -91
  167. coach_wizards/documentation_wizard.py +0 -91
  168. coach_wizards/generate_wizards.py +0 -347
  169. coach_wizards/localization_wizard.py +0 -173
  170. coach_wizards/migration_wizard.py +0 -91
  171. coach_wizards/monitoring_wizard.py +0 -91
  172. coach_wizards/observability_wizard.py +0 -91
  173. coach_wizards/performance_wizard.py +0 -91
  174. coach_wizards/prompt_engineering_wizard.py +0 -661
  175. coach_wizards/refactoring_wizard.py +0 -91
  176. coach_wizards/scaling_wizard.py +0 -90
  177. coach_wizards/security_wizard.py +0 -92
  178. coach_wizards/testing_wizard.py +0 -91
  179. empathy_framework-4.6.6.dist-info/RECORD +0 -410
  180. empathy_llm_toolkit/wizards/__init__.py +0 -43
  181. empathy_llm_toolkit/wizards/base_wizard.py +0 -364
  182. empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
  183. empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
  184. empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
  185. empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
  186. empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
  187. empathy_os/wizard_factory_cli.py +0 -170
  188. empathy_software_plugin/wizards/__init__.py +0 -42
  189. empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
  190. empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
  191. empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
  192. empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
  193. empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
  194. empathy_software_plugin/wizards/base_wizard.py +0 -288
  195. empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
  196. empathy_software_plugin/wizards/code_review_wizard.py +0 -604
  197. empathy_software_plugin/wizards/debugging/__init__.py +0 -50
  198. empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
  199. empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
  200. empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
  201. empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
  202. empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
  203. empathy_software_plugin/wizards/debugging/verification.py +0 -369
  204. empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
  205. empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
  206. empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
  207. empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
  208. empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
  209. empathy_software_plugin/wizards/performance/__init__.py +0 -9
  210. empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
  211. empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
  212. empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
  213. empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
  214. empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
  215. empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
  216. empathy_software_plugin/wizards/security/__init__.py +0 -32
  217. empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
  218. empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
  219. empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
  220. empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
  221. empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
  222. empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
  223. empathy_software_plugin/wizards/testing/__init__.py +0 -27
  224. empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
  225. empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
  226. empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
  227. empathy_software_plugin/wizards/testing_wizard.py +0 -274
  228. wizards/__init__.py +0 -82
  229. wizards/admission_assessment_wizard.py +0 -644
  230. wizards/care_plan.py +0 -321
  231. wizards/clinical_assessment.py +0 -769
  232. wizards/discharge_planning.py +0 -77
  233. wizards/discharge_summary_wizard.py +0 -468
  234. wizards/dosage_calculation.py +0 -497
  235. wizards/incident_report_wizard.py +0 -454
  236. wizards/medication_reconciliation.py +0 -85
  237. wizards/nursing_assessment.py +0 -171
  238. wizards/patient_education.py +0 -654
  239. wizards/quality_improvement.py +0 -705
  240. wizards/sbar_report.py +0 -324
  241. wizards/sbar_wizard.py +0 -608
  242. wizards/shift_handoff_wizard.py +0 -535
  243. wizards/soap_note_wizard.py +0 -679
  244. wizards/treatment_plan.py +0 -15
  245. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/WHEEL +0 -0
  246. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/entry_points.txt +0 -0
  247. {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,497 +0,0 @@
1
- """
2
- Dosage Calculation Wizard Router
3
- Provides step-by-step guidance for safe medication dosage calculations
4
- """
5
-
6
- import uuid
7
- from datetime import datetime
8
- from typing import Any
9
-
10
- from fastapi import APIRouter, HTTPException, status
11
- from pydantic import BaseModel, Field
12
- from src.utils.api_responses import create_success_response
13
-
14
- router = APIRouter(prefix="/wizards/dosage-calculation", tags=["wizards", "dosage-calculation"])
15
-
16
- # In-memory session storage (use Redis in production)
17
- wizard_sessions: dict[str, dict[str, Any]] = {}
18
-
19
-
20
- class DosageCalculationStart(BaseModel):
21
- """Initial dosage calculation request"""
22
-
23
- calculation_type: str = Field(..., description="Type of calculation")
24
- patient_weight: float | None = Field(None, description="Patient weight in kg (if weight-based)")
25
- special_considerations: str | None = Field(
26
- None, description="Any special considerations (pediatric, renal impairment, etc.)"
27
- )
28
-
29
-
30
- class BasicDosageStep(BaseModel):
31
- """Basic dosage calculation parameters"""
32
-
33
- ordered_dose: float = Field(..., description="Ordered dose amount")
34
- ordered_dose_unit: str = Field(..., description="Ordered dose unit")
35
- available_strength: float = Field(..., description="Available medication strength")
36
- available_strength_unit: str = Field(..., description="Available strength unit")
37
- available_volume: float = Field(..., description="Available volume")
38
- available_volume_unit: str = Field(..., description="Available volume unit")
39
-
40
-
41
- class WeightBasedDosageStep(BaseModel):
42
- """Weight-based dosage calculation parameters"""
43
-
44
- dose_per_kg: float = Field(..., description="Dose per kg")
45
- dose_unit: str = Field(..., description="Dose unit")
46
- patient_weight: float = Field(..., description="Patient weight in kg")
47
- frequency_per_day: int = Field(..., description="Number of doses per day")
48
- available_concentration: float = Field(..., description="Available concentration")
49
- concentration_unit: str = Field(..., description="Concentration unit (mg/ml, mcg/ml, etc.)")
50
-
51
-
52
- class IVRateStep(BaseModel):
53
- """IV rate calculation parameters"""
54
-
55
- total_volume: float = Field(..., description="Total volume to infuse")
56
- volume_unit: str = Field(..., description="Volume unit")
57
- infusion_time: float = Field(..., description="Infusion time")
58
- time_unit: str = Field(..., description="Time unit")
59
- drop_factor: int | None = Field(None, description="Drop factor (if using gravity)")
60
-
61
-
62
- class PediatricDosageStep(BaseModel):
63
- """Pediatric dosage calculation parameters"""
64
-
65
- child_weight: float = Field(..., description="Child weight in kg")
66
- child_age_months: int | None = Field(None, description="Child age in months")
67
- adult_dose: float = Field(..., description="Adult dose")
68
- dose_unit: str = Field(..., description="Dose unit")
69
- calculation_method: str = Field(
70
- ..., description="Calculation method: clark_rule, young_rule, fried_rule, bsa_method"
71
- )
72
- bsa: float | None = Field(None, description="Body surface area if using BSA method")
73
-
74
-
75
- class DosageCalculationResponse(BaseModel):
76
- """Dosage calculation result"""
77
-
78
- wizard_id: str
79
- step: str
80
- calculation_result: dict[str, Any]
81
- safety_checks: list[str]
82
- next_steps: list[str]
83
- formula_used: str
84
- show_work: list[str]
85
-
86
-
87
- @router.post("/start", response_model=DosageCalculationResponse)
88
- def start_dosage_calculation(request: DosageCalculationStart):
89
- """Start a new dosage calculation wizard session"""
90
- try:
91
- wizard_id = str(uuid.uuid4())
92
-
93
- # Initialize session
94
- wizard_sessions[wizard_id] = {
95
- "wizard_id": wizard_id,
96
- "calculation_type": request.calculation_type,
97
- "patient_weight": request.patient_weight,
98
- "special_considerations": request.special_considerations,
99
- "created_at": datetime.utcnow().isoformat(),
100
- "current_step": "parameters",
101
- "completed_steps": [],
102
- }
103
-
104
- # Determine next steps based on calculation type
105
- next_steps = get_next_steps_for_type(request.calculation_type)
106
-
107
- return create_success_response(
108
- {
109
- "wizard_id": wizard_id,
110
- "step": "started",
111
- "calculation_result": {
112
- "type": request.calculation_type,
113
- "status": "ready_for_parameters",
114
- },
115
- "safety_checks": [
116
- "Always verify calculations with a colleague",
117
- "Check for drug allergies and contraindications",
118
- "Confirm patient identity with two identifiers",
119
- "Review maximum safe doses",
120
- ],
121
- "next_steps": next_steps,
122
- "formula_used": f"Preparing {request.calculation_type} calculation",
123
- "show_work": [f"Calculation type: {request.calculation_type}"],
124
- }
125
- )
126
-
127
- except Exception as e:
128
- raise HTTPException(
129
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
130
- detail=f"Error starting dosage calculation wizard: {str(e)}",
131
- )
132
-
133
-
134
- @router.post("/{wizard_id}/basic-dosage", response_model=DosageCalculationResponse)
135
- def calculate_basic_dosage(wizard_id: str, dosage_data: BasicDosageStep):
136
- """Calculate basic dosage using dose/strength formula"""
137
- session = get_session(wizard_id)
138
-
139
- try:
140
- # Perform calculation
141
- result = perform_basic_dosage_calculation(dosage_data)
142
-
143
- # Update session
144
- session["basic_dosage_result"] = result
145
- session["completed_steps"].append("basic_dosage")
146
- session["current_step"] = "verification"
147
-
148
- return create_success_response(
149
- {
150
- "wizard_id": wizard_id,
151
- "step": "basic_dosage_calculated",
152
- "calculation_result": result,
153
- "safety_checks": [
154
- f"Verify: Give {result['volume_to_give']:.2f} {dosage_data.available_volume_unit}",
155
- "Check if this volume is reasonable for the route",
156
- "Confirm dose is within safe range",
157
- "Double-check your calculation",
158
- ],
159
- "next_steps": [
160
- "Review calculation with colleague",
161
- "Prepare medication",
162
- "Perform final safety checks",
163
- ],
164
- "formula_used": "Volume = (Ordered Dose × Available Volume) ÷ Available Strength",
165
- "show_work": result["show_work"],
166
- }
167
- )
168
-
169
- except Exception as e:
170
- raise HTTPException(
171
- status_code=status.HTTP_400_BAD_REQUEST,
172
- detail=f"Error in basic dosage calculation: {str(e)}",
173
- )
174
-
175
-
176
- @router.post("/{wizard_id}/weight-based", response_model=DosageCalculationResponse)
177
- def calculate_weight_based_dosage(wizard_id: str, dosage_data: WeightBasedDosageStep):
178
- """Calculate weight-based dosage"""
179
- session = get_session(wizard_id)
180
-
181
- try:
182
- result = perform_weight_based_calculation(dosage_data)
183
-
184
- session["weight_based_result"] = result
185
- session["completed_steps"].append("weight_based")
186
- session["current_step"] = "verification"
187
-
188
- return create_success_response(
189
- {
190
- "wizard_id": wizard_id,
191
- "step": "weight_based_calculated",
192
- "calculation_result": result,
193
- "safety_checks": [
194
- f"Total daily dose: {result['total_daily_dose']:.2f} {dosage_data.dose_unit}",
195
- f"Per dose: {result['dose_per_administration']:.2f} {dosage_data.dose_unit}",
196
- f"Volume per dose: {result['volume_per_dose']:.2f} ml",
197
- "Verify weight is accurate",
198
- "Check maximum recommended dose",
199
- ],
200
- "next_steps": [
201
- "Confirm dosing schedule",
202
- "Review with pharmacist if needed",
203
- "Prepare first dose",
204
- ],
205
- "formula_used": "Total Daily Dose = Dose/kg × Weight × Frequency",
206
- "show_work": result["show_work"],
207
- }
208
- )
209
-
210
- except Exception as e:
211
- raise HTTPException(
212
- status_code=status.HTTP_400_BAD_REQUEST,
213
- detail=f"Error in weight-based calculation: {str(e)}",
214
- )
215
-
216
-
217
- @router.post("/{wizard_id}/iv-rate", response_model=DosageCalculationResponse)
218
- def calculate_iv_rate(wizard_id: str, rate_data: IVRateStep):
219
- """Calculate IV infusion rate"""
220
- session = get_session(wizard_id)
221
-
222
- try:
223
- result = perform_iv_rate_calculation(rate_data)
224
-
225
- session["iv_rate_result"] = result
226
- session["completed_steps"].append("iv_rate")
227
- session["current_step"] = "verification"
228
-
229
- return create_success_response(
230
- {
231
- "wizard_id": wizard_id,
232
- "step": "iv_rate_calculated",
233
- "calculation_result": result,
234
- "safety_checks": [
235
- f"Rate: {result['ml_per_hour']:.1f} ml/hr",
236
- f"Drops per minute: {result.get('drops_per_minute', 'N/A')}",
237
- "Verify pump settings",
238
- "Check IV site before starting",
239
- "Monitor patient throughout infusion",
240
- ],
241
- "next_steps": [
242
- "Set pump to calculated rate",
243
- "Document infusion start",
244
- "Schedule monitoring intervals",
245
- ],
246
- "formula_used": "Rate (ml/hr) = Total Volume ÷ Time (hours)",
247
- "show_work": result["show_work"],
248
- }
249
- )
250
-
251
- except Exception as e:
252
- raise HTTPException(
253
- status_code=status.HTTP_400_BAD_REQUEST,
254
- detail=f"Error in IV rate calculation: {str(e)}",
255
- )
256
-
257
-
258
- @router.post("/{wizard_id}/pediatric", response_model=DosageCalculationResponse)
259
- def calculate_pediatric_dosage(wizard_id: str, pediatric_data: PediatricDosageStep):
260
- """Calculate pediatric dosage using various methods"""
261
- session = get_session(wizard_id)
262
-
263
- try:
264
- result = perform_pediatric_calculation(pediatric_data)
265
-
266
- session["pediatric_result"] = result
267
- session["completed_steps"].append("pediatric")
268
- session["current_step"] = "verification"
269
-
270
- return create_success_response(
271
- {
272
- "wizard_id": wizard_id,
273
- "step": "pediatric_calculated",
274
- "calculation_result": result,
275
- "safety_checks": [
276
- f"Calculated pediatric dose: {result['calculated_dose']:.2f} {pediatric_data.dose_unit}",
277
- "CRITICAL: Verify dose is appropriate for age/weight",
278
- "Check pediatric dosing references",
279
- "Consider maximum safe dose limits",
280
- "Have pediatric emergency protocols ready",
281
- ],
282
- "next_steps": [
283
- "Verify with pediatric dosing guide",
284
- "Review with physician if dose seems high",
285
- "Prepare medication with extra care",
286
- "Monitor closely after administration",
287
- ],
288
- "formula_used": result["formula_used"],
289
- "show_work": result["show_work"],
290
- }
291
- )
292
-
293
- except Exception as e:
294
- raise HTTPException(
295
- status_code=status.HTTP_400_BAD_REQUEST,
296
- detail=f"Error in pediatric calculation: {str(e)}",
297
- )
298
-
299
-
300
- @router.get("/{wizard_id}/summary", response_model=dict[str, Any])
301
- def get_calculation_summary(wizard_id: str):
302
- """Get summary of all calculations performed"""
303
- session = get_session(wizard_id)
304
-
305
- summary = {
306
- "wizard_id": wizard_id,
307
- "calculation_type": session.get("calculation_type"),
308
- "completed_steps": session.get("completed_steps", []),
309
- "results": {},
310
- "final_safety_checklist": [
311
- "All calculations double-checked",
312
- "Patient identity verified with two identifiers",
313
- "Allergies and contraindications reviewed",
314
- "Dose within safe parameters",
315
- "Route and timing appropriate",
316
- "Equipment prepared and checked",
317
- "Monitoring plan in place",
318
- ],
319
- }
320
-
321
- # Include all completed calculation results
322
- for step in [
323
- "basic_dosage_result",
324
- "weight_based_result",
325
- "iv_rate_result",
326
- "pediatric_result",
327
- ]:
328
- if step in session:
329
- summary["results"][step] = session[step]
330
-
331
- return create_success_response(summary)
332
-
333
-
334
- def get_session(wizard_id: str) -> dict[str, Any]:
335
- """Get wizard session or raise error"""
336
- if wizard_id not in wizard_sessions:
337
- raise HTTPException(
338
- status_code=status.HTTP_404_NOT_FOUND, detail="Wizard session not found"
339
- )
340
- return wizard_sessions[wizard_id]
341
-
342
-
343
- def get_next_steps_for_type(calculation_type: str) -> list[str]:
344
- """Get next steps based on calculation type"""
345
- steps_map = {
346
- "basic_dosage": ["Enter ordered dose and available strength", "Calculate volume to give"],
347
- "weight_based": ["Enter dose per kg and patient weight", "Calculate total daily dose"],
348
- "iv_rate": ["Enter volume and infusion time", "Calculate ml/hr rate"],
349
- "pediatric": ["Enter child weight and adult dose", "Select calculation method"],
350
- "complex": ["Choose specific calculation type", "Enter all required parameters"],
351
- }
352
- return steps_map.get(calculation_type, ["Enter calculation parameters"])
353
-
354
-
355
- def perform_basic_dosage_calculation(data: BasicDosageStep) -> dict[str, Any]:
356
- """Perform basic dosage calculation"""
357
- # Convert units if needed (basic unit matching for now)
358
- if data.ordered_dose_unit != data.available_strength_unit:
359
- # In a real implementation, add unit conversion
360
- pass
361
-
362
- # Calculate volume to give
363
- volume_to_give = (data.ordered_dose * data.available_volume) / data.available_strength
364
-
365
- show_work = [
366
- f"Ordered dose: {data.ordered_dose} {data.ordered_dose_unit}",
367
- f"Available: {data.available_strength} {data.available_strength_unit} per {data.available_volume} {data.available_volume_unit}",
368
- f"Calculation: ({data.ordered_dose} × {data.available_volume}) ÷ {data.available_strength}",
369
- f"Calculation: {data.ordered_dose * data.available_volume} ÷ {data.available_strength}",
370
- f"Result: {volume_to_give:.2f} {data.available_volume_unit}",
371
- ]
372
-
373
- return {
374
- "volume_to_give": volume_to_give,
375
- "unit": data.available_volume_unit,
376
- "ordered_dose": data.ordered_dose,
377
- "available_strength": data.available_strength,
378
- "show_work": show_work,
379
- "reasonable_check": "OK" if 0.1 <= volume_to_give <= 50 else "REVIEW - Unusual volume",
380
- }
381
-
382
-
383
- def perform_weight_based_calculation(data: WeightBasedDosageStep) -> dict[str, Any]:
384
- """Perform weight-based dosage calculation"""
385
- total_daily_dose = data.dose_per_kg * data.patient_weight
386
- dose_per_administration = total_daily_dose / data.frequency_per_day
387
- volume_per_dose = dose_per_administration / data.available_concentration
388
-
389
- show_work = [
390
- f"Dose per kg: {data.dose_per_kg} {data.dose_unit}/kg",
391
- f"Patient weight: {data.patient_weight} kg",
392
- f"Total daily dose: {data.dose_per_kg} × {data.patient_weight} = {total_daily_dose:.2f} {data.dose_unit}",
393
- f"Doses per day: {data.frequency_per_day}",
394
- f"Dose per administration: {total_daily_dose:.2f} ÷ {data.frequency_per_day} = {dose_per_administration:.2f} {data.dose_unit}",
395
- f"Available concentration: {data.available_concentration} {data.concentration_unit}",
396
- f"Volume per dose: {dose_per_administration:.2f} ÷ {data.available_concentration} = {volume_per_dose:.2f} ml",
397
- ]
398
-
399
- return {
400
- "total_daily_dose": total_daily_dose,
401
- "dose_per_administration": dose_per_administration,
402
- "volume_per_dose": volume_per_dose,
403
- "frequency": data.frequency_per_day,
404
- "show_work": show_work,
405
- }
406
-
407
-
408
- def perform_iv_rate_calculation(data: IVRateStep) -> dict[str, Any]:
409
- """Perform IV rate calculation"""
410
- # Convert time to hours if needed
411
- time_hours = data.infusion_time
412
- if data.time_unit == "minutes":
413
- time_hours = data.infusion_time / 60
414
-
415
- ml_per_hour = data.total_volume / time_hours
416
-
417
- show_work = [
418
- f"Total volume: {data.total_volume} {data.volume_unit}",
419
- f"Infusion time: {data.infusion_time} {data.time_unit}",
420
- f"Rate calculation: {data.total_volume} ÷ {time_hours} hours = {ml_per_hour:.1f} ml/hr",
421
- ]
422
-
423
- result = {
424
- "ml_per_hour": ml_per_hour,
425
- "total_volume": data.total_volume,
426
- "infusion_time_hours": time_hours,
427
- "show_work": show_work,
428
- }
429
-
430
- # Calculate drops per minute if drop factor provided
431
- if data.drop_factor:
432
- drops_per_minute = (ml_per_hour * data.drop_factor) / 60
433
- result["drops_per_minute"] = f"{drops_per_minute:.0f} drops/min"
434
- show_work.append(
435
- f"Drops per minute: ({ml_per_hour:.1f} × {data.drop_factor}) ÷ 60 = {drops_per_minute:.0f} drops/min"
436
- )
437
-
438
- return result
439
-
440
-
441
- def perform_pediatric_calculation(data: PediatricDosageStep) -> dict[str, Any]:
442
- """Perform pediatric dosage calculation using various methods"""
443
-
444
- if data.calculation_method == "clark_rule":
445
- # Clark's Rule: Child dose = (Child weight / 70 kg) × Adult dose
446
- child_dose = (data.child_weight / 70) * data.adult_dose
447
- formula_used = "Clark's Rule: Child dose = (Child weight ÷ 70 kg) × Adult dose"
448
- show_work = [
449
- "Clark's Rule calculation:",
450
- f"Child weight: {data.child_weight} kg",
451
- f"Adult dose: {data.adult_dose} {data.dose_unit}",
452
- f"Calculation: ({data.child_weight} ÷ 70) × {data.adult_dose}",
453
- f"Result: {child_dose:.2f} {data.dose_unit}",
454
- ]
455
-
456
- elif data.calculation_method == "young_rule" and data.child_age_months:
457
- # Young's Rule: Child dose = (Age in months / (Age in months + 150)) × Adult dose
458
- child_dose = (data.child_age_months / (data.child_age_months + 150)) * data.adult_dose
459
- formula_used = "Young's Rule: Child dose = (Age in months ÷ (Age + 150)) × Adult dose"
460
- show_work = [
461
- "Young's Rule calculation:",
462
- f"Child age: {data.child_age_months} months",
463
- f"Adult dose: {data.adult_dose} {data.dose_unit}",
464
- f"Calculation: ({data.child_age_months} ÷ ({data.child_age_months} + 150)) × {data.adult_dose}",
465
- f"Result: {child_dose:.2f} {data.dose_unit}",
466
- ]
467
-
468
- elif data.calculation_method == "bsa_method" and data.bsa:
469
- # BSA Method: Child dose = (Child BSA / 1.73 m²) × Adult dose
470
- child_dose = (data.bsa / 1.73) * data.adult_dose
471
- formula_used = "BSA Method: Child dose = (Child BSA ÷ 1.73 m²) × Adult dose"
472
- show_work = [
473
- "BSA Method calculation:",
474
- f"Child BSA: {data.bsa} m²",
475
- f"Adult dose: {data.adult_dose} {data.dose_unit}",
476
- f"Calculation: ({data.bsa} ÷ 1.73) × {data.adult_dose}",
477
- f"Result: {child_dose:.2f} {data.dose_unit}",
478
- ]
479
-
480
- else:
481
- # Default to weight-based calculation
482
- # Assume 1-2 mg/kg as a conservative estimate
483
- child_dose = data.child_weight * 1.5 # This is just an example
484
- formula_used = "Weight-based estimation (requires verification)"
485
- show_work = [
486
- "Weight-based estimation:",
487
- f"Child weight: {data.child_weight} kg",
488
- "⚠️ This is an estimate - verify with pediatric references",
489
- ]
490
-
491
- return {
492
- "calculated_dose": child_dose,
493
- "method_used": data.calculation_method,
494
- "formula_used": formula_used,
495
- "show_work": show_work,
496
- "safety_note": "ALWAYS verify pediatric doses with current pediatric references",
497
- }