7169 Commits
Author SHA1 Message Date
Classic298andClaude 9a54bc4bbb perf: halve function-table queries in get_all_models (#27230)
get_all_models ran four function-table queries: global actions, active
actions, global filters, active filters. Global functions are by
definition (type, is_active=True, is_global=True) — a subset of the
active set — so the global id sets can be derived from the active-rows
queries' is_global flag. Four queries become two, and each dropped
query returned full rows including every plugin's source code.

Also folds the mid-function 'models.default_metadata' read into the
Config.get_many already issued at the top of the function (one fewer
round trip; the existing `or {}` default handling is preserved).


Claude-Session: https://claude.ai/code/session_01MHg5zs1VBjvRWQ54qHpfYD

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-23 12:11:51 -04:00
Classic298andClaude Fable 5 32242a6788 perf: 40% LESS CPU usage: cut per-instance CPU cost of shared socket.io Redis pub/sub channel (#27282)
* perf: cut per-instance CPU cost of shared socket.io Redis pub/sub channel

Profiling a multi-instance deployment (py-spy --gil) showed ~44% of worker
CPU in the socket.io pub/sub listener. Two causes, two fixes:

- Add hiredis so redis-py parses the RESP protocol in C instead of pure
  Python (redis/_parsers/resp3.py alone accounted for ~28% of GIL samples;
  redis-py auto-selects the hiredis parser when importable).

- Subclass AsyncRedisManager to drop emits whose target room has no local
  participants before upstream _handle_emit re-encodes the full packet.
  Every instance receives every emit published on the shared channel, so
  with N instances all but the hosting one were paying full packet
  re-serialization per message just to deliver it to nobody. Broadcasts
  (room=None) are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9CQ9qnp3sZGYQQwztsCJT

* fix: restrict pub/sub emit early-out to string rooms

Adversarial review against python-socketio 5.16.2 found one divergence
from upstream: for a degenerate empty-sequence room (emit to room=[]) on
an instance whose namespace has no local clients, the filter's
get_participants probe raises IndexError from room[0] where upstream
returns silently at the namespace guard and still publishes to Redis.
Open WebUI only ever emits to scalar string rooms or room=None, so the
case is unreachable today; guard on isinstance(room, str) anyway so any
non-string room shape passes through to upstream behavior unchanged.

Every open-webui emit uses a string room, so the fast path still covers
all real traffic.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9CQ9qnp3sZGYQQwztsCJT

* Update requirements.txt

* Update pyproject.toml

* Update requirements-min.txt

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-23 12:11:38 -04:00
Timothy Jaeryang Baek bb12b1a18b refac 2026-07-23 04:16:14 -04:00
Timothy Jaeryang Baek cc9a44569e refac 2026-07-23 04:01:30 -04:00
Timothy Jaeryang Baek 48625e657f refac 2026-07-23 03:54:19 -04:00
Classic298andClaude 073cd65afe Log upstream provider rejections at warn/error level (#27238)
When an upstream provider rejects a request (e.g. a 400 for a
max_tokens value above the model's ceiling), the actionable error
message was only published to event sinks, which are invisible unless
an event function or webhook is configured. Admins had to query the
provider's API directly to diagnose failures (open-webui#27237).

Add a single log line in publish_model_provider_request_failed — the
chokepoint every upstream failure path (OpenAI-compatible chat,
embeddings, responses, token counting, and Ollama) already routes
through — recording status, provider, url, model, error code, and the
upstream message truncated to 1000 chars. 4xx logs at WARNING, 5xx at
ERROR. Client-facing responses are unchanged, so no additional error
detail is exposed in the chat.


Claude-Session: https://claude.ai/code/session_018VecyiPejru1EVF5yfe2sU

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-23 03:42:48 -04:00
Timothy Jaeryang Baek 48cc9d388e refac 2026-07-23 03:39:56 -04:00
Timothy Jaeryang Baek e18e249d5d refac 2026-07-23 03:39:30 -04:00
Timothy Jaeryang Baek af629177f4 refac 2026-07-23 03:31:32 -04:00
Classic298 3cf3f8e189 fix: add missing folders field to SharingPermissions so the permission persists (#27296)
`sharing.folders` is present in `DEFAULT_USER_PERMISSIONS` but absent from the `SharingPermissions` response/update schema, so the admin default and group permission API silently drops it on every round-trip and the setting is never saved. Add `folders: bool = False`, matching the config default (`USER_PERMISSIONS_FOLDERS_ALLOW_SHARING`), restoring parity with `DEFAULT_USER_PERMISSIONS`.

Fixes #27120.
2026-07-23 03:24:51 -04:00
Timothy Jaeryang Baek 9f00b62b3a refac 2026-07-23 03:22:51 -04:00
Timothy Jaeryang Baek 6ff1df326c refac 2026-07-23 03:05:29 -04:00
Timothy Jaeryang Baek 060d5da473 refac 2026-07-23 03:01:01 -04:00
Timothy Jaeryang Baek cf887b68ea refac 2026-07-23 02:54:56 -04:00
Timothy Jaeryang Baek 409fb39717 refac 2026-07-21 13:53:30 -04:00
Timothy Jaeryang Baek 8631dc83dc refac 2026-07-20 22:27:13 -04:00
Timothy Jaeryang Baek 49e57f4e7e chore: format 2026-07-20 22:11:42 -04:00
Timothy Jaeryang Baek 0c7ddbdb4f refac 2026-07-20 19:49:34 -04:00
Timothy Jaeryang Baek af9a315ac3 refac 2026-07-20 01:33:47 -04:00
Timothy Jaeryang Baek 1a32d92d08 refac 2026-07-17 06:50:16 -04:00
Timothy Jaeryang Baek 9281adc564 refac 2026-07-17 06:34:17 -04:00
Timothy Jaeryang Baek f3a3550784 refac 2026-07-17 06:29:19 -04:00
Timothy Jaeryang Baek e5e2cd7876 refac 2026-07-17 04:48:21 -04:00
Timothy Jaeryang Baek 56f2cb5302 refac 2026-07-17 04:11:11 -04:00
Timothy Jaeryang Baek 743b9fd3ce refac 2026-07-16 21:57:43 -04:00
Timothy Jaeryang Baek 2e857a82d7 refac 2026-07-16 02:47:51 -04:00
Timothy Jaeryang Baek c3ce0c5080 refac 2026-07-16 02:42:47 -04:00
Timothy Jaeryang Baek 75894161e4 refac 2026-07-16 02:35:44 -04:00
Timothy Jaeryang Baek a410ca36af refac 2026-07-16 01:46:02 -04:00
Timothy Jaeryang Baek 4d27bfff92 refac 2026-07-16 01:42:24 -04:00
Timothy Jaeryang Baek b80d204b81 refac 2026-07-16 01:37:21 -04:00
Timothy Jaeryang Baek e6c2b8ad59 refac 2026-07-16 01:34:50 -04:00
Timothy Jaeryang Baek cf235738f5 refac 2026-07-16 01:27:52 -04:00
Timothy Jaeryang Baek 200d447f62 refac 2026-07-16 01:10:13 -04:00
Timothy Jaeryang Baek c55e373b99 refac 2026-07-16 00:58:34 -04:00
Timothy Jaeryang Baek 771a024b40 refac 2026-07-16 00:39:31 -04:00
Timothy Jaeryang Baek b23ddeb280 refac 2026-07-16 00:30:44 -04:00
Timothy Jaeryang Baek e389874fe2 refac 2026-07-15 23:55:31 -04:00
Timothy Jaeryang Baek 2b8ef9340e refac 2026-07-15 23:51:37 -04:00
Timothy Jaeryang Baek 2712103c59 refac 2026-07-15 23:32:17 -04:00
Timothy Jaeryang Baek f67252b5e8 refac 2026-07-15 23:27:58 -04:00
Timothy Jaeryang Baek ee000c503c refac 2026-07-15 23:21:06 -04:00
Timothy Jaeryang Baek 588f129695 refac 2026-07-15 22:45:00 -04:00
Timothy Jaeryang Baek e65fdf1ca5 refac 2026-07-15 22:36:47 -04:00
Timothy Jaeryang Baek 185bca8552 refac 2026-07-15 22:34:52 -04:00
Timothy Jaeryang Baek 423cafd4e7 refac 2026-07-15 21:43:47 -04:00
Timothy Jaeryang Baek 3fcb7b2d64 refac 2026-07-15 15:06:08 -04:00
Timothy Jaeryang Baek 04311d559d refac 2026-07-15 02:53:39 -04:00
Timothy Jaeryang Baek 7a9928ef17 refac 2026-07-14 23:08:41 -04:00
Timothy Jaeryang Baek 50d3c927bf refac 2026-07-14 17:34:00 -04:00