homelab-codex-ws/services/kb-query/service.yaml
oskar b1b6692382 feat(kb-query): domyslny mode /search = hybrid (DoD (d) fazy mailowej)
Eval na pelnym korpusie 2026-08-06 (187 025 zembedowanych chunkow mailowych
w HNSW) dal PASS: kryterium 1 (regresja paperless) bez degradacji zadnego
istniejacego hitu we flat ani w hybrid, mailowe hit@3 5/5. Koszt hybrydy to
jedno dodatkowe zapytanie SQL na wyszukiwanie. Surowe wyniki:
eval-http-2026-08-06.json / eval-direct-2026-08-06.json w ~/kb/mail/ingest-logs
na PIHA (niecommitowane, artefakt runu).

- app/main.py: Query("cascade") -> Query("hybrid"); pattern bez zmian, wiec
  jawne ?mode=cascade i ?mode=flat dzialaja dokladnie jak dotad.
- app/static/app.js: przy odznaczonym "tryb flat (debug)" UI nie wysyla juz
  parametru mode w ogole -- dziedziczy default API. Default zdefiniowany
  w jednym miejscu (serwer), nie zduplikowany w JS.
- testy: nowa klasa TestSearchEndpointModeDefault (TestClient bez lifespan,
  fake pool/router) sprawdza kontrakt HTTP -- brak mode => tor hybrid
  (weryfikowany po obecnosci koperty gmail osiagalnej wylacznie galezia
  hybrid, nie po samej etykiecie), jawne mode=flat / mode=cascade => stare
  tory, nieznany mode => 422. Frontend: buildSearchUrl pomija mode gdy brak.
- docs: kb/services/kb-query.md (tabela trybow + endpoint + przyklad
  odpowiedzi + opis przelacznika w UI), env.example/service.yaml (komentarze
  SUMMARY_MODEL; default mode nie jest konfigurowalny przez env),
  kb/phases/kb-m5-faza-mailowa.md (DoD (d) SPELNIONE 2026-08-06 + wzmianki
  w Kroku 3, Wyniku bramki, decyzjach Etapu B i tabeli planu).

Weryfikacja: pytest services/kb-query -> 46 passed; node --test
tests/frontend/app.test.js -> 6/6; docker build OK + smoke run (uvicorn
startuje, bez KB_DSN swiadomie konczy sie RuntimeError z env.example).
Deploy NIE wykonany -- operator wdraza z mastera na PIHA po mergu.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 13:30:06 +02:00

42 lines
2.5 KiB
YAML

service:
name: kb-query
owner_node: piha
role: kb-search-api # module 5 phase 4: first user-facing HTTP entry point to the KB (API + minimal search UI, plan §7)
exposure: private # LAN/Tailscale only, npm@PIHA vhost (kb.kapala.org) is a later step
dependencies:
- kb-postgres
- ollama-piha # soft: local CPU embed fallback (Krok 2) -- kb-query starts without it
- forgejo # OIDC identity provider, wired in a later step (plan §8); not yet enforced
# ollama@SOLARIA is an external, optional runtime dependency (primary embed backend), not
# a hard dependency here -- SOLARIA sleeps ~16 h/day; the embed router (app/embed_router.py)
# then falls back to ollama-piha on this host. /search 503s only when BOTH legs are down;
# /healthz always answers (same tolerance pattern as llm-gateway).
ports:
- container: 8080
host: 8230 # LAN_BIND_IP only, never 0.0.0.0
protocol: tcp
healthcheck:
type: http
endpoint: http://192.168.31.5:8230/healthz # LAN bind — localhost does not answer
interval: 30s
timeout: 10s
retries: 5
restart_policy: unless-stopped
persistence:
paths: [] # stateless — kb-postgres holds all state
runtime:
config_files:
- .env # KB_DSN, LAN_BIND_IP (gitignored, from env.example)
env_vars:
- LAN_BIND_IP # required — compose port-bind interpolation
- KB_DSN # required — asyncpg DSN for kb-postgres@PIHA
- EMBED_PRIMARY_URL # optional — primary embed backend, defaults to http://solaria:11434
- EMBED_FALLBACK_URL # optional — local fallback (ollama-piha); empty disables the fallback leg
- EMBED_PRIMARY_NAME # optional — log/response label, defaults to solaria
- EMBED_FALLBACK_NAME # optional — log/response label, defaults to piha
- EMBED_HEALTH_TTL_S # optional — primary health verdict cache, defaults to 30
- EMBED_HEALTH_TIMEOUT_S # optional — /api/tags probe timeout, defaults to 1.5
- EMBED_PRIMARY_TIMEOUT_S # optional — hard timeout for a primary embed call, defaults to 3
- EMBED_MODEL # optional — defaults to bge-m3; startup invariant vs document_chunk/document_summary + per-backend /api/tags check
- SUMMARY_MODEL # optional — defaults to claude-haiku-4-5; stage-1 summary model for the cascade/hybrid paths (hybrid = default mode since 2026-08-06)