Commit graph

15327 commits

Author SHA1 Message Date
theeggorchicken
a0c82c8e4c
fix: race condition in signup allows multiple admin accounts (#21631)
The signup_handler function checks has_users() before inserting a new user
and assigns the admin role based on that check. With multiple uvicorn workers,
concurrent signup requests during first-user registration can all observe an
empty user table before any insert completes, causing multiple accounts to
receive the admin role.

Fix: insert with the default role first, then check user count after the
insert. Only promote to admin if this is the only user in the database.
This eliminates the TOCTOU window between the check and the insert.
2026-02-21 15:37:08 -06:00
Timothy Jaeryang Baek
631e30e22d refac 2026-02-21 15:35:34 -06:00
Timothy Jaeryang Baek
c114fd6876 refac 2026-02-21 15:33:21 -06:00
G30
c2172e43eb
fix(ui): prevent drag-and-drop ghost cursors and text highlighting on admin and workspace navigation tabs (#21701) 2026-02-21 15:23:58 -06:00
Timothy Jaeryang Baek
1ad3656872 refac 2026-02-21 15:22:50 -06:00
Timothy Jaeryang Baek
ff7f38d343 refac 2026-02-21 15:20:31 -06:00
Timothy Jaeryang Baek
bc482b9cce refac 2026-02-21 15:17:36 -06:00
Timothy Jaeryang Baek
4c94f5d434 refac 2026-02-21 15:16:22 -06:00
Timothy Jaeryang Baek
4b9f821b58 enh: OAUTH_GROUP_DEFAULT_SHARE 2026-02-21 15:08:06 -06:00
Timothy Jaeryang Baek
35598b8017 enh: ENABLE_ADMIN_ANALYTICS 2026-02-21 14:56:19 -06:00
Classic298
45e23c3ad0
perf: eliminate 2 redundant full chat deserialization on every message send (#21596)
* perf: eliminate 2 redundant full chat deserialization on every message send (#162)

Problem:
Every message send triggered get_chat_by_id_and_user_id which loads the
entire Chat row — including the potentially massive JSON blob containing
the full conversation history — even when the caller only needed a
simple yes/no ownership check or a single column value.

Two call sites in the message-send hot path were doing this:

1. main.py ownership verification: loaded the entire chat object including
   all message history JSON, then checked `if chat is None`. The JSON blob
   was immediately discarded — only the existence of the row mattered.

2. middleware.py folder check: loaded the entire chat object including all
   message history JSON, then read only `chat.folder_id` — a plain column
   on the chat table that requires zero JSON parsing.

Fix:
- Added `chat_exists_by_id_and_user_id()`: uses SQL EXISTS subquery which
  returns a boolean without loading any row data. The database can satisfy
  this from the primary key index alone.

- Added `get_chat_folder_id()`: queries only the `folder_id` column via
  `db.query(Chat.folder_id)`, which tells SQLAlchemy to SELECT only that
  single column instead of the entire row.

Both new methods preserve the same error handling semantics (return
False/None on exception) and user_id filtering (ownership check) as
the original get_chat_by_id_and_user_id.

Impact:
- Best case (typical): eliminates deserializing 2 full chat JSON blobs per
  message send. For long conversations (hundreds of messages with tool
  calls, images, file attachments), this blob can be multiple megabytes.
- Worst case: no regression — the new queries are strictly cheaper than
  the old ones (less data transferred, less Python object construction,
  no Pydantic model_validate overhead).
- The 3 remaining full chat loads in process_chat_payload (load_messages_from_db,
  add_file_context, chat_image_generation_handler) are left untouched as
  they genuinely need the full history and require separate analysis.

* Address maintainer feedback: rename method and inline call (#166)

- Rename chat_exists_by_id_and_user_id -> is_chat_owner
- Remove intermediate chat_owned variable; call is_chat_owner directly in if condition
2026-02-21 14:53:31 -06:00
lazariv
5759917f54
feat: Adding You.com as a web search provider (#21599)
* Add ydc.py provider implementation

* Add PersistentConfig entry for you.com

* Add Youcom search function import

* Update you.com configuration

* Add you.com as a web search engine option in frontend

* Add YOUCOM_API_KEY to main.py
2026-02-21 14:51:56 -06:00
Classic298
d247adb60c
feat: add citation sources for fetch_url tool results (#21669)
feat: add citation sources for fetch_url tool results

URL fetches now produce clickable citation sources in the UI, matching
the existing behavior of search_web and knowledge file tools. When a
model calls fetch_url during native tool calling, the fetched URL
appears as a citable source with a content preview, giving users full
transparency into what pages the model referenced.
2026-02-21 14:49:19 -06:00
G30
8c713a171d
fix(backend): catch 404 http exceptions before generalized exception block in files router (#21687) 2026-02-21 14:48:51 -06:00
Timothy Jaeryang Baek
7e42d727e8 refac 2026-02-21 14:39:28 -06:00
Classic298
9f7dd31e12
feat: scroll to rich ui once rendered (#21698)
* Update Chat.svelte

* Update Chat.svelte
2026-02-21 14:35:32 -06:00
Timothy Jaeryang Baek
5d4547f934 enh: RAG_EMBEDDING_CONCURRENT_REQUESTS 2026-02-21 14:33:48 -06:00
G30
5522b91c32
fix(ui): align profile dropdown items and prevent phantom synthetic drag clicks (#21699) 2026-02-21 14:31:35 -06:00
Timothy Jaeryang Baek
3242dad8ae refac 2026-02-21 14:29:40 -06:00
G30
6d8a6e6d8b
fix(model-selector): resolve virtual scroll bug when typing quickly (#21659) 2026-02-21 14:22:50 -06:00
Timothy Jaeryang Baek
8265422ba0 refac 2026-02-21 14:22:20 -06:00
Timothy Jaeryang Baek
10c13b686c refac 2026-02-21 14:19:28 -06:00
Classic298
b1dc58ddb7
feat: add sortable columns to groups admin panel (#21692)
* feat: add sortable columns to groups admin panel

Make the Group and Users column headers in the admin groups list clickable to sort groups alphabetically by name or numerically by member count. Clicking a column toggles ascending/descending order, indicated by a chevron icon. When no sort is active, the default API order (by updated_at) is preserved.

* Update Groups.svelte

* Update Groups.svelte
2026-02-21 14:18:37 -06:00
Timothy Jaeryang Baek
a9312d2537 refac 2026-02-21 14:15:32 -06:00
Classic298
4228bf71c4
fix: gate model default features on global config and user permissions (#21690)
fix: gate model default features on global config and user permissions

If you disabled code interpreter globally and in user permissions but
enabled it as a default feature on a model, the code interpreter pill
still appeared in the chat input. Same issue for web search and image
generation.

The setDefaults function in Chat.svelte activated model default features
based solely on the model's capability flag, ignoring whether the feature
was globally enabled or allowed by user permissions. Added the same
global config and user permission checks already used by the integrations
menu visibility and the features object sent to the backend.
2026-02-21 13:54:47 -06:00
Classic298
ac620118c1
fix group search (#21691) 2026-02-21 13:53:47 -06:00
G30
d650c987ec
fix: resolve backend execution deadlock when syncing stats with cyclic chat history (#21681) 2026-02-20 23:04:36 -05:00
Timothy Jaeryang Baek
092a358b3c refac 2026-02-20 16:55:06 -06:00
Timothy Jaeryang Baek
ae05586fda refac: oauth session management 2026-02-20 16:49:43 -06:00
G30
f5e5632afc
fix(chat): prevent stuck drop overlay when dragging outside window in firefox (#21664) 2026-02-20 14:01:24 -06:00
Timothy Jaeryang Baek
2a804541e0 refac
Co-Authored-By: Leandro Ygor Loli <77518998+leandroyloli@users.noreply.github.com>
2026-02-19 16:57:32 -06:00
Timothy Jaeryang Baek
8c485b260f refac 2026-02-19 16:53:21 -06:00
Classic298
d664922feb
Avoid loading full chat JSON blob for pinned/archived/shared list endpoints (#21591)
Co-authored-by: Tim Baek <tim@openwebui.com>
2026-02-19 16:48:23 -06:00
fchevallieratecna
9950cc8c28
fix(i18n): correct French typo "Analtique" → "Analytique" (#21512) 2026-02-19 16:42:57 -06:00
Classic298
3db6d49e57
Query title column directly in get_chat_title_by_id instead of loading full chat (#157) (#21590)
Previously loaded the entire ChatModel (including the full conversation JSON
blob) just to extract the title string. Now queries only the Chat.title
column directly, which is already a top-level DB column.
2026-02-19 16:41:46 -06:00
VasilyLebedev123
6d67ac371d
fix: correct unpacking order of distances, documents, and metadatas in hybrid search query (#21562)
Co-authored-by: Vasily Lebedev <Vasily.Lebedev@sapowernetworks.com.au>
2026-02-19 16:38:40 -06:00
Classic298
326599b8db
Fix O(n²) performance in get_message_list by replacing insert(0) with append+reverse (#21588)
Co-authored-by: Jordan <CenteredAxis@users.noreply.github.com>
2026-02-19 16:38:01 -06:00
Classic298
c5c31ab769
fix: respect BYPASS_ADMIN_ACCESS_CONTROL in file list/search endpoints (#21595) 2026-02-19 16:36:48 -06:00
Kylapaallikko
43eb2351d2
Update fi-FI translation.json (#21538)
Added missing translations.
2026-02-19 16:36:32 -06:00
Timothy Jaeryang Baek
0a700aafe4 refac 2026-02-19 16:32:41 -06:00
Timothy Jaeryang Baek
91a0301c9e refac 2026-02-19 16:29:19 -06:00
Timothy Jaeryang Baek
6ac593209c refac 2026-02-19 16:09:54 -06:00
Shirasawa
12bea8cd88
i18n: improve Chinese translation (#21530) 2026-02-19 16:06:23 -06:00
joaoback
1dfe546b6b
i18n: pt-BR - add translations for newly added UI items + consistency pass (#21527)
Translate all remaining untranslated strings to Brazilian Portuguese (pt-BR)

Translated ~100 previously untranslated entries (empty "" values) across the Open WebUI i18n JSON file. Changes include:

Translated UI labels, form fields, tooltips, and error messages
Kept brand/product names unchanged where appropriate (e.g., Bing, Brave, Gemini, OpenAI, YouTube)
Translated technical terms with context-appropriate Brazilian Portuguese equivalents (e.g., "Timeout" → "Tempo limite", "Config" → "Configuração", "Endpoint URL" → "URL do Endpoint")
Added translations for search engine integrations (Kagi, Perplexity, SerpApi, Tavily, Yacy, Yandex, etc.)
Translated plural forms for source retrieval messages (sources_one, sources_many, sources_other)
No untranslated entries remain in the file.
2026-02-19 16:06:08 -06:00
Classic298
ff837031e4
Update iframe sandbox attributes based on settings (#21529)
Co-authored-by: :o <52920416+gg0h@users.noreply.github.com>
2026-02-19 16:05:47 -06:00
Timothy Jaeryang Baek
139f02a9d9 refac 2026-02-19 16:04:41 -06:00
Timothy Jaeryang Baek
4bef69cc63 refac 2026-02-19 16:03:03 -06:00
Timothy Jaeryang Baek
723185c22f refac 2026-02-19 15:59:58 -06:00
Classic298
35763a352c
Optimize shared chats list to use column projection (#163) (#21614)
The GET /chats/shared endpoint was loading full Chat rows including
the entire conversation history JSON blob, only to discard it and
return SharedChatResponse (id, title, share_id, timestamps). Now
uses with_entities() to select only the 5 needed columns, avoiding
deserialization of potentially large chat JSON for every shared chat.
2026-02-19 15:50:03 -06:00
Patrick Monteith
27c76c677a
fix: clamp SCIM pagination args instead of rejecting them (#21577)
RFC 7644 §3.4.2.4 specifies that out-of-range pagination values MUST be
clamped, not rejected. The previous implementation used FastAPI Query
constraints (ge=1, le=100) which caused a 422 response for values like
startIndex=0 or count=9999 — violating the spec.

For both /Users and /Groups:
- startIndex < 1 is now treated as 1 (spec: "SHALL be interpreted as 1")
- count < 0 is now treated as 0 (spec: "SHALL be interpreted as 0")
- count > 100 is clamped to the server maximum of 100

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 15:08:42 -06:00