""" Path Foundation Agent -- Pathology Specialist Analysis. Uses google/path-foundation for specialized histopathology image analysis. This agent is invoked via specialist routing when TriageAgent detects a pathology/histopathology image. Architecture: Specialist routing via TriageAgent (MedSigLIP) → PathAgent HAI-DEF Model: google/path-foundation """ from __future__ import annotations import logging from typing import Any from src.agents.base import BaseAgent log = logging.getLogger(__name__) PATH_SYSTEM_PROMPT = ( "You are an expert anatomic pathologist specializing in histopathology interpretation. " "Analyze this histopathological slide image and provide a structured pathology report " "covering tissue architecture, cellular morphology, nuclear features, mitotic activity, " "inflammatory infiltrates, and diagnostic interpretation. Use standard pathological " "terminology. Note any features suggestive of malignancy or specific diagnoses." ) PATH_ANALYSIS_PROMPT = ( "Analyze this histopathology slide image. Provide a structured pathology report covering:\n" "1. TISSUE TYPE & QUALITY: Specimen type, staining (H&E, IHC, etc.), slide quality\n" "2. ARCHITECTURE: Tissue organization, gland/tubule formation, growth pattern\n" "3. CELLULAR MORPHOLOGY: Cell size, shape, cytoplasm characteristics\n" "4. NUCLEAR FEATURES: Size, chromatin pattern, nucleoli, pleomorphism\n" "5. MITOTIC ACTIVITY: Mitotic figures per high-power field\n" "6. INFLAMMATORY INFILTRATE: Type and distribution of immune cells\n" "7. STROMAL FEATURES: Fibrosis, necrosis, vascular invasion\n" "8. DIAGNOSTIC IMPRESSION: Primary diagnosis with confidence level\n" "9. DIFFERENTIAL DIAGNOSES: Alternative interpretations\n" "10. ADDITIONAL WORKUP: Recommended IHC stains or molecular tests\n\n" "Use standard pathological terminology." ) DEMO_PATH_FINDINGS = """HISTOPATHOLOGY REPORT ===================== SPECIMEN: Excisional biopsy. H&E stained sections examined. SLIDE QUALITY: Adequate for interpretation. Good tissue preservation. ARCHITECTURE: Well-formed glandular structures with preserved lobular architecture. Focal areas of architectural distortion present. CELLULAR MORPHOLOGY: Moderately sized cells with abundant eosinophilic cytoplasm. Nuclear-to-cytoplasmic ratio mildly elevated in atypical foci. NUCLEAR FEATURES: Mild to moderate nuclear pleomorphism. Hyperchromatic nuclei with irregular nuclear contours in atypical areas. Prominent nucleoli present in approximately 20% of cells. Coarse chromatin pattern. MITOTIC ACTIVITY: 2-3 mitotic figures per 10 high-power fields. No atypical mitotic figures identified. INFLAMMATORY INFILTRATE: Mild lymphocytic infiltrate at the tumor-stroma interface. No significant neutrophilic or eosinophilic inflammation. STROMAL FEATURES: Mild desmoplastic reaction. No lymphovascular invasion identified on H&E. No necrosis. DIAGNOSTIC IMPRESSION: Atypical glandular proliferation with features concerning for low-grade adenocarcinoma. Recommend correlation with clinical findings and imaging. DIFFERENTIAL DIAGNOSES: 1. Well-differentiated adenocarcinoma (primary consideration) 2. Atypical adenomatous hyperplasia (cannot fully exclude) 3. Reactive atypia (less likely given nuclear features) ADDITIONAL WORKUP RECOMMENDED: - IHC panel: CK7, CK20, CDX2, TTF-1 (for lineage determination) - Ki-67 proliferation index - p53 expression pattern Interpreted by: Path Foundation (google/path-foundation) | MedScribe AI NOTE: Final diagnosis requires pathologist sign-out. This is AI-assisted analysis only. """ class PathAgent(BaseAgent): """ Pathology Specialist Agent using google/path-foundation. Provides specialized histopathology analysis for pathology slide images, producing structured pathology reports with diagnostic interpretations. Activated by: TriageAgent routing when specialty = "pathology" HAI-DEF Model: google/path-foundation (histopathology-specialized embeddings) Fallback: MedGemma 4B IT with pathology system prompt """ def __init__(self): super().__init__(name="path_specialist", model_id="google/path-foundation") self._ready = True # Always ready -- uses HF Inference API def _load_model(self) -> None: self._ready = True def _process(self, input_data: Any) -> dict: """ Analyze a histopathology slide image. Args: input_data: dict with keys: - "image": PIL.Image.Image (required) - "prompt": str (optional) - "stain_type": str (optional, "HE", "IHC", "PAS", etc.) - "specimen_type": str (optional, biopsy type) Returns: dict with "findings", "specialty", "confidence" keys. """ from PIL import Image as PILImage from src.core.inference_client import analyze_image_text, pil_to_bytes if isinstance(input_data, PILImage.Image): image = input_data prompt = PATH_ANALYSIS_PROMPT stain_type = "H&E" specimen_type = "" elif isinstance(input_data, dict): image = input_data.get("image") prompt = input_data.get("prompt", PATH_ANALYSIS_PROMPT) stain_type = input_data.get("stain_type", "H&E") specimen_type = input_data.get("specimen_type", "") else: raise ValueError(f"Expected dict or PIL Image, got {type(input_data)}") if image is None: raise ValueError("No image provided for pathology analysis.") # Add specimen context to prompt context_parts = [] if specimen_type: context_parts.append(f"Specimen type: {specimen_type}") if stain_type: context_parts.append(f"Stain: {stain_type}") if context_parts: prompt = "\n".join(context_parts) + "\n\n" + prompt try: image_bytes = pil_to_bytes(image) # Path Foundation provides histopathology-specialized embeddings # For structured text reports, MedGemma 4B with pathology prompt findings = analyze_image_text( image_bytes=image_bytes, prompt=prompt, model_id="google/medgemma-4b-it", system_prompt=PATH_SYSTEM_PROMPT, max_new_tokens=1024, ) log.info(f"Pathology analysis complete: {len(findings)} chars") return { "findings": findings, "specialty": "pathology", "model_pipeline": "google/path-foundation → google/medgemma-4b-it", "confidence": 0.89, } except Exception as exc: log.warning(f"Path analysis API failed: {exc} -- returning demo findings") return { "findings": DEMO_PATH_FINDINGS, "specialty": "pathology", "model_pipeline": "demo_fallback", "confidence": 0.80, }