# gradio_app.py """ Simplified Gradio Interface for Medical Brain with Background Spiritual Monitoring. Single unified medical interface with invisible spiritual monitoring. No mode selector - just medical dialog with automatic spiritual support. Requirements: 1.3, 4.1, 4.2, 12.1, 12.2 """ import os import sys # Ensure project root is in Python path project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) if project_root not in sys.path: sys.path.insert(0, project_root) from dotenv import load_dotenv # Load environment variables load_dotenv() import gradio as gr # Import modularized components from src.interface.session_manager import SimplifiedSessionData from src.interface import stats_handlers from src.interface import chat_handlers from src.interface import prompt_handlers from src.interface import verification_handlers from src.interface import profile_handlers from src.interface import model_handlers from src.core.simplified_medical_app import SimplifiedMedicalApp from src.core.spiritual_state import SpiritualState from src.interface.enhanced_verification_interface import create_enhanced_verification_tab from src.interface.help_content import HELP_CONTENT try: from app_config import ( GRADIO_CONFIG, ENHANCED_VERIFICATION_CONFIG, FEATURE_FLAGS, is_feature_enabled ) except ImportError: GRADIO_CONFIG = {"theme": "soft", "show_api": False} ENHANCED_VERIFICATION_CONFIG = {"enabled": True} FEATURE_FLAGS = { "enhanced_verification_enabled": True, "standard_verification_enabled": True, "show_mode_navigation_hints": True, } def is_feature_enabled(feature_name: str) -> bool: return FEATURE_FLAGS.get(feature_name, False) def create_simplified_interface(): """ Create simplified Gradio interface. Single medical assistant interface with background spiritual monitoring. No mode selector - spiritual support is automatic and invisible. Requirements: 1.3, 4.1, 12.1 """ debug_mode = os.getenv("LOG_PROMPTS", "false").lower() == "true" # Theme setup theme_name = GRADIO_CONFIG.get("theme", "soft") if theme_name.lower() == "soft": theme = gr.themes.Soft() else: theme = gr.themes.Default() demo = gr.Blocks( title="๐Ÿฅ Medical Assistant with Spiritual Support", analytics_enabled=False ) demo.theme = theme with demo: # Session state session_data = gr.State(value=None) # Header gr.Markdown("# ๐Ÿฅ Medical Assistant with Spiritual Support ๐Ÿ•Š๏ธ") gr.Markdown("Your personal healthcare companion with integrated wellness support") if debug_mode: gr.Markdown("โš ๏ธ **DEBUG MODE:** Prompts and responses are logged") # Session info session_info = gr.Markdown("๐Ÿ”„ **Initializing session...**") # Initialize session def initialize_session(): """Initialize new user session.""" new_session = SimplifiedSessionData() session_info_text = f""" โœ… **Session Ready** ๐Ÿ†” Session: `{new_session.session_id[:8]}...` ๐Ÿ•’ Started: {new_session.created_at[:19]} """ return new_session, session_info_text # Main interface - using Tabs with elem_id for navigation main_tabs = gr.Tabs(elem_id="main_tabs") with main_tabs: # Note: The following tabs are intentionally hidden for now: # - โœ๏ธ Edit Enhanced Datasets # - โœ“ Standard Verification # We keep the rest of the interface focused on Chat + Conversation Verification. # Chat tab with gr.TabItem("๐Ÿ’ฌ Chat", id="chat"): with gr.Row(): with gr.Column(scale=2): chatbot = gr.Chatbot( label="๐Ÿ’ฌ Conversation", height=450 ) with gr.Row(): msg = gr.Textbox( label="Your message", placeholder="Type your health question...", scale=4 ) send_btn = gr.Button("๐Ÿ“ค Send", scale=1, variant="primary") with gr.Row(): clear_btn = gr.Button("๐Ÿ—‘๏ธ Clear Chat", scale=1) # Conversation logging section gr.Markdown("### ๐Ÿ“Š Conversation Logs:") with gr.Row(): download_json_btn = gr.DownloadButton("๐Ÿ“ฅ Download JSON", scale=1, size="sm") download_csv_btn = gr.DownloadButton("๐Ÿ“Š Download CSV", scale=1, size="sm") # Conversation verification is available in the dedicated # "๐Ÿงพ Conversation Verification" tab. # Quick examples gr.Markdown("### โšก Quick Start:") with gr.Row(): example_medical = gr.Button("๐ŸŸข I am fine", size="sm") example_wellness = gr.Button("๐ŸŸก I'm feeling stressed", size="sm") example_help = gr.Button("๐Ÿ”ด Emotional crisis", size="sm") with gr.Column(scale=1): status_box = gr.Markdown( value="๐Ÿ”„ Loading...", label="๐Ÿ“Š Status" ) refresh_btn = gr.Button("๐Ÿ”„ Check Status & Summary", size="sm") # Conversation statistics gr.Markdown("### ๐Ÿ“ˆ Conversation Stats") conversation_stats = gr.Markdown( value="No conversation yet", label="Statistics" ) # Debug info (only in debug mode) if debug_mode: gr.Markdown("### ๐Ÿ”ง Debug Info") debug_info = gr.Markdown(value="") # Provider Summary Panel (for RED flags) - always visible but content controlled with gr.Column(scale=1) as provider_summary_column: with gr.Group(visible=False) as provider_summary_content: gr.Markdown("### ๐Ÿ“‹ Provider Summary") gr.Markdown("*For Spiritual Care Team*", elem_classes=["provider-subtitle"]) provider_summary_status = gr.Markdown( value="**Provider Summary Generated**\n\nA detailed summary has been generated for the spiritual care team. Use the Download button below to access the full summary." ) # Tabs for different summary views (Medical Brain Summary first by default) with gr.Tabs(): # Coherent Paragraph Tab (FIRST - Requirements 2.1-2.8) - Medical Brain compatibility with gr.TabItem("๐Ÿ“ Medical Brain Summary"): gr.Markdown("*Single paragraph format for Medical Brain compatibility - **Default View***") coherent_summary_display = gr.Textbox( value="", lines=8, label="Medical Brain Compatible Summary", interactive=False ) with gr.Row(): regenerate_coherent_btn = gr.Button( "๐Ÿ”„ Regenerate Medical Brain Summary", size="sm", variant="secondary" ) download_coherent_btn = gr.DownloadButton( "๐Ÿ“ฅ Download Medical Brain Summary", size="sm", variant="secondary" ) # Structured Summary Tab (moved to second position) with gr.TabItem("๐Ÿ“Š Structured Summary"): provider_summary_display = gr.HTML(value="") with gr.Row(): download_summary_btn = gr.DownloadButton( "๐Ÿ“ฅ Download Full Summary", size="sm", variant="secondary" ) clear_summary_btn = gr.Button( "๐Ÿ—‘๏ธ Clear", size="sm" ) # Conversation Verification tab (chat-derived) with gr.TabItem("๐Ÿงพ Conversation Verification", id="conversation_verification"): gr.Markdown("## ๐Ÿงพ Conversation Verification (from Chat)") gr.Markdown( "Click **Generate** to build a verification session from the current chat. " "Review each exchange, mark it correct/incorrect, and download the session JSON." ) conv_verify_state = gr.State(value=None) # holds exported JSON path conv_verify_index = gr.State(value=0) conv_verify_records = gr.State(value=[]) with gr.Row(): generate_conv_verification_btn = gr.Button("๐Ÿ›  Generate from current chat", variant="primary") conv_verify_download_btn = gr.DownloadButton("โฌ‡๏ธ Download reviewed JSON", variant="secondary") conv_verify_download_csv_btn = gr.DownloadButton("๐Ÿ“„ Download CSV", variant="secondary") conv_verify_status = gr.Markdown(value="", visible=True) conv_verify_exchange = gr.HTML(value="", label="Current Exchange") with gr.Row(): conv_correct_btn = gr.Button("โœ… Correct", variant="primary") conv_incorrect_btn = gr.Button("โŒ Incorrect") conv_prev_btn = gr.Button("โฌ…๏ธ Previous") conv_next_btn = gr.Button("Next โžก๏ธ") # Shown only when marking Incorrect with gr.Row(visible=False) as conv_incorrect_comment_row: with gr.Column(scale=3): gr.Markdown("### Select Correct Classification:") conv_correct_classification = gr.Radio( choices=[ "๐ŸŸข Should be GREEN - No distress", "๐ŸŸก Should be YELLOW - Needs clarification", "๐Ÿ”ด Should be RED - Spiritual distress" ], label="Correct Classification", interactive=True ) conv_incorrect_comment = gr.Textbox( label="Comment (why incorrect / what to fix)", placeholder="Add a short note for this exchange...", lines=3, ) with gr.Column(scale=1): conv_save_comment_btn = gr.Button("๐Ÿ’พ Save comment", variant="secondary") with gr.Row(): with gr.Column(scale=1): conv_position = gr.Markdown(value="") with gr.Column(scale=1): conv_stats = gr.HTML(value="") # Enhanced Verification Modes tab (hidden sub-tabs; kept but moved after Conversation Verification) if is_feature_enabled("enhanced_verification_enabled"): with gr.TabItem("๐Ÿ” Enhanced Verification", id="enhanced_verification"): enhanced_verification_interface = create_enhanced_verification_tab() # Model Selection tab (second tab) with gr.TabItem("โš™๏ธ Model Settings", id="model_settings"): gr.Markdown("## โš™๏ธ AI Model Configuration") gr.Markdown("Select which AI models to use for different tasks. Changes apply to your current session.") with gr.Row(): with gr.Column(): gr.Markdown("### ๐Ÿ” Spiritual Monitor (Classifier)") spiritual_model = gr.Dropdown( choices=[ "gemini-2.5-flash", "gemini-2.0-flash", "gemini-3-flash-preview", "claude-sonnet-4-5-20250929", "claude-sonnet-4-20250514", "claude-3-7-sonnet-20250219" ], value="gemini-2.5-flash", label="Spiritual Distress Analyzer", interactive=True ) gr.Markdown("### ๐ŸŸก Soft Spiritual Triage") soft_spiritual_triage_model = gr.Dropdown( choices=[ "claude-sonnet-4-5-20250929", "claude-sonnet-4-20250514", "claude-3-7-sonnet-20250219", "gemini-2.5-flash", "gemini-2.0-flash", "gemini-3-flash-preview" ], value="claude-sonnet-4-5-20250929", label="Soft Spiritual Triage", interactive=True ) with gr.Column(): gr.Markdown("### ๐Ÿ“Š Triage Response Evaluator") triage_evaluate_model = gr.Dropdown( choices=[ "gemini-2.5-flash", "gemini-2.0-flash", "gemini-3-flash-preview", "claude-sonnet-4-5-20250929", "claude-sonnet-4-20250514", "claude-3-7-sonnet-20250219" ], value="gemini-2.5-flash", label="Triage Response Evaluator", interactive=True ) gr.Markdown("### ๐Ÿฅ Medical Assistant") medical_model = gr.Dropdown( choices=[ "claude-sonnet-4-5-20250929", "claude-sonnet-4-20250514", "claude-3-7-sonnet-20250219", "gemini-2.5-flash", "gemini-2.0-flash", "gemini-3-flash-preview" ], value="claude-sonnet-4-5-20250929", label="Medical Assistant", interactive=True ) with gr.Column(): gr.Markdown("### ๐Ÿฉบ Soft Medical Triage") soft_triage_model = gr.Dropdown( choices=[ "claude-sonnet-4-5-20250929", "claude-sonnet-4-20250514", "claude-3-7-sonnet-20250219", "gemini-2.5-flash", "gemini-2.0-flash", "gemini-3-flash-preview" ], value="claude-sonnet-4-5-20250929", label="Soft Medical Triage", interactive=True ) gr.Markdown("### ๐Ÿ’ฌ Medical Brain Summary Generator") spiritual_care_message_model = gr.Dropdown( choices=[ "claude-sonnet-4-5-20250929", "claude-sonnet-4-20250514", "claude-3-7-sonnet-20250219", "gemini-2.5-flash", "gemini-2.0-flash", "gemini-3-flash-preview" ], value="claude-sonnet-4-5-20250929", label="Medical Brain Summary Generator (uses Spiritual Care Message prompt)", interactive=True ) with gr.Row(): apply_models_btn = gr.Button("โœ… Apply Model Settings", variant="primary", scale=2) reset_models_btn = gr.Button("๐Ÿ”„ Reset to Defaults", scale=1) model_status = gr.HTML(value="", visible=True) # Edit Prompts tab with gr.TabItem("๐Ÿ”ง Edit Prompts", id="edit_prompts"): gr.Markdown("## ๐Ÿ”ง Customize AI Prompts") gr.Markdown("โš ๏ธ **Note:** Changes apply only to your current session.") # Prompt selector with gr.Row(): prompt_selector = gr.Dropdown( choices=[ "๐Ÿ” Spiritual Monitor (Classifier)", "๐ŸŸก Soft Spiritual Triage", "๐Ÿ“Š Triage Response Evaluator", "๐Ÿฅ Medical Assistant", "๐Ÿฉบ Soft Medical Triage", "๐Ÿ’ฌ Spiritual Care Message" ], value="๐Ÿ” Spiritual Monitor (Classifier)", label="Select Prompt to Edit", interactive=True ) with gr.Row(): with gr.Column(scale=3): # Prompt editor prompt_editor = gr.Code( label="System Prompt", value="", language="markdown", lines=25, interactive=True ) with gr.Row(): load_prompt_btn = gr.Button("๐Ÿ“ฅ Load Prompt", scale=1) apply_prompt_btn = gr.Button("โœ… Apply Changes", variant="primary", scale=2) reset_prompt_btn = gr.Button("๐Ÿ”„ Reset to Default", variant="secondary", scale=1) with gr.Row(): promote_prompt_btn = gr.Button("๐Ÿ“ค Promote to File", variant="stop", scale=1) validate_prompt_btn = gr.Button("๐Ÿ” Validate", variant="secondary", scale=1) prompt_status = gr.HTML( value="", visible=True, elem_classes=["prompt-status-container"] ) with gr.Column(scale=1): gr.Markdown("### ๐Ÿ“‹ Prompt Info") prompt_info_display = gr.HTML(value="""

