"""Define domain ports for retrieval.""" from __future__ import annotations from abc import ABC, abstractmethod from app.domain.documents.models import Chunk from .models import RetrievalQuery, RetrievedChunk # Keep domain contracts explicit so adapters can swap implementations cleanly. class EmbeddingProvider(ABC): """Provide the Embedding Provider provider.""" @abstractmethod def embed_texts(self, texts: list[str]) -> list[list[float]]: """Embed texts for the Embedding Provider instance.""" pass @abstractmethod def embed_query(self, text: str) -> list[float]: """Embed query for the Embedding Provider instance.""" pass class VectorIndex(ABC): """Provide the Vector Index index implementation.""" @abstractmethod def upsert(self, chunks: list[Chunk], vectors: list[list[float]]) -> int: """Handle upsert for the Vector Index instance.""" pass @abstractmethod def delete_by_document(self, doc_id: str) -> int: """Delete by document for the Vector Index instance.""" pass @abstractmethod def search(self, query_vector: list[float], top_k: int, filters: str | None = None) -> list[RetrievedChunk]: """Handle search for the Vector Index instance.""" pass @abstractmethod def health(self) -> dict: """Handle health for the Vector Index instance.""" pass class Retriever(ABC): """Provide the Retriever retriever.""" @abstractmethod def retrieve(self, query: RetrievalQuery) -> list[RetrievedChunk]: """Handle retrieve for the Retriever instance.""" pass @abstractmethod def search(self, query: str, top_k: int, filters: str | None = None) -> list[RetrievedChunk]: """Handle search for the Retriever instance.""" pass