5604 Commits
Author SHA1 Message Date
Classic298 ed3cf83553 refac: recheck live chat access after archiving and bulk unsharing (#32887)
Archiving a chat, archiving all chats and unsharing all chats now run the same live access recheck as the other chat changes.
2026-10-22 08:32:51 +09:00
Classic298 a9adb2b78e perf: posting in a channel takes seconds when many members are online (#32889)
Every message posted in a channel waited until the server had re-checked the login of every online member of that channel, one connected session at a time with a few database lookups each, before the post went through. In a large channel that added seconds to every single message. The result only decides who gets a notification, and the message is already delivered to everyone before this step, so the check now runs right after the post returns, as the first step of the work that sends notifications and bot replies. Members are re-checked exactly as before, including disconnecting any session whose login is no longer valid.

Postgres 16, standard channel, median time for a post to return:

| Online members | Before | After |
| --- | --- | --- |
| 100 | 0.37 s | 0.03 s |
| 300 | 1.6 s | 0.05 s |
| 1,000 | 3.4 s | 0.10 s |
2026-10-22 07:48:19 +09:00
Timothy Jaeryang Baek c9415a688e refac 2026-10-22 07:40:01 +09:00
Classic298 bae611e785 perf: saving a group or changing its members takes seconds when many users are online (#32882)
Since 0.12.0, every group save and every member add or remove made the server recheck access for every chat that any online user had open in a browser tab, one database lookup at a time, before the save finished. With a few thousand people online, saving a group took several seconds, and every one of those open chats reloaded its contents afterwards. When a group change can affect what someone may see, the server already makes that person's browser reconnect, and an open chat checks its access again on reconnect, so group changes now skip the recheck for everyone else. Folder and chat sharing changes keep it.

Postgres 16, 2,000-member group, one open chat per online user:

| Online users | Saving the group without permission changes, before | after | Adding a member, before | after |
| --- | --- | --- | --- | --- |
| 1,000 | 2.0 s | under 0.05 s | 2.2 s | under 0.05 s |
| 3,000 | 6.7 s | under 0.05 s | 6.6 s | under 0.05 s |
2026-10-22 07:08:49 +09:00
Classic298 b7d1de05ab perf: changing permissions on a large group is slow (#32883)
When a group change affects its members (new permissions, parent group or default models, or deleting the group), the server makes every member's browser reconnect so it picks up the new permissions without a page reload. To find each member's connections it read through the whole list of connected users again for every single member, so saving a 2,000-member group with 3,000 people online spent almost 9 seconds on this with Redis as the websocket manager, and about 1 second without. It now finds all members' connections in one pass.

Changing one permission on a 2,000-member group, time the save spends making members reconnect:

| Online users | Redis, before | Redis, after | No Redis, before | No Redis, after |
| --- | --- | --- | --- | --- |
| 1,000 | 2.8 s | 0.15 s | 0.09 s | <0.01 s |
| 3,000 | 8.7 s | 0.28 s | 1.2 s | <0.01 s |
2026-10-22 07:08:30 +09:00
Classic298 cb7d7e851d fix: model import silently skips a model whose ID is already taken (#32866)
Importing a model JSON on the Workspace Models page as a regular user skipped any model whose ID already belonged to another user's model they cannot edit, or to a model from one of the instance's connections such as OpenAI or Ollama. There was no message, so the model just never showed up. The import now stops at that model with the error "Uh-oh! This model id is already registered. Please choose another model id string."; the models before it in the file are imported and the ones after it are not. Admins, and users who can edit the existing model, are unaffected and still overwrite it.
2026-10-22 06:12:10 +09:00
Classic298 d1e31cbb81 refactor: remove unused development route (#32869)
Removes a leftover development-only route that nothing in the app calls.
2026-10-22 06:11:00 +09:00
Classic298 a915df8ce1 chore: Python 3.12 and Debian 13 base image (#32861)
The Docker image now runs Python 3.12 on Debian 13 (trixie) instead of Python 3.11 on Debian 12, and the pip install docs recommend 3.12. Image size stays about the same: the slim image is 1 MB smaller and the standard image is about 50 MB larger, mostly from the newer ffmpeg and pandoc that Debian 13 ships. Admins should know that custom functions, tools and anything installed with pip inside the container now run on Python 3.12, so a package that only has builds for 3.11 needs a newer version. Installing with pip still works on both Python 3.11 and 3.12.
2026-10-22 04:51:57 +09:00
Classic298 db5b874944 feat: let everyone who can use a model pick its model controls (#32860)
Picking a model control option, such as a Thinking level, needed both the Allow Chat Controls and Allow Chat Params permissions, so admins had to hand out the Advanced Parameters panel just to let people pick a preset. Model control picks now work for anyone with access to the model and are saved per model to their account. Allow Chat Controls still hides the Chat Controls panel and Allow Chat Params still hides the Advanced Parameters panel, in the chat and in personal Settings. Parameters a person saves to their account are no longer filtered by these two permissions, since any chat message could already set any parameter without them.

Fixes #32626
2026-10-22 04:44:53 +09:00
Classic298 3e0564d11a fix: MinerU local mode fails every document on a 4.x server that requires an API key (#32838)
A self-hosted MinerU 4.x server started with an API key rejected every document with a 401, even with the key filled in under Documents settings, because local mode never sent it. The key is now sent with the document requests to a 4.x server whenever one is set. Servers without a key are unaffected.

Fixes #32836
2026-10-22 02:26:37 +09:00
Classic298 6367a3cc40 fix: OAuth connections send no token when the user calls the API (#32826)
A model connection with its auth type set to OAuth only forwarded the user's sign-in token for requests coming from the browser. The same user calling the API with their bearer token or an API key sent nothing upstream, so an SSO-protected model server rejected every API call and its models could not be listed or used. These connections now fall back to the user's latest sign-in session the same way tool servers already do.

Fixes #32820
2026-10-22 02:13:50 +09:00
Classic298 21f770fb73 fix: OAuth 2.1 (Static) MCP connections send no client secret to servers like X Ads (#32818)
With OAuth 2.1 (Static), when the authorization server did not accept the client secret as a form field, Open WebUI used whichever auth method the server's metadata listed first. X Ads lists "none" (public client, no secret) first, so the token exchange went out without the configured client secret and X rejected it with "Missing valid authorization header". When the server supports HTTP Basic auth, the secret is now sent that way, no matter which method it lists first.

Fixes #32813
2026-10-21 16:38:34 +09:00
Timothy Jaeryang Baek 3539ad6321 refac 2026-10-21 16:35:31 +09:00
Timothy Jaeryang Baek dc2ac86060 refac 2026-10-21 16:01:14 +09:00
Timothy Jaeryang Baek d1705c1078 refac 2026-10-21 15:04:00 +09:00
Timothy Jaeryang Baek f5e8f84e69 refac 2026-10-21 12:58:04 +09:00
Timothy Jaeryang Baek 131ddc32ec refac 2026-10-21 11:07:10 +09:00
Timothy Jaeryang Baek 2a86805648 refac 2026-10-21 11:06:17 +09:00
Timothy Jaeryang Baek 243ef36c49 refac 2026-10-21 09:53:09 +09:00
Timothy Jaeryang Baek d5cd7f4907 refac 2026-10-21 09:26:26 +09:00
Timothy Jaeryang Baek b4a58be193 refac 2026-10-21 09:15:15 +09:00
Classic298 56eca192ab feat: context compaction now runs on chats with few messages that are over the threshold (#32794)
Context compaction summarizes older messages and keeps the most recent ones verbatim, splitting the chat at a user message. It skipped the chat whenever the first follow-up message sat too close to the end to keep the share set in the Retained Messages admin setting. So a fresh chat with one question and one reply carrying a lot of tool output never compacted: the follow-up failed with a context length error, and regenerating or editing that follow-up failed the same way. Now compaction splits at the first follow-up message in that case, keeping fewer messages than Retained Messages asks for, so the chat keeps working. Chats where a split already met that share compact as before, and compaction between tool calls is unchanged.

Fixes #32781
2026-10-21 08:35:13 +09:00
Classic298 217766ed0f fix: MCP list results from FastMCP servers reach the model twice (#32726)
When a tool on a server built with the standalone FastMCP package returned a list, the model got the list twice, once as plain text and once as structured data, so every list result cost two to three times the tokens. That package sends the whole list as a single piece of text, a format Open WebUI did not recognise as a duplicate. The list now reaches the model once, and structured data that the text does not already contain is still passed along.

Fixes #32719
2026-10-21 04:46:02 +09:00
Classic298 cd74e6d126 fix: dropped realtime call sometimes shows "Voice connection failed" (#32730)
When the voice provider ended a realtime call, the overlay sometimes said "Voice connection failed" instead of "Voice provider connection closed". It happened when microphone audio reached the server at the same moment the provider hung up, so forwarding that audio failed and the generic error was shown. Anything that fails to reach the provider because it just closed the connection now reports that the provider closed the call.

Fixes #32729
2026-10-21 04:45:54 +09:00
Timothy Jaeryang Baek 6c61227d90 refac 2026-10-21 03:44:42 +09:00
Classic298 794e57cf7e fix: misleading ask_user error when questions are not sent as a list (#32727)
When a model sent the ask_user questions as anything other than a list, for example a JSON-encoded string, the tool answered "ask_user requires 1-3 questions." The model had sent the right number of questions, so it did not understand the error and often repeated the same call in a loop. It now gets a separate error saying the questions must be an array of question objects, and the count error only appears when the count is actually wrong.

Fixes #32662
2026-10-21 03:33:10 +09:00
Classic298 2355b8a369 fix: requests hang or fail with 503 after pages are closed while loading (#32617)
Closing a page while the server was still sending it data (a file's processing status, a chat export) could interrupt a database read halfway. On SQLite the connection used for it was then never given back, and a later unrelated request could hang forever when that connection was finally cleaned up; once enough were lost, every request needing the database waited 30 seconds and failed with a 503. The connection is now kept and rolled back instead of being thrown away inside the interrupted request, and the session is closed once instead of twice, as either alone still lost connections. Closing 600 chat exports and 300 file status streams mid-load on SQLite used to lose 60 (the whole pool in that test) and 56 connections, now none; Postgres lost none before or after.

Fixes #32609
2026-10-21 03:23:05 +09:00
G30 97f5c4e973 fix: Archive All Chats takes chats out of their folders, so deleting a folder no longer deletes them (#32647) 2026-10-21 03:18:03 +09:00
Classic298 c7e159bdd6 fix: voice calls do not forward user info headers to the realtime provider (#32733)
With ENABLE_FORWARD_USER_INFO_HEADERS turned on, voice calls in Realtime mode connected to the configured realtime provider without any user info headers, so a gateway in front of the provider could not tell which user was on the call. The call connection now sends the same user headers (or the signed user JWT, when configured) as chat requests and realtime text-to-speech already do.
2026-10-21 03:13:37 +09:00
G30 54fc21d685 fix: deleting a channel message also deletes its thread replies (#32666) 2026-10-21 02:44:43 +09:00
Classic298 93ba628f3a fix: generated images never show up after the user answers the model's question or approves a tool (#32680)
When the model asked the user a question, or a tool call was approved or rejected, the reply was saved in a way that broke adding anything to it later in the same turn. If the model then generated an image, the image was created but never shown, the tool returned "unsupported operand type(s) for +: 'NoneType' and 'list'" and the model kept retrying, generating more hidden images. Progress status updates for that reply were also silently dropped. Both now work after a question or tool approval.

Fixes #32678
2026-10-21 02:39:39 +09:00
G30 ab6976b5bf fix: when two tools have a function with the same name, the model can call both (#32670) 2026-10-21 02:25:31 +09:00
G30 fd1e59b25f fix: an array query parameter reaches an OpenAPI tool server as repeated values (#32677) 2026-10-21 02:18:13 +09:00
Classic298 c901bc39d3 fix: embeddings API fails for connections with a Prefix ID (#32724)
Calling the embeddings API with a model from a connection that has a Prefix ID sent the prefixed model name to the provider, which rejected it as an unknown model. The prefix is now removed before the request goes out, the same way chat requests already do it, so every model on such a connection works through the embeddings API again.

Fixes #32715
2026-10-21 02:01:29 +09:00
G30 312d113fd0 Merge pull request #32709 from silentoplayz/fix/prompt-save-unchanged-no-version
fix: saving a prompt without changes adds no version to its history
2026-10-21 01:06:59 +09:00
Timothy Jaeryang Baek 079fb19e75 refac 2026-10-16 18:58:58 +04:00
Timothy Jaeryang Baek 4b81b12ed4 chore: format 2026-10-16 15:20:15 +04:00
Timothy Jaeryang Baek 362b01d0b2 refac 2026-10-16 14:48:08 +04:00
Timothy Jaeryang Baek 5cf7c03332 refac 2026-10-16 14:35:09 +04:00
Timothy Jaeryang Baek 92e64c1d59 refac 2026-10-16 14:31:39 +04:00
Classic298 51a4d58270 feat: tools come back on their own after all OpenAPI tool servers were unreachable (#32533)
With Redis, if every tool server was unreachable when Open WebUI loaded the tool server list, it cached an empty list and served it forever. The tools stayed missing from chats and the tool list after the servers came back, until a restart, a save in the tool server settings or a manual delete of the cached Redis key. An empty cached list is now only trusted while no OpenAPI tool server is enabled, so the next request that loads tools fetches the servers again, the same way terminal servers already behave. While an enabled server stays unreachable, each such request tries it again and can wait for its timeout.

Fixes #29573
2026-10-16 14:10:33 +04:00
Classic298 3ccea416b4 fix: built-in tools disappear when a model has a custom tools parameter (#32530)
Adding a custom parameter named tools to a model, for example to turn on a provider's native web search, made Open WebUI drop all of its own tools for that model: notes, knowledge, tasks and any tools attached to the model stopped working, and attached files lost their context. Those tools now stay, and the model's custom tools are sent alongside them. API calls that pass their own tools, or an empty list to turn tools off, behave as before.

Fixes #32528
2026-10-16 14:09:32 +04:00
Classic298 823670d9fa fix: arXiv PDF links reach the model as raw bytes (#32524)
Files read from a URL are sent to a document parser based on their file name. An arXiv link like arxiv.org/pdf/1706.03762 has a dot in the paper ID, so the name was read as having the extension ".03762", the PDF went to the plain text reader and the model got raw PDF bytes. When the part after the dot is not a known file type, the extension now comes from the file type the server reports, so these links are read as PDFs. Files the server only labels as generic binary keep their name as before.
2026-10-16 14:09:08 +04:00
Classic298 a5942da0a2 fix: PDFs from some sites reach the model as raw bytes (#32523)
Before Open WebUI reads a URL for the model, it checks whether the URL is a web page or a file. That check went out without the user agent, browser headers and SSL verification setting the web loader uses, so sites that block unknown clients (Wikimedia, for example) refused it. The URL was then treated as a web page and the model got the raw PDF bytes instead of the document text. The check now sends the same request as the web loader, so it gets the same answer and files go to document extraction again.
2026-10-16 14:08:50 +04:00
Timothy Jaeryang BaekandClassic298 f5a26f53a0 refac
Co-Authored-By: Classic298 <27028174+Classic298@users.noreply.github.com>
2026-10-16 04:20:53 +04:00
Timothy Jaeryang Baek 788a61180b refac 2026-10-16 04:20:14 +04:00
G30 5dff6489d2 fix: someone with Write access saving a shared prompt or tool no longer makes it private (#32493)
The prompt and tool editors resend every stored grant on Save, and the
update routes ran that whole list through filter_allowed_access_grants.
A collaborator without the public sharing permission therefore had the
owner's Public grant stripped, and the stripped list replaced the stored
one, so one Save made the prompt or tool private for everyone else.

Keep grants that are already stored and filter only the ones the save
adds, as the model update route has done since 754c4b576.
2026-10-16 03:20:45 +04:00
Timothy Jaeryang Baek 597b00a547 refac 2026-10-16 03:17:14 +04:00
G30 ad3e5a6c42 fix: a chat you clone or fork from someone's share is yours to regenerate in (#32508)
Since cloned and forked chats keep each message's original author, a
copy of someone else's shared chat kept the sharer as the author of
every prompt and reply. Regenerate and Continue in the copy then failed
with "You can only regenerate your own messages.", and edits to those
messages were dropped on save, although the copy belongs to the person
who made it.

When a shared chat is cloned, or forked by someone other than its owner,
give the source owner's messages to the new owner, the same per-message
loop shared_chat_response uses to set authors. Messages written by other
participants of an Allow replies chat keep their authors.
2026-10-16 03:13:44 +04:00
Classic298 ae6793dd4f fix: OAuth token refresh ignores the client_secret_basic auth method (#32507)
When Open WebUI authenticates to the OAuth provider with client_secret_basic, either because OAUTH_TOKEN_ENDPOINT_AUTH_METHOD is set to it or because an MCP tool server's OAuth provider only offers that method, sign-in sent the client ID and secret in an HTTP Basic header but the token refresh always put them in the request body. Providers that only accept Basic rejected every refresh with invalid_client, so once the access token expired Open WebUI deleted the user's saved OAuth tokens, and model connections and tool servers set to forward the user's OAuth token stopped working until the user signed in again. The refresh now authenticates the same way sign-in does for client_secret_basic, with the credentials only in the Basic header. Setups using client_secret_post, or leaving the setting unset, still send the credentials in the request body exactly as before.

Fixes #32506
2026-10-16 03:01:35 +04:00