Commit Graph
569 Commits
Author SHA1 Message Date
Timothy Jaeryang Baek 25898116ea chore: format 2026-04-12 18:12:59 -05:00
Classic298 4292358bd5 feat: log provider errors to console for better insights (#23379)
* fix: log provider errors that were silently swallowed

* Update main.py

* fix: wrap non-JSON SSE error responses in JSON so middleware handles them
2026-04-12 18:07:20 -05:00
Classic298andClaude e7ff4768f8 fix: Add ownership checks to global task endpoints (#23454)
* Add ownership checks to global task endpoints

- Restrict GET /api/tasks and POST /api/tasks/stop/{task_id} to admin-only
- Add new scoped POST /api/tasks/chat/{chat_id}/stop endpoint with ownership
  check so regular users can stop their own chat tasks
- Allow admins to access the scoped chat task endpoints alongside owners
- Update frontend to use the new scoped stop endpoint when a chatId is available

https://claude.ai/code/session_01K7zPDvvjRu8AxJ4Br2HhZc

* Handle temporary (local:) chat IDs in scoped task endpoints

Temporary chats use local:<socketId> as chat_id which doesn't exist in
the DB. The scoped endpoints now skip ownership checks for local: IDs
(they aren't enumerable) and use {chat_id:path} to handle the colon in
the URL path.

https://claude.ai/code/session_01K7zPDvvjRu8AxJ4Br2HhZc

* Verify session ownership for local: chat IDs and URL-encode chat_id

- For local:<socketId> chat IDs, look up the socket's owner in
  SESSION_POOL and verify it matches the requesting user (or admin)
- URL-encode chat_id in frontend fetch calls to handle special
  characters (colon in local: IDs) safely

https://claude.ai/code/session_01K7zPDvvjRu8AxJ4Br2HhZc

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-12 17:56:43 -05:00
Timothy Jaeryang Baek c47dd7b771 refac 2026-04-12 17:22:06 -05:00
Classic298 83024d00bb fix: enforce API key endpoint restrictions at the auth layer, not middleware (#23637)
The APIKeyRestrictionMiddleware only inspected the Authorization header for sk- tokens, but get_current_user also reads API keys from cookies and x-api-key headers. This allowed complete bypass of endpoint restrictions by sending the key via an alternate transport.

Moves the restriction check into get_current_user_by_api_key so it runs regardless of how the API key was delivered. Removes the now-redundant middleware.
2026-04-12 16:33:41 -05:00
Timothy Jaeryang Baek 5ee791d5d2 refac 2026-04-12 16:25:01 -05:00
Timothy Jaeryang Baek 27169124f2 refac: async db 2026-04-12 14:22:11 -05:00
Timothy Jaeryang Baek 406251c2f3 enh: automation 2026-04-11 17:06:58 -06:00
Timothy Jaeryang Baek 4cee67e2be feat: mistral tts 2026-04-02 19:31:15 -05:00
Timothy Jaeryang Baek 0dd9f462ff feat: oauth backchannel logout 2026-04-02 08:46:34 -05:00
Timothy Jaeryang Baek 70c87a1ed1 refac 2026-04-01 05:54:58 -05:00
Timothy Jaeryang Baek c8ef5a4f38 chore: format 2026-04-01 04:36:02 -05:00
Timothy Jaeryang Baek 378673408e refac 2026-03-31 23:39:54 -05:00
Timothy Jaeryang Baek e6f38f52c8 feat: automation 2026-03-31 23:36:01 -05:00
Timothy Jaeryang BaekandJoost Mul 601bb78358 feat: oauth 2.1 static mcp
Co-Authored-By: Joost Mul <6438009+donmul@users.noreply.github.com>
2026-03-24 17:58:21 -05:00
Timothy Jaeryang Baek aa59b32374 refac 2026-03-21 18:49:22 -05:00
Timothy Jaeryang Baek f23296b22d refac 2026-03-20 16:30:41 -05:00
Timothy Jaeryang Baek b8ea267f8e refac 2026-03-17 18:01:18 -05:00
Timothy Jaeryang Baek de3317e26b refac 2026-03-17 17:58:01 -05:00
Timothy Jaeryang Baek b171b0216b refac 2026-03-17 17:54:59 -05:00
Jacob Leksan 14d876c259 Added Readiness probe (#22507) 2026-03-15 18:17:57 -05:00
Timothy Jaeryang Baek afa0609ece feat: support whitelist filtering in AuditLoggingMiddleware (#22515)
Add AUDIT_INCLUDED_PATHS env var for whitelist-based audit filtering.
When set, only matching paths are audited and AUDIT_EXCLUDED_PATHS is
ignored. Auth endpoints (signin/signout/signup) are always logged
regardless of filtering mode.
2026-03-11 15:41:42 -05:00
Timothy Jaeryang Baek c97767424f refac/fix 2026-03-08 17:26:29 -05:00
Ethan T. 61bbb99d9e fix: replace bare except with Exception in oauth.py (#22420)
* fix: replace bare except with except Exception in main.py

* fix: replace bare except with Exception in oauth.py

In Python 3, bare 'except:' is discouraged as it catches all
SystemExit and KeyboardInterrupt exceptions. Changed to 'except Exception:'
to only catch actual exceptions.
2026-03-08 16:36:53 -05:00
Timothy Jaeryang Baek ce0ca894fe enh: code interpreter pyodide fs 2026-03-07 19:23:18 -06:00
Algorithm5838 39deadcab1 perf: convert APIKeyRestrictionMiddleware to pure ASGI (#22188) 2026-03-06 14:54:03 -06:00
Timothy Jaeryang Baek 1357dc6737 chore: format 2026-02-28 21:28:59 -06:00
Timothy Jaeryang Baek 4737e1f118 feat: open terminal integration 2026-02-27 13:08:59 -06:00
Timothy Jaeryang Baek 9044abf3bb chore: format 2026-02-23 01:40:53 -06:00
Andrei Efanov 9e81e1dda1 feat: add LOG_FORMAT=json for structured JSON logging (#21747)
* feat: add LOG_FORMAT env var with JSON formatter for early logging

Introduce LOG_FORMAT environment variable (set to "json" to enable).
When active, logging.basicConfig() uses a JSONFormatter that outputs
single-line JSON objects with fields: ts, level, msg, caller, error,
stacktrace. This covers all log messages emitted during module imports
before Loguru's start_logger() takes over.

* feat: add JSON sink for Loguru when LOG_FORMAT=json

Add _json_sink() as a Loguru sink function that writes single-line JSON
to stdout. In start_logger(), conditionally use the JSON sink instead of
the plain-text stdout_format when LOG_FORMAT is set to "json".

* feat: suppress ASCII banner and fix alembic logging in JSON mode

- Wrap the ASCII art banner print in main.py with a LOG_FORMAT != "json"
  guard so JSON output stays machine-parseable.
- Skip alembic's fileConfig() call in migrations/env.py when
  LOG_FORMAT=json to prevent it from replacing the JSON log handlers
  installed during early startup.
2026-02-22 17:40:17 -06:00
Timothy Jaeryang Baek c341f97cfe feat: default model metadata & params 2026-02-22 16:54:34 -06:00
Classic298 e0087acfb4 fix: model fallback routing for all model types and default model selection (#21736)
fix: model fallback routing for all model types and default model selection

Backend: When ENABLE_CUSTOM_MODEL_FALLBACK is active and a custom model's
base model is unavailable, the fallback now swaps the model and form data
to the configured default model directly. This ensures routing uses the
fallback model's type (pipe, Ollama, or OpenAI) instead of the original
model's type, which previously caused "Model not found" errors when the
fallback was a different backend type.

Frontend: Fixed default model selection in new chat initialization where
the admin-configured default models were always overwritten by the first
available model. The first-available fallback now only triggers when the
configured defaults don't resolve to valid available models.
2026-02-22 15:24:14 -06:00
Timothy Jaeryang Baek 631e30e22d refac 2026-02-21 15:35:34 -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
Timothy Jaeryang Baek 5d4547f934 enh: RAG_EMBEDDING_CONCURRENT_REQUESTS 2026-02-21 14:33:48 -06:00
Timothy Jaeryang Baek 91a0301c9e refac 2026-02-19 16:29:19 -06:00
Timothy Jaeryang Baek 337109e99c refac 2026-02-16 13:10:01 -06:00
Timothy Jaeryang Baek 09dc28df1e chore: format 2026-02-16 00:43:32 -06:00
Timothy Jaeryang Baek b780d5c556 refac 2026-02-15 18:41:16 -06:00
Timothy Jaeryang BaekandSpootyMcSpoot f20cc6d7e6 refac
Co-Authored-By: SpootyMcSpoot <6732450+spootymcspoot@users.noreply.github.com>
2026-02-15 17:29:55 -06:00
Classic298andClaude 8cf32ae2a7 fix: prevent worker death during document upload by using run_coroutine_threadsafe (#21158)
* fix: prevent worker death during document upload by using run_coroutine_threadsafe

Replace asyncio.run() with asyncio.run_coroutine_threadsafe() in
save_docs_to_vector_db() to prevent uvicorn worker health check failures.

The issue: asyncio.run() creates a new event loop and blocks the thread
completely, preventing the worker from responding to health checks during
long-running embedding operations (>5 seconds default timeout).

The fix: Schedule the async embedding work on the main event loop using
run_coroutine_threadsafe(). This keeps the main loop responsive to health
check pings while the sync caller waits for the result.

Changes:
- main.py: Store main event loop reference in app.state.main_loop at startup
- retrieval.py: Use run_coroutine_threadsafe() instead of asyncio.run()

https://claude.ai/code/session_01UQSYvSTkXb57sFb7M85Kcw

* add env var

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-12 15:22:57 -06:00
Classic298andClaude d02e826c9d Fix idle in transaction leaks in Open WebUI (#20868)
* fix: add ScopedSession.remove() to prevent idle transaction leaks

The HTTP middleware was calling ScopedSession.commit() but not
ScopedSession.remove(), causing database connections to remain
"checked out" from the pool indefinitely. This resulted in
"idle in transaction" connections in PostgreSQL that could persist
for 30-50+ minutes.

With SQLAlchemy's scoped_session:
- commit() commits but keeps the session active
- remove() is required to return the connection to the pool

This fix adds the missing remove() call, ensuring connections are
properly returned after each HTTP request.

Also includes IDLE_TRANSACTION_ANALYSIS.md documenting the full
root cause analysis and additional recommendations.

* Delete IDLE_TRANSACTION_ANALYSIS.md

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-02-11 18:20:03 -06:00
Timothy Jaeryang Baek 60ada21c15 refac 2026-02-11 16:40:40 -06:00
Timothy Jaeryang Baek f376d4f378 chore: format 2026-02-11 16:24:11 -06:00
Timothy Jaeryang Baek c2207887b3 feat: skills backend 2026-02-11 14:00:34 -06:00
Timothy Jaeryang Baek 3e56261c5e refac 2026-02-11 02:06:43 -06:00
Tim Baek 48a0abb40f Merge pull request #21277 from open-webui/acl
refac: acl
2026-02-09 13:34:36 -06:00
Timothy Jaeryang Baek d193c143a5 refac 2026-02-08 21:18:38 -06:00