refactor(search): address PR #750 round 9 review feedback
- Add concurrency-safety comments to per-verifier accessible sets in _verify_notes/_verify_files/_verify_deck_cards. Same rationale as accessible_by_type in verify_search_results: anyio is cooperative, set.add() is not an await point. - Document 401 exclusion in _is_definitive_404_or_403 (treated as transient because it usually signals expired credentials, not permanent denial). - Note multi-user compounding in the news verifier semaphore comment: N concurrent users hold N slots out of the shared budget. - Log inaccessible doc ids with a type tag (e.g. "int:42" vs "str:42") so ghost-record logs disambiguate id types. - Type the BatchVerifier alias and the four verifier function signatures with NextcloudClientProtocol instead of Any (algorithms.py exposes the right interface; the protocol is runtime_checkable). - Surface verified_chunk_count vs dropped_count semantics in the nc_semantic_search tool docstring Returns block (chunks vs unique documents). - Add comments to the two max_concurrent=20 sites in server/semantic.py noting they are intentionally distinct from settings.verification_concurrency (different request phases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
3153c9dac4
commit
852ffa3678
@@ -87,7 +87,16 @@ def configure_semantic_tools(mcp: FastMCP):
|
||||
context_chars: Number of characters to include before/after matched chunk (default: 300)
|
||||
|
||||
Returns:
|
||||
SemanticSearchResponse with matching documents ranked by fusion scores
|
||||
SemanticSearchResponse with matching documents ranked by fusion scores.
|
||||
|
||||
Verification fields (ADR-019 verify-on-read):
|
||||
- verified_chunk_count: chunk rows that passed access checks
|
||||
(sized in chunks; counted before trimming to ``limit``, so it
|
||||
can exceed ``len(results)`` when a doc has multiple matching
|
||||
chunks).
|
||||
- dropped_count: unique ``(doc_id, doc_type)`` pairs evicted as
|
||||
ghost records during this search (sized in documents, not
|
||||
chunks).
|
||||
"""
|
||||
settings = get_settings()
|
||||
client = await get_client(ctx)
|
||||
@@ -248,8 +257,15 @@ def configure_semantic_tools(mcp: FastMCP):
|
||||
context_chars,
|
||||
)
|
||||
|
||||
# Fetch context for all results in parallel
|
||||
# Limit concurrent requests to prevent connection pool exhaustion
|
||||
# Fetch context for all results in parallel.
|
||||
# Limit concurrent requests to prevent connection pool exhaustion.
|
||||
#
|
||||
# Intentionally distinct from settings.verification_concurrency:
|
||||
# that knob bounds Nextcloud round-trips during access
|
||||
# verification (ADR-019); this one bounds context-expansion
|
||||
# fetches that run only when ``include_context=True``. Operators
|
||||
# tuning one rarely want the other in lockstep, so they share
|
||||
# the default value (20) but not the env var.
|
||||
max_concurrent = 20
|
||||
semaphore = anyio.Semaphore(max_concurrent)
|
||||
expanded_results = [None] * len(results)
|
||||
@@ -507,7 +523,15 @@ def configure_semantic_tools(mcp: FastMCP):
|
||||
accessible_results = [None] * len(search_response.results)
|
||||
full_contents = [None] * len(search_response.results)
|
||||
|
||||
# Limit concurrent requests to prevent connection pool exhaustion
|
||||
# Limit concurrent requests to prevent connection pool exhaustion.
|
||||
#
|
||||
# Intentionally distinct from settings.verification_concurrency:
|
||||
# that knob bounds Nextcloud round-trips during access
|
||||
# verification (ADR-019). This one bounds the answer tool's
|
||||
# full-content fetch — a separate request phase tied to RAG
|
||||
# answer generation. Operators tuning one rarely want the other
|
||||
# in lockstep, so they share the default value (20) but not the
|
||||
# env var.
|
||||
max_concurrent = 20
|
||||
semaphore = anyio.Semaphore(max_concurrent)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user