Compare commits

...
4 changed files with 40 additions and 4 deletions
+1
View File
@@ -331,6 +331,7 @@ def bulk_update_documents(document_ids) -> None:
if ai_config.llm_index_enabled:
update_llm_index(
rebuild=False,
document_ids=document_ids,
)
+6 -2
View File
@@ -401,6 +401,10 @@ class TestAIIndex(DirectoriesMixin, TestCase):
"documents.tasks.update_llm_index",
) as update_llm_index,
):
tasks.bulk_update_documents([doc.pk for doc in docs])
doc_ids = [doc.pk for doc in docs]
tasks.bulk_update_documents(doc_ids)
self.assertEqual(update_document_in_llm_index.apply_async.call_count, 0)
update_llm_index.assert_called_once()
update_llm_index.assert_called_once_with(
rebuild=False,
document_ids=doc_ids,
)
+17 -2
View File
@@ -318,8 +318,16 @@ def update_llm_index(
*,
iter_wrapper: IterWrapper[Document] = identity,
rebuild=False,
document_ids: Iterable[int] | None = None,
) -> str:
"""Rebuild or incrementally update the LLM index."""
"""Rebuild or incrementally update the LLM index.
``document_ids``, when given, scopes an incremental update to just those
documents instead of scanning the whole library -- callers that already
know which documents changed (e.g. a bulk edit) should pass this to avoid
an O(library size) scan per call. Ignored whenever a rebuild actually
happens, since a rebuild always covers the whole library regardless.
"""
with write_store() as store:
try:
with _exclude_readers():
@@ -369,9 +377,16 @@ def update_llm_index(
store.add(nodes)
msg = "LLM index rebuilt successfully."
else:
scoped_documents = (
Document.objects.filter(id__in=document_ids)
.select_related("correspondent", "document_type", "storage_path")
.prefetch_related("tags")
if document_ids is not None
else documents
)
existing = store.get_modified_times()
changed = 0
for document in iter_wrapper(documents):
for document in iter_wrapper(scoped_documents):
doc_id = str(document.id)
if existing.get(doc_id) == document.modified.isoformat():
continue
@@ -252,6 +252,22 @@ def test_update_llm_index_partial_update(
assert store.table_exists(), (
"Expected the vector store table to exist after incremental update"
)
before = store.get_modified_times()
# A further edit, scoped via document_ids to just doc3 -- doc2 must be
# left exactly as it was, proving document_ids restricts the scan
# instead of falling back to the whole library.
doc3.modified = timezone.now()
doc3.save()
result = indexing.update_llm_index(rebuild=False, document_ids=[doc3.pk])
assert result == "LLM index updated successfully."
with indexing.get_vector_store() as store:
after = store.get_modified_times()
assert after[str(doc3.pk)] == doc3.modified.isoformat()
assert after[str(doc2.pk)] == before[str(doc2.pk)]
@pytest.mark.django_db