refactor(search): address PR #750 review feedback

- Cap all_results to limit*2 after sort in the per-doc_types branch of
  nc_semantic_search to bound over-verification (was unbounded N-types).
- Switch BatchVerifier from (client, doc_ids, user_id) to (client, results,
  semaphore). Verifiers now read file paths and deck board/stack ids from
  SearchResult.metadata instead of doing fresh Qdrant scrolls — eliminates
  one duplicate round-trip per file/deck-card verification.
- Bound per-id verification concurrency with a shared anyio.Semaphore
  (default 20, matching server/semantic.py context-expansion convention).
  Prevents httpx pool exhaustion / rate limiting on large search pages.
- Propagate stack_id from Qdrant payload to SearchResult.metadata in both
  bm25_hybrid.py and semantic.py (board_id was already propagated).
- Drop now-unused _resolve_file_path / _resolve_deck_metadata helpers.
- Drop redundant int(d) in requested predicate from _verify_news_items.
- Rewrite eviction comment to be honest about inline (not background)
  execution and the resulting latency coupling.
- ADR-019 status: Proposed -> Accepted.
- Add news property to NextcloudClientProtocol.
- Widen SearchResult.id and SemanticSearchResult.id to int | str to match
  BatchVerifier signature and document support for future string-id types.
- Flip openWorldHint to True on nc_semantic_search_answer (it calls into
  Nextcloud via nc_semantic_search).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-05-01 08:22:28 +02:00
co-authored by Claude Opus 4.7
parent d90e793d19
commit 7784ec02d7
8 changed files with 380 additions and 270 deletions
+9 -2
View File
@@ -67,6 +67,11 @@ class NextcloudClientProtocol(Protocol):
"""Tables client for accessing table row documents."""
...
@property
def news(self) -> Any:
"""News client for accessing news item documents."""
...
async def get_indexed_doc_types(user_id: str) -> set[str]:
"""Query Qdrant to get actually-indexed document types for a user.
@@ -127,7 +132,9 @@ class SearchResult:
"""A single search result with metadata and score.
Attributes:
id: Document ID (int for all document types)
id: Document ID. Numeric for indexed types today (notes, files,
deck cards, news items), but typed as ``int | str`` to allow
future doc types that use string identifiers (e.g., file paths).
doc_type: Document type (note, file, calendar, contact, etc.)
title: Document title
excerpt: Content excerpt showing match context
@@ -144,7 +151,7 @@ class SearchResult:
point_id: Qdrant point ID for batch vector retrieval (None if not from Qdrant)
"""
id: int
id: int | str
doc_type: str
title: str
excerpt: str