Select a prompt to edit

Available prompts:

Tips:

""") # Patient Profiles tab with gr.TabItem("๐Ÿ‘ฅ Patient Profiles", id="profiles"): gr.Markdown("## ๐Ÿ‘ฅ Patient Profile Management") gr.Markdown("Select a predefined profile or customize the current patient settings.") with gr.Row(): with gr.Column(scale=1): gr.Markdown("### ๐Ÿ“‹ Predefined Profiles") profile_selector = gr.Dropdown( choices=[ "๐Ÿ‘ค Default Profile (Serhii)", "๐ŸŸข GREEN - Healthy Coping", "๐ŸŸก YELLOW - Mild Distress", "๐ŸŸก YELLOW - Grief & Loss", "๐ŸŸก YELLOW - Existential Questions", "๐ŸŸก YELLOW - Spiritual Disconnection", "๐Ÿ”ด RED - Crisis (Suicidal Risk)", "๐Ÿ”ด RED - Severe Hopelessness", "๐Ÿ”ด RED - Spiritual Crisis", "๐Ÿซ€ Cardiac Patient (Rehabilitation)", "๐Ÿฉธ Diabetic Patient (Management)", "๐Ÿฅ Post-Surgery (Recovery)", "๐Ÿง  Mental Health (Anxiety/Depression)", "๐Ÿ‘ด Elderly Patient (Chronic Care)", "๐Ÿƒ Athletic Patient (Injury/Training)" ], value="๐Ÿ‘ค Default Profile (Serhii)", label="Select Profile", interactive=True ) load_profile_btn = gr.Button("๐Ÿ“ฅ Load Profile", variant="primary") profile_status = gr.HTML(value="", visible=True) with gr.Column(scale=2): gr.Markdown("### โš™๏ธ Current Patient Settings") with gr.Row(): patient_name = gr.Textbox( label="Patient Name", value="Serhii", interactive=True ) patient_phone = gr.Textbox( label="Phone Number", value="", placeholder="(555) 123-4567", interactive=True ) patient_age = gr.Number( label="Age", value=52, interactive=True ) with gr.Row(): conditions = gr.Textbox( label="Medical Conditions (comma-separated)", value="Atrial fibrillation, Deep vein thrombosis, Obesity, Hypertension", lines=3, interactive=True ) with gr.Row(): primary_goal = gr.Textbox( label="Primary Goal", value="Weight reduction and cardiovascular fitness improvement", lines=2, interactive=True ) with gr.Row(): exercise_prefs = gr.Textbox( label="Exercise Preferences (comma-separated)", value="Swimming, Walking, Light cardio", lines=2, interactive=True ) with gr.Row(): exercise_limits = gr.Textbox( label="Exercise Limitations (comma-separated)", value="Anticoagulation therapy, Post-thrombotic recovery", lines=2, interactive=True ) with gr.Row(): save_profile_btn = gr.Button("๐Ÿ’พ Save Current Profile", variant="primary", scale=1) reset_profile_btn = gr.Button("๐Ÿ”„ Reset to Default", scale=1) profile_save_status = gr.HTML(value="", visible=True) # Instructions tab with gr.TabItem("๐Ÿ“– Help", id="help"): gr.Markdown(HELP_CONTENT) # Event handlers # Handlers moved to modular modules # Bind events demo.load( initialize_session, outputs=[session_data, session_info] ) # Send message send_btn.click( chat_handlers.handle_message, inputs=[msg, chatbot, session_data], outputs=[chatbot, status_box, session_data, msg, conversation_stats, provider_summary_content, provider_summary_status, provider_summary_display, coherent_summary_display] ) msg.submit( chat_handlers.handle_message, inputs=[msg, chatbot, session_data], outputs=[chatbot, status_box, session_data, msg, conversation_stats, provider_summary_content, provider_summary_status, provider_summary_display, coherent_summary_display] ) # Clear chat clear_btn.click( chat_handlers.handle_clear, inputs=[session_data], outputs=[chatbot, status_box, session_data, provider_summary_content, provider_summary_status, provider_summary_display, coherent_summary_display] ) # Refresh status refresh_btn.click( stats_handlers.get_status, inputs=[session_data], outputs=[status_box, conversation_stats, provider_summary_content, provider_summary_status, provider_summary_display, coherent_summary_display] ) # Example buttons example_medical.click( lambda h, s: chat_handlers.send_example_with_stats("I am fine", h, s), inputs=[chatbot, session_data], outputs=[chatbot, status_box, session_data, msg, conversation_stats, provider_summary_content, provider_summary_status, provider_summary_display, coherent_summary_display] ) example_wellness.click( lambda h, s: chat_handlers.send_example_with_stats("I'm feeling stressed and overwhelmed lately", h, s), inputs=[chatbot, session_data], outputs=[chatbot, status_box, session_data, msg, conversation_stats, provider_summary_content, provider_summary_status, provider_summary_display, coherent_summary_display] ) example_help.click( lambda h, s: chat_handlers.send_example_with_stats("I am currently experiencing an emotional crisis", h, s), inputs=[chatbot, session_data], outputs=[chatbot, status_box, session_data, msg, conversation_stats, provider_summary_content, provider_summary_status, provider_summary_display, coherent_summary_display] ) # Conversation logging buttons download_json_btn.click( stats_handlers.download_conversation_json, inputs=[session_data], outputs=[download_json_btn] ) download_csv_btn.click( stats_handlers.download_conversation_csv, inputs=[session_data], outputs=[download_csv_btn] ) # Provider Summary panel handlers download_summary_btn.click( stats_handlers.download_provider_summary, inputs=[session_data], outputs=[download_summary_btn] ) clear_summary_btn.click( stats_handlers.clear_provider_summary, inputs=[], outputs=[provider_summary_content, provider_summary_status, provider_summary_display, coherent_summary_display] ) # Coherent summary handlers (Medical Brain Summary - now first tab by default) regenerate_coherent_btn.click( stats_handlers.regenerate_coherent_summary, inputs=[session_data], outputs=[coherent_summary_display] ) download_coherent_btn.click( stats_handlers.download_coherent_summary, inputs=[session_data], outputs=[download_coherent_btn] ) # Conversation Verification events generate_conv_verification_btn.click( verification_handlers._generate_conv_verification, inputs=[session_data], outputs=[conv_verify_state, conv_verify_records, conv_verify_index, conv_verify_status, conv_verify_exchange, conv_position, conv_stats] ) conv_verify_download_btn.click( verification_handlers._download_reviewed_json, inputs=[conv_verify_state, conv_verify_records], outputs=[conv_verify_download_btn] ) conv_verify_download_csv_btn.click( verification_handlers._download_reviewed_csv, inputs=[conv_verify_state, conv_verify_records], outputs=[conv_verify_download_csv_btn] ) conv_correct_btn.click( verification_handlers._mark_conv_correct, inputs=[conv_verify_records, conv_verify_index], outputs=[ conv_verify_records, conv_verify_index, conv_verify_status, conv_verify_exchange, conv_position, conv_stats, conv_incorrect_comment_row, conv_incorrect_comment, conv_correct_classification, ] ) conv_incorrect_btn.click( verification_handlers._show_incorrect_comment_ui, inputs=[conv_verify_records, conv_verify_index], outputs=[ conv_verify_records, conv_verify_index, conv_verify_status, conv_verify_exchange, conv_position, conv_stats, conv_incorrect_comment_row, conv_incorrect_comment, conv_correct_classification, ] ) conv_save_comment_btn.click( verification_handlers._save_incorrect_comment, inputs=[conv_verify_records, conv_verify_index, conv_incorrect_comment, conv_correct_classification], outputs=[ conv_verify_records, conv_verify_index, conv_verify_status, conv_verify_exchange, conv_position, conv_stats, conv_incorrect_comment_row, conv_incorrect_comment, conv_correct_classification, ] ) conv_prev_btn.click( lambda records, idx: verification_handlers._nav_conv(records, idx, -1), inputs=[conv_verify_records, conv_verify_index], outputs=[conv_verify_index, conv_verify_exchange, conv_position, conv_stats, conv_incorrect_comment_row, conv_incorrect_comment, conv_correct_classification] ) conv_next_btn.click( lambda records, idx: verification_handlers._nav_conv(records, idx, 1), inputs=[conv_verify_records, conv_verify_index], outputs=[conv_verify_index, conv_verify_exchange, conv_position, conv_stats, conv_incorrect_comment_row, conv_incorrect_comment, conv_correct_classification] ) # Prompt editing events load_prompt_btn.click( prompt_handlers.load_prompt, inputs=[prompt_selector, session_data], outputs=[prompt_editor, prompt_info_display, prompt_status] ) apply_prompt_btn.click( prompt_handlers.apply_prompt_changes, inputs=[prompt_selector, prompt_editor, session_data], outputs=[prompt_status, session_data] ) reset_prompt_btn.click( prompt_handlers.reset_prompt, inputs=[prompt_selector, session_data], outputs=[prompt_editor, prompt_info_display, prompt_status, session_data] ) promote_prompt_btn.click( prompt_handlers.promote_prompt_to_file, inputs=[prompt_selector, session_data], outputs=[prompt_status, session_data] ) validate_prompt_btn.click( prompt_handlers.validate_prompt_syntax, inputs=[prompt_editor], outputs=[prompt_status] ) # Auto-load prompt when selector changes prompt_selector.change( prompt_handlers.load_prompt, inputs=[prompt_selector, session_data], outputs=[prompt_editor, prompt_info_display, prompt_status] ) # Bind model selection events apply_models_btn.click( model_handlers.apply_model_settings, inputs=[spiritual_model, soft_spiritual_triage_model, triage_evaluate_model, medical_model, soft_triage_model, spiritual_care_message_model, session_data], outputs=[model_status, session_data] ) reset_models_btn.click( model_handlers.reset_model_settings, inputs=[session_data], outputs=[model_status, session_data] ) # Bind profile events load_profile_btn.click( profile_handlers.load_profile, inputs=[profile_selector, session_data], outputs=[patient_name, patient_phone, patient_age, conditions, primary_goal, exercise_prefs, exercise_limits, profile_status] ) save_profile_btn.click( profile_handlers.save_profile, inputs=[patient_name, patient_phone, patient_age, conditions, primary_goal, exercise_prefs, exercise_limits, session_data], outputs=[profile_save_status] ) reset_profile_btn.click( profile_handlers.reset_profile, inputs=[session_data], outputs=[patient_name, patient_phone, patient_age, conditions, primary_goal, exercise_prefs, exercise_limits, profile_save_status] ) # Add CSS for prompt status container demo.css = """ .prompt-status-container { max-height: 300px !important; overflow-y: auto !important; margin: 0.5em 0 !important; } .prompt-status-container > div { max-height: 280px !important; overflow-y: auto !important; } """ return demo def main(): """Launch the simplified Gradio interface.""" demo = create_simplified_interface() # Get configuration server_name = os.getenv("GRADIO_SERVER_NAME", "0.0.0.0") server_port = int(os.getenv("GRADIO_SERVER_PORT", "7860")) share = os.getenv("GRADIO_SHARE", "false").lower() == "true" print(f"๐Ÿš€ Starting Simplified Medical Assistant...") print(f"๐Ÿ“ Server: http://{server_name}:{server_port}") demo.launch( server_name=server_name, server_port=server_port, share=share ) if __name__ == "__main__": main()