fix(ingest): warn when provider=none disables in-cluster; precise model fallback

Address claude-review round 4 on #922:

- Important 1: build_ocr_backend now warns when gateway_only + provider=none +
  DOCUMENT_OCR_INCLUSTER_ENABLED=true — provider=none suppresses the gateway-only
  in-cluster tier too (it never uses the mistral provider), which surprises an
  operator who set none just to disable Mistral. Restructured so the gateway_only
  branch is evaluated before the generic provider=none return. Two tests cover
  the warn-when-enabled / silent-when-disabled cases.
- Nit 3: model fallback uses `model if model is not None else ...` (not `or`), so
  an empty model string no longer silently falls back to the upstream default and
  misroutes a per-tier rung. Test added.
- Nit 4: the no-surya-literal guard now uses rglob so future
  document_processors/ subdirs are covered.

Deferred (pre-existing / out of scope for this PR):
- Important 2 (_GatewayOcrBackend opens a new httpx.AsyncClient per ocr() call):
  a pre-existing pattern affecting both OCR rungs; a shared pooled client needs
  careful per-pod lifecycle handling (event-loop binding, aclose) and is better
  as its own change. Follow-up.
- Nit 5 (_MANAGED_QUEUES vs the CLI all-queues list): the two sets differ
  deliberately (the CLI list includes ingest-maintenance, _MANAGED_QUEUES does
  not), so a shared constant wouldn't cleanly dedupe them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-06-18 00:56:02 +02:00
co-authored by Claude Opus 4.8
parent ebbf905dc5
commit 0614709960
2 changed files with 68 additions and 4 deletions
@@ -239,11 +239,22 @@ def build_ocr_backend(
disabled (warn) rather than misrouted to a direct backend that can't serve it.
"""
provider = settings.document_ocr_provider
model = model or settings.document_ocr_model
if provider == "none":
return None
# `is not None` (not truthiness): an empty model string must NOT silently fall
# back to the upstream default and misroute a per-tier rung.
model = model if model is not None else settings.document_ocr_model
if gateway_only:
# The in-cluster tier is gateway-only and never touches the `mistral`
# provider, but provider=none still suppresses it. Warn so an operator who
# set provider=none to disable Mistral doesn't silently lose the GPU tier.
if provider == "none":
if settings.document_ocr_incluster_enabled:
logger.warning(
"DOCUMENT_OCR_PROVIDER=none disables in-cluster OCR even with "
"DOCUMENT_OCR_INCLUSTER_ENABLED=true; set it to 'gateway' or "
"'auto' to keep the in-cluster tier"
)
return None
if settings.embedding_gateway_url:
return _GatewayOcrBackend(
settings.embedding_gateway_url,
@@ -256,6 +267,9 @@ def build_ocr_backend(
)
return None
if provider == "none":
return None
if provider in ("gateway", "auto") and settings.embedding_gateway_url:
return _GatewayOcrBackend(
settings.embedding_gateway_url,