798 Commits

  • fix: coding agent chats started with a terminal selected never get a title (#33971)
    A chat with a coding agent that was started with a terminal selected kept the default title, even with title generation on and a task model set. The title is now generated once the agent has replied, the same way as for any other model.
    
    Fixes #33970
  • perf: load the config and the session check at the same time on page load (#33914)
    Every page load fetched the app config, then checked the login session, then fetched the config a second time to pick up the logged-in settings, three requests in a row before the sidebar and chat could start loading. Now the first config request sends the login token, so it already returns the logged-in settings and the second fetch is gone, and the session check runs alongside it. A deleted or deactivated user whose old login was still saved in the browser landed on the "backend not detected" error page on every reload; they now go to the sign-in page.
    
    | Local run, 150 ms added to every request | dev branch | this change |
    |---|---|---|
    | Requests before the sidebar loads | 3 in a row | 2 in parallel |
    | Sidebar requests start at | 1240 ms | 875 ms |
  • fix: coding agent reply shows a raw id once its terminal is gone (#33880)
    After chatting with a coding agent through an Open Terminal connection, reopening the chat once that terminal was removed, switched off or no longer available to the user showed a long internal id such as agent:<terminal>:opencode:<model> at the top of the reply instead of the agent's name, both on the reply and in the chat overview. The name was only remembered while the chat stayed open, so every reload lost it. The name is now saved with the reply.
    
    Fixes #33879
  • fix: client IP header placeholders send 127.0.0.1 for automations, timers and sub-agents (#33891)
    When a connection's custom headers use {{USER_IP}} or {{X_FORWARDED_FOR}}, automation runs, timers, sub-agent runs and the model list fetch at startup filled them with 127.0.0.1. A provider that logs or rate-limits per client address then saw these requests as coming from the Open WebUI host. No client sends these requests, so the header is now sent with an empty value for them. Normal chats still send the real client address.
    
    Fixes #33882
  • feat: client IP placeholders for connection custom headers (#33833)
    Connection custom headers had no way to tell the upstream provider which client a request came from. Adding {{USER_IP}} and {{X_FORWARDED_FOR}} fills in the client address Open WebUI resolves for the request, for example {"X-Real-IP": "{{USER_IP}}"}. Both are empty when there is no client request, such as automations and background jobs. Headers that don't use them are unaffected.
    
    Fixes #33819
  • perf: sending a message in an existing chat loads the chat once instead of twice (#33669)
    When a message is sent in an existing chat, the server loaded the full chat, then loaded it again right after to check that the user has write access. The check now reuses the chat it already loaded. Who can write to a chat does not change. The saving grows with chat size and is small for ordinary chats.
    
    Time saved per message, measured on SQLite, best of 3 runs, sizes are the chat as stored in the database, images embedded:
    
    | Chat | Time saved |
    | --- | --- |
    | 7 MB, text only | 34 ms |
    | 49 MB, with images | 204 ms |
  • fix: chat stops with no answer when an MCP server request fails mid-chat (#33272)
    When an MCP tool server could not be reached for a tool call (server restarted, connection reset by a proxy or load balancer, a request timing out), the whole chat was cancelled as if the user had pressed stop, and the log only said "Task was cancelled!". Now only that tool call fails, the model gets the connection error as the tool result and the reply finishes, and the underlying connection error is logged. The MCP SDK cancels whatever task opened the session when a single request fails, so each MCP session now runs in its own task instead of the chat's.
    
    Fixes #33268
  • fix: "More Concise" and "Add Details" now revise the reply instead of answering the instruction (#33084)
    Choosing Add Details, More Concise, or typing a suggestion under a reply sent the model your original question followed straight by the bare instruction, with the reply itself missing, so it answered the instruction on its own (for example "OK, I'll keep answers shorter") instead of rewriting that reply. The model now receives the reply it is being asked to change, so it returns a shorter, more detailed or altered version of it. Plain Try Again and temporary chats were not affected.
    
    Fixes #33083
  • fix: built-in tool toggles show while their feature is off (#32964)
    * fix: built-in tool toggles show while their feature is off
    
    The model editor listed the Memory, Notes, Channels, Notifications, Web Search, Image Generation, Code Interpreter, Automations, Calendar and Sub-agents built-in tools even when the admin had turned that feature off for the whole instance, where those toggles do nothing. Each of them is now hidden while its feature is off, and the choices saved on a model are kept for when it is turned back on. The server now also reports whether sub-agents are on, and saving the Sub-agents settings updates the editor without a reload.
    
    Refs #32830
    
    * refac: name the feature switch map like the rest of the codebase
    
    Uses the same name the model capabilities change uses for its matching map.
    
    * refac: keep each tool's feature switch next to its label
    
    Each built-in tool now carries its feature switch alongside its label and description, so the list is defined in one place.
  • fix: Terminal capability shows while no terminal server exists (#32966)
    * fix: Terminal capability shows while no terminal server exists
    
    The Terminal capability showed in the model editor even when the admin had set up no terminal server and direct integrations were off, which is the default, so it did nothing. It now shows only when an enabled terminal server exists or users can add their own through direct integrations, and the value saved on a model is kept. The server now reports whether any enabled terminal server exists, since the editor itself only sees the servers the current user can access and a model can be shared with other users.
    
    Refs #32830
    
    * fix: hide the default terminal picker when no terminal is available
    
    The model editor still showed the default terminal line when no terminal server or direct integration was available. It now follows the same rule as the Terminal capability.
  • fix: saved direct tool servers still apply after direct integrations is turned off (#32996)
    Tool servers and Open Terminal connections a user added in their Integrations settings kept loading and were still used in every chat after the admin turned Direct Integrations off, which only hid the settings tab. They are now ignored while Direct Integrations is off, for admins and users alike, and the server ignores them even when a request still includes them. The saved connections stay in each user's settings and come back as soon as the switch is turned on again.
  • fix: auto-generation settings show while the admin turned them off (#32973)
    Settings > Interface offered the title, follow-up and chat tag auto-generation switches even when the admin turned those generations off, so switching them did nothing. Each switch now only shows while its generation is on. The settings for keeping and inserting follow-up prompts stay, because they still apply to follow-ups saved in existing chats. Saved choices are kept and apply again once the admin turns the generation back on.
    
    Refs #32830
  • fix: editing a WebP image fails with the built-in image editor (#32902)
    Editing a WebP image (an uploaded one, or one generated by a provider that returns WebP) failed in the Docker image. Python only learns the WebP type from a system file the image does not ship, so the picture went to the image provider labelled with no type at all, and providers rejected it. WebP is now registered at startup like the other types Open WebUI already sets, so the provider receives it as image/webp.
    
    Fixes #32899
  • 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
  • feat: record the requested model as its own field in the audit log (#32429)
    The audit log only showed which model a request used inside the logged request body, which is cut off at MAX_BODY_LOG_SIZE, so the model went missing whenever a long prompt came before it. Audit entries for chat and completion requests, including the OpenAI, Ollama and Anthropic-compatible endpoints, now carry a model_id field with the model the client asked for, at every AUDIT_LOG_LEVEL and however long the request is. Other requests log it as null.
    
    Fixes #30097
  • fix: browser gets stuck in a reload loop after a server upgrade (#31631)
    After a server upgrade, browsers could keep reusing their cached copy of the old app page for days, since it was sent with no caching instructions. That old page points at files the new version no longer has, so the app reloads into the same cached page and loops until a hard refresh. The app page now tells the browser to check for a newer version on every visit, which is a tiny request when nothing changed. Other files are cached as before, and an admin-set CACHE_CONTROL still takes precedence.
    
    Fixes #31630
  • fix: Chat failed notifications are not sent when the provider returns an error status (#32198)
    Notification targets subscribed to Chat failed stayed silent when the provider answered a chat with an error status, such as a 500, or could not be reached at all. Those failures show up as an error in the chat, but only a few uncommon failures were announced to the targets. Now these failures notify Chat failed targets too, with the error text and a link to the chat.
    
    Fixes #32003
  • fix: user can no longer chat after losing access to model controls they had used (#32194)
    A user who had picked an option in a model control (the per-model selector in the chat input, for example High on a Thinking control) could not chat any more once the admin switched off Allow Chat Controls or Allow Chat Params for them. Every message failed with "You cannot change model parameters.", and the user could not clear the saved selection because the selector is hidden for them. When either permission is off, the saved selection is now skipped when sending, so messages go through with the model's default options, and it applies again if the permission comes back.
    
    Fixes #31995
  • fix: automations, timers and sub-agents fail with "Message already exists" (#32177)
    Automation runs, timers and sub-agents stopped getting a reply after the shared chats rework: the chat shows an empty answer and the run fails with `409 Message already exists or has an invalid ID.` Each of them creates the empty answer before asking the model, and the backend began refusing to fill an answer that is already in the chat; the server-side API flow in the docs and API calls without a user message broke the same way. Such an empty answer is now filled in again when it belongs to the same user and answers the same message, and API calls without a user message work as before, saving the reply on its own as the docs describe. A firing timer or sub-agent also no longer cancels the chat's other timers that are set to stop when the user writes next. Answers that are already finished, or that belong to another user in a shared chat, are still refused.
    
    Fixes #32066