sentinel / apps /streamlit_ui /pages /2_Configuration.py
jeuko's picture
Sync from GitHub (main)
8018595 verified
"""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)