fix(searcher): preserve backend diagnostics before HNSW probe

This commit is contained in:
Igor Lins e Silva 2026-07-14 19:37:32 -03:00
parent 2c6cecf1fe
commit 8a87fc66e2
2 changed files with 37 additions and 2 deletions

View File

@ -498,7 +498,16 @@ def search(query: str, palace_path: str, wing: str = None, room: str = None, n_r
# collection.count(); both happen before the old query-only guard and can
# hit the same native crash. Non-Chroma backends never use Chroma's HNSW
# files or sqlite-specific fallback and proceed normally.
if resolve_backend_name(palace_path) == "chroma" and _hnsw_capacity_diverged(palace_path):
try:
backend_name = resolve_backend_name(palace_path)
except (BackendMismatchError, KeyError):
# Preserve _open_collection_or_explain's state-specific diagnostics
# for mixed artifacts and unknown backend selections. This probe is
# only an early Chroma safety fence; it must not become a second,
# less-helpful backend validation path.
backend_name = None
if backend_name == "chroma" and _hnsw_capacity_diverged(palace_path):
return _print_search_results_bm25_only(query, palace_path, wing, room, n_results)
col = _open_collection_or_explain(palace_path, opener=get_collection)

View File

@ -11,7 +11,14 @@ import pytest
from _chroma_palace_helper import make_minimal_chroma_sqlite
from mempalace.searcher import SearchError, build_where_filter, search, search_memories
from mempalace.backends import BackendMismatchError
from mempalace.searcher import (
SearchError,
build_where_filter,
get_collection,
search,
search_memories,
)
# ── build_where_filter (unit) ──────────────────────────────────────────
@ -616,3 +623,22 @@ class TestSearchCLI:
mock_probe.assert_not_called()
mock_col.query.assert_called_once()
assert "backend-native result" in capsys.readouterr().out
@pytest.mark.parametrize(
"resolution_error",
[BackendMismatchError("mixed backend artifacts"), KeyError("unknown_backend")],
)
def test_search_delegates_backend_resolution_errors_to_open_diagnostic(
self, fake_palace_path, resolution_error
):
"""The early HNSW fence must not replace normal CLI diagnostics."""
with (
patch("mempalace.searcher.resolve_backend_name", side_effect=resolution_error),
patch("mempalace.searcher._hnsw_capacity_diverged") as mock_probe,
patch("mempalace.searcher._open_collection_or_explain", return_value=None) as mock_open,
):
with pytest.raises(SearchError):
search("anything", fake_palace_path)
mock_probe.assert_not_called()
mock_open.assert_called_once_with(fake_palace_path, opener=get_collection)