Spaces:
Running
Running
fix: Remove Qdrant order_by and upgrade reranker dependencies
Browse files- Fixed 400 error: Cannot use offset with order_by
- Upgraded transformers to 4.45.0 for tokenizer fix
- Upgraded FlagEmbedding to 1.2.11 for reranker fix
- Simplified browse method (client-side sorting)
Run: pip install --upgrade FlagEmbedding transformers
requirements.txt
CHANGED
|
@@ -11,11 +11,11 @@ python-dotenv>=1.0.1
|
|
| 11 |
psycopg2-binary>=2.9.9
|
| 12 |
SQLAlchemy>=2.0.29
|
| 13 |
sentence-transformers>=2.7.0
|
| 14 |
-
transformers>=4.
|
| 15 |
torch>=2.0.0
|
| 16 |
numpy>=1.26.0
|
| 17 |
tiktoken>=0.6.0
|
| 18 |
-
FlagEmbedding>=1.2.
|
| 19 |
redis>=5.0.0
|
| 20 |
python-jose[cryptography]>=3.3.0
|
| 21 |
passlib[bcrypt]>=1.7.4
|
|
|
|
| 11 |
psycopg2-binary>=2.9.9
|
| 12 |
SQLAlchemy>=2.0.29
|
| 13 |
sentence-transformers>=2.7.0
|
| 14 |
+
transformers>=4.45.0 # DeBERTa intent classifier + reranker tokenizer (upgraded for compatibility)
|
| 15 |
torch>=2.0.0
|
| 16 |
numpy>=1.26.0
|
| 17 |
tiktoken>=0.6.0
|
| 18 |
+
FlagEmbedding>=1.2.11 # BGE reranker (upgraded for tokenizer fix)
|
| 19 |
redis>=5.0.0
|
| 20 |
python-jose[cryptography]>=3.3.0
|
| 21 |
passlib[bcrypt]>=1.7.4
|
src/infrastructure/adapters/__pycache__/duckduckgo_adapter.cpython-313.pyc
ADDED
|
Binary file (10.4 kB). View file
|
|
|
src/infrastructure/adapters/qdrant_adapter.py
CHANGED
|
@@ -343,6 +343,7 @@ class QdrantAdapter(VectorStorePort):
|
|
| 343 |
|
| 344 |
try:
|
| 345 |
# Fetch more than needed so we can deduplicate to first chunk per article
|
|
|
|
| 346 |
results, next_page_offset = self.client.scroll(
|
| 347 |
collection_name=settings.QDRANT_COLLECTION,
|
| 348 |
scroll_filter=filter_obj,
|
|
@@ -350,10 +351,6 @@ class QdrantAdapter(VectorStorePort):
|
|
| 350 |
offset=offset,
|
| 351 |
with_payload=True,
|
| 352 |
with_vectors=False,
|
| 353 |
-
order_by=models.OrderBy(
|
| 354 |
-
key="published_at",
|
| 355 |
-
direction=models.Direction.DESC
|
| 356 |
-
)
|
| 357 |
)
|
| 358 |
|
| 359 |
# Keep only the lowest chunk_index per doc_id (first chunk of each article)
|
|
@@ -366,7 +363,7 @@ class QdrantAdapter(VectorStorePort):
|
|
| 366 |
seen_docs[doc_id] = (point, chunk_index)
|
| 367 |
|
| 368 |
deduped = [v[0] for v in seen_docs.values()]
|
| 369 |
-
#
|
| 370 |
deduped.sort(
|
| 371 |
key=lambda p: (p.payload or {}).get("published_at") or "",
|
| 372 |
reverse=True,
|
|
@@ -374,33 +371,5 @@ class QdrantAdapter(VectorStorePort):
|
|
| 374 |
return {"articles": deduped[:limit], "next_offset": next_page_offset}
|
| 375 |
|
| 376 |
except Exception as e:
|
| 377 |
-
# If order_by fails (older Qdrant version), retry without it
|
| 378 |
-
if "order_by" in str(e).lower():
|
| 379 |
-
logger.warning(f"Qdrant order_by not supported, falling back to client-side sort: {e}")
|
| 380 |
-
try:
|
| 381 |
-
results, next_page_offset = self.client.scroll(
|
| 382 |
-
collection_name=settings.QDRANT_COLLECTION,
|
| 383 |
-
scroll_filter=filter_obj,
|
| 384 |
-
limit=limit * 8,
|
| 385 |
-
offset=offset,
|
| 386 |
-
with_payload=True,
|
| 387 |
-
with_vectors=False,
|
| 388 |
-
)
|
| 389 |
-
seen_docs: dict = {}
|
| 390 |
-
for point in results:
|
| 391 |
-
payload = point.payload or {}
|
| 392 |
-
doc_id = payload.get("doc_id", point.id)
|
| 393 |
-
chunk_index = payload.get("chunk_index", 0)
|
| 394 |
-
if doc_id not in seen_docs or chunk_index < seen_docs[doc_id][1]:
|
| 395 |
-
seen_docs[doc_id] = (point, chunk_index)
|
| 396 |
-
deduped = [v[0] for v in seen_docs.values()]
|
| 397 |
-
deduped.sort(
|
| 398 |
-
key=lambda p: (p.payload or {}).get("published_at") or "",
|
| 399 |
-
reverse=True,
|
| 400 |
-
)
|
| 401 |
-
return {"articles": deduped[:limit], "next_offset": next_page_offset}
|
| 402 |
-
except Exception as e2:
|
| 403 |
-
logger.error(f"Error browsing Qdrant (fallback): {e2}")
|
| 404 |
-
return {"articles": [], "next_offset": None}
|
| 405 |
logger.error(f"Error browsing Qdrant: {e}")
|
| 406 |
return {"articles": [], "next_offset": None}
|
|
|
|
| 343 |
|
| 344 |
try:
|
| 345 |
# Fetch more than needed so we can deduplicate to first chunk per article
|
| 346 |
+
# NOTE: Qdrant doesn't support order_by with offset, so we do client-side sorting
|
| 347 |
results, next_page_offset = self.client.scroll(
|
| 348 |
collection_name=settings.QDRANT_COLLECTION,
|
| 349 |
scroll_filter=filter_obj,
|
|
|
|
| 351 |
offset=offset,
|
| 352 |
with_payload=True,
|
| 353 |
with_vectors=False,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 354 |
)
|
| 355 |
|
| 356 |
# Keep only the lowest chunk_index per doc_id (first chunk of each article)
|
|
|
|
| 363 |
seen_docs[doc_id] = (point, chunk_index)
|
| 364 |
|
| 365 |
deduped = [v[0] for v in seen_docs.values()]
|
| 366 |
+
# Client-side sort by published_at (descending - newest first)
|
| 367 |
deduped.sort(
|
| 368 |
key=lambda p: (p.payload or {}).get("published_at") or "",
|
| 369 |
reverse=True,
|
|
|
|
| 371 |
return {"articles": deduped[:limit], "next_offset": next_page_offset}
|
| 372 |
|
| 373 |
except Exception as e:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 374 |
logger.error(f"Error browsing Qdrant: {e}")
|
| 375 |
return {"articles": [], "next_offset": None}
|