From ae7d2289e8dc1d8936046651e8f825e7eff52d15 Mon Sep 17 00:00:00 2001 From: Trenton Holmes <797416+stumpylog@users.noreply.github.com> Date: Sat, 29 Aug 2026 15:06:47 -0700 Subject: [PATCH] sort similar documents by weight, use unrestricted-user check consistently (existed before, but good to be consistent) --- src/paperless_ai/ai_classifier.py | 16 +++++++++------- src/paperless_ai/taxonomy.py | 12 ++++++++---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/paperless_ai/ai_classifier.py b/src/paperless_ai/ai_classifier.py index f86dbfe32..e52a7cd7f 100644 --- a/src/paperless_ai/ai_classifier.py +++ b/src/paperless_ai/ai_classifier.py @@ -204,18 +204,20 @@ def get_taxonomy_context( ai_config = AIConfig() try: if ai_config.llm_embedding_backend: - # None means "no restriction" to retrieve_similar_nodes. A superuser - # (like no user at all) can see every document, so skip materializing - # every visible pk into a Python list and passing it through as an IN - # filter: for a large library that is a wasted quadratic scan in the - # vector store at best, and past ~32,763 documents a hard - # sqlite3.OperationalError (SQLite's bound-parameter limit) at worst. + # None means "no restriction" to retrieve_similar_nodes. An + # unrestricted user (no user at all, or an active superuser -- see + # user_is_unrestricted) can see every document, so skip + # materializing every visible pk into a Python list and passing it + # through as an IN filter: for a large library that is a wasted + # quadratic scan in the vector store at best, and past ~32,763 + # documents a hard sqlite3.OperationalError (SQLite's + # bound-parameter limit) at worst. # permitted_object_ids() has its own superuser shortcut that would # return every Document's id anyway, so this changes nothing about # which documents are considered -- only how we get there. visible_document_ids = ( None - if user is None or user.is_superuser + if user_is_unrestricted(user) else list(permitted_object_ids(user, Document, "view_document")) ) nodes = retrieve_similar_nodes( diff --git a/src/paperless_ai/taxonomy.py b/src/paperless_ai/taxonomy.py index dedf0fdba..dd599691e 100644 --- a/src/paperless_ai/taxonomy.py +++ b/src/paperless_ai/taxonomy.py @@ -126,10 +126,14 @@ def _node_document_weights(nodes: list["NodeWithScore"]) -> list[SimilarDocument weights[int(document_id)] += float(node.score or 0.0) except (TypeError, ValueError): # pragma: no cover continue - return [ - SimilarDocument(document_id=document_id, weight=weight) - for document_id, weight in weights.items() - ] + return sorted( + ( + SimilarDocument(document_id=document_id, weight=weight) + for document_id, weight in weights.items() + ), + key=lambda similar: similar["weight"], + reverse=True, + ) def _visible_ranked_candidates(