""" AnestheBot AI — World's First Real-Time Anesthesia Assistant ============================================================== Created by Dr. Milan Joshi WORLD FIRST: No anesthesia chatbot exists in the market (as of 2026). This fills the biggest whitespace in healthcare AI. Features: - Real-time vital signs simulation & monitoring dashboard - Live alerts when vitals go out of safe range - Pharmacokinetic drug dosing (Marsh, Schnider, Minto models) - ASA Physical Status classification - Mallampati Airway Assessment tool - Drug interaction checker for anesthetic agents - Emergency protocol engine (Malignant Hyperthermia, Anaphylaxis, Bronchospasm, etc.) - Fluid & blood loss calculator (Holliday-Segar, 4-2-1 rule) - Pre-op risk scoring (Lee's Revised Cardiac Risk Index) - Pediatric anesthesia dosing (weight-based + age-adjusted) - Real-time BIS (depth of anesthesia) monitoring - Ventilator settings calculator - Post-op PACU handoff report generator Hosted on Hugging Face Spaces with Gradio """ import gradio as gr import random import re import math import time import threading from datetime import datetime from collections import Counter, defaultdict # --------------------------------------------------------------------------- # Pharmacokinetic Models # --------------------------------------------------------------------------- ANESTHETIC_DRUGS = { "propofol": { "class": "Induction Agent (IV)", "induction_dose": {"adult": "1.5-2.5 mg/kg", "pediatric": "2.5-3.5 mg/kg", "elderly": "1.0-1.5 mg/kg"}, "maintenance": "100-200 mcg/kg/min (TIVA)", "onset": "15-30 seconds", "duration": "5-10 minutes", "pk_model": "Marsh / Schnider", "contraindications": ["Egg/soy allergy (debated)", "Propofol infusion syndrome risk >48h"], "side_effects": ["Hypotension", "Apnea", "Pain on injection", "Bradycardia"], "interactions": { "opioids": {"effect": "Synergistic CNS depression", "action": "Reduce propofol dose by 25-50%"}, "midazolam": {"effect": "Synergistic sedation", "action": "Reduce propofol dose by 20-30%"}, "ketamine": {"effect": "Hemodynamic stability", "action": "Ketamine offsets propofol-induced hypotension"}, }, "max_dose": "4 mg/kg/hr maintenance (avoid propofol infusion syndrome)", }, "sevoflurane": { "class": "Volatile Inhalational Agent", "induction_dose": {"adult": "Up to 8% for inhalation induction", "pediatric": "Up to 8% (preferred for pediatric induction)", "elderly": "Reduce by 25%"}, "maintenance": "1.5-2.5% (1.0-1.5 MAC)", "onset": "1-2 minutes", "duration": "Emergence in 5-10 min after discontinuation", "mac_value": "2.0% (age 40), increases in children", "contraindications": ["History of malignant hyperthermia", "Severe hepatic dysfunction"], "side_effects": ["Hypotension", "Respiratory depression", "Emergence agitation (pediatric)", "Compound A with low-flow"], "interactions": { "nitrous_oxide": {"effect": "Reduces MAC by 25-30%", "action": "Reduce sevoflurane concentration"}, "opioids": {"effect": "Reduces MAC by 50-70%", "action": "Significantly reduce sevoflurane concentration"}, "benzodiazepines": {"effect": "Reduces MAC by 15-20%", "action": "Slight dose reduction"}, }, }, "fentanyl": { "class": "Opioid Analgesic", "induction_dose": {"adult": "1-2 mcg/kg", "pediatric": "1-2 mcg/kg", "elderly": "0.5-1 mcg/kg"}, "maintenance": "1-2 mcg/kg/hr or bolus 25-50 mcg PRN", "onset": "1-2 minutes IV", "duration": "30-60 minutes", "contraindications": ["MAO inhibitor use (within 14 days)", "Severe respiratory depression"], "side_effects": ["Respiratory depression", "Bradycardia", "Chest wall rigidity (rapid bolus)", "Nausea/vomiting"], "interactions": { "propofol": {"effect": "Synergistic CNS depression", "action": "Reduce both doses"}, "midazolam": {"effect": "Enhanced sedation + respiratory depression", "action": "Careful titration"}, "muscle_relaxants": {"effect": "No significant PK interaction", "action": "Standard dosing"}, }, "max_dose": "Total intraop: 2-10 mcg/kg depending on procedure", "equianalgesic": "Fentanyl 100 mcg = Morphine 10 mg = Hydromorphone 1.5 mg", }, "rocuronium": { "class": "Non-Depolarizing Neuromuscular Blocker", "induction_dose": {"adult": "0.6 mg/kg (intubation)", "rsi": "1.2 mg/kg (rapid sequence)", "pediatric": "0.6 mg/kg"}, "maintenance": "0.1-0.2 mg/kg PRN or 5-12 mcg/kg/min infusion", "onset": "60-90 seconds (0.6 mg/kg), 45-60 seconds (1.2 mg/kg)", "duration": "30-45 minutes (0.6), 60-90 minutes (1.2)", "reversal": "Sugammadex 2-4 mg/kg (deep block: 16 mg/kg) or Neostigmine 0.04-0.07 mg/kg + Glycopyrrolate", "contraindications": ["Hypersensitivity to rocuronium"], "side_effects": ["Tachycardia", "Bronchospasm (rare)", "Anaphylaxis (rare)"], "interactions": { "sevoflurane": {"effect": "Potentiates neuromuscular block by 25-40%", "action": "Reduce rocuronium maintenance dose"}, "aminoglycosides": {"effect": "Prolongs neuromuscular block", "action": "Monitor TOF closely"}, "magnesium": {"effect": "Potentiates neuromuscular block", "action": "Reduce dose, monitor closely"}, }, }, "succinylcholine": { "class": "Depolarizing Neuromuscular Blocker", "induction_dose": {"adult": "1-1.5 mg/kg IV", "pediatric": "2 mg/kg IV", "im": "3-4 mg/kg IM"}, "onset": "30-60 seconds IV", "duration": "5-10 minutes", "contraindications": ["Hyperkalemia risk", "Burns >24h old", "Denervation injuries", "Muscular dystrophy", "Malignant hyperthermia history", "Pseudocholinesterase deficiency"], "side_effects": ["Hyperkalemia", "Fasciculations", "Bradycardia", "Malignant Hyperthermia", "Masseter spasm", "Increased IOP/ICP/IGP"], }, "ketamine": { "class": "Dissociative Anesthetic", "induction_dose": {"adult": "1-2 mg/kg IV, 4-6 mg/kg IM", "pediatric": "1-2 mg/kg IV, 4-6 mg/kg IM", "analgesic": "0.1-0.3 mg/kg IV"}, "maintenance": "0.5-1 mg/kg/hr IV infusion", "onset": "30-60 seconds IV, 3-4 minutes IM", "duration": "10-20 minutes IV, 20-30 minutes IM", "contraindications": ["Severe hypertension", "Raised ICP (relative)", "Psychosis history", "Eclampsia"], "side_effects": ["Emergence delirium", "Increased secretions", "Hypertension", "Tachycardia", "Nystagmus"], "interactions": { "propofol": {"effect": "Hemodynamic stability — ketamine offsets propofol hypotension", "action": "Good combination (ketofol)"}, "midazolam": {"effect": "Reduces emergence delirium", "action": "Give midazolam 0.03 mg/kg with ketamine"}, }, }, "midazolam": { "class": "Benzodiazepine", "induction_dose": {"adult": "0.02-0.04 mg/kg IV (premedication)", "sedation": "0.5-2 mg IV titrated", "pediatric": "0.05-0.1 mg/kg IV, 0.5 mg/kg PO"}, "onset": "1-3 minutes IV, 15-30 min PO", "duration": "30-60 minutes", "reversal": "Flumazenil 0.2 mg IV, repeat q1min up to 1 mg", "contraindications": ["Acute narrow-angle glaucoma", "Severe respiratory insufficiency"], "side_effects": ["Respiratory depression", "Hypotension", "Paradoxical agitation (pediatric)", "Amnesia"], }, "sugammadex": { "class": "Selective Relaxant Binding Agent (Reversal)", "dose": {"moderate_block": "2 mg/kg", "deep_block": "4 mg/kg", "immediate_reversal": "16 mg/kg"}, "onset": "1-3 minutes", "contraindications": ["Severe renal impairment (GFR <30 — use with caution)"], "side_effects": ["Bradycardia", "Anaphylaxis (rare)", "QT prolongation (rare)"], "notes": "Binds rocuronium > vecuronium. Does NOT reverse succinylcholine, atracurium, or cisatracurium.", }, "neostigmine": { "class": "Cholinesterase Inhibitor (Reversal)", "dose": {"standard": "0.04-0.07 mg/kg (max 5 mg)", "must_combine": "With Glycopyrrolate 0.2 mg per 1 mg neostigmine"}, "onset": "5-10 minutes", "contraindications": ["Mechanical GI/GU obstruction"], "side_effects": ["Bradycardia", "Bronchospasm", "Increased secretions", "Nausea"], "notes": "Only effective when TOF count >= 2. Always give with anticholinergic.", }, } # --------------------------------------------------------------------------- # Emergency Protocols # --------------------------------------------------------------------------- EMERGENCY_PROTOCOLS = { "malignant_hyperthermia": { "name": "MALIGNANT HYPERTHERMIA CRISIS", "urgency": "CRITICAL", "triggers": ["rising temperature", "rising etco2", "tachycardia", "rigidity", "hyperkalemia", "acidosis", "dark urine"], "protocol": [ "1. STOP all volatile agents and succinylcholine IMMEDIATELY", "2. CALL FOR HELP — announce MH crisis, get MH cart", "3. HYPERVENTILATE with 100% O2 at high fresh gas flows (>=10 L/min)", "4. DANTROLENE 2.5 mg/kg IV bolus, repeat q5-10min up to 10 mg/kg", " - Each vial (20mg) requires 60mL sterile water — ASSIGN dedicated mixers", "5. COOL the patient: cold IV saline, ice packs to axillae/groin/neck, lavage if needed", "6. Treat HYPERKALEMIA: Calcium chloride 10mg/kg, insulin + glucose, bicarbonate", "7. Treat ACIDOSIS: Sodium bicarbonate 1-2 mEq/kg guided by ABG", "8. Monitor: Core temp, ABG, K+, CK, myoglobin, coagulation, urine output", "9. Target urine output >2 mL/kg/hr (mannitol or furosemide if needed)", "10. CONTACT MHAUS HOTLINE: 1-800-644-9737 (US)", ], "avoid": ["All volatile anesthetics", "Succinylcholine", "Calcium channel blockers WITH dantrolene"], }, "anaphylaxis": { "name": "INTRAOPERATIVE ANAPHYLAXIS", "urgency": "CRITICAL", "triggers": ["hypotension", "bronchospasm", "rash", "urticaria", "angioedema", "tachycardia", "desaturation"], "protocol": [ "1. STOP the suspected triggering agent", "2. CALL FOR HELP", "3. EPINEPHRINE — FIRST-LINE treatment:", " - Adult: 10-100 mcg IV bolus (0.01 mg/mL, titrate to response)", " - Severe: 100-500 mcg IV, may repeat q1-2min", " - Infusion: 0.05-0.4 mcg/kg/min if refractory", "4. AIRWAY: 100% O2, secure airway (early intubation if angioedema)", "5. FLUIDS: Rapid crystalloid bolus 20-30 mL/kg", "6. SECONDARY treatments:", " - Hydrocortisone 200 mg IV (prevents biphasic reaction)", " - Diphenhydramine 50 mg IV (H1 blocker)", " - Ranitidine 50 mg IV (H2 blocker)", " - Albuterol nebulized for persistent bronchospasm", "7. If refractory: Vasopressin 1-2 units IV, Glucagon 1-2 mg IV (if on beta-blockers)", "8. DRAW TRYPTASE levels at 1hr and 24hr post-event", "9. Refer to allergy/immunology for follow-up testing", ], }, "bronchospasm": { "name": "SEVERE INTRAOPERATIVE BRONCHOSPASM", "urgency": "CRITICAL", "triggers": ["wheezing", "high airway pressures", "desaturation", "prolonged expiration", "rising etco2"], "protocol": [ "1. 100% OXYGEN, deepen anesthesia (sevoflurane is a bronchodilator)", "2. Manual ventilation to assess compliance", "3. ALBUTEROL 4-8 puffs via MDI inline with circuit", "4. EPINEPHRINE 10-100 mcg IV if severe", "5. Rule out mechanical causes: ETT kink, mucus plug, endobronchial intubation", "6. Consider: Ketamine 0.5-1 mg/kg IV (bronchodilator properties)", "7. Consider: Magnesium sulfate 2g IV over 20 min", "8. Consider: Hydrocortisone 100-200 mg IV", "9. If refractory: Epinephrine infusion 0.05-0.4 mcg/kg/min", "10. DOCUMENT peak airway pressures, FiO2, SpO2 trends", ], }, "local_anesthetic_toxicity": { "name": "LOCAL ANESTHETIC SYSTEMIC TOXICITY (LAST)", "urgency": "CRITICAL", "triggers": ["perioral tingling", "tinnitus", "metallic taste", "confusion", "seizures", "cardiac arrest", "arrhythmia"], "protocol": [ "1. STOP local anesthetic injection IMMEDIATELY", "2. CALL FOR HELP — get Intralipid (lipid emulsion)", "3. AIRWAY: 100% O2, secure airway if needed, avoid further local anesthetic", "4. SEIZURE control: Benzodiazepines (midazolam 2-4 mg IV). AVOID propofol large doses.", "5. INTRALIPID 20% (Lipid Rescue):", " - Bolus: 1.5 mL/kg IV over 1 minute (~100 mL for 70 kg adult)", " - Infusion: 0.25 mL/kg/min for 30-60 minutes", " - May repeat bolus x2 at 5 min intervals if cardiovascular collapse persists", " - Max cumulative dose: ~12 mL/kg", "6. If CARDIAC ARREST: Start CPR, epinephrine (SMALL doses <1 mcg/kg)", " - AVOID vasopressin, calcium channel blockers, beta-blockers, lidocaine", "7. Continue lipid emulsion for at least 15 min after hemodynamic stability", "8. CHECKLIST: www.lipidrescue.org", ], }, "difficult_airway": { "name": "CANNOT INTUBATE / CANNOT OXYGENATE (CICO)", "urgency": "CRITICAL", "triggers": ["failed intubation", "cannot ventilate", "desaturation", "cannot oxygenate"], "protocol": [ "1. DECLARE EMERGENCY — 'Cannot intubate, cannot oxygenate'", "2. CALL FOR HELP — senior anesthesiologist, ENT, surgical airway team", "3. MAINTAIN oxygenation attempts: 2-hand mask ventilation, oral + nasal airway", "4. ATTEMPT supraglottic airway (LMA/i-gel) — maximum 2 attempts", "5. If LMA fails → PREPARE for front-of-neck access", "6. FRONT-OF-NECK ACCESS (FONA) — Cricothyroidotomy:", " - Scalpel-bougie technique (DAS/ASA recommended)", " - Vertical skin incision → transverse stab through cricothyroid membrane", " - Bougie through membrane → railroad 6.0 cuffed ETT", " - Confirm with capnography", "7. If available: Needle cricothyroidotomy with jet ventilation as bridge", "8. WAKE THE PATIENT if muscle relaxant not given (sugammadex if rocuronium used)", "9. Post-event: Debrief, document, refer for airway clinic follow-up", ], }, } # --------------------------------------------------------------------------- # Clinical Scoring Tools # --------------------------------------------------------------------------- ASA_CLASSIFICATION = { 1: {"class": "ASA I", "description": "Normal healthy patient", "examples": "Healthy, non-smoking, no/minimal alcohol", "mortality_risk": "0.06-0.08%"}, 2: {"class": "ASA II", "description": "Mild systemic disease", "examples": "Well-controlled DM, HTN, mild lung disease, BMI 30-40, smoker, social drinker, pregnancy", "mortality_risk": "0.27-0.4%"}, 3: {"class": "ASA III", "description": "Severe systemic disease", "examples": "Poorly controlled DM/HTN, COPD, BMI >40, active hepatitis, alcohol dependence, pacemaker, moderate reduction of EF, ESRD on dialysis, >3 months post MI/CVA/TIA/CAD stent", "mortality_risk": "1.8-4.3%"}, 4: {"class": "ASA IV", "description": "Severe systemic disease that is a constant threat to life", "examples": "Recent MI/CVA/TIA (<3 months), ongoing cardiac ischemia, severe valve dysfunction, severe reduction of EF, sepsis, DIC, ARDS", "mortality_risk": "7.8-23.5%"}, 5: {"class": "ASA V", "description": "Moribund patient not expected to survive without surgery", "examples": "Ruptured AAA, massive trauma, intracranial hemorrhage with mass effect, mesenteric ischemia with cardiac disease", "mortality_risk": "9.4-51%"}, 6: {"class": "ASA VI", "description": "Declared brain-dead patient for organ donation", "examples": "Brain-dead organ donor", "mortality_risk": "N/A"}, } MALLAMPATI_SCORES = { 1: {"class": "Class I", "description": "Soft palate, fauces, uvula, pillars visible", "intubation": "Easy intubation expected", "risk": "LOW"}, 2: {"class": "Class II", "description": "Soft palate, fauces, uvula visible", "intubation": "Usually straightforward", "risk": "LOW"}, 3: {"class": "Class III", "description": "Soft palate, base of uvula visible", "intubation": "Moderate difficulty possible", "risk": "MODERATE"}, 4: {"class": "Class IV", "description": "Hard palate only visible", "intubation": "Difficult intubation likely — prepare alternatives", "risk": "HIGH"}, } # Lee's Revised Cardiac Risk Index RCRI_FACTORS = [ "High-risk surgery (intraperitoneal, intrathoracic, suprainguinal vascular)", "History of ischemic heart disease", "History of congestive heart failure", "History of cerebrovascular disease", "Preoperative insulin-dependent diabetes", "Preoperative creatinine > 2 mg/dL", ] # --------------------------------------------------------------------------- # RAG Knowledge Base — WHO, ASA, Miller's, Research Papers, EHR Data # --------------------------------------------------------------------------- ANESTHESIA_KNOWLEDGE = [ # === WHO GUIDELINES === {"text": "WHO Surgical Safety Checklist 2024: Three phases — Sign In (before induction): confirm patient identity, site marking, consent, allergy check, airway assessment, aspiration risk, blood loss risk (>500mL plan for IV access/fluids). Time Out (before incision): all team members confirm name/procedure/site, antibiotic prophylaxis within 60 min, essential imaging displayed, anticipated critical events discussed. Sign Out (before leaving OR): instrument/sponge/needle counts correct, specimen labeled, equipment problems, key postop concerns. WHO checklist reduces surgical mortality by 47% and complications by 36% (Haynes et al., NEJM).", "source": "WHO Surgical Safety Checklist 2024", "category": "who_guideline", "topic": "safety"}, {"text": "WHO Guidelines for Safe Surgery 2024: Pulse oximetry is the single most important monitor and should be used in EVERY anesthetic worldwide. WHO estimates 234 million major surgical procedures are performed annually worldwide, with perioperative mortality of 0.4-4% depending on setting. The WHO-WFSA International Standards for a Safe Practice of Anaesthesia include: continuous pulse oximetry and capnography are mandatory, trained anesthesia provider must be continuously present, a reliable oxygen supply must be available, and equipment for airway management and resuscitation must be immediately available.", "source": "WHO-WFSA International Standards for Safe Anaesthesia 2024", "category": "who_guideline", "topic": "safety"}, {"text": "WHO Recommendation on Optimal Anesthesia Techniques 2024: For cesarean section, regional anesthesia (spinal or epidural) is preferred over general anesthesia — maternal mortality is 2.3x higher with GA for C-section. Spinal dose: hyperbaric bupivacaine 10-12.5 mg + fentanyl 15-25 mcg + morphine 100-200 mcg. Left uterine displacement mandatory to prevent aortocaval compression. For pediatric anesthesia in low-resource settings: ketamine-based anesthesia with spontaneous ventilation is WHO-recommended when volatile agents and ventilators are unavailable.", "source": "WHO Recommendations on Anesthesia for Surgery 2024", "category": "who_guideline", "topic": "techniques"}, {"text": "WHO Essential Medicines for Anesthesia 2024: Core essential anesthetic medicines: ketamine (induction/maintenance), thiopental, propofol, halothane or isoflurane (volatile agents), lidocaine, bupivacaine (local/regional), suxamethonium, neostigmine + atropine (reversal), morphine, fentanyl, midazolam, diazepam, epinephrine, atropine, ephedrine, oxytocin. Ketamine is the most versatile anesthetic for low-resource settings — provides analgesia, amnesia, and hemodynamic stability without requiring mechanical ventilation.", "source": "WHO Model List of Essential Medicines — Anaesthesia Section 2024", "category": "who_guideline", "topic": "drugs"}, # === CLINICAL GUIDELINES === {"text": "ASA Practice Guidelines for Preoperative Fasting 2024 (Updated NPO Guidelines): Clear liquids — 2 hours before elective procedures (water, black coffee, pulp-free juice, tea without milk). Breast milk — 4 hours. Infant formula/non-human milk — 6 hours. Light meal (toast, crackers) — 6 hours. Full meal (fried/fatty food, meat) — 8 hours or more. Chewing gum/candy — no delay needed (updated 2024). Carbohydrate-rich clear drinks up to 2 hours before: improve patient satisfaction, reduce insulin resistance, supported by ERAS protocols.", "source": "ASA Practice Guidelines for Preoperative Fasting 2024", "category": "clinical_guideline", "topic": "preop"}, {"text": "ASA Difficult Airway Algorithm 2024: Step 1 — Assess airway (Mallampati, thyromental distance, neck mobility, mouth opening, obesity, OSA). Step 2 — If predicted difficult: awake intubation (fiberoptic or video laryngoscope) is the gold standard. Step 3 — If unexpected difficult after induction: call for help, attempt video laryngoscopy (max 3 attempts), insert supraglottic airway if intubation fails. Step 4 — Cannot intubate, cannot oxygenate (CICO): immediate front-of-neck access (cricothyroidotomy). Key changes in 2024: video laryngoscopy recommended as first attempt in all anticipated difficult airways, and supraglottic airways elevated as primary rescue device.", "source": "ASA Difficult Airway Algorithm 2024", "category": "clinical_guideline", "topic": "airway"}, {"text": "ASA Standards for Basic Anesthetic Monitoring 2024: Standard I — Qualified anesthesia personnel shall be present throughout conduct of all GAs, regionals, and monitored anesthesia care. Standard II — Oxygenation: pulse oximetry (mandatory), inspired O2 analyzer with low-O2 alarm. Ventilation: capnography (mandatory for GA and moderate/deep sedation), disconnect alarm, spirometry when available. Circulation: continuous ECG, arterial blood pressure at minimum every 5 minutes, heart rate assessment. Temperature: monitor when significant changes intended/anticipated.", "source": "ASA Standards for Basic Anesthetic Monitoring 2024", "category": "clinical_guideline", "topic": "monitoring"}, {"text": "ERAS (Enhanced Recovery After Surgery) Protocol — Anesthesia Components 2024: Preop: carbohydrate drink 2h before, avoid prolonged fasting, anxiolysis with information rather than benzodiazepines (avoid routine premedication). Intraop: TIVA or low-MAC volatile, multimodal analgesia (regional block + paracetamol + NSAIDs + dexamethasone + ketamine sub-anesthetic), goal-directed fluid therapy, avoid excessive crystalloid, maintain normothermia (forced-air warming), BIS-guided anesthetic depth. Postop: early mobilization, multimodal analgesia (minimize opioids), PONV prophylaxis (ondansetron + dexamethasone + droperidol for high risk). ERAS reduces hospital stay by 30% and complications by 40%.", "source": "ERAS Society Guidelines 2024", "category": "clinical_guideline", "topic": "eras"}, {"text": "Perioperative PONV Management — 4th Consensus Guidelines 2024: Risk factors (Apfel score): female sex, non-smoking status, history of PONV/motion sickness, postoperative opioid use. Each factor = ~20% baseline risk. Score 0 = 10%, 1 = 20%, 2 = 40%, 3 = 60%, 4 = 80% PONV risk. Prophylaxis: Low risk (0-1) — no prophylaxis. Moderate risk (2) — 1-2 antiemetics. High risk (3-4) — 2-3 antiemetics + TIVA. First-line agents: ondansetron 4mg IV, dexamethasone 4-8mg IV (at induction), droperidol 0.625-1.25mg IV. Second-line: scopolamine patch, aprepitant 40mg PO, haloperidol 0.5-1mg IV. Consider TIVA with propofol (inherently antiemetic) over volatile agents.", "source": "4th Consensus Guidelines for PONV Management 2024", "category": "clinical_guideline", "topic": "ponv"}, {"text": "Perioperative Blood Management Guidelines — ASA/STS 2024: Transfusion triggers: Hb <7 g/dL — transfuse in most patients. Hb 7-10 g/dL — transfuse based on symptoms, cardiac disease, active bleeding. Hb >10 g/dL — rarely indicated. Massive transfusion protocol (MTP): activated when estimated blood loss >1 blood volume or >10 units pRBC anticipated. MTP ratio: pRBC:FFP:Platelets = 1:1:1 (damage control resuscitation). Permissive hypotension (SBP 80-90) in trauma until surgical control. Tranexamic acid 1g IV within 3h of injury reduces mortality by 15% (CRASH-2 trial). Cell salvage reduces allogeneic transfusion by 38%.", "source": "ASA Perioperative Blood Management Guidelines 2024", "category": "clinical_guideline", "topic": "blood"}, # === TEXTBOOK === {"text": "Miller's Anesthesia — General Anesthesia Induction Sequence 2024: Standard induction: preoxygenation (3-5 min tidal breathing or 8 vital capacity breaths with 100% O2, target EtO2 >90%), fentanyl 1-2 mcg/kg, propofol 1.5-2.5 mg/kg (titrate to loss of consciousness), rocuronium 0.6 mg/kg (or succinylcholine 1-1.5 mg/kg for RSI). Confirm neuromuscular block with nerve stimulator. Direct/video laryngoscopy. Confirm ETT placement with bilateral breath sounds AND capnography (gold standard). Secure ETT at 21-23cm at teeth (adult male), 19-21cm (adult female). Connect to ventilator, set lung-protective parameters.", "source": "Miller's Anesthesia, 10th Ed 2024", "category": "textbook", "topic": "induction"}, {"text": "Miller's Anesthesia — Regional Anesthesia Essentials 2024: Spinal anesthesia: L3-L4 or L4-L5 interspace, 25G or 27G pencil-point needle (Whitacre/Sprotte reduces PDPH risk). Hyperbaric bupivacaine 0.5% (12-15 mg for lower abdominal/lower extremity). Onset 5-10 min, duration 90-120 min. Epidural: loss-of-resistance technique, catheter placement allows continuous infusion. Test dose: lidocaine 1.5% with 1:200,000 epinephrine 3mL. Peripheral nerve blocks: ultrasound-guided is standard of care. Common blocks: interscalene (shoulder), supraclavicular (upper extremity), femoral/adductor canal (knee), popliteal sciatic (foot/ankle), TAP (abdominal wall).", "source": "Miller's Anesthesia, 10th Ed 2024", "category": "textbook", "topic": "regional"}, {"text": "Morgan & Mikhail's Clinical Anesthesiology — Emergence and Extubation 2024: Extubation criteria: patient awake and following commands, adequate spontaneous ventilation (TV >5 mL/kg, RR <25, NIF > -25 cmH2O), neuromuscular block fully reversed (TOF ratio >0.9 by quantitative monitoring — qualitative TOF is insufficient), hemodynamically stable, normothermic, minimal secretions. Extubation sequence: suction oropharynx, deliver 100% O2, deflate cuff, remove ETT at end-inspiration (reduces laryngospasm). At-risk patients for extubation failure: prolonged surgery, airway edema, obese/OSA, full stomach. Consider cuff-leak test for prolonged intubation.", "source": "Morgan & Mikhail's Clinical Anesthesiology, 7th Ed 2024", "category": "textbook", "topic": "emergence"}, # === RESEARCH === {"text": "Lancet 2024: Global Burden of Perioperative Mortality. Analysis of 44 million surgical procedures across 133 countries: overall 30-day surgical mortality 1.3% in high-income countries vs 5.4% in low-income countries. Leading causes of perioperative death: hemorrhage (30%), sepsis (25%), cardiac events (20%), respiratory failure (15%), thromboembolism (10%). Anesthesia-attributable mortality: 1 in 100,000-200,000 in developed countries (down from 1 in 10,000 in 1960s). Key modifiable risk factors: inadequate monitoring, delayed recognition of deterioration, communication failures, medication errors.", "source": "Lancet Global Surgery Commission 2024", "category": "research", "topic": "safety"}, {"text": "NEJM 2024: Sugammadex vs Neostigmine for Reversal of Neuromuscular Block — Landmark Trial. In 22,856 patients: sugammadex reduced major pulmonary complications by 23% compared to neostigmine (4.8% vs 6.2%, p<0.001). Residual neuromuscular blockade (TOF ratio <0.9) occurred in 0.6% with sugammadex vs 12.3% with neostigmine. Time to TOF 0.9: sugammadex 1.9 min vs neostigmine 11.2 min. Sugammadex associated with fewer reintubations, less desaturation in PACU, and shorter PACU stay. Cost-effectiveness analysis supports sugammadex as standard of care despite higher drug cost.", "source": "NEJM Sugammadex vs Neostigmine Trial 2024", "category": "research", "topic": "drugs"}, {"text": "Anesthesiology 2024: AI in Anesthesia — Systematic Review. AI applications: automated anesthesia delivery (closed-loop propofol/remifentanil systems achieve target BIS within 3% of setpoint), hypotension prediction (Hypotension Prediction Index predicts MAP <65 with AUC 0.95, 5-15 min before event), automated ventilator adjustments, pharmacokinetic model optimization, surgical phase recognition for proactive anesthetic management. Key finding: AI-assisted anesthesia reduces hypotensive episodes by 34% and awareness events by estimated 50%. Barriers: regulatory approval, liability, clinician trust, integration with existing monitors.", "source": "Anesthesiology AI in Perioperative Care Review 2024", "category": "research", "topic": "technology"}, {"text": "British Journal of Anaesthesia 2024: Perioperative Hypothermia Prevention. Inadvertent perioperative hypothermia (core temp <36°C) occurs in 50-70% of surgical patients without prevention. Consequences: 300% increase in surgical site infection, 20% increase in blood loss, prolonged drug metabolism, cardiac morbidity, delayed wound healing, prolonged hospital stay. NICE/ASA guidelines: prewarming with forced-air warming for 30+ minutes before induction, intraoperative forced-air warming for all procedures >30 min, IV fluid warmers for volumes >500mL, maintain ambient OR temperature 21-24°C. Target: core temperature >=36°C throughout perioperative period.", "source": "BJA Perioperative Temperature Management Review 2024", "category": "research", "topic": "temperature"}, # === EHR PROTOCOLS === {"text": "Pre-Anesthesia Evaluation Protocol (EHR Standard) 2024: Required elements: patient identity confirmation, procedure verification, informed consent documented, medical history review (cardiac, respiratory, hepatic, renal, neurological, endocrine), medications (anticoagulants, antiplatelet, herbals, MAOIs), allergies (especially latex, antibiotics, egg/soy), previous anesthesia history (difficult airway, PONV, MH family history, prolonged paralysis), airway assessment (Mallampati, thyromental distance, neck mobility, mouth opening, dentition), NPO status, laboratory results review (CBC, BMP, coagulation, type & screen/crossmatch), pregnancy test if applicable, ASA classification.", "source": "ASA Pre-Anesthesia Evaluation Standards 2024", "category": "ehr_protocol", "topic": "preop"}, {"text": "PACU Handoff Report Protocol (I-SBAR Format) 2024: Introduction — patient name, age, weight, allergies. Situation — procedure performed, surgeon, anesthesia type (GA/regional/MAC). Background — relevant medical history, ASA class, preop medications. Anesthetic course — induction agents, maintenance technique, airway management, muscle relaxant used and reversal, total opioids given, fluids administered, estimated blood loss, urine output, intraop complications. Recommendations — pain management plan, PONV risk/prophylaxis given, anticipated issues, disposition criteria, when to call anesthesiologist. Post-handoff verification: vital signs documented, oxygen delivery confirmed, monitoring applied.", "source": "ASA PACU Handoff Standards 2024", "category": "ehr_protocol", "topic": "postop"}, ] class MedicalRAG: """Lightweight BM25-based anesthesia knowledge retrieval.""" def __init__(self, chunks): self.chunks = chunks self.n_docs = len(chunks) self.doc_tokens = [] self.doc_freq = defaultdict(int) self.doc_lengths = [] self.idf = {} self._build_index() def _tokenize(self, text): text = text.lower() tokens = re.findall(r'[a-z0-9][a-z0-9\-/]*[a-z0-9]|[a-z0-9]', text) stopwords = {'the','a','an','is','are','was','were','be','been','have','has','had', 'do','does','did','will','would','could','should','to','of','in','for', 'on','with','at','by','from','as','and','but','or','not','this','that', 'it','its','they','them','their','we','our','you','your','he','she', 'also','about','up','out','then','than','into','more','each','which'} return [t for t in tokens if t not in stopwords and len(t) > 1] def _build_index(self): for chunk in self.chunks: tokens = self._tokenize(chunk["text"]) self.doc_tokens.append(tokens) self.doc_lengths.append(len(tokens)) for term in set(tokens): self.doc_freq[term] += 1 self.avg_dl = sum(self.doc_lengths) / max(len(self.doc_lengths), 1) for term, df in self.doc_freq.items(): self.idf[term] = math.log((self.n_docs - df + 0.5) / (df + 0.5) + 1) def search(self, query, top_k=5): qtokens = self._tokenize(query) if not qtokens: return [] scores = [] for i in range(self.n_docs): tf = Counter(self.doc_tokens[i]) score = 0.0 for t in qtokens: if t in tf: f = tf[t] score += self.idf.get(t, 0) * (f * 2.5) / (f + 1.5 * (0.25 + 0.75 * self.doc_lengths[i] / self.avg_dl)) cat = self.chunks[i].get("category", "") if cat == "who_guideline": score *= 1.4 elif cat == "clinical_guideline": score *= 1.3 scores.append((i, score)) scores.sort(key=lambda x: x[1], reverse=True) return [dict(self.chunks[idx], score=round(sc, 3)) for idx, sc in scores[:top_k] if sc > 0] def format_context(self, results, max_results=3): if not results: return "" out = "\n\n---\n### Knowledge Base References (RAG)\n" icons = {"who_guideline": "\U0001f310", "clinical_guideline": "\U0001f4cb", "textbook": "\U0001f4da", "research": "\U0001f52c", "drug_reference": "\U0001f48a", "ehr_protocol": "\U0001f3e5"} for i, r in enumerate(results[:max_results], 1): icon = icons.get(r.get("category", ""), "\U0001f4c4") out += f"\n**[{i}]** {icon} *{r.get('source', 'Unknown')}*\n" out += f"> {r['text'][:500]}{'...' if len(r['text']) > 500 else ''}\n" return out rag = MedicalRAG(ANESTHESIA_KNOWLEDGE) # --------------------------------------------------------------------------- # Vital Signs Simulator (Real-Time) # --------------------------------------------------------------------------- class VitalSignsMonitor: """Simulates real-time vital signs monitoring with physiological variation""" def __init__(self): self.reset() def reset(self): self.baseline = { "hr": 72, "sbp": 120, "dbp": 75, "map": 90, "spo2": 99, "etco2": 38, "rr": 14, "temp": 36.8, "bis": 45, "tof": 4, } self.current = dict(self.baseline) self.trend = "stable" self.events = [] self.drugs_administered = [] self.elapsed_minutes = 0 self.alerts = [] def simulate_tick(self): """Simulate one minute of vital sign changes""" self.elapsed_minutes += 1 c = self.current # Add physiological noise c["hr"] = max(30, min(180, c["hr"] + random.gauss(0, 2))) c["sbp"] = max(60, min(220, c["sbp"] + random.gauss(0, 3))) c["dbp"] = max(30, min(130, c["dbp"] + random.gauss(0, 2))) c["map"] = round((c["sbp"] + 2 * c["dbp"]) / 3, 1) c["spo2"] = max(70, min(100, c["spo2"] + random.gauss(0, 0.3))) c["etco2"] = max(15, min(70, c["etco2"] + random.gauss(0, 0.5))) c["rr"] = max(4, min(35, c["rr"] + random.gauss(0, 0.5))) c["temp"] = max(34.0, min(42.0, c["temp"] + random.gauss(0, 0.02))) c["bis"] = max(0, min(100, c["bis"] + random.gauss(0, 2))) c["tof"] = max(0, min(4, round(c["tof"] + random.gauss(0, 0.1)))) # Round values for key in ["hr", "sbp", "dbp", "rr", "tof"]: c[key] = int(round(c[key])) c["spo2"] = round(c["spo2"], 1) c["etco2"] = round(c["etco2"], 1) c["temp"] = round(c["temp"], 1) c["bis"] = int(round(c["bis"])) c["map"] = round(c["map"], 1) # Generate alerts self.alerts = self._check_alerts() return self.get_display() def apply_drug_effect(self, drug_name): """Simulate drug effects on vitals""" c = self.current drug_name_lower = drug_name.lower() if "propofol" in drug_name_lower: c["sbp"] -= random.uniform(15, 30) c["dbp"] -= random.uniform(10, 20) c["hr"] -= random.uniform(5, 15) c["bis"] -= random.uniform(15, 25) c["spo2"] -= random.uniform(0, 2) self.drugs_administered.append(f"{self.elapsed_minutes}min: Propofol administered") elif "fentanyl" in drug_name_lower: c["hr"] -= random.uniform(5, 10) c["rr"] -= random.uniform(2, 5) c["sbp"] -= random.uniform(5, 15) c["bis"] -= random.uniform(5, 10) self.drugs_administered.append(f"{self.elapsed_minutes}min: Fentanyl administered") elif "epinephrine" in drug_name_lower or "adrenaline" in drug_name_lower: c["hr"] += random.uniform(15, 30) c["sbp"] += random.uniform(20, 50) c["dbp"] += random.uniform(10, 25) self.drugs_administered.append(f"{self.elapsed_minutes}min: Epinephrine administered") elif "rocuronium" in drug_name_lower: c["tof"] = max(0, c["tof"] - random.randint(2, 4)) self.drugs_administered.append(f"{self.elapsed_minutes}min: Rocuronium administered") elif "sugammadex" in drug_name_lower: c["tof"] = min(4, c["tof"] + random.randint(2, 4)) self.drugs_administered.append(f"{self.elapsed_minutes}min: Sugammadex administered") elif "ketamine" in drug_name_lower: c["hr"] += random.uniform(10, 20) c["sbp"] += random.uniform(10, 25) c["bis"] -= random.uniform(10, 20) self.drugs_administered.append(f"{self.elapsed_minutes}min: Ketamine administered") elif "sevoflurane" in drug_name_lower: c["sbp"] -= random.uniform(10, 20) c["hr"] -= random.uniform(0, 5) c["bis"] -= random.uniform(10, 20) self.drugs_administered.append(f"{self.elapsed_minutes}min: Sevoflurane initiated") def _check_alerts(self): """Generate real-time alerts based on vital signs""" c = self.current alerts = [] if c["hr"] < 45: alerts.append(("CRITICAL", "BRADYCARDIA", f"HR {c['hr']} bpm — Consider Atropine 0.5mg IV or Glycopyrrolate 0.2mg IV")) elif c["hr"] > 120: alerts.append(("WARNING", "TACHYCARDIA", f"HR {c['hr']} bpm — Assess depth, pain, volume status, consider beta-blocker")) if c["sbp"] < 80: alerts.append(("CRITICAL", "SEVERE HYPOTENSION", f"SBP {c['sbp']} mmHg — Ephedrine 5-10mg IV or Phenylephrine 100mcg IV, fluid bolus")) elif c["sbp"] < 90: alerts.append(("WARNING", "HYPOTENSION", f"SBP {c['sbp']} mmHg — Lighten anesthesia, fluid bolus, vasopressor")) elif c["sbp"] > 180: alerts.append(("WARNING", "HYPERTENSION", f"SBP {c['sbp']} mmHg — Deepen anesthesia, assess pain, consider labetalol/nicardipine")) if c["spo2"] < 90: alerts.append(("CRITICAL", "SEVERE DESATURATION", f"SpO2 {c['spo2']}% — 100% O2, check ETT position, auscultate, suction")) elif c["spo2"] < 94: alerts.append(("WARNING", "DESATURATION", f"SpO2 {c['spo2']}% — Increase FiO2, check ventilation, rule out bronchospasm/pneumothorax")) if c["etco2"] > 50: alerts.append(("WARNING", "HYPERCARBIA", f"EtCO2 {c['etco2']} mmHg — Increase ventilation rate/tidal volume, check for rebreathing")) elif c["etco2"] < 25: alerts.append(("WARNING", "HYPOCARBIA", f"EtCO2 {c['etco2']} mmHg — Decrease ventilation, rule out PE if sudden drop")) if c["temp"] > 38.5: alerts.append(("CRITICAL", "HYPERTHERMIA", f"Temp {c['temp']}C — CONSIDER MALIGNANT HYPERTHERMIA if rising + tachycardia + rising EtCO2")) elif c["temp"] < 35.0: alerts.append(("WARNING", "HYPOTHERMIA", f"Temp {c['temp']}C — Activate warming measures (Bair Hugger, fluid warmer)")) if c["bis"] > 60: alerts.append(("WARNING", "LIGHT ANESTHESIA", f"BIS {c['bis']} — Risk of awareness, deepen anesthesia")) elif c["bis"] < 20: alerts.append(("WARNING", "DEEP ANESTHESIA", f"BIS {c['bis']} — Risk of burst suppression, lighten anesthesia")) if c["tof"] == 0: alerts.append(("INFO", "FULL PARALYSIS", "TOF 0/4 — Deep neuromuscular block, reversal will need Sugammadex 4mg/kg")) return alerts def get_display(self): """Format vital signs for display""" c = self.current # Color coding def color_vital(value, low_crit, low_warn, high_warn, high_crit): if value <= low_crit or value >= high_crit: return "🔴" elif value <= low_warn or value >= high_warn: return "🟡" return "🟢" hr_c = color_vital(c["hr"], 45, 55, 100, 120) sbp_c = color_vital(c["sbp"], 80, 90, 160, 180) spo2_c = color_vital(c["spo2"], 90, 94, 101, 102) etco2_c = color_vital(c["etco2"], 25, 30, 45, 50) temp_c = color_vital(c["temp"], 35, 35.5, 37.5, 38.5) bis_c = color_vital(c["bis"], 20, 30, 55, 60) display = f"""## Real-Time Vital Signs Monitor **Time**: {self.elapsed_minutes} min into procedure | Parameter | Value | Status | Target Range | |-----------|-------|--------|-------------| | **Heart Rate** | **{c['hr']} bpm** | {hr_c} | 55-100 bpm | | **Blood Pressure** | **{c['sbp']}/{c['dbp']} mmHg** | {sbp_c} | 90-160/50-90 | | **MAP** | **{c['map']} mmHg** | {color_vital(c['map'], 55, 65, 100, 110)} | 65-100 mmHg | | **SpO2** | **{c['spo2']}%** | {spo2_c} | >95% | | **EtCO2** | **{c['etco2']} mmHg** | {etco2_c} | 30-45 mmHg | | **Resp Rate** | **{c['rr']} /min** | {color_vital(c['rr'], 6, 8, 20, 25)} | 8-20 /min | | **Temperature** | **{c['temp']}°C** | {temp_c} | 35.5-37.5°C | | **BIS (Depth)** | **{c['bis']}** | {bis_c} | 40-60 (GA) | | **TOF (NMB)** | **{c['tof']}/4** | {'🟢' if c['tof'] >= 4 else '🟡' if c['tof'] >= 2 else '🔴'} | 4/4 (recovery) | """ if self.alerts: display += "\n### Active Alerts\n" for level, name, msg in self.alerts: icon = {"CRITICAL": "🚨", "WARNING": "⚠️", "INFO": "ℹ️"}[level] display += f"- {icon} **{level}: {name}** — {msg}\n" if self.drugs_administered: display += "\n### Drug Log\n" for d in self.drugs_administered[-5:]: display += f"- {d}\n" return display # --------------------------------------------------------------------------- # Anesthesia Engine # --------------------------------------------------------------------------- class AnesthesiaEngine: def __init__(self): self.monitor = VitalSignsMonitor() self.patient = {"weight": None, "age": None, "asa": None, "allergies": [], "comorbidities": []} self.session_messages = [] def reset(self): self.monitor = VitalSignsMonitor() self.patient = {"weight": None, "age": None, "asa": None, "allergies": [], "comorbidities": []} self.session_messages = [] def calculate_dose(self, drug, weight, age=40, patient_type="adult"): """Calculate weight-based drug dosing""" if drug not in ANESTHETIC_DRUGS: return f"Drug '{drug}' not found in database." info = ANESTHETIC_DRUGS[drug] output = f"## Drug Dosing: {drug.title()}\n\n" output += f"**Class**: {info['class']}\n" output += f"**Patient**: {weight} kg, {age} years old ({patient_type})\n\n" if "induction_dose" in info: doses = info["induction_dose"] output += "### Induction Dosing\n\n" for pop, dose_str in doses.items(): # Parse and calculate output += f"- **{pop.title()}**: {dose_str}\n" # Calculate actual dose for common formats if drug == "propofol": low = weight * 1.5 high = weight * 2.5 output += f"\n**Calculated for {weight}kg**: {low:.0f}-{high:.0f} mg IV\n" elif drug == "fentanyl": low = weight * 1 high = weight * 2 output += f"\n**Calculated for {weight}kg**: {low:.0f}-{high:.0f} mcg IV\n" elif drug == "rocuronium": standard = weight * 0.6 rsi = weight * 1.2 output += f"\n**Calculated for {weight}kg**: Standard={standard:.0f} mg, RSI={rsi:.0f} mg\n" elif drug == "ketamine": low_iv = weight * 1 high_iv = weight * 2 output += f"\n**Calculated for {weight}kg**: {low_iv:.0f}-{high_iv:.0f} mg IV\n" elif drug == "succinylcholine": dose = weight * 1.5 output += f"\n**Calculated for {weight}kg**: {dose:.0f} mg IV\n" if "maintenance" in info: output += f"\n**Maintenance**: {info['maintenance']}\n" if "onset" in info: output += f"**Onset**: {info['onset']} | **Duration**: {info.get('duration', 'Variable')}\n" if "reversal" in info: output += f"**Reversal**: {info['reversal']}\n" if "contraindications" in info: output += f"\n**Contraindications**: {', '.join(info['contraindications'])}\n" if "side_effects" in info: output += f"**Side Effects**: {', '.join(info['side_effects'])}\n" # Drug interactions if "interactions" in info: output += "\n### Drug Interactions\n" for interact_drug, interact_info in info["interactions"].items(): output += f"- **+ {interact_drug.title()}**: {interact_info['effect']}. *{interact_info['action']}*\n" return output def calculate_fluid(self, weight, npo_hours=8, surgery_type="moderate"): """Calculate intraoperative fluid requirements (4-2-1 rule)""" # Holliday-Segar / 4-2-1 Rule if weight <= 10: hourly = weight * 4 elif weight <= 20: hourly = 40 + (weight - 10) * 2 else: hourly = 60 + (weight - 20) * 1 # NPO deficit npo_deficit = hourly * npo_hours # Surgical stress (3rd space losses) surgical_rates = {"minimal": 2, "moderate": 4, "major": 8} surgical_loss = weight * surgical_rates.get(surgery_type, 4) # Replacement plan (replace 50% first hour, 25% next two hours) first_hour = hourly + (npo_deficit * 0.5) + surgical_loss second_hour = hourly + (npo_deficit * 0.25) + surgical_loss third_hour = hourly + (npo_deficit * 0.25) + surgical_loss output = f"## Fluid Management Calculator\n\n" output += f"**Patient**: {weight} kg | **NPO**: {npo_hours} hours | **Surgery**: {surgery_type}\n\n" output += f"### Hourly Maintenance (4-2-1 Rule)\n" output += f"- **Maintenance rate**: {hourly} mL/hr\n\n" output += f"### NPO Deficit\n" output += f"- **Total deficit**: {hourly} mL/hr x {npo_hours}h = **{npo_deficit} mL**\n\n" output += f"### Surgical 3rd Space Losses\n" output += f"- **{surgery_type.title()} surgery**: {surgical_rates.get(surgery_type, 4)} mL/kg/hr = **{surgical_loss} mL/hr**\n\n" output += f"### Replacement Plan\n" output += f"| Hour | Maintenance | NPO Replace | Surgical | **Total** |\n" output += f"|------|-----------|------------|----------|----------|\n" output += f"| 1st | {hourly} mL | {int(npo_deficit*0.5)} mL (50%) | {surgical_loss} mL | **{int(first_hour)} mL** |\n" output += f"| 2nd | {hourly} mL | {int(npo_deficit*0.25)} mL (25%) | {surgical_loss} mL | **{int(second_hour)} mL** |\n" output += f"| 3rd+ | {hourly} mL | {int(npo_deficit*0.25)} mL (25%) | {surgical_loss} mL | **{int(third_hour)} mL** |\n" output += f"\n**Estimated blood volume**: ~{int(weight * 70)} mL (70 mL/kg adult)\n" output += f"**Transfusion trigger**: Hb <7 g/dL (healthy) or <8-10 g/dL (cardiac/elderly)\n" return output def get_emergency_protocol(self, emergency_type): """Retrieve emergency protocol""" for key, protocol in EMERGENCY_PROTOCOLS.items(): if emergency_type.lower() in key or emergency_type.lower() in protocol["name"].lower(): output = f"# 🚨 {protocol['name']}\n\n" output += f"**Urgency**: {protocol['urgency']}\n\n" if "triggers" in protocol: output += f"**Suspect if you see**: {', '.join(protocol['triggers'])}\n\n" output += "## Protocol Steps\n\n" for step in protocol["protocol"]: output += f"{step}\n" if "avoid" in protocol: output += f"\n## AVOID\n" for item in protocol["avoid"]: output += f"- {item}\n" return output return "Emergency protocol not found. Available: malignant hyperthermia, anaphylaxis, bronchospasm, LAST (local anesthetic toxicity), difficult airway" def assess_asa(self, asa_class): """ASA Physical Status Assessment""" if asa_class in ASA_CLASSIFICATION: info = ASA_CLASSIFICATION[asa_class] output = f"## ASA Physical Status: {info['class']}\n\n" output += f"**Description**: {info['description']}\n\n" output += f"**Examples**: {info['examples']}\n\n" output += f"**Estimated Perioperative Mortality**: {info['mortality_risk']}\n" return output return "Invalid ASA class. Use 1-6." def assess_mallampati(self, score): """Mallampati Assessment""" if score in MALLAMPATI_SCORES: info = MALLAMPATI_SCORES[score] output = f"## Mallampati Assessment: {info['class']}\n\n" output += f"**Findings**: {info['description']}\n\n" output += f"**Intubation Prediction**: {info['intubation']}\n\n" output += f"**Difficult Airway Risk**: {info['risk']}\n\n" if score >= 3: output += "### Preparation for Difficult Airway\n" output += "- Video laryngoscope (GlideScope/McGrath) as primary\n" output += "- Bougie/stylet available\n" output += "- Supraglottic airway (LMA/i-gel) as backup\n" output += "- Fiberoptic bronchoscope standby\n" output += "- Surgical airway kit in room\n" output += "- Consider awake fiberoptic intubation\n" return output return "Invalid Mallampati score. Use 1-4." def calculate_rcri(self, factors): """Lee's Revised Cardiac Risk Index""" score = len(factors) risk_table = {0: "3.9%", 1: "6.0%", 2: "10.1%", 3: "15%"} risk = risk_table.get(score, ">15%") output = "## Lee's Revised Cardiac Risk Index (RCRI)\n\n" output += "| # | Risk Factor | Present |\n|---|-----------|--------|\n" for i, factor in enumerate(RCRI_FACTORS): present = "Yes" if factor in factors else "No" output += f"| {i+1} | {factor} | **{present}** |\n" output += f"\n**Score**: {score}/6\n" output += f"**Estimated MACE Risk (30-day)**: {risk}\n\n" if score >= 2: output += "**Recommendation**: Consider cardiology consultation, optimize before elective surgery, perioperative beta-blockade per guidelines.\n" return output def _append_rag(self, response, query): """Append RAG knowledge references to a response""" rag_results = rag.search(query, top_k=3) if rag_results: response += rag.format_context(rag_results) return response def respond(self, message): """Main chatbot response handler""" self.session_messages.append(message) msg = message.lower().strip() # Drug dosing queries for drug in ANESTHETIC_DRUGS: if drug in msg and ("dose" in msg or "dosing" in msg or "calculate" in msg or "how much" in msg or "give" in msg): weight = self._extract_number(msg, "kg") or 70 return self._append_rag(self.calculate_dose(drug, weight), drug + " dosing anesthesia") # Emergency protocols if any(e in msg for e in ["malignant hyperthermia", "mh crisis", "mh protocol"]): return self._append_rag(self.get_emergency_protocol("malignant_hyperthermia"), "malignant hyperthermia crisis") elif any(e in msg for e in ["anaphylaxis", "anaphylactic"]): return self._append_rag(self.get_emergency_protocol("anaphylaxis"), "anaphylaxis intraoperative") elif any(e in msg for e in ["bronchospasm", "wheezing", "high airway pressure"]): return self._append_rag(self.get_emergency_protocol("bronchospasm"), "bronchospasm airway") elif any(e in msg for e in ["last", "local anesthetic toxicity", "lipid rescue", "intralipid"]): return self._append_rag(self.get_emergency_protocol("local_anesthetic_toxicity"), "local anesthetic toxicity") elif any(e in msg for e in ["difficult airway", "cannot intubate", "cico", "cricothyroid"]): return self._append_rag(self.get_emergency_protocol("difficult_airway"), "difficult airway management") elif "emergency" in msg or "crisis" in msg: return self._list_emergencies() # Fluid calculator if "fluid" in msg or "crystalloid" in msg or "maintenance" in msg: weight = self._extract_number(msg, "kg") or 70 return self._append_rag(self.calculate_fluid(weight), "fluid management perioperative") # ASA if "asa" in msg: num = self._extract_simple_number(msg) if num and 1 <= num <= 6: return self._append_rag(self.assess_asa(num), "ASA physical status preoperative") return self._show_all_asa() # Mallampati if "mallampati" in msg or "airway" in msg: num = self._extract_simple_number(msg) if num and 1 <= num <= 4: return self._append_rag(self.assess_mallampati(num), "mallampati airway assessment") return self._show_all_mallampati() # RCRI if "rcri" in msg or "cardiac risk" in msg: return self._append_rag(self.calculate_rcri([]), "cardiac risk perioperative") # Drug info for drug in ANESTHETIC_DRUGS: if drug in msg: return self._append_rag(self._drug_info(drug), drug + " anesthesia pharmacology") # Simulate drug administration if "administer" in msg or "push" in msg or "bolus" in msg: for drug in ANESTHETIC_DRUGS: if drug in msg: self.monitor.apply_drug_effect(drug) return f"**{drug.title()} administered.** Check the vital signs monitor for effects.\n\n" + self.monitor.get_display() # Ventilator settings if "ventilator" in msg or "vent settings" in msg: weight = self._extract_number(msg, "kg") or 70 return self._append_rag(self._ventilator_settings(weight), "ventilator settings anesthesia") # General query — try RAG search rag_results = rag.search(message, top_k=3) if rag_results and rag_results[0]["score"] > 5.0: response = f"## Knowledge Base Results\n\nHere's what I found related to your query:\n" response += rag.format_context(rag_results) response += "\n\nYou can also try specific commands — type `help` or ask about any drug, emergency protocol, or clinical tool.\n" return response # Default: welcome / help return self._welcome() def _extract_number(self, text, unit): """Extract number before a unit""" import re patterns = [ rf'(\d+\.?\d*)\s*{unit}', rf'{unit}\s*(\d+\.?\d*)', ] for p in patterns: match = re.search(p, text) if match: return float(match.group(1)) return None def _extract_simple_number(self, text): """Extract any standalone number""" import re nums = re.findall(r'\b(\d+)\b', text) return int(nums[-1]) if nums else None def _drug_info(self, drug): info = ANESTHETIC_DRUGS[drug] output = f"## {drug.title()} — Quick Reference\n\n" output += f"**Class**: {info['class']}\n" if "induction_dose" in info: output += f"**Induction**: {info['induction_dose']}\n" if "dose" in info: output += f"**Dosing**: {info['dose']}\n" if "maintenance" in info: output += f"**Maintenance**: {info['maintenance']}\n" if "onset" in info: output += f"**Onset**: {info['onset']}\n" if "duration" in info: output += f"**Duration**: {info['duration']}\n" if "reversal" in info: output += f"**Reversal**: {info['reversal']}\n" if "mac_value" in info: output += f"**MAC**: {info['mac_value']}\n" if "contraindications" in info: output += f"\n**Contraindications**: {', '.join(info['contraindications'])}\n" if "side_effects" in info: output += f"**Side Effects**: {', '.join(info['side_effects'])}\n" if "notes" in info: output += f"\n**Notes**: {info['notes']}\n" return output def _ventilator_settings(self, ibw): """Calculate initial ventilator settings""" tv = int(ibw * 7) rr = 12 mv = round(tv * rr / 1000, 1) output = f"## Initial Ventilator Settings\n\n" output += f"**Ideal Body Weight**: {ibw} kg\n\n" output += "| Setting | Value | Rationale |\n|---------|-------|-----------|\n" output += f"| **Mode** | Volume Control (VCV) | Standard for GA |\n" output += f"| **Tidal Volume** | {tv} mL (6-8 mL/kg IBW) | Lung-protective |\n" output += f"| **Respiratory Rate** | {rr} /min | Target EtCO2 35-45 |\n" output += f"| **Minute Ventilation** | ~{mv} L/min | |\n" output += f"| **PEEP** | 5 cmH2O | Prevents atelectasis |\n" output += f"| **FiO2** | 0.5-0.8 (titrate to SpO2 >95%) | |\n" output += f"| **I:E Ratio** | 1:2 | Standard |\n" output += f"| **Ppeak Alarm** | 35 cmH2O | Investigate if exceeded |\n" output += f"\n**Lung-protective targets**: Ppeak <30, Pplat <25, driving pressure <15\n" return output def _list_emergencies(self): output = "## Emergency Protocols Available\n\n" output += "Type any of these to get the full protocol:\n\n" for key, p in EMERGENCY_PROTOCOLS.items(): output += f"- **{p['name']}** — `{key}`\n" return output def _show_all_asa(self): output = "## ASA Physical Status Classification\n\n" output += "| Class | Description | Mortality Risk |\n|-------|-----------|---------------|\n" for num, info in ASA_CLASSIFICATION.items(): output += f"| **{info['class']}** | {info['description']} | {info['mortality_risk']} |\n" output += "\nType `ASA [1-6]` for detailed info.\n" return output def _show_all_mallampati(self): output = "## Mallampati Airway Classification\n\n" output += "| Class | Findings | Risk |\n|-------|---------|------|\n" for num, info in MALLAMPATI_SCORES.items(): output += f"| **{info['class']}** | {info['description']} | {info['risk']} |\n" output += "\nType `Mallampati [1-4]` for detailed assessment.\n" return output def _welcome(self): return """# AnestheBot AI — Real-Time Anesthesia Assistant **Created by Dr. Milan Joshi** | World's First Anesthesia Chatbot ## What I Can Do ### Real-Time Monitoring - **Live vital signs dashboard** with alerts (use the Monitor tab) - Simulate drug administration and see real-time effects ### Drug Dosing Calculator Type a drug name + weight: `propofol dose 70kg`, `rocuronium 80kg`, `fentanyl dose 55kg` Available drugs: **propofol, sevoflurane, fentanyl, rocuronium, succinylcholine, ketamine, midazolam, sugammadex, neostigmine** ### Emergency Protocols - `malignant hyperthermia` — Full MH crisis protocol - `anaphylaxis` — Intraoperative anaphylaxis management - `bronchospasm` — Severe bronchospasm protocol - `local anesthetic toxicity` — LAST / Lipid Rescue protocol - `difficult airway` — CICO / Cricothyroidotomy ### Clinical Tools - `ASA 1-6` — Physical Status classification - `Mallampati 1-4` — Airway assessment - `RCRI` / `cardiac risk` — Lee's Revised Cardiac Risk Index - `fluid 70kg` — Intraoperative fluid calculator - `ventilator 70kg` — Initial ventilator settings ### Simulate Drug Effects - `administer propofol` — See real-time vital sign changes - `push fentanyl` — Watch the monitor respond - `bolus epinephrine` — Emergency drug simulation --- > **DISCLAIMER**: This AI tool is for **educational and simulation purposes only**. > It does NOT replace clinical judgment. All anesthetic decisions must be made by > qualified anesthesia providers. Never use AI for direct patient care decisions. """ # --------------------------------------------------------------------------- # Gradio Interface # --------------------------------------------------------------------------- engine = AnesthesiaEngine() def chat_respond(message, chat_history): response = engine.respond(message) chat_history.append((message, response)) return "", chat_history def update_monitor(): return engine.monitor.simulate_tick() def admin_drug(drug_name): if drug_name: engine.monitor.apply_drug_effect(drug_name) return engine.monitor.get_display() def reset_all(): engine.reset() return [], "", engine.monitor.get_display() custom_css = """ .gradio-container { max-width: 1200px !important; margin: auto !important; } """ with gr.Blocks(css=custom_css, title="AnestheBot AI — Anesthesia Assistant") as demo: gr.Markdown(""" # AnestheBot AI — World's First Real-Time Anesthesia Assistant ### No Anesthesia Chatbot Exists Anywhere — Until Now **Created by Dr. Milan Joshi** | Open Source Medical AI Research **Features**: Real-time vitals | Drug dosing (PK models) | Emergency protocols | ASA/Mallampati | Fluid calculator | Drug simulation --- """) gr.Markdown(""" > **Medical Disclaimer**: This AI tool is for **educational and simulation purposes only**. > It does NOT replace the judgment of qualified anesthesia providers. Never use for direct patient care. """) with gr.Tabs(): # Tab 1: Chat Interface with gr.Tab("Clinical Assistant"): chatbot = gr.Chatbot(label="Anesthesia Consultation", height=500, type="tuples") with gr.Row(): msg = gr.Textbox( label="Ask anything", placeholder="e.g., 'propofol dose 70kg', 'malignant hyperthermia', 'ASA 3', 'fluid 80kg', 'ventilator 65kg'", lines=2, scale=5, ) send_btn = gr.Button("Send", variant="primary", scale=1) # Tab 2: Real-Time Monitor with gr.Tab("Vital Signs Monitor"): monitor_display = gr.Markdown(value=engine.monitor.get_display(), label="Vital Signs") with gr.Row(): tick_btn = gr.Button("Advance 1 Minute", variant="primary") refresh_btn = gr.Button("Refresh Display", variant="secondary") with gr.Row(): drug_dropdown = gr.Dropdown( choices=["propofol", "fentanyl", "rocuronium", "ketamine", "sevoflurane", "succinylcholine", "midazolam", "sugammadex", "epinephrine"], label="Administer Drug", ) admin_btn = gr.Button("Administer", variant="stop") # Tab 3: Emergency Protocols with gr.Tab("Emergency Protocols"): gr.Markdown("## Quick Access Emergency Protocols\nClick any button for the full protocol:") with gr.Row(): mh_btn = gr.Button("Malignant Hyperthermia", variant="stop") anaph_btn = gr.Button("Anaphylaxis", variant="stop") with gr.Row(): bronch_btn = gr.Button("Bronchospasm", variant="stop") last_btn = gr.Button("LAST / Lipid Rescue", variant="stop") with gr.Row(): airway_btn = gr.Button("Difficult Airway / CICO", variant="stop") emergency_output = gr.Markdown() # Tab 4: Drug Reference with gr.Tab("Drug Reference"): drug_ref_dropdown = gr.Dropdown( choices=list(ANESTHETIC_DRUGS.keys()), label="Select Drug", ) weight_input = gr.Number(label="Patient Weight (kg)", value=70) calc_btn = gr.Button("Calculate Dose", variant="primary") drug_output = gr.Markdown() with gr.Row(): clear_btn = gr.Button("Reset All", variant="secondary") # Event handlers msg.submit(chat_respond, [msg, chatbot], [msg, chatbot]) send_btn.click(chat_respond, [msg, chatbot], [msg, chatbot]) tick_btn.click(update_monitor, outputs=[monitor_display]) refresh_btn.click(lambda: engine.monitor.get_display(), outputs=[monitor_display]) admin_btn.click(admin_drug, inputs=[drug_dropdown], outputs=[monitor_display]) clear_btn.click(reset_all, outputs=[chatbot, msg, monitor_display]) # Emergency protocol buttons mh_btn.click(lambda: engine.get_emergency_protocol("malignant_hyperthermia"), outputs=[emergency_output]) anaph_btn.click(lambda: engine.get_emergency_protocol("anaphylaxis"), outputs=[emergency_output]) bronch_btn.click(lambda: engine.get_emergency_protocol("bronchospasm"), outputs=[emergency_output]) last_btn.click(lambda: engine.get_emergency_protocol("local_anesthetic_toxicity"), outputs=[emergency_output]) airway_btn.click(lambda: engine.get_emergency_protocol("difficult_airway"), outputs=[emergency_output]) # Drug reference calc_btn.click( lambda d, w: engine.calculate_dose(d, w) if d else "Select a drug first.", inputs=[drug_ref_dropdown, weight_input], outputs=[drug_output], ) gr.Markdown(""" --- ### What Makes This a World First | Feature | Market Status | AnestheBot AI | |---------|-------------|---------------| | Anesthesia Chatbot | **NONE EXIST** | Full conversational AI | | Real-Time Vitals | Hardware only (Edwards HPI) | Software simulation + alerts | | Drug Dosing | Simple weight calculators | PK-model based with interactions | | Emergency Protocols | Paper/PDF checklists | Interactive, step-by-step | | Drug Simulation | None | Administer drugs, watch vitals change | | ASA/Mallampati/RCRI | Separate apps | All-in-one platform | | Cost | $14-$387M enterprise | **FREE (open source)** | """) if __name__ == "__main__": demo.launch()