open-webui/backend/open_webui/models
Classic298 310ae91302
perf: make tools defer_content real and batch tool and knowledge access filters (#27387)
Tools.get_tools(defer_content=True) contained the literal dead statement "stmt = stmt": the deferral was a no-op, so every tools listing loaded the full Python source of every tool (five caller sites pass defer_content=True expecting the optimization: the tools list endpoints and the user and group permission overviews). The listing now selects every column except content, and ToolModel.content becomes optional to represent deferred rows; router projections are content-less response models, so nothing downstream reads the source on these paths.

On top of that, get_tools_by_user_id issued one grant query per non-owned tool and Knowledges.get_knowledge_bases_by_user_id did the same per knowledge base (the latter also sits inside per-file access checks). Both now resolve grants for all non-owned rows in a single get_accessible_resource_ids call, the same batch helper the model listing already uses.

Benchmark (real SQLite DB):

| metric | before | after |
| --- | --- | --- |
| tools listing, 33 tools x ~200 KB source | 5.13 ms | 3.18 ms |
| grant queries per accessible-tools call, N non-owned tools | N | 1 |
| grant queries per accessible-KBs call, N non-owned KBs | N | 1 |

The listing row scales with source size; on Postgres the deferral additionally avoids shipping every tool's source over the wire per listing, and each removed grant query was a real round trip.

Functionally verified: deferred listings match full listings field for field with content None, grants included and router projections working; access filtering returns exactly owned plus granted tools and knowledge bases and nothing for strangers; full (non-deferred) reads still carry the source.
2026-07-23 17:51:07 -05:00
..
access_grants.py refac: modernize type annotations (PEP 604 / PEP 585) 2026-05-12 17:10:15 +09:00
auths.py refac 2026-06-29 03:16:59 -05:00
automations.py refac: modernize type annotations (PEP 604 / PEP 585) 2026-05-12 17:10:15 +09:00
calendar.py refac 2026-06-01 14:09:54 -07:00
channels.py refac: modernize type annotations (PEP 604 / PEP 585) 2026-05-12 17:10:15 +09:00
chat_messages.py refac 2026-07-20 01:33:47 -04:00
chats.py refac 2026-07-23 04:01:30 -04:00
config.py refac 2026-07-23 04:16:14 -04:00
feedbacks.py refac 2026-06-29 13:03:14 -05:00
files.py feat(ui): show total file count in FilesModal title (#25873) 2026-06-17 02:55:13 +02:00
folders.py refac 2026-06-29 13:03:14 -05:00
functions.py chore: format 2026-07-23 13:41:16 -04:00
groups.py refac: modernize type annotations (PEP 604 / PEP 585) 2026-05-12 17:10:15 +09:00
knowledge.py perf: make tools defer_content real and batch tool and knowledge access filters (#27387) 2026-07-23 17:51:07 -05:00
memories.py refac 2026-06-29 13:03:14 -05:00
messages.py refac 2026-06-29 13:03:14 -05:00
models.py perf: batch the file access check queries (#27383) 2026-07-23 17:50:08 -05:00
notes.py refac 2026-07-17 06:50:16 -04:00
oauth_sessions.py refac: modernize type annotations (PEP 604 / PEP 585) 2026-05-12 17:10:15 +09:00
prompt_history.py fix: bind prompt history/version ops to the authorized prompt (#25056) 2026-06-01 12:07:52 -07:00
prompts.py chore: format 2026-06-01 13:56:55 -07:00
shared_chats.py feat(ui): add 'Unshare All Shared Chats' button to Shared Chats modal (#25848) 2026-06-17 03:06:41 +02:00
skills.py refac 2026-07-17 04:11:11 -04:00
tags.py chore: format 2026-06-01 13:56:55 -07:00
tools.py perf: make tools defer_content real and batch tool and knowledge access filters (#27387) 2026-07-23 17:51:07 -05:00
users.py refac 2026-07-23 14:29:27 -04:00