from __future__ import annotations from functools import lru_cache from typing import Literal, Protocol from pydantic import BaseModel from app.core.config import get_settings EvidenceState = Literal["grounded", "insufficient", "unavailable"] class SourceCard(BaseModel): document_id: str title: str version: str section: str excerpt: str class GroundedAnswer(BaseModel): answer: str evidence_state: EvidenceState sources: list[SourceCard] provider: str correlation_id: str class KnowledgeHealth(BaseModel): provider: str available: bool detail: str tenant: str workspace: str collection: str # A provider may be healthy without exposing a corpus-size endpoint. `None` means # unknown, never "zero procedures". document_count: int | None class KnowledgeProvider(Protocol): name: str def health(self, language: str = "en-GB") -> KnowledgeHealth: ... def ask( self, question: str, correlation_id: str, language: str = "en-GB" ) -> GroundedAnswer: ... @lru_cache def get_knowledge_provider() -> KnowledgeProvider: settings = get_settings() if settings.knowledge_provider == "ragcore": from app.services.knowledge.ragcore import RAGcoreKnowledgeProvider return RAGcoreKnowledgeProvider() from app.services.knowledge.demo import DemoKnowledgeProvider return DemoKnowledgeProvider()