import logging
import gradio as gr
from typing import Optional
from src.interface.session_manager import SimplifiedSessionData
logger = logging.getLogger(__name__)
def format_prompt_with_html(prompt_text: str) -> str:
"""Format prompt with HTML tags for better visualization."""
import re
import html
# Escape HTML first to prevent injection
formatted = html.escape(prompt_text)
# Highlight XML-like opening tags
formatted = re.sub(
r'<([a-z_]+)(?:\s+[^>]*)?>',
r'<\1>',
formatted,
flags=re.IGNORECASE
)
# Highlight XML-like closing tags
formatted = re.sub(
r'</([a-z_]+)>',
r'</\1>',
formatted,
flags=re.IGNORECASE
)
# Highlight XML attributes
formatted = re.sub(
r'([a-z_]+)="([^"]+)"',
r'\1="\2"',
formatted,
flags=re.IGNORECASE
)
# Highlight bullet points
formatted = re.sub(
r'^([-•]\s+.+)$',
r'
\1
',
formatted,
flags=re.MULTILINE
)
# Highlight numbered lists
formatted = re.sub(
r'^(\d+\.\s+.+)$',
r'\1
',
formatted,
flags=re.MULTILINE
)
# Highlight important keywords
keywords = [
'IMPORTANT', 'CRITICAL', 'REQUIRED', 'MUST', 'SHALL',
'WARNING', 'NOTE', 'TASK', 'GOAL', 'OUTPUT', 'ANY'
]
for keyword in keywords:
formatted = re.sub(
f'\\b({keyword})\\b',
r'\1',
formatted,
flags=re.IGNORECASE
)
# Highlight JSON/code blocks
formatted = re.sub(
r'(\{[^}]+\})',
r'\1',
formatted
)
# Convert newlines to
for proper display
formatted = formatted.replace('\n', '
')
# Wrap in container with monospace font for code-like appearance
formatted = f'{formatted}
'
return formatted
def _prompt_name_to_agent(prompt_name: str) -> str:
"""Map UI prompt selection to internal agent/prompt key."""
mapping = {
"🔍 Spiritual Monitor (Classifier)": "SpiritualDistressAnalyzer",
"🟡 Soft Spiritual Triage": "SoftSpiritualTriage",
"📊 Triage Response Evaluator": "TriageResponseEvaluator",
"🏥 Medical Assistant": "MedicalAssistant",
"🩺 Soft Medical Triage": "SoftMedicalTriage",
}
return mapping.get(prompt_name, prompt_name)
def load_prompt(prompt_name: str, session: Optional[SimplifiedSessionData] = None):
"""Load selected prompt for editing using enhanced prompt editor."""
try:
from src.interface.enhanced_prompt_editor import EnhancedPromptEditor
# Initialize enhanced editor
editor = EnhancedPromptEditor()
# Get session ID
session_id = getattr(session, 'session_id', 'default_session') if session else 'default_session'
# Use enhanced editor to load prompt
prompt_content, info_html, status_html = editor.load_prompt_for_editing(prompt_name, session_id)
return prompt_content, info_html, status_html
except Exception as e:
# Fallback to old system if enhanced editor fails
logger.warning(f"Enhanced prompt editor failed, using fallback: {e}")
from src.core.spiritual_monitor import SYSTEM_PROMPT_SPIRITUAL_MONITOR
from src.core.soft_triage_manager import (
SYSTEM_PROMPT_TRIAGE_QUESTION,
SYSTEM_PROMPT_TRIAGE_EVALUATE
)
from src.config.prompts import (
SYSTEM_PROMPT_MEDICAL_ASSISTANT,
SYSTEM_PROMPT_SOFT_MEDICAL_TRIAGE
)
prompts = {
"🔍 Spiritual Monitor (Classifier)": SYSTEM_PROMPT_SPIRITUAL_MONITOR,
"🟡 Soft Spiritual Triage": SYSTEM_PROMPT_TRIAGE_QUESTION,
"📊 Triage Response Evaluator": SYSTEM_PROMPT_TRIAGE_EVALUATE,
"🏥 Medical Assistant": SYSTEM_PROMPT_MEDICAL_ASSISTANT,
"🩺 Soft Medical Triage": SYSTEM_PROMPT_SOFT_MEDICAL_TRIAGE
}
prompt_text = prompts.get(prompt_name, "")
info = f"""**Loaded:** {prompt_name}
**Length:** {len(prompt_text)} characters
**Status:** Fallback mode (enhanced editor unavailable)"""
status = """
⚠️ Fallback Mode
Using basic prompt editor. Enhanced features unavailable.
"""
return prompt_text, info, status
def apply_prompt_changes(prompt_name: str, prompt_text: str, session: SimplifiedSessionData):
"""Apply custom prompt changes using enhanced prompt editor."""
try:
from src.interface.enhanced_prompt_editor import EnhancedPromptEditor
if session is None:
session = SimplifiedSessionData()
# Initialize enhanced editor
editor = EnhancedPromptEditor()
# Get session ID
session_id = getattr(session, 'session_id', 'default_session')
# Use enhanced editor to apply changes
status_html, success = editor.apply_prompt_changes(prompt_name, prompt_text, session_id)
if success:
# Also store in session for backward compatibility
if not hasattr(session, 'custom_prompts'):
session.custom_prompts = {}
agent_key = _prompt_name_to_agent(prompt_name)
session.custom_prompts[agent_key] = prompt_text
# Apply to session app instance if available
if hasattr(session, 'app_instance') and hasattr(session.app_instance, 'set_prompt_overrides'):
session.app_instance.set_prompt_overrides(session.custom_prompts)
return status_html, session
except Exception as e:
# Fallback to old system
logger.warning(f"Enhanced prompt editor failed, using fallback: {e}")
if session is None:
session = SimplifiedSessionData()
if not prompt_text.strip():
error_html = """
❌ Error
Prompt cannot be empty
"""
return error_html, session
# Store custom prompt in session (session-scoped)
if not hasattr(session, 'custom_prompts'):
session.custom_prompts = {}
agent_key = _prompt_name_to_agent(prompt_name)
session.custom_prompts[agent_key] = prompt_text
status = f"""
⚠️ Fallback Mode - Changes Applied
Prompt: {prompt_name}
Length: {len(prompt_text)} characters
Enhanced features unavailable, using basic session storage.
"""
return status, session
def reset_prompt(prompt_name: str, session: SimplifiedSessionData):
"""Reset prompt to default using enhanced prompt editor."""
try:
from src.interface.enhanced_prompt_editor import EnhancedPromptEditor
if session is None:
session = SimplifiedSessionData()
# Initialize enhanced editor
editor = EnhancedPromptEditor()
# Get session ID
session_id = getattr(session, 'session_id', 'default_session')
# Use enhanced editor to reset prompt
prompt_content, info_html, status_html = editor.reset_prompt_to_default(prompt_name, session_id)
# Also remove from session for backward compatibility
agent_key = _prompt_name_to_agent(prompt_name)
if hasattr(session, 'custom_prompts') and agent_key in session.custom_prompts:
del session.custom_prompts[agent_key]
# Apply to session app instance if available
if hasattr(session, 'app_instance') and hasattr(session.app_instance, 'set_prompt_overrides'):
session.app_instance.set_prompt_overrides(getattr(session, 'custom_prompts', {}))
return prompt_content, info_html, status_html, session
except Exception as e:
# Fallback to old system
logger.warning(f"Enhanced prompt editor failed, using fallback: {e}")
if session is None:
session = SimplifiedSessionData()
# Remove from custom prompts
agent_key = _prompt_name_to_agent(prompt_name)
if hasattr(session, 'custom_prompts') and agent_key in session.custom_prompts:
del session.custom_prompts[agent_key]
# Reload default
prompt_text, info, status = load_prompt(prompt_name, session)
reset_status = """
🔄 Fallback Mode - Reset Complete
Prompt restored using basic system. Enhanced features unavailable.
"""
return prompt_text, info, reset_status, session
def promote_prompt_to_file(prompt_name: str, session: SimplifiedSessionData):
"""Promote session prompt override to permanent file."""
try:
from src.interface.enhanced_prompt_editor import EnhancedPromptEditor
if session is None:
return """
❌ Error
No session data available
""", session
# Initialize enhanced editor
editor = EnhancedPromptEditor()
# Get session ID
session_id = getattr(session, 'session_id', 'default_session')
# Use enhanced editor to promote prompt
status_html, success = editor.promote_session_to_file(prompt_name, session_id)
return status_html, session
except Exception as e:
logger.warning(f"Enhanced prompt editor failed: {e}")
return f"""
❌ Error
Failed to promote prompt: {str(e)}
""", session
def validate_prompt_syntax(prompt_text: str):
"""Validate prompt syntax and structure."""
try:
from src.interface.enhanced_prompt_editor import EnhancedPromptEditor
# Initialize enhanced editor
editor = EnhancedPromptEditor()
# Use enhanced editor to validate prompt
validation_html, is_valid = editor.validate_prompt_syntax(prompt_text)
return validation_html
except Exception as e:
logger.warning(f"Enhanced prompt editor failed: {e}")
return f"""
❌ Validation Error
Failed to validate prompt: {str(e)}
"""