Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,18 @@
layer with defaults, and the filter helpers both backends share move from the base into
`search_filters`. No query behavior changes.

- **#1558**: Retrieval leaves `SearchRepositoryBase`. `SearchReader` runs one prepared
query over one `ProjectScope` in whichever mode it asks for, and `SemanticSearch` owns
vector and hybrid retrieval (adapter lookup, manifest hydration, the structured filter
pass, score fusion, reranking, pagination) over a `VectorRetrieval` that is present or
absent rather than probed with `hasattr`. The repository keeps what only it knows
(whether semantic search is enabled and its vector tables exist) and builds a reader
per call from its current state. Hydrated chunks are a typed `HydratedChunk`, which
retires the `best_distance` compatibility branch and the per-backend
`_distance_to_similarity` hooks the adapters had already replaced. Test doubles
construct the pipeline directly instead of subclassing the repository. No query
behavior changes.


## v0.23.2 (2026-08-25)

Expand Down
9 changes: 0 additions & 9 deletions src/basic_memory/repository/postgres_search_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,15 +490,6 @@ async def _delete_stale_chunks(
expected_deletions=expected_deletions,
)

@override
def _distance_to_similarity(self, distance: float) -> float:
"""Convert pgvector cosine distance to cosine similarity.

pgvector's <=> operator returns cosine distance in [0, 2],
where cos_distance = 1 - cos_similarity.
"""
return max(0.0, 1.0 - distance)

@override
def _timestamp_now_expr(self) -> str:
return "NOW()"
Expand Down
22 changes: 22 additions & 0 deletions src/basic_memory/repository/search_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,28 @@ class PreparedSearchQuery:
retrieval_mode: SearchRetrievalMode = SearchRetrievalMode.FTS
min_similarity: float | None = None

@property
def has_filters(self) -> bool:
"""Whether any predicate beyond the text itself narrows the result set.

Vector retrieval cannot evaluate these itself; when any is present it asks
the full-text pass which of its candidates the filters admit.
"""
return any(
(
self.permalink,
self.permalink_match,
self.title,
self.note_types,
self.after_date,
self.search_item_types,
self.categories,
self.metadata_filters,
self.file_path_prefix,
self.temporal,
)
)


# Interrogative/function words contribute lexical noise when a strict
# full-text query is relaxed: "when OR did OR a" matches loud wrong documents
Expand Down
Loading
Loading