Fix doctor's vector-index check to match documented guidance

This commit is contained in:
Yiorgis Gozadinos 2026-06-23 15:39:44 +03:00
parent 195dce7511
commit f22341f003
No known key found for this signature in database
2 changed files with 17 additions and 9 deletions

View file

@ -548,17 +548,20 @@ def _check_vector_index(stats: dict) -> CheckResult:
chunks = stats["chunks"] chunks = stats["chunks"]
num_chunks = chunks.get("num_rows", 0) num_chunks = chunks.get("num_rows", 0)
if not chunks.get("has_vector_index"): if not chunks.get("has_vector_index"):
if num_chunks >= 256: if num_chunks >= 100_000:
return CheckResult( return CheckResult(
name="vector_index", name="vector_index",
severity=Severity.WARN, severity=Severity.WARN,
message="No vector index; similarity search falls back to a scan.", message=(
"No vector index on a large collection; "
"similarity search scans every chunk and may be slow."
),
remediation="haiku-rag create-index", remediation="haiku-rag create-index",
) )
return CheckResult( return CheckResult(
name="vector_index", name="vector_index",
severity=Severity.OK, severity=Severity.OK,
message=f"No vector index yet (need {256 - num_chunks} more chunks).", message="No vector index; similarity search is exact (brute-force).",
) )
unindexed = chunks.get("num_unindexed_rows", 0) unindexed = chunks.get("num_unindexed_rows", 0)
if unindexed > 0: if unindexed > 0:
@ -663,7 +666,7 @@ async def _probe_endpoint(
def _endpoint_result( def _endpoint_result(
url: str, entry: dict, reachable: bool, error: str | None, payload: dict | None entry: dict, reachable: bool, error: str | None, payload: dict | None
) -> CheckResult: ) -> CheckResult:
kind = entry["kind"] kind = entry["kind"]
display = entry["display"] display = entry["display"]
@ -709,9 +712,7 @@ async def run_provider_checks(config: AppConfig) -> list[CheckResult]:
*(_probe_endpoint(client, url) for url in targets) *(_probe_endpoint(client, url) for url in targets)
) )
for url, (reachable, error, payload) in zip(targets, probes): for url, (reachable, error, payload) in zip(targets, probes):
results.append( results.append(_endpoint_result(targets[url], reachable, error, payload))
_endpoint_result(url, targets[url], reachable, error, payload)
)
for provider in sorted(local): for provider in sorted(local):
results.append( results.append(

View file

@ -593,14 +593,21 @@ def test_embedding_drift_ok_without_stored_identity():
assert _check_embedding_drift({}, _config()).severity is Severity.OK assert _check_embedding_drift({}, _config()).severity is Severity.OK
def test_vector_index_ok_below_threshold(): def test_vector_index_ok_without_index_on_small_collection():
stats = {"chunks": {"num_rows": 10, "has_vector_index": False}} stats = {"chunks": {"num_rows": 10, "has_vector_index": False}}
assert _check_vector_index(stats).severity is Severity.OK assert _check_vector_index(stats).severity is Severity.OK
def test_vector_index_warns_when_missing_above_threshold(): def test_vector_index_ok_without_index_on_moderate_collection():
stats = {"chunks": {"num_rows": 300, "has_vector_index": False}} stats = {"chunks": {"num_rows": 300, "has_vector_index": False}}
result = _check_vector_index(stats) result = _check_vector_index(stats)
assert result.severity is Severity.OK
assert result.remediation is None
def test_vector_index_warns_for_large_collection_without_index():
stats = {"chunks": {"num_rows": 100_000, "has_vector_index": False}}
result = _check_vector_index(stats)
assert result.severity is Severity.WARN assert result.severity is Severity.WARN
assert result.remediation == "haiku-rag create-index" assert result.remediation == "haiku-rag create-index"