Commit Graph
17050 Commits
Author SHA1 Message Date
Timothy Jaeryang Baek 7ed7e81e84 refac 2026-06-29 10:39:54 -05:00
Timothy Jaeryang Baek 303c426c3f refac 2026-06-29 10:39:47 -05:00
Timothy Jaeryang Baek f9c3ccd869 refac 2026-06-29 10:04:29 -05:00
Timothy Jaeryang BaekandClassic298 eb53281c9a refac
Co-Authored-By: Classic298 <27028174+Classic298@users.noreply.github.com>
2026-06-29 06:08:31 -05:00
Timothy Jaeryang Baek a285a390c1 refac 2026-06-29 06:01:05 -05:00
Classic298 75df948f34 feat: forward client User-Agent to model backends via {{USER_AGENT}} placeholder (#26333)
Adds a {{USER_AGENT}} custom-header placeholder that relays the inbound
client's User-Agent to upstream model backends, so providers see the real
client instead of Open WebUI's internal aiohttp UA. This makes upstream
usage/cost attribution and backend telemetry possible, and is opt-in
per-connection (no global flag): admins add {{USER_AGENT}} to a connection's
custom headers in Admin > Settings > Connections.

The placeholder is sourced from the live inbound request (with a metadata
fallback for detached RAG/tool calls), so it resolves on every prompt-sending
path, not just chat completions:

- OpenAI completions, Responses API, and proxy — all route through
  get_headers_and_cookies, which now passes the request into get_custom_headers.
- Anthropic Messages API (/api/v1/messages) — already covered, it delegates
  to the chat completion handler.
- Ollama (/api/chat, /v1/completions, /v1/chat/completions, /v1/messages,
  /v1/responses) — previously had no custom-header support at all; send_request
  now applies per-connection custom headers (with templating) for every
  Ollama prompt endpoint.

Custom headers are applied after the built-in user-info headers so explicit
admin-configured headers take precedence. The other existing placeholders
({{CHAT_ID}}, {{USER_ID}}, ...) now also work on the newly covered paths.

Frontend: the connection editor's Headers field is now shown for Ollama
connections too (previously gated to non-Ollama), so the placeholder can be
configured there.

Ref: open-webui/open-webui#26159
2026-06-29 05:58:19 -05:00
Timothy Jaeryang Baek 260f3c3a22 refac 2026-06-29 05:56:08 -05:00
Timothy Jaeryang Baek b0487dd6dd refac 2026-06-29 05:49:54 -05:00
Timothy Jaeryang Baek 70e4ffcc65 refac 2026-06-29 05:49:49 -05:00
Timothy Jaeryang Baek 0883638027 refac 2026-06-29 05:47:21 -05:00
Timothy Jaeryang Baek ee5de69e37 refac 2026-06-29 05:46:55 -05:00
Timothy Jaeryang Baek 0cc331d1c6 refac 2026-06-29 05:46:51 -05:00
Timothy Jaeryang Baek 41f256321b refac 2026-06-29 05:46:47 -05:00
Timothy Jaeryang Baek 44b9463498 refac 2026-06-29 05:44:47 -05:00
Timothy Jaeryang Baek e6d35fc4cc refac 2026-06-29 05:39:17 -05:00
Timothy Jaeryang Baek 396d9ac181 refac 2026-06-29 05:27:51 -05:00
Timothy Jaeryang Baek 67a7b23b85 refac 2026-06-29 05:26:34 -05:00
Timothy Jaeryang Baek edf2c6c8f7 refac 2026-06-29 05:23:20 -05:00
Timothy Jaeryang Baek 0eba3df119 refac 2026-06-29 05:21:49 -05:00
Timothy Jaeryang Baek aa851d93c6 refac 2026-06-29 05:18:12 -05:00
Timothy Jaeryang Baek fa76764c3b refac 2026-06-29 05:16:57 -05:00
Timothy Jaeryang Baek 83ec36cd38 refac 2026-06-29 05:15:55 -05:00
Timothy Jaeryang Baek cdd7b88bec refac 2026-06-29 05:14:57 -05:00
Timothy Jaeryang Baek 8927c9bb3d refac 2026-06-29 05:14:34 -05:00
Timothy Jaeryang Baek 422a4768ea refac 2026-06-29 05:14:03 -05:00
maco c65b29ec0f fix: handle MCP resource content type blob and URI variants (#25260) 2026-06-29 05:12:11 -05:00
Timothy Jaeryang Baek 0be069c165 refac 2026-06-29 05:04:00 -05:00
G30 5ffd4e53c3 fix(ui): prevent long default group name from overflowing admin settings layout (#25685) 2026-06-29 04:59:01 -05:00
G30 4fa3a74827 fix(chat): prevent sortable sidebar drags from triggering file upload overlay (#25675)
Add a custom MIME type (application/x-open-webui-drag) to intentional
chat and folder drag sources. The onDragOver handler in MessageInput
now checks for this type instead of the generic text/plain, which
SortableJS also sets during reorder operations for pinned menu items
(Notes, Workspace) and pinned Models.
2026-06-29 04:58:30 -05:00
Timothy Jaeryang Baek 416baef813 refac 2026-06-29 04:57:28 -05:00
Timothy Jaeryang BaekandPedro Machado 45fea34bd0 refac
Co-Authored-By: Pedro Machado <45520277+pedrofcm@users.noreply.github.com>
2026-06-29 04:46:56 -05:00
Timothy Jaeryang Baek 953432b5fe refac 2026-06-29 04:43:40 -05:00
Timothy Jaeryang Baek e5b5e5917b refac 2026-06-29 04:43:08 -05:00
Timothy Jaeryang Baek 67c9de8efd refac 2026-06-29 04:42:59 -05:00
Timothy Jaeryang Baek a3b487422d refac 2026-06-29 04:42:02 -05:00
G30andTim Baek f53ec857c0 feat: support folder, note, and model drag-and-drop from sidebar as context references (#25771)
* feat(ui): add drag-to-reorder for pinned notes in sidebar

* feat(chat): support folder, note, and model drag-and-drop from sidebar as context references

---------

Co-authored-by: Tim Baek <tim@openwebui.com>
2026-06-29 04:41:16 -05:00
Timothy Jaeryang Baek b617d56c60 refac 2026-06-29 04:37:38 -05:00
Alberto de la Cruz 718b226177 fix: discover MCP Protected Resource Metadata when server does not return 401 (#25980)
get_protected_resource_metadata() only attempted RFC 9728 discovery when
the anonymous `initialize` probe returned 401 with a WWW-Authenticate
header. Some remote MCP servers — notably Google's Gmail/Drive/Calendar
MCPs (gmailmcp.googleapis.com, etc.) — answer 200 to an anonymous
initialize, so OAuth scope and authorization-server discovery silently
failed and connections to them could not be established.

Run the discovery regardless of the probe's HTTP status: prefer the
resource_metadata URL from WWW-Authenticate when present, and otherwise
fall back to the RFC 9728 §4.2 well-known URIs. The trade-off is a couple
of extra well-known GETs during MCP connection setup for servers that
expose no PRM document; behavior for 401-responding servers is unchanged.
2026-06-29 04:34:36 -05:00
Timothy Jaeryang Baek f8ec63203c refac 2026-06-29 04:31:43 -05:00
Timothy Jaeryang Baek fd7a59d37a refac 2026-06-29 04:27:48 -05:00
G30 ea6d02da0f fix(ui): use correct field name for prompt clone title suffix (#25800) 2026-06-29 04:25:21 -05:00
Timothy Jaeryang Baek ab84bbf08c refac 2026-06-29 04:19:33 -05:00
Timothy Jaeryang Baek b58b0ea7ca refac 2026-06-29 04:13:17 -05:00
Timothy Jaeryang Baek d3676b4f71 refac 2026-06-29 04:11:46 -05:00
Timothy Jaeryang Baek c4688b958d refac 2026-06-29 04:03:06 -05:00
Timothy Jaeryang Baek 33b91bd8ae refac 2026-06-29 03:58:00 -05:00
Classic298andClaude 4c05abbe59 fix: respect model visibility in workspace base model selector (#25668)
The base model selector in the model creation workspace listed every
model from the global store, ignoring the per-model visibility (hidden)
flag. Models marked as not visible were correctly hidden from the chat
model selector but still appeared in the workspace 'Base Model (From)'
dropdown.

Filter out hidden models (info.meta.hidden) to match the chat selector
behavior, while still keeping a model visible if it is the currently
selected base, so editing a preset built on a now-hidden base does not
show a blank dropdown.

Fixes #25665

https://claude.ai/code/session_01CUvzYN9DjvwTpNCT5QL33B

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-29 03:51:26 -05:00
Classic298 0fc630b34b fix: per-user model cache used static key= (cross-user model exposure) (#25783)
routers/openai.py and routers/ollama.py decorated get_all_models with
`@cached(key=lambda _, user: ...)`. In aiocache 0.12, `key=` is a STATIC
cache key: get_cache_key returns `self.key` verbatim (the lambda object)
without calling it, so every caller collides to ONE shared entry within
the TTL. The intended per-user namespacing never happened — one user's
permission-filtered model list could be served to another user (or an
anonymous caller) during the cache window.

The per-call hook is `key_builder=` (called as key_builder(func, *args,
**kwargs)). Switch both sites to key_builder with a (func, request,
user=None) signature so the key is built per call. user=None mirrors
ollama's optional-user signature and stays correct whether user is passed
positionally, as a kwarg, or omitted.

Verified offline: old form returns the same key object for distinct users
(collision); new form yields distinct openai_all_models_<id> /
ollama_all_models_<id> keys, and the unauthenticated base key when no user.
These two were the only @cached(key=lambda ...) sites in the backend.
2026-06-29 03:51:02 -05:00
G30 ee11069ef2 perf(ollama): offload multi-GB model file I/O with asyncio.to_thread (#25829)
The Ollama model upload and download handlers perform three stages
of sync file I/O on multi-GB model files inside async handlers:

1. Persist upload — file.file.read() + write() in a loop
2. SHA-256 hash — calculate_sha256() reads the file sequentially
3. Read for blob push — open().read() loads entire model into memory

All three stages block the event loop for the duration of the I/O.
For a 4GB model, each stage freezes the event loop for 10+ seconds
while every other user's request stalls.

Wrap each blocking stage in asyncio.to_thread() in both handlers:

- upload_model(): persist upload, calculate_sha256, blob read
- download_file_stream(): calculate_sha256, blob read

Benchmark (full pipeline: write + SHA-256 + read back, 3 trials):
- 200MB: max jitter 145ms → 1ms (145x improvement)
- 500MB: max jitter 1,026ms → 1ms (1,026x improvement)

File I/O is pure I/O — no GIL contention. asyncio.to_thread()
completely eliminates event loop blocking.
2026-06-29 03:48:48 -05:00
G30 b05be8a907 fix(notes): refresh pinned notes sidebar when a note is deleted (#25640) 2026-06-29 03:48:22 -05:00