RandomZ / app /optimization /health_warnings.py
StormShadow308's picture
feat: RAG upload sanitisation layer before vector indexing
e561e67
Raw
History Blame Contribute Delete
3.77 kB
"""Runtime configuration warnings for Phase 1/2 feature alignment."""
from __future__ import annotations
from app.config import settings
from app.redis_client import job_queue_enabled, redis_configured
from app.retrieval.semantic_cache import is_semantic_cache_active
def collect_optimization_warnings() -> list[str]:
"""Return human-readable misconfiguration / feature-gap warnings."""
warnings: list[str] = []
backend = (settings.vectorstore_backend or "faiss").strip().lower()
if settings.enable_async_pipeline and backend != "qdrant":
warnings.append(
"ENABLE_ASYNC_PIPELINE=true but VECTORSTORE_BACKEND is not qdrant; "
"hybrid retrieval and semantic cache require Qdrant."
)
if settings.semantic_cache_enabled and not is_semantic_cache_active():
warnings.append(
"SEMANTIC_CACHE_ENABLED=true but semantic cache is inactive "
"(requires VECTORSTORE_BACKEND=qdrant)."
)
if settings.enable_hybrid_retrieval and backend != "qdrant":
warnings.append(
"ENABLE_HYBRID_RETRIEVAL=true has no effect unless VECTORSTORE_BACKEND=qdrant."
)
if (
settings.enable_speculative_executor
and settings.enable_async_pipeline
and settings.notes_only_generation
and not settings.agentic_inspector_when_notes_only
):
warnings.append(
"ENABLE_SPECULATIVE_EXECUTOR=true but notes_only_generation=true forces the "
"standard pipeline on POST /generate (inspector/speculation skipped). "
"Set AGENTIC_INSPECTOR_WHEN_NOTES_ONLY=true or NOTES_ONLY_GENERATION=false."
)
if settings.enable_prompt_caching and not settings.enable_async_pipeline:
warnings.append(
"ENABLE_PROMPT_CACHING=true requires ENABLE_ASYNC_PIPELINE=true."
)
if settings.enable_temporal_workflow and "sqlite" in (settings.database_url or "").lower():
if not settings.allow_sqlite_parallel_sections:
warnings.append(
"Temporal + SQLite: parallel section activities are disabled by default; "
"use PostgreSQL for parallel Temporal sections."
)
if backend == "qdrant":
from pathlib import Path
faiss_dir = Path(settings.faiss_index_path)
try:
if faiss_dir.is_dir() and any(faiss_dir.iterdir()):
warnings.append(
"FAISS index data still present on disk; re-ingest into Qdrant "
"(scripts/reingest_qdrant.py) if you migrated backends."
)
except OSError:
pass
if settings.enable_job_queue and not redis_configured():
warnings.append(
"ENABLE_JOB_QUEUE=true requires REDIS_URL; "
"generation will fall back to in-process tasks until Redis is configured."
)
if settings.enable_rag_upload_sanitisation and not (settings.openai_api_key or "").strip():
warnings.append(
"ENABLE_RAG_UPLOAD_SANITISATION=true but OPENAI_API_KEY is unset; "
"uploads are indexed using regex-only redaction (weaker than the LLM sanitiser)."
)
return warnings
def collect_optimization_hints() -> list[str]:
"""Non-blocking operational hints (not misconfigurations)."""
hints: list[str] = []
if job_queue_enabled():
hints.append(
"Job queue enabled: ensure `python jobs_worker.py` is running "
"(or `docker compose --profile redis --profile jobs up`)."
)
if redis_configured() and not settings.enable_job_queue:
hints.append(
"REDIS_URL is set: distributed rate limits are active across API replicas."
)
return hints