"""Streamlit page: Configuration.""" from pathlib import Path import streamlit as st import yaml from ui_utils import initialize_session_state from sentinel.config import AppConfig, ModelConfig, ResourcePaths from sentinel.factory import SentinelFactory initialize_session_state() st.title("⚙️ Model Configuration") # Define base paths relative to project root root = Path(__file__).resolve().parents[3] model_dir = root / "configs" / "model" model_options = sorted([p.stem for p in model_dir.glob("*.yaml")]) default_model = ( "gemini_2.5_pro" if ("gemini_2.5_pro" in model_options) else model_options[0] ) # Model selection current_model = st.session_state.config.get("model") or default_model selected_model = st.selectbox( "Model Config", model_options, index=model_options.index(current_model) if current_model in model_options else 0, ) st.session_state.config["model"] = selected_model # Cancer modules selection cancer_dir = root / "configs" / "knowledge_base" / "cancer_modules" cancer_options = sorted([p.stem for p in cancer_dir.glob("*.yaml")]) selected_cancers = st.multiselect( "Cancer Modules", cancer_options, default=st.session_state.config.get("cancer_modules", cancer_options), ) st.session_state.config["cancer_modules"] = selected_cancers # Diagnostic protocols selection protocol_dir = root / "configs" / "knowledge_base" / "dx_protocols" protocol_options = sorted([p.stem for p in protocol_dir.glob("*.yaml")]) selected_protocols = st.multiselect( "Diagnostic Protocols", protocol_options, default=st.session_state.config.get("dx_protocols", protocol_options), ) st.session_state.config["dx_protocols"] = selected_protocols @st.cache_data(show_spinner=False) def generate_prompt_preview( model_config: str, cancer_modules: list, dx_protocols: list, _user_profile=None ) -> str: """Generate prompt preview using the factory system. Args: model_config (str): Name of the Hydra model configuration to load. cancer_modules (list): Cancer module slugs selected by the user. dx_protocols (list): Diagnostic protocol slugs to include. _user_profile: Optional cached profile used when formatting prompts. Returns: str: Markdown-formatted prompt or an error message if generation fails. """ try: # Load model config to get provider and model name model_config_path = root / "configs" / "model" / f"{model_config}.yaml" with open(model_config_path) as f: model_data = yaml.safe_load(f) # Create knowledge base paths knowledge_base_paths = ResourcePaths( persona=root / "prompts" / "persona" / "default.md", instruction_assessment=root / "prompts" / "instruction" / "assessment.md", instruction_conversation=root / "prompts" / "instruction" / "conversation.md", output_format_assessment=root / "configs" / "output_format" / "assessment.yaml", output_format_conversation=root / "configs" / "output_format" / "conversation.yaml", cancer_modules_dir=root / "configs" / "knowledge_base" / "cancer_modules", dx_protocols_dir=root / "configs" / "knowledge_base" / "dx_protocols", ) # Create app config app_config = AppConfig( model=ModelConfig( provider=model_data["provider"], model_name=model_data["model_name"] ), knowledge_base_paths=knowledge_base_paths, selected_cancer_modules=cancer_modules, selected_dx_protocols=dx_protocols, ) # Create factory and get prompt builder factory = SentinelFactory(app_config) # Generate assessment prompt prompt = factory.prompt_builder.build_assessment_prompt() # Format prompt with user data if available user_json = _user_profile.model_dump_json() if _user_profile is not None else "" formatted_prompt = prompt.format(user_data=user_json) return formatted_prompt except Exception as e: return f"Error generating prompt preview: {e!s}" # Generate prompt preview if selected_model: prompt_text = generate_prompt_preview( selected_model, selected_cancers, selected_protocols, st.session_state.user_profile, ) st.subheader("Prompt Preview") st.text_area("System Prompt", value=prompt_text, height=500, disabled=True)