diff --git a/services/docs/service.py b/services/docs/service.py index b20cf8e..29a5158 100644 --- a/services/docs/service.py +++ b/services/docs/service.py @@ -57,6 +57,7 @@ class DocsService: metadata=r.get("metadata"), ) for r in results + if isinstance(r, dict) ] async def index(self, directory: str) -> IndexResult: diff --git a/tests/test_docs_query_nondict_rows.py b/tests/test_docs_query_nondict_rows.py new file mode 100644 index 0000000..91871f1 --- /dev/null +++ b/tests/test_docs_query_nondict_rows.py @@ -0,0 +1,26 @@ +import asyncio + +from services.docs.service import DocsService + + +class _FakeRag: + """Stands in for RAGManager.search. A corrupt or stale Chroma index can + return a non-dict row alongside the well-formed ones.""" + + def search(self, query, k=5): + return [ + {"text": "alpha", "source": "a.txt", "score": 0.9}, + "corrupt-row", + None, + ] + + +def test_query_skips_non_dict_rag_rows(): + # Bypass __init__ (it builds a real RAGManager / Chroma client) and inject + # a fake search backend. + svc = DocsService.__new__(DocsService) + svc.rag = _FakeRag() + out = asyncio.run(svc.query("anything")) + # old code called r.get(...) on the str/None rows and raised AttributeError. + assert [c.text for c in out] == ["alpha"] + assert out[0].source == "a.txt"