Programmatic search — returns a dict instead of printing. Used by the MCP server and other callers that need data. Args: query: Natural language search query. palace_path: Path to the ChromaDB palace directory. wing: Optional wing filter. room: Optional room
(
query: str,
palace_path: str,
wing: str = None,
room: str = None,
source_file: str = None,
n_results: int = 5,
max_distance: float = 0.0,
vector_disabled: bool = False,
candidate_strategy: str = "vector",
collection_name: str = None,
)
| 1034 | |
| 1035 | |
| 1036 | def search_memories( |
| 1037 | query: str, |
| 1038 | palace_path: str, |
| 1039 | wing: str = None, |
| 1040 | room: str = None, |
| 1041 | source_file: str = None, |
| 1042 | n_results: int = 5, |
| 1043 | max_distance: float = 0.0, |
| 1044 | vector_disabled: bool = False, |
| 1045 | candidate_strategy: str = "vector", |
| 1046 | collection_name: str = None, |
| 1047 | ) -> dict: |
| 1048 | """Programmatic search — returns a dict instead of printing. |
| 1049 | |
| 1050 | Used by the MCP server and other callers that need data. |
| 1051 | |
| 1052 | Args: |
| 1053 | query: Natural language search query. |
| 1054 | palace_path: Path to the ChromaDB palace directory. |
| 1055 | wing: Optional wing filter. |
| 1056 | room: Optional room filter. |
| 1057 | source_file: Optional exact source_file filter. Matches the full |
| 1058 | stored source_file value verbatim (#1815). |
| 1059 | n_results: Max results to return. |
| 1060 | max_distance: Max cosine distance threshold. The palace collection uses |
| 1061 | cosine distance (hnsw:space=cosine) — 0 = identical, 2 = opposite. |
| 1062 | Results with distance > this value are filtered out. A value of |
| 1063 | 0.0 disables filtering. Typical useful range: 0.3–1.0. |
| 1064 | vector_disabled: When True, route to the sqlite-only BM25 fallback |
| 1065 | (#1222). Set by the MCP server when the HNSW capacity probe |
| 1066 | detects a divergence that would segfault chromadb on segment |
| 1067 | load. |
| 1068 | candidate_strategy: How candidates for the hybrid re-rank are gathered. |
| 1069 | |
| 1070 | * ``"vector"`` (default) — preserves historical behavior: top |
| 1071 | ``n_results * 3`` rows from the vector index are the rerank pool. |
| 1072 | Cheap; works well when query and target docs agree in the |
| 1073 | embedding space. |
| 1074 | * ``"union"`` — also pull top ``n_results * 3`` lexical candidates |
| 1075 | through the backend's ``lexical_search`` capability and merge |
| 1076 | them into the rerank pool (deduped by source_file). Catches docs |
| 1077 | with strong BM25 signal that are vector-distant from the query. |
| 1078 | Perf depends on the selected backend; opt in until the cost is |
| 1079 | characterized. |
| 1080 | |
| 1081 | When ``max_distance > 0.0`` is also set, BM25-only candidates |
| 1082 | are skipped — they have no vector distance and would silently |
| 1083 | violate the requested distance threshold. |
| 1084 | """ |
| 1085 | # Validate the strategy eagerly so invalid values fail the same way |
| 1086 | # regardless of whether the call routes through the vector path or |
| 1087 | # the BM25-only fallback below. |
| 1088 | _validate_candidate_strategy(candidate_strategy) |
| 1089 | |
| 1090 | if vector_disabled: |
| 1091 | return _vector_disabled_search( |
| 1092 | query=query, |
| 1093 | palace_path=palace_path, |