Spaces:
Runtime error
Runtime error
| """FastAPI application exposing cancer risk assessment endpoints.""" | |
| from pathlib import Path | |
| from fastapi import FastAPI, HTTPException | |
| from sentinel.config import AppConfig, ModelConfig, ResourcePaths | |
| from sentinel.factory import SentinelFactory | |
| from sentinel.models import InitialAssessment | |
| from sentinel.user_input import UserInput | |
| app = FastAPI( | |
| title="Cancer Risk Assessment Assistant", | |
| description="API for assessing cancer risks using LLMs.", | |
| ) | |
| # Define base paths relative to the project root | |
| BASE_DIR = Path(__file__).resolve().parents[2] # Go up to project root | |
| CONFIGS_DIR = BASE_DIR / "configs" | |
| PROMPTS_DIR = BASE_DIR / "prompts" | |
| def create_knowledge_base_paths() -> ResourcePaths: | |
| """Build resource path configuration resolved from the repository root. | |
| Returns: | |
| ResourcePaths: Paths pointing to persona, prompt, and configuration | |
| assets required by the API routes. | |
| """ | |
| return ResourcePaths( | |
| persona=PROMPTS_DIR / "persona" / "default.md", | |
| instruction_assessment=PROMPTS_DIR / "instruction" / "assessment.md", | |
| instruction_conversation=PROMPTS_DIR / "instruction" / "conversation.md", | |
| output_format_assessment=CONFIGS_DIR / "output_format" / "assessment.yaml", | |
| output_format_conversation=CONFIGS_DIR / "output_format" / "conversation.yaml", | |
| cancer_modules_dir=CONFIGS_DIR / "knowledge_base" / "cancer_modules", | |
| dx_protocols_dir=CONFIGS_DIR / "knowledge_base" / "dx_protocols", | |
| ) | |
| async def read_root() -> dict: | |
| """Return a simple greeting message. | |
| Returns: | |
| dict: A dictionary containing a greeting message. | |
| """ | |
| return {"message": "Hello, world!"} | |
| async def assess( | |
| provider: str, | |
| user_input: UserInput, | |
| model: str | None = None, | |
| cancer_modules: list[str] | None = None, | |
| dx_protocols: list[str] | None = None, | |
| ) -> InitialAssessment: | |
| """Assess cancer risk for a user. | |
| Args: | |
| provider (str): LLM provider identifier (for example ``"openai"`` or | |
| ``"anthropic"``). | |
| user_input (UserInput): Structured demographics and clinical | |
| information supplied by the client. | |
| model (str | None): Optional model name overriding the provider | |
| default. | |
| cancer_modules (list[str] | None): Optional list of cancer module slugs | |
| to include in the knowledge base. | |
| dx_protocols (list[str] | None): Optional list of diagnostic protocol | |
| slugs to include. | |
| Returns: | |
| InitialAssessment: Parsed model output describing the initial | |
| assessment. | |
| Raises: | |
| HTTPException: 400 for invalid input, 500 for unexpected errors. | |
| """ | |
| try: | |
| # Create knowledge base paths | |
| knowledge_base_paths = create_knowledge_base_paths() | |
| # Set default model name if not provided | |
| if model is None: | |
| model_defaults = { | |
| "openai": "gpt-4o-mini", | |
| "anthropic": "claude-3-5-sonnet-20241022", | |
| "google": "gemini-1.5-pro", | |
| } | |
| model = model_defaults.get(provider, "gpt-4o-mini") | |
| # Set default modules if not provided | |
| if cancer_modules is None: | |
| cancer_modules_dir = knowledge_base_paths.cancer_modules_dir | |
| cancer_modules = [p.stem for p in cancer_modules_dir.glob("*.yaml")] | |
| if dx_protocols is None: | |
| dx_protocols_dir = knowledge_base_paths.dx_protocols_dir | |
| dx_protocols = [p.stem for p in dx_protocols_dir.glob("*.yaml")] | |
| # Create AppConfig | |
| app_config = AppConfig( | |
| model=ModelConfig(provider=provider, model_name=model), | |
| knowledge_base_paths=knowledge_base_paths, | |
| selected_cancer_modules=cancer_modules, | |
| selected_dx_protocols=dx_protocols, | |
| ) | |
| # Create factory and conversation manager | |
| factory = SentinelFactory(app_config) | |
| conversation_manager = factory.create_conversation_manager() | |
| # Run assessment | |
| response = conversation_manager.initial_assessment(user_input) | |
| return response | |
| except ValueError as e: | |
| raise HTTPException(status_code=400, detail=str(e)) | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Internal Server Error: {e!s}") | |