from datetime import datetime from typing import Literal from uuid import UUID from pydantic import BaseModel, Field from app.schemas.catalog import Category, Input class RetrievalRequest(Input): query: str = Field(min_length=1, max_length=500) mode: Literal["keyword"] = "keyword" top_k: int = Field(default=5, ge=1, le=20) category: Category | None = None class RetrievalHit(BaseModel): rank: int knowledge_id: int knowledge_version: int document_id: int | None document_version: int | None source_id: int | None source_version: int | None source_name: str | None source_url: str title: str category: str snippet: str snippet_start: int snippet_end: int score: float matched_terms: list[str] class RetrievalConfig(BaseModel): tokenizer: str scorer: str k1: float b: float title_weight: int stopwords_version: str class RetrievalResponse(BaseModel): run_id: UUID query: str mode: Literal["keyword"] status: Literal["ok", "no_evidence"] top_k: int category: str | None query_terms: list[str] corpus_size: int corpus_fingerprint: str total_hits: int results: list[RetrievalHit] elapsed_ms: float created_at: datetime config: RetrievalConfig