fix(vector-sync): use resolved collection name in orphan sweep

The startup sweep was reading settings.qdrant_collection (the raw config
value, default "nextcloud_content") instead of settings.get_collection_name(),
which is what every other vector-sync operation uses. When QDRANT_COLLECTION
is not overridden, get_collection_name() auto-generates a
{deployment-id}-{model-name} name; the sweep was targeting a non-existent
collection and silently returning (0, 0).

Also adds the AsyncQdrantClient type annotation that was missing on
sweep_orphan_placeholders, and renames its parameter from collection_name
to collection to make it clear the value must be the resolved name.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-05-22 21:29:48 +02:00
co-authored by Claude Opus 4.7
parent a5cbe91b29
commit c03223a41c
2 changed files with 10 additions and 10 deletions
+3 -4
View File
@@ -1452,15 +1452,14 @@ def get_app(transport: str = "streamable-http", enabled_apps: list[str] | None =
return
try:
qdrant_client = await get_qdrant_client()
swept, kept = await sweep_orphan_placeholders(
qdrant_client, settings.qdrant_collection
)
collection = settings.get_collection_name()
swept, kept = await sweep_orphan_placeholders(qdrant_client, collection)
logger.info(
"vector_sync.orphan_sweep",
extra={
"swept": swept,
"kept": kept,
"collection": settings.qdrant_collection,
"collection": collection,
},
)
except Exception:
+7 -6
View File
@@ -21,7 +21,7 @@ import logging
import time
import uuid
from qdrant_client import models
from qdrant_client import AsyncQdrantClient, models
from qdrant_client.models import FieldCondition, Filter, MatchValue, PointStruct
from nextcloud_mcp_server.config import get_settings
@@ -340,8 +340,8 @@ _ORPHAN_SWEEP_BATCH_SIZE = 100
async def sweep_orphan_placeholders(
qdrant_client,
collection_name: str,
qdrant_client: AsyncQdrantClient,
collection: str,
*,
batch_size: int = _ORPHAN_SWEEP_BATCH_SIZE,
) -> tuple[int, int]:
@@ -362,7 +362,8 @@ async def sweep_orphan_placeholders(
Args:
qdrant_client: Async Qdrant client.
collection_name: Target collection.
collection: Target collection (resolved name from
``settings.get_collection_name()``, not the raw config key).
batch_size: Scroll page size. Default 100 — small enough that
a single delete payload is reasonable, large enough that
round-trip count stays bounded for typical placeholder
@@ -383,7 +384,7 @@ async def sweep_orphan_placeholders(
while True:
points, offset = await qdrant_client.scroll(
collection_name=collection_name,
collection_name=collection,
scroll_filter=placeholder_filter,
limit=batch_size,
offset=offset,
@@ -404,7 +405,7 @@ async def sweep_orphan_placeholders(
if orphan_ids:
await qdrant_client.delete(
collection_name=collection_name,
collection_name=collection,
points_selector=orphan_ids,
)
swept += len(orphan_ids)