refactor: troca PDF+OCR por corpus USFX em domínio público

- corpus/: Almeida (João Ferreira de Almeida) em USFX, domínio público,
  66 livros / 1189 capítulos / 31098 versículos, versionado com SHA-256
- app/corpus.py: parser USFX (texto no tail de <v/>), nomes canônicos dos
  livros, aliases (abreviaturas e numerais romanos), VerseChunk sem página
- indexer: descobre *.xml em CORPUS_DIR, progresso em versículos, lote
  configurável, manifesto incremental por SHA-256
- remove extraction.py, parallel.py, bible_parser.py, Tesseract e PyMuPDF
- campo page removido de Source/SearchResult/StatusResponse e do frontend
- embedder: propriedade name; status reporta o embedder em uso, não o do .env
- create_app constrói o embedder ANTES do store (o default HashEmbedder do
  VectorStore impedia o modelo configurado de ser carregado em produção)
- fallback do modelo agora aparece em /api/status.errors
- torch 2.6.0 + transformers 5.22.1 pinados (transformers 5.x exige torch>=2.6)
This commit is contained in:
omp committed 2026-11-02 11:16:07 -03:00
1 parent 621679cee5
commit 2043d5ddcf
34 files changed
+34561 -1842

No files matched your search

+5 -18
View File
@@ -18,7 +18,7 @@ class Settings(BaseSettings):
)
# Caminhos
pdf_dir: Path = Path("/data/pdfs")
corpus_dir: Path = Path("/data/corpus")
vector_db_dir: Path = Path("/data/vector_db")
# Provedor de LLM: ollama | openai | groq | anthropic | stub
@@ -44,12 +44,10 @@ class Settings(BaseSettings):
min_similarity: float = 0.35
collection_name: str = "biblia"
# OCR
ocr_dpi: int = 200
ocr_language: str = "por+eng"
ocr_timeout: int = 120
ocr_workers: int = 4
min_legible_ratio: float = 0.35
# Ingestão
# Tamanho do lote gravado no banco vetorial por vez: limita a memória e dá
# granularidade ao progresso da indexação.
index_batch_size: int = 512
# API
cors_origins: str = "http://localhost:8080,http://127.0.0.1:8080"
@@ -57,24 +55,13 @@ class Settings(BaseSettings):
max_message_length: int = 4000
max_history_turns: int = 10
# Limites de ingestão
max_pdf_bytes: int = 200 * 1024 * 1024
# Indexação automática na inicialização
auto_index: bool = True
@property
def ocr_cache_dir(self) -> Path:
return self.vector_db_dir / "ocr_cache"
@property
def manifest_path(self) -> Path:
return self.vector_db_dir / "manifest.json"
@property
def book_index_path(self) -> Path:
return self.vector_db_dir / "book_index.json"
@property
def cors_origin_list(self) -> list[str]:
return [origin.strip() for origin in self.cors_origins.split(",") if origin.strip()]