Batching /api/embed juz istnial (Krok 1 fazy mailowej, batch 64). Recon przed Etapem B wykazal w torze backfillu blad blokujacy i dwie luki. BUG (blokujacy dla Etapu B): flush_embed_buffer lapal wylacznie aiohttp.ClientError, a wyczerpanie ClientTimeout(total=...) rzuca goly builtins.TimeoutError, ktory NIE jest jego podklasa (zweryfikowane empirycznie na aiohttp 3.14.3). Zawieszona Ollama — czyli jej udokumentowany failure mode, "przyjmuje polaczenie i milczy" — wywalala caly run nieobsluzonym wyjatkiem, bez breakera i bez flushu threadingu. Na plastrze 50k = utrata zarobionej pracy. Klasy przejsciowe nazwane teraz jawnie w TRANSIENT_EMBED_ERRORS. kb-retrieval: - embed_batch(timeout_s=...) — bound per zadanie, skalowalny z batch size - embed_batch_resilient() — retry z backoffem wykladniczym, a po ich wyczerpaniu probe /api/tags rozstrzyga: backend zywy -> bisekcja izolujaca trujacy chunk (jeden zly tekst kosztowal caly batch 64, bo /api/embed jest all-or-nothing); backend martwy -> natychmiastowe gave_up bez bisekcji, ktora spalilaby 2n-1 zadan i opoznila breaker. EmbeddingDimensionError nigdy nie jest retry'owane. - failed_indices wyprowadzane z wyniku, nie akumulowane per span — przy gave_up w srodku bisekcji porzucone poddrzewo nigdy nie dochodzi do liscia. mail-body-ingest: - breaker liczy give-upy (backend padl), nie dowolne nieudane batche; porazka czesciowa przy zywym backendzie nie przesuwa licznika, bo te chunki i tak zlapie kolejny run przez idempotencje - wiersze zembedowane w umierajacym batchu sa commitowane przed abortem - parametryzacja: --batch-size/--embed-retries/--embed-backoff/--embed-timeout, kazdy z odpowiednikiem env MAIL_INGEST_*; bledna wartosc env = glosny SystemExit - metryka embed_ms_per_chunk (porownywalna miedzy runami, w odroznieniu od sredniej per batch) + embed_requests_total/embed_calls jako sygnal zdrowia mail-body-ingest-bench: nowy entry point, sweep batch size na realnych chunkach. Read-only (SELECT + inferencja, zero sciezki zapisu), warmup przed pomiarem, ten sam zbior chunkow dla kazdego rozmiaru. Czyni liczby z planu §1.4 odtwarzalnymi. Fallback SOLARIA->PIHA dla backfillu SWIADOMIE nie powstaje (potwierdzone przez operatora): 271k chunkow x 790 ms CPU ~ 60 h na 8 GB PIHA dzielonym z HA i Paperlessem. Wlasciwa odpowiedzia na martwy backend jest exit 2 i wznowienie plastra. Tor online (kb-query -> embed_router) zachowuje fallback — rozdzial torow udokumentowany w docstringu embed.py i w kb/services/. Testy: 117 zielonych (62 job + 22 klient embed + reszta pakietow), w tym regresja na TimeoutError, bisekcja, ograniczony koszt przy martwym backendzie i porazka czesciowa nieprzesuwajaca breakera. Bez uruchamiania backfillu. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
33 lines
623 B
TOML
33 lines
623 B
TOML
[build-system]
|
|
requires = ["setuptools>=68"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[project]
|
|
name = "mail-body-ingest"
|
|
version = "0.1.0"
|
|
requires-python = ">=3.11"
|
|
dependencies = [
|
|
"asyncpg>=0.29",
|
|
"aiohttp>=3.9",
|
|
"structlog>=24.1",
|
|
"kb-mail",
|
|
"kb-retrieval",
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
dev = [
|
|
"pytest>=8.1",
|
|
"pytest-asyncio>=0.23",
|
|
]
|
|
|
|
[project.scripts]
|
|
mail-body-ingest = "mail_body_ingest.ingest:main"
|
|
mail-body-ingest-bench = "mail_body_ingest.benchmark:main"
|
|
|
|
[tool.setuptools.packages.find]
|
|
where = ["src"]
|
|
|
|
[tool.pytest.ini_options]
|
|
asyncio_mode = "auto"
|
|
testpaths = ["tests"]
|