Spaces:
Sleeping
Sleeping
| # simplified_chat_handlers.py | |
| """ | |
| Chat handlers for simplified interface with Provider Summary replacement. | |
| Based on Or_4.txt requirement: | |
| "Instead of showing the final user message (consent confirmation), | |
| show the Provider Summary message for the spiritual care team." | |
| """ | |
| import gradio as gr | |
| import html | |
| from src.interface.session_manager import SimplifiedSessionData | |
| from src.interface.stats_handlers import get_conversation_stats | |
| def handle_message_simplified(message: str, history, session: SimplifiedSessionData): | |
| """ | |
| Handle user message with Provider Summary replacement for simplified interface. | |
| Key difference from standard handler: | |
| - When RED flag is triggered and consent is given, the last assistant message | |
| is replaced with the Provider Summary (message for spiritual care team) | |
| instead of the confirmation message to the user. | |
| - All assistant messages are prefixed with "To patient:" or "To spiritual care team:" | |
| """ | |
| if session is None: | |
| session = SimplifiedSessionData() | |
| session.update_activity() | |
| # Apply per-session model overrides (if configured) | |
| custom_models = getattr(session, 'custom_models', None) | |
| if custom_models: | |
| session.app_instance.set_model_overrides(custom_models) | |
| else: | |
| session.app_instance.set_model_overrides({}) | |
| # Apply per-session prompt overrides (if configured) | |
| custom_prompts = getattr(session, 'custom_prompts', None) | |
| if custom_prompts: | |
| session.app_instance.set_prompt_overrides(custom_prompts) | |
| else: | |
| session.app_instance.set_prompt_overrides({}) | |
| # Store previous spiritual state to detect transitions | |
| previous_state = session.app_instance.spiritual_state.spiritual_state | |
| # Process message | |
| new_history, status = session.app_instance.process_message(message, history) | |
| # Check if we just transitioned to RED state (consent was given) | |
| current_state = session.app_instance.spiritual_state.spiritual_state | |
| consent_just_given = (previous_state.value == "awaiting_consent" and | |
| current_state.value == "red") | |
| # SIMPLIFIED INTERFACE MODIFICATION: | |
| # Replace last assistant message with Provider Summary if consent was just given | |
| if consent_just_given: | |
| last_summary = session.app_instance.get_last_provider_summary() | |
| if last_summary and new_history: | |
| # Get the COHERENT NARRATIVE summary (LLM-generated from spiritual_care_message.txt) | |
| # This is the Medical Brain compatible format, not the structured format | |
| try: | |
| provider_summary_text = session.app_instance.provider_summary_generator.format_coherent_paragraph(last_summary) | |
| if not provider_summary_text: | |
| # Fallback to structured format if coherent generation fails | |
| provider_summary_text = session.app_instance.provider_summary_generator.format_for_export(last_summary) | |
| except Exception as e: | |
| print(f"ERROR: Failed to generate coherent summary: {e}") | |
| # Fallback to structured format | |
| provider_summary_text = session.app_instance.provider_summary_generator.format_for_export(last_summary) | |
| # Format with clear addressee label after classification | |
| # Provider Summary should also have classification info, then "**To spiritual care team:**" | |
| summary_display = f"""**To spiritual care team:** | |
| {provider_summary_text}""" | |
| # Replace the last assistant message with the provider summary | |
| # History format: list of dicts with 'role' and 'content' | |
| if len(new_history) > 0: | |
| last_item = new_history[-1] | |
| if isinstance(last_item, dict) and last_item.get('role') == 'assistant': | |
| # Replace the content | |
| new_history[-1] = { | |
| 'role': 'assistant', | |
| 'content': summary_display | |
| } | |
| elif isinstance(last_item, (list, tuple)) and len(last_item) > 1: | |
| # Old format: (user_msg, assistant_msg) | |
| new_history[-1] = (last_item[0], summary_display) | |
| print(f"DEBUG: Replaced last message with Provider Summary (coherent narrative)") | |
| print(f"DEBUG: Summary length: {len(provider_summary_text)} chars") | |
| else: | |
| # Add "To patient:" after classification status for all other assistant messages | |
| if new_history and len(new_history) > 0: | |
| last_item = new_history[-1] | |
| if isinstance(last_item, dict) and last_item.get('role') == 'assistant': | |
| content = last_item.get('content', '') | |
| # Only add prefix if not already present | |
| if 'To patient:' not in content and 'To spiritual care team:' not in content: | |
| # Insert "To patient:" after the classification line | |
| # Format: "π’ GREEN (95%)\n*Indicators...*\n*Reasoning...*\n\nActual message" | |
| # We need to insert "To patient:\n" after the classification block | |
| lines = content.split('\n') | |
| # Find where classification ends (after reasoning line or after first empty line) | |
| insert_index = 0 | |
| for i, line in enumerate(lines): | |
| if line.strip().startswith('*') or line.strip().startswith('π’') or line.strip().startswith('π‘') or line.strip().startswith('π΄') or line.strip().startswith('βͺ'): | |
| insert_index = i + 1 | |
| elif insert_index > 0 and line.strip() == '': | |
| # Found empty line after classification | |
| insert_index = i | |
| break | |
| # Insert "**To patient:**" at the right position (after the empty line) | |
| if insert_index > 0 and insert_index < len(lines): | |
| lines.insert(insert_index, '**To patient:**') | |
| lines.insert(insert_index + 1, '') # Add empty line after "**To patient:**" | |
| new_content = '\n'.join(lines) | |
| else: | |
| # Fallback: add at the beginning | |
| new_content = f"**To patient:**\n\n{content}" | |
| new_history[-1] = { | |
| 'role': 'assistant', | |
| 'content': new_content | |
| } | |
| elif isinstance(last_item, (list, tuple)) and len(last_item) > 1: | |
| content = last_item[1] | |
| if 'To patient:' not in content and 'To spiritual care team:' not in content: | |
| # Same logic for tuple format | |
| lines = content.split('\n') | |
| insert_index = 0 | |
| for i, line in enumerate(lines): | |
| if line.strip().startswith('*') or line.strip().startswith('π’') or line.strip().startswith('π‘') or line.strip().startswith('π΄') or line.strip().startswith('βͺ'): | |
| insert_index = i + 1 | |
| elif insert_index > 0 and line.strip() == '': | |
| insert_index = i + 1 | |
| break | |
| if insert_index > 0 and insert_index < len(lines): | |
| lines.insert(insert_index, '**To patient:**') | |
| lines.insert(insert_index + 1, '') # Add empty line after "**To patient:**" | |
| new_content = '\n'.join(lines) | |
| else: | |
| new_content = f"**To patient:**\n\n{content}" | |
| new_history[-1] = (last_item[0], new_content) | |
| # Get updated conversation stats | |
| stats = get_conversation_stats(session) | |
| return ( | |
| new_history, | |
| status, | |
| session, | |
| "", # Clear input | |
| stats | |
| ) | |
| def handle_clear_simplified(session: SimplifiedSessionData): | |
| """ | |
| Handle clear chat button for simplified interface. | |
| Resets entire session including: | |
| - Chat history | |
| - Spiritual monitoring state | |
| - Conversation statistics | |
| """ | |
| if session is None: | |
| session = SimplifiedSessionData() | |
| session.update_activity() | |
| new_history, status = session.app_instance.reset_session() | |
| return ( | |
| new_history, # Clear chat history | |
| status, # Reset status | |
| session # Updated session | |
| ) | |
| def send_example_simplified(example_text: str, history, session: SimplifiedSessionData): | |
| """Send example message in simplified interface.""" | |
| return handle_message_simplified(example_text, history, session) | |