fix(wiki): LLM error handling — graceful degradation on Ollama unavailable

Wrap llm.generate() in compile_concept with a broad try/except;
log a warning and return an empty ConceptPage (no crash) when the
LLM endpoint is unreachable. Add logging module import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tarik Moussa
2026-06-14 03:47:04 +02:00
parent 946a80418e
commit 89228a1f62

View File

@@ -11,12 +11,14 @@ Compile-state (hash tracking for incremental re-runs) is persisted to
Graceful degradation: Graceful degradation:
- Missing ``formulas`` table (F-09 not present) → no formula embedding, no crash. - Missing ``formulas`` table (F-09 not present) → no formula embedding, no crash.
- Missing ``verify_citations`` (F-10 not present) → local substring grounding check. - Missing ``verify_citations`` (F-10 not present) → local substring grounding check.
- LLM unavailable (httpx.ConnectError or any exception) → empty ConceptPage, no crash.
""" """
from __future__ import annotations from __future__ import annotations
import hashlib import hashlib
import json import json
import logging
import re import re
import textwrap import textwrap
from dataclasses import dataclass, field from dataclasses import dataclass, field
@@ -28,6 +30,8 @@ import yaml
from codex.config import get_settings from codex.config import get_settings
logger = logging.getLogger(__name__)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Dataclasses # Dataclasses
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -442,7 +446,11 @@ def compile_concept(
h = _chunk_hash(chunks) h = _chunk_hash(chunks)
prompt = _build_synthesis_prompt(concept, chunks) prompt = _build_synthesis_prompt(concept, chunks)
try:
raw_output = llm.generate(prompt, model=settings.wiki_llm_model) raw_output = llm.generate(prompt, model=settings.wiki_llm_model)
except Exception as exc: # noqa: BLE001
logger.warning("LLM unavailable (%s): skipping concept %s", exc, concept.slug)
return ConceptPage(concept=concept, markdown="", claims=[], chunk_hash=h)
claims = _parse_claims(raw_output) claims = _parse_claims(raw_output)
claims = _run_grounding_guard(claims, chunks) claims = _run_grounding_guard(claims, chunks)