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 return
try: try:
qdrant_client = await get_qdrant_client() qdrant_client = await get_qdrant_client()
swept, kept = await sweep_orphan_placeholders( collection = settings.get_collection_name()
qdrant_client, settings.qdrant_collection swept, kept = await sweep_orphan_placeholders(qdrant_client, collection)
)
logger.info( logger.info(
"vector_sync.orphan_sweep", "vector_sync.orphan_sweep",
extra={ extra={
"swept": swept, "swept": swept,
"kept": kept, "kept": kept,
"collection": settings.qdrant_collection, "collection": collection,
}, },
) )
except Exception: except Exception:
+7 -6
View File
@@ -21,7 +21,7 @@ import logging
import time import time
import uuid import uuid
from qdrant_client import models from qdrant_client import AsyncQdrantClient, models
from qdrant_client.models import FieldCondition, Filter, MatchValue, PointStruct from qdrant_client.models import FieldCondition, Filter, MatchValue, PointStruct
from nextcloud_mcp_server.config import get_settings from nextcloud_mcp_server.config import get_settings
@@ -340,8 +340,8 @@ _ORPHAN_SWEEP_BATCH_SIZE = 100
async def sweep_orphan_placeholders( async def sweep_orphan_placeholders(
qdrant_client, qdrant_client: AsyncQdrantClient,
collection_name: str, collection: str,
*, *,
batch_size: int = _ORPHAN_SWEEP_BATCH_SIZE, batch_size: int = _ORPHAN_SWEEP_BATCH_SIZE,
) -> tuple[int, int]: ) -> tuple[int, int]:
@@ -362,7 +362,8 @@ async def sweep_orphan_placeholders(
Args: Args:
qdrant_client: Async Qdrant client. 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 batch_size: Scroll page size. Default 100 — small enough that
a single delete payload is reasonable, large enough that a single delete payload is reasonable, large enough that
round-trip count stays bounded for typical placeholder round-trip count stays bounded for typical placeholder
@@ -383,7 +384,7 @@ async def sweep_orphan_placeholders(
while True: while True:
points, offset = await qdrant_client.scroll( points, offset = await qdrant_client.scroll(
collection_name=collection_name, collection_name=collection,
scroll_filter=placeholder_filter, scroll_filter=placeholder_filter,
limit=batch_size, limit=batch_size,
offset=offset, offset=offset,
@@ -404,7 +405,7 @@ async def sweep_orphan_placeholders(
if orphan_ids: if orphan_ids:
await qdrant_client.delete( await qdrant_client.delete(
collection_name=collection_name, collection_name=collection,
points_selector=orphan_ids, points_selector=orphan_ids,
) )
swept += len(orphan_ids) swept += len(orphan_ids)