Files
wehub-resource-sync e4dcfc49aa
Tests / Import Check (Python 3.13) (push) Has been cancelled
Tests / Import Check (Python 3.14) (push) Has been cancelled
Tests / Python Tests (Python 3.11) (push) Has been cancelled
Tests / Python Tests (Python 3.12) (push) Has been cancelled
Tests / Python Tests (Python 3.14) (push) Has been cancelled
Tests / Test Summary (push) Has been cancelled
Tests / Lint and Format (push) Has been cancelled
Tests / Web Node Tests (push) Has been cancelled
Tests / Import Check (Python 3.11) (push) Has been cancelled
Tests / Import Check (Python 3.12) (push) Has been cancelled
Tests / Python Tests (Python 3.13) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:00:43 +08:00

201 lines
6.1 KiB
Python

"""Per-engine environment preflight checks.
Powers the "check whether this engine can run right now" affordance on each
engine's detail page. Every check is best-effort and never raises — a failed
import or missing config becomes a failed/optional check, not an exception.
A check is ``{key, label, ok, detail, optional}``. Overall ``ok`` is true when
every *required* (non-optional) check passes.
"""
from __future__ import annotations
from typing import Any
from .factory import (
DEFAULT_PROVIDER,
GRAPHRAG_PROVIDER,
LIGHTRAG_PROVIDER,
PAGEINDEX_PROVIDER,
normalize_provider_name,
)
def _check(key: str, label: str, ok: bool, detail: str = "", *, optional: bool = False) -> dict:
return {"key": key, "label": label, "ok": bool(ok), "detail": detail, "optional": optional}
def _active_chat_model() -> tuple[str | None, str]:
"""Return ``(model, binding)`` for the active chat LLM, or ``(None, "")``."""
try:
from deeptutor.services.config import resolve_llm_runtime_config
cfg = resolve_llm_runtime_config()
return getattr(cfg, "model", None), str(getattr(cfg, "binding", "") or "")
except Exception:
return None, ""
def _active_embedding() -> tuple[str | None, int]:
"""Return ``(model, dim)`` for the active embedding model, or ``(None, 0)``."""
try:
from deeptutor.services.embedding import get_embedding_config
cfg = get_embedding_config()
return getattr(cfg, "model", None), int(getattr(cfg, "dim", 0) or 0)
except Exception:
return None, 0
def _llamaindex_preflight() -> dict:
emb_model, emb_dim = _active_embedding()
checks = [
_check(
"embedding",
"Active embedding model",
bool(emb_model) and emb_dim > 0,
f"{emb_model} · {emb_dim}d" if emb_model else "Configure one in the model catalog.",
)
]
try:
from .pipelines.llamaindex.retrievers import _import_bm25_retriever
bm25_ok = _import_bm25_retriever() is not None
except Exception:
bm25_ok = False
checks.append(
_check(
"bm25",
"BM25 hybrid retrieval",
bm25_ok,
"Installed." if bm25_ok else "Not installed — hybrid falls back to vector-only.",
optional=True,
)
)
return _finalize(checks)
def _pageindex_preflight() -> dict:
try:
from .pipelines.pageindex.config import DEFAULT_API_BASE_URL, get_pageindex_config
cfg = get_pageindex_config(require_key=False)
configured = bool(cfg.api_key)
base = cfg.api_base_url or DEFAULT_API_BASE_URL
except Exception:
configured, base = False, ""
return _finalize(
[
_check(
"api_key",
"API key configured",
configured,
base if configured else "Add a PageIndex API key under Credentials.",
)
]
)
def _graphrag_preflight() -> dict:
try:
from .pipelines.graphrag.config import is_graphrag_available
installed = is_graphrag_available()
except Exception:
installed = False
emb_model, emb_dim = _active_embedding()
chat_model, _ = _active_chat_model()
return _finalize(
[
_check(
"package",
"GraphRAG package installed",
installed,
"Installed." if installed else "pip install 'deeptutor[graphrag]'",
),
_check(
"chat",
"Active chat model",
bool(chat_model),
chat_model or "Configure one in the model catalog.",
),
_check(
"embedding",
"Active embedding model",
bool(emb_model) and emb_dim > 0,
f"{emb_model} · {emb_dim}d" if emb_model else "Configure one in the model catalog.",
),
]
)
def _lightrag_preflight() -> dict:
try:
from .pipelines.lightrag.config import is_lightrag_available
installed = is_lightrag_available()
except Exception:
installed = False
emb_model, emb_dim = _active_embedding()
chat_model, binding = _active_chat_model()
vision_ok = False
if chat_model:
try:
from deeptutor.services.llm.capabilities import supports_vision
vision_ok = supports_vision(binding, chat_model)
except Exception:
vision_ok = False
return _finalize(
[
_check(
"package",
"RAG-Anything package installed",
installed,
"Installed." if installed else "pip install 'deeptutor[rag-lightrag]'",
),
_check(
"chat",
"Active chat model",
bool(chat_model),
chat_model or "Configure one in the model catalog.",
),
_check(
"embedding",
"Active embedding model",
bool(emb_model) and emb_dim > 0,
f"{emb_model} · {emb_dim}d" if emb_model else "Configure one in the model catalog.",
),
_check(
"vision",
"Vision model for multimodal",
vision_ok,
"Active chat model supports vision."
if vision_ok
else "Active chat model has no vision — multimodal documents fall back to text.",
optional=True,
),
]
)
def _finalize(checks: list[dict]) -> dict:
ok = all(c["ok"] for c in checks if not c["optional"])
return {"ok": ok, "checks": checks}
_PREFLIGHTS = {
DEFAULT_PROVIDER: _llamaindex_preflight,
PAGEINDEX_PROVIDER: _pageindex_preflight,
GRAPHRAG_PROVIDER: _graphrag_preflight,
LIGHTRAG_PROVIDER: _lightrag_preflight,
}
def engine_preflight(provider: str) -> dict[str, Any]:
"""Run the requirement checks for ``provider`` and return the report."""
return _PREFLIGHTS[normalize_provider_name(provider)]()
__all__ = ["engine_preflight"]