-
Notifications
You must be signed in to change notification settings - Fork 0
Groups #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: coderabbitai/docstrings/4269df0
Are you sure you want to change the base?
Groups #19
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the 📝 WalkthroughSummary by CodeRabbit
Summary by CodeRabbit
WalkthroughThis pull request introduces widespread improvements across CI/CD pipelines, backend logic, frontend components, and dependency management. Changes include updates to GitHub Actions workflows, version bumps in CHANGELOG and dependency files, new environment variables and configurations for direct connections and code execution, refined access control and messaging logic in backend modules, and several UI and styling adjustments in Svelte components. Docker-compose files are restructured as well. Overall, the update modernizes development workflows, adds new API endpoints and configuration options, and adjusts styling for better clarity and consistency. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant "Admin Settings\n(Svelte Component)"
participant "API Config\nEndpoints"
participant Backend
User->>Admin Settings: Update Direct Connections / Code Execution settings
Admin Settings->>API Config Endpoints: Submit configuration update request
API Config Endpoints->>Backend: Validate token and update configuration
Backend-->>API Config Endpoints: Return updated config/status
API Config Endpoints-->>Admin Settings: Success response
Admin Settings-->>User: Display success notification
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 32
🔭 Outside diff range comments (1)
backend/open_webui/routers/memories.py (1)
19-20
:⚠️ Potential issueUpdate test endpoint to include user parameter.
The test endpoint
get_embeddings
needs to be updated to include the user parameter for consistency with other changes.@router.get("/ef") -async def get_embeddings(request: Request): - return {"result": request.app.state.EMBEDDING_FUNCTION("hello world")} +async def get_embeddings(request: Request, user=Depends(get_verified_user)): + return {"result": request.app.state.EMBEDDING_FUNCTION("hello world", user)}
🧹 Nitpick comments (115)
pyproject.toml (3)
58-58
: Transformers Dependency
Thetransformers
library has been added without a specified version. It is advisable to pin a version or define a version range to ensure reproducible builds and avoid unexpected breaking changes in the future.
100-102
: New Google API Dependencies
Addedgoogle-api-python-client
,google-auth-httplib2
, andgoogle-auth-oauthlib
without specified versions. Consider pinning these dependencies to mitigate risks from future breaking changes and ensure reproducible builds.
116-116
: New Dependency: firecrawl-py
Addedfirecrawl-py==1.12.0
. Ensure that the new functionality provided by this library is covered by appropriate tests and integrated correctly within your codebase.backend/open_webui/retrieval/web/jina_search.py (2)
31-31
: Cap count more explicitly or document the rationale.The payload restricts
count
to a maximum of 10. This is likely intended, but ensure it is clearly documented or validated externally so that calling code is aware of this cap.
33-34
: Check response for partial successes.While
response.raise_for_status()
helps, consider verifying partial or unexpected response data (e.g., a truncated result set). For reliability, you might also handle JSON decoding errors separately if the API fails in non-2XX scenarios.backend/open_webui/retrieval/web/google_pse.py (3)
20-30
: Enforce or clarify the maximum count in docs/code.The docstring indicates a maximum of 100 results, but there’s no explicit check for
count <= 100
. Ifcount
is greater than 100, the loop might continue, though subsequent pages might fail. Clarify this either by enforcing it in code or documenting what behavior to expect beyond 100 results.
34-35
: Initialize container variables close to usage.
all_results = []
andstart_index = 1
are logically tied to the pagination loop below. Consider grouping them with the loop for improved clarity and maintainability.
37-58
: Validate pagination termination logic.The
while count > 0:
condition andif not results: break
approach is correct, but ensure it gracefully handles any intermittent errors or empty pages from the API. Consider adding a specific limit on how many pages you attempt.src/lib/apis/utils/index.ts (4)
3-4
: Remove or handle unused error variable.The
error
variable is assigned but never used upon returning. You could eliminate it for clarity or rethrow it to maintain consistent error handling.-export const getGravatarUrl = async (token: string, email: string) => { - let error = null; +export const getGravatarUrl = async (token: string, email: string) => {🧰 Tools
🪛 ESLint
[error] 4-4: 'error' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
26-58
: Suggest consolidating error handling.The new
executeCode
function effectively captures errors, but consider consolidating the.then(async ...)
and.catch(...)
logic intotry/catch
for improved readability and consistent control flow.
60-60
: Apply consistent approach or remove leftover variable.Like other functions,
formatPythonCode
sets anerror
variable, but usage patterns differ across the file. Maintaining a consistent or simpler approach would reduce confusion.
94-105
: Handle large attachments for chat PDF.
downloadChatAsPDF
sends logs via JSON. Ifmessages
is large, consider chunked approaches or compression. Otherwise, you risk request size limits or timeouts.🧰 Tools
🪛 ESLint
[error] 95-95: 'error' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
backend/open_webui/utils/code_interpreter.py (2)
98-99
: Consider clarifying variable naming for outputs.Renaming variables such as
stdout
,stderr
, andresult
to more descriptive names (e.g.,captured_stdout
,captured_stderr
,captured_result
) could improve readability and maintainability without altering functionality.
131-133
: Ensure closed WebSocket connection on timeout.When a timeout occurs, the code appends a timeout message to
stderr
and breaks out of the loop. Consider explicitly closing the WebSocket to avoid potential resource leaks.backend/open_webui/utils/payload.py (1)
14-14
: Use shorterparams.get("system")
call.The default value
None
is redundant. You can replaceparams.get("system", None)
withparams.get("system")
to adhere to the static analysis suggestion.🧰 Tools
🪛 Ruff (0.8.2)
14-14: Use
params.get("system")
instead ofparams.get("system", None)
Replace
params.get("system", None)
withparams.get("system")
(SIM910)
src/lib/apis/openai/index.ts (2)
211-236
: Reduce duplication with verify logic.
getOpenAIModelsDirect
and thedirect
branch ofverifyOpenAIConnection
share similar fetching and error handling patterns. Consider extracting common behavior into a shared helper for maintainability and consistency.
281-302
: Consolidate error handling.The direct connection logic includes similar fetch/catch approaches as elsewhere. Extracting a shared error-handling utility could simplify maintenance and keep error reporting consistent.
backend/open_webui/routers/configs.py (1)
61-66
: Consider concurrency control for config updates.When multiple requests update the config concurrently, there could be race conditions. If config changes must be consistent under concurrent writes, consider adding locks or switching to a thread-safe/unified storage mechanism (e.g., a database or an atomic file write).
src/lib/components/admin/Settings/Connections.svelte (2)
107-118
: Add error handling for internal request failures.While catching rejections with
.catch((error) => { ... })
is good, you might also log or handle errors in a more user-friendly way, ensuring the UI properly reflects partial failures of other update requests in case of parallel calls.
196-202
: Improve resilience in the combinedsubmitHandler
.The
submitHandler
updates multiple services (OpenAI, Ollama, Direct Connections) in quick succession. On partial failure (e.g., if Ollama fails to update), the subsequent calls still proceed. Depending on your requirements, consider short‐circuiting on errors or enumerating them for finer user feedback.backend/open_webui/routers/pipelines.py (3)
12-12
: Avoid mixing synchronousrequests
import while migrating to async.
You still importrequests
(line 16) yet introducedaiohttp
(line 12). If all requests in this file go throughaiohttp
, consider removing therequests
import to reduce confusion and ensure consistency.- import requests
69-78
: Use of shared session context.
Creating a newaiohttp.ClientSession()
inside each function call can be efficient if done once, but repeated usage in a larger scope may be beneficial. Consider centralizing session creation if there's a performance bottleneck.
83-104
: UnusedClientResponseError
variable and exception chaining.
- Variable
e
inexcept aiohttp.ClientResponseError as e
(line 95) isn’t used. Consider omitting the variable name:-except aiohttp.ClientResponseError as e: +except aiohttp.ClientResponseError:
- Best practice: chain exceptions (line 102) for better traceback.
🧰 Tools
🪛 Ruff (0.8.2)
95-95: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
102-102: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
backend/open_webui/utils/oauth.py (4)
4-52
: Consolidate logging configuration and remove duplicates.
Lines 38–43 and 48–52 define log configurations with multiple environment variables. Consider merging them or ensuring only one place sets logging to reduce confusion.
85-90
: Clearer debug logs.
These newly added debug logs add clarity for admin role assignment, but consider using structured logs (e.g., including user IDs) for faster issue diagnosis.
139-146
: Nestedwith
statements & raise-from usage.
- Lines 257–260: Static analysis suggests a single
with
statement for multiple contexts.- Line 284: Use
raise ... from e
for more informative tracebacks.
419-426
: Cookie security checks.
Usinghttponly=True, samesite, secure=True
is good. Periodically review if advanced settings (e.g., domain scoping) are needed for multi-domain setups.backend/open_webui/routers/knowledge.py (3)
20-20
: Remove unused import.
Static analysis indicatesStorage
is imported but not used.-from open_webui.storage.provider import Storage
🧰 Tools
🪛 Ruff (0.8.2)
20-20:
open_webui.storage.provider.Storage
imported but unusedRemove unused import:
open_webui.storage.provider.Storage
(F401)
267-271
: File addition permission checks.
Reiterates the write permission logic for a different route. DRY principle might help centralize repeated access control checks.
510-539
: Bulk model reference cleanup.
Updating each model to remove references to the deleted knowledge base is a good approach. Keep an eye on performance if references become large.backend/open_webui/retrieval/utils.py (2)
218-233
: Refine partial error handling.
get_all_items_from_collections
logs exceptions and continues, which could lead to partially merged results. If this behavior is intended, ensure the caller is aware of potential incomplete merges. Otherwise, consider raising an exception to signal that some collections failed.
319-326
: Avoid assigning alambda
expression to a variable.According to static analysis (E731), it is more readable and debuggable to define a named function instead of assigning
lambda
tofunc
.- func = lambda query, user=None: generate_embeddings( - engine=embedding_engine, - model=embedding_model, - text=query, - url=url, - key=key, - user=user, - ) + def func(query, user=None): + return generate_embeddings( + engine=embedding_engine, + model=embedding_model, + text=query, + url=url, + key=key, + user=user, + )🧰 Tools
🪛 Ruff (0.8.2)
319-326: Do not assign a
lambda
expression, use adef
Rewrite
func
as adef
(E731)
backend/open_webui/retrieval/web/utils.py (3)
87-96
: Enhance metadata extraction.
extract_metadata
is straightforward. Consider also extracting additional SEO meta tags (e.g., Open Graph data) if relevant for your workflow.
98-114
: SSL verification is helpful but be mindful of performance.
verify_ssl_cert
performs a socket connection each time. For a large batch of URLs, consider caching or reusing connections to reduce overhead.
447-450
: Use a ternary operator for brevity.You can streamline choosing a parser based on file extension with an inline conditional. This improves readability.
- if url.endswith(".xml"): - parser = "xml" - else: - parser = self.default_parser + parser = "xml" if url.endswith(".xml") else self.default_parser🧰 Tools
🪛 Ruff (0.8.2)
447-450: Use ternary operator
parser = "xml" if url.endswith(".xml") else self.default_parser
instead ofif
-else
-blockReplace
if
-else
-block withparser = "xml" if url.endswith(".xml") else self.default_parser
(SIM108)
backend/open_webui/routers/tasks.py (1)
579-580
: Avoid specifying default ofNone
if you're usingget
.Where you do
form_data.get("chat_id", None)
, you can omitNone
as it’s the default return if key is missing:- "chat_id": form_data.get("chat_id", None), + "chat_id": form_data.get("chat_id"),🧰 Tools
🪛 Ruff (0.8.2)
579-579: Use
form_data.get("chat_id")
instead ofform_data.get("chat_id", None)
Replace
form_data.get("chat_id", None)
withform_data.get("chat_id")
(SIM910)
backend/open_webui/routers/images.py (5)
58-61
: Add Gemini config to get_config
These lines add the Gemini API block to the config response. Consider validating or providing defaults in case configuration is incomplete.
246-251
: Set default Gemini model
Using "imagen-3.0-generate-002" as a fallback. Consider making this configurable if additional Gemini models become available.
327-330
: Limited Gemini model list
Only one default Gemini model is returned here. This is acceptable for now but might require more robust listing in the future.
423-433
: Refactor load_url_image_data
Handles optional request headers and returns image content and MIME type. Consider using a ternary expression per the static analysis suggestion.-def load_url_image_data(url, headers=None): - if headers: - r = requests.get(url, headers=headers) - else: - r = requests.get(url) +def load_url_image_data(url, headers=None): + r = requests.get(url, headers=headers) if headers else requests.get(url)🧰 Tools
🪛 Ruff (0.8.2)
425-428: Use ternary operator
r = requests.get(url, headers=headers) if headers else requests.get(url)
instead ofif
-else
-blockReplace
if
-else
-block withr = requests.get(url, headers=headers) if headers else requests.get(url)
(SIM108)
521-547
: Gemini engine for image generation
Adds new logic to call the Gemini API with thex-goog-api-key
header. Consider optionally adding user info headers for consistency with other providers.backend/open_webui/routers/audio.py (2)
197-198
: Store Deepgram key
Ensure the key isn’t logged or inadvertently exposed in error messages.
539-601
: Deepgram transcription block
Implements new STT logic for Deepgram. Consider usingraise ... from e
to preserve traceback context in exceptions.except Exception as e: log.exception(e) - raise Exception(detail if detail else "Open WebUI: Server Connection Error") + raise Exception(detail if detail else "Open WebUI: Server Connection Error") from e🧰 Tools
🪛 Ruff (0.8.2)
578-580: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
600-600: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
src/lib/apis/index.ts (3)
4-8
: Use a more specific type for 'connections'.
Declaringconnections
asobject | null
sacrifices compile-time type safety. Consider creating an interface or a more descriptive type to clarify the exact shape of theconnections
parameter.
34-36
: Consolidate nested checks on 'connections'.
You already checkconnections && !base
at line 34, but line 37 re-checksif (connections)
. Merging or simplifying these conditions can reduce confusion.
77-83
: Remove unused 'err' variable or log it for debugging.
Static analysis flags thaterr
is never used. If you want to keep it for logging, use it in the block; otherwise, remove it from the function parameters.- .catch((err) => { + .catch(() => { return { object: 'list', data: [], urlIdx: idx }; });🧰 Tools
🪛 ESLint
[error] 77-77: 'err' is defined but never used.
(@typescript-eslint/no-unused-vars)
backend/open_webui/routers/auths.py (1)
170-170
: Remove unused local variable.
LDAP_SERVER_LABEL
is never referenced after assignment. You can remove the assignment to clean up the code.🧰 Tools
🪛 Ruff (0.8.2)
170-170: Local variable
LDAP_SERVER_LABEL
is assigned to but never usedRemove assignment to unused variable
LDAP_SERVER_LABEL
(F841)
backend/open_webui/main.py (4)
158-159
: Remove unused imports for whisper models.
WHISPER_MODEL_AUTO_UPDATE
andWHISPER_MODEL_DIR
are not used anywhere, so it’s best to remove them to avoid confusion and maintain a clean import list.Apply something like:
- from open_webui.config import ( - WHISPER_MODEL_AUTO_UPDATE, - WHISPER_MODEL_DIR, - ... - ) + from open_webui.config import ( + ... + )🧰 Tools
🪛 Ruff (0.8.2)
158-158:
open_webui.config.WHISPER_MODEL_AUTO_UPDATE
imported but unusedRemove unused import
(F401)
159-159:
open_webui.config.WHISPER_MODEL_DIR
imported but unusedRemove unused import
(F401)
961-961
: Prefer shorter.get()
calls.
Replaceform_data.get("model", None)
withform_data.get("model")
to simplify and conform to best practices.- model_id = form_data.get("model", None) + model_id = form_data.get("model")🧰 Tools
🪛 Ruff (0.8.2)
961-961: Use
form_data.get("model")
instead ofform_data.get("model", None)
Replace
form_data.get("model", None)
withform_data.get("model")
(SIM910)
989-989
: Shorten argument usage for 'variables'.
Replaceform_data.get("variables", None)
withform_data.get("variables")
for consistency and readability.- "variables": form_data.get("variables", None), + "variables": form_data.get("variables"),🧰 Tools
🪛 Ruff (0.8.2)
989-989: Use
form_data.get("variables")
instead ofform_data.get("variables", None)
Replace
form_data.get("variables", None)
withform_data.get("variables")
(SIM910)
1013-1016
: Enhance clarity when re-raising exceptions.
You might consider using Python’sraise e from e
orraise e from None
for better traceback clarity. Example:except Exception as e: raise e from None🧰 Tools
🪛 Ruff (0.8.2)
1013-1016: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
backend/open_webui/routers/ollama.py (7)
267-272
: Consolidate repeated fallback
Retrievingapi_config
with the same fallback pattern appears multiple times. It might be helpful to encapsulate it in a single helper for maintainability.+def get_ollama_api_config(configs, idx, url): + return configs.get(str(idx), configs.get(url, {}))
287-292
: Repeated logic
This code block replicates the same fallback approach forapi_config
. Avoid duplication by using a shared function if possible.
474-479
: Similar pattern
Repeated fallback snippet. Refactoring could reduce code duplication.
921-924
: Similar fallback approach
Again, consider centralizing repeated code for maintainability.
1228-1232
: Handles fallback
Similar logic for retrievingapi_config
again. Consolidation in one place still recommended.
1476-1476
: Remove extraneous f-string
Ruff identified an f-string without placeholders.- log.info(f"Uploaded to /api/blobs") + log.info("Uploaded to /api/blobs")🧰 Tools
🪛 Ruff (0.8.2)
1476-1476: f-string without any placeholders
Remove extraneous
f
prefix(F541)
1500-1500
: Another f-string without placeholders
Removing the redundantf
prefix.- log.info(f"API SUCCESS!") + log.info("API SUCCESS!")🧰 Tools
🪛 Ruff (0.8.2)
1500-1500: f-string without any placeholders
Remove extraneous
f
prefix(F541)
backend/open_webui/routers/retrieval.py (1)
797-799
: Combine multiple isinstance checks
Ruff suggests merging these calls for clarity.- if ( - isinstance(value, datetime) - or isinstance(value, list) - or isinstance(value, dict) - ): + if isinstance(value, (datetime, list, dict)):🧰 Tools
🪛 Ruff (0.8.2)
797-799: Multiple
isinstance
calls forvalue
, merge into a single callMerge
isinstance
calls forvalue
(SIM101)
backend/open_webui/config.py (1)
5-5
: Remove the unusedbase64
import.Static analysis suggests that
base64
is imported but not used anywhere in this file. Deleting it will help maintain a cleaner codebase.- import base64
🧰 Tools
🪛 Ruff (0.8.2)
5-5:
base64
imported but unusedRemove unused import:
base64
(F401)
backend/open_webui/utils/middleware.py (12)
8-8
: Remove the unusedaiocache.cached
import.It seems that
cached
is never used in this file. Removing it will keep dependencies lean and the code clutter-free.- from aiocache import cached
🧰 Tools
🪛 Ruff (0.8.2)
8-8:
aiocache.cached
imported but unusedRemove unused import:
aiocache.cached
(F401)
9-9
: Remove the unusedtyping.Any
import.The
Any
type is not referenced, so dropping the import helps reduce unnecessary code.- from typing import Any
🧰 Tools
🪛 Ruff (0.8.2)
9-9:
typing.Any
imported but unusedRemove unused import:
typing.Any
(F401)
10-10
: Remove the unusedrandom
import.This import is never used. Removing it will help maintain minimal imports.
- import random
🧰 Tools
🪛 Ruff (0.8.2)
10-10:
random
imported but unusedRemove unused import:
random
(F401)
13-13
: Remove the unusedinspect
import.Since the
inspect
module is not used anywhere, removing it will clean up the file.- import inspect
🧰 Tools
🪛 Ruff (0.8.2)
13-13:
inspect
imported but unusedRemove unused import:
inspect
(F401)
42-44
: Remove unusedprocess_pipeline_outlet_filter
import.
process_pipeline_outlet_filter
is imported but never referenced. Removing it will help simplify the imports.-from open_webui.routers.pipelines import ( - process_pipeline_inlet_filter, - process_pipeline_outlet_filter, +from open_webui.routers.pipelines import process_pipeline_inlet_filter🧰 Tools
🪛 Ruff (0.8.2)
44-44:
open_webui.routers.pipelines.process_pipeline_outlet_filter
imported but unusedRemove unused import:
open_webui.routers.pipelines.process_pipeline_outlet_filter
(F401)
436-436
: Remove the unusednegative_prompt
variable.The variable
negative_prompt
is set but never used. Deleting it avoids confusion and clutter.- negative_prompt = ""
🧰 Tools
🪛 Ruff (0.8.2)
436-436: Local variable
negative_prompt
is assigned to but never usedRemove assignment to unused variable
negative_prompt
(F841)
499-499
: Remove the unnecessary 'f' prefix in the string.No placeholders are used here, so removing the
f
keeps it consistent and avoids confusion.- "description": f"An error occurred while generating an image", + "description": "An error occurred while generating an image",🧰 Tools
🪛 Ruff (0.8.2)
499-499: f-string without any placeholders
Remove extraneous
f
prefix(F541)
696-696
: Remove the unusedvariables
assignment.The
variables
local variable is never used. Deleting it will keep things concise.- variables = form_data.pop("variables", None)
🧰 Tools
🪛 Ruff (0.8.2)
696-696: Local variable
variables
is assigned to but never usedRemove assignment to unused variable
variables
(F841)
715-715
: Raise exceptions with clearer chaining.Using
raise ... from e
preserves the original traceback and clarifies exception chaining.- raise Exception(f"Error: {e}") + raise Exception(f"Error: {e}") from e🧰 Tools
🪛 Ruff (0.8.2)
715-715: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
1180-1180
: Rename the unused loop index to underscore.This loop index is not used in the body. Renaming it to
_idx
clarifies that it’s intentionally unused.- for idx, block in enumerate(content_blocks): + for _idx, block in enumerate(content_blocks):🧰 Tools
🪛 Ruff (0.8.2)
1180-1180: Loop control variable
idx
not used within loop bodyRename unused
idx
to_idx
(B007)
1373-1374
: Remove the unusede
variable in the exception handler.Since
e
is never referenced, simply catching and ignoring the exception without naming it clarifies the intent.- except Exception as e: + except Exception: pass🧰 Tools
🪛 Ruff (0.8.2)
1373-1373: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
1568-1570
: Combine nestedif
statements.You can streamline these checks into a single
if
condition for better readability.- if content_blocks: - if content_blocks[-1]["type"] == "text": + if content_blocks and content_blocks[-1]["type"] == "text": # ...🧰 Tools
🪛 Ruff (0.8.2)
1568-1570: Use a single
if
statement instead of nestedif
statements(SIM102)
backend/open_webui/retrieval/web/main.py (1)
1-1
: LGTM! Good addition of URL validation.Adding URL validation before domain parsing is a good defensive programming practice. It helps prevent potential errors from invalid URLs and improves the robustness of the filtering logic.
Consider logging invalid URLs at debug level to help with troubleshooting:
if not validators.url(url): + log.debug(f"Skipping invalid URL: {url}") continue
Also applies to: 15-16
backend/open_webui/retrieval/web/exa.py (2)
12-12
: Consider making the API base URL configurable.Move
EXA_API_BASE
to a configuration file to allow for environment-specific overrides.
40-46
: Extract magic numbers into named constants.The default count of 5 should be defined as a named constant at the module level.
+DEFAULT_RESULT_COUNT = 5 + payload = { "query": query, - "numResults": count or 5, + "numResults": count or DEFAULT_RESULT_COUNT, "includeDomains": filter_list, "contents": {"text": True, "highlights": True}, "type": "auto", # Use the auto search type (keyword or neural) }backend/open_webui/retrieval/web/bocha.py (3)
13-34
: Simplify nested dictionary access.Consider using a more flat structure or dictionary get() method with default values to reduce nesting.
def _parse_response(response): - result = {} - if "data" in response: - data = response["data"] - if "webPages" in data: - webPages = data["webPages"] - if "value" in webPages: - result["webpage"] = [ - { - "id": item.get("id", ""), - "name": item.get("name", ""), - "url": item.get("url", ""), - "snippet": item.get("snippet", ""), - "summary": item.get("summary", ""), - "siteName": item.get("siteName", ""), - "siteIcon": item.get("siteIcon", ""), - "datePublished": item.get("datePublished", "") - or item.get("dateLastCrawled", ""), - } - for item in webPages["value"] - ] - return result + web_pages = response.get("data", {}).get("webPages", {}).get("value", []) + return { + "webpage": [ + { + "id": item.get("id", ""), + "name": item.get("name", ""), + "url": item.get("url", ""), + "snippet": item.get("snippet", ""), + "summary": item.get("summary", ""), + "siteName": item.get("siteName", ""), + "siteIcon": item.get("siteIcon", ""), + "datePublished": item.get("datePublished", "") or item.get("dateLastCrawled", ""), + } + for item in web_pages + ] + }
46-46
: Extract hardcoded values into constants.Move the API URL and timeout into module-level constants.
+BOCHA_API_URL = "https://api.bochaai.com/v1/web-search?utm_source=ollama" +REQUEST_TIMEOUT = 5 + - url = "https://api.bochaai.com/v1/web-search?utm_source=ollama" + url = BOCHA_API_URL - response = requests.post(url, headers=headers, data=payload, timeout=5) + response = requests.post(url, headers=headers, data=payload, timeout=REQUEST_TIMEOUT)Also applies to: 53-53
56-56
: Remove debug print statement.Remove the print statement used for debugging.
- print(results)
backend/open_webui/__init__.py (1)
16-21
: Enhance version display with additional information.Consider including more details in the version output, such as Python version and system information, to help with troubleshooting.
def version_callback(value: bool): if value: from open_webui.env import VERSION + import platform + import sys - typer.echo(f"Open WebUI version: {VERSION}") + typer.echo(f"""Open WebUI version: {VERSION} +Python version: {sys.version.split()[0]} +Platform: {platform.platform()}""") raise typer.Exit()backend/open_webui/internal/db.py (1)
103-104
: LGTM! Consider adding schema validation.The schema configuration is properly implemented. Consider adding validation to ensure DATABASE_SCHEMA is a valid identifier.
+def validate_schema_name(schema: str) -> str: + if not schema.isidentifier(): + raise ValueError(f"Invalid schema name: {schema}") + return schema + metadata_obj = MetaData(schema=DATABASE_SCHEMA) +validate_schema_name(DATABASE_SCHEMA) Base = declarative_base(metadata=metadata_obj)scripts/prepare-pyodide.js (1)
118-118
: Consider moving proxy initialization.The proxy should be initialized before any network operations to ensure all requests use the configured proxy.
-initNetworkProxyFromEnv(); -await downloadPackages(); -await copyPyodide(); +initNetworkProxyFromEnv(); +try { + await downloadPackages(); + await copyPyodide(); +} catch (error) { + console.error('Failed to download or copy packages:', error); + process.exit(1); +}backend/open_webui/utils/filter.py (2)
10-11
: Address the TODO comment.The TODO comment indicates a potential issue with the FunctionModel's valve handling.
Would you like me to help implement the valve handling in the FunctionModel?
74-84
: Simplify nested conditions and improve error handling.The nested if statements can be simplified, and the error handling could be more informative.
- if "__user__" in sig.parameters: - if hasattr(function_module, "UserValves"): + if "__user__" in sig.parameters and hasattr(function_module, "UserValves"): try: params["__user__"]["valves"] = function_module.UserValves( **Functions.get_user_valves_by_id_and_user_id( filter_id, params["__user__"]["id"] ) ) except Exception as e: - print(e) + print(f"Error setting user valves for filter {filter_id}: {e}")🧰 Tools
🪛 Ruff (0.8.2)
74-75: Use a single
if
statement instead of nestedif
statements(SIM102)
backend/open_webui/routers/utils.py (1)
31-38
: Improve error handling in format_code endpoint.The exception handling could be more specific and informative.
try: formatted_code = black.format_str(form_data.code, mode=black.Mode()) return {"code": formatted_code} except black.NothingChanged: return {"code": form_data.code} except Exception as e: - raise HTTPException(status_code=400, detail=str(e)) + raise HTTPException( + status_code=400, + detail=f"Failed to format code: {str(e)}" + ) from e🧰 Tools
🪛 Ruff (0.8.2)
31-31: Do not perform function call
Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
38-38: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
backend/open_webui/utils/response.py (1)
27-80
: Consider adding type hints for nested dictionaries.The function handles complex calculations and data transformations well. However, consider adding type hints for the nested dictionary structure to improve code maintainability.
-def convert_ollama_usage_to_openai(data: dict) -> dict: +def convert_ollama_usage_to_openai(data: Dict[str, Any]) -> Dict[str, Union[str, int, float, Dict[str, int]]]:backend/open_webui/routers/prompts.py (1)
150-154
: Consider extracting access control logic to a helper function.The same access control logic is duplicated in both update and delete operations. Consider extracting it to a helper function for better maintainability.
+def has_prompt_write_access(user, prompt) -> bool: + return ( + prompt.user_id == user.id + or has_access(user.id, "write", prompt.access_control) + or user.role == "admin" + ) @router.delete("/command/{command}/delete", response_model=bool) async def delete_prompt_by_command(command: str, user=Depends(get_verified_user)): prompt = Prompts.get_prompt_by_command(f"/{command}") if not prompt: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail=ERROR_MESSAGES.NOT_FOUND, ) - if ( - prompt.user_id != user.id - and not has_access(user.id, "write", prompt.access_control) - and user.role != "admin" - ): + if not has_prompt_write_access(user, prompt):backend/open_webui/utils/pdf_generator.py (1)
80-81
: Consider using a template engine for HTML generation.While the HTML escaping is correct, consider using a template engine like Jinja2 for more maintainable HTML generation and automatic escaping.
Also applies to: 89-89
src/lib/apis/configs/index.ts (1)
61-173
: Reduce code duplication by extracting common API request logic.The new functions are well-implemented but contain significant code duplication in error handling logic. This pattern is repeated across all API functions in the file.
Consider extracting the common fetch logic into a reusable function:
async function makeRequest<T>( endpoint: string, token: string, method: 'GET' | 'POST' = 'GET', body?: object ): Promise<T> { let error = null; const res = await fetch(`${WEBUI_API_BASE_URL}${endpoint}`, { method, headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` }, ...(body && { body: JSON.stringify(body) }) }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); }) .catch((err) => { console.log(err); error = err.detail; return null; }); if (error) { throw error; } return res; } // Example usage: export const getDirectConnectionsConfig = (token: string) => makeRequest('/configs/direct_connections', token); export const setDirectConnectionsConfig = (token: string, config: object) => makeRequest('/configs/direct_connections', token, 'POST', config);backend/open_webui/utils/auth.py (1)
12-12
: Remove unused imports.The
List
andDict
imports fromtyping
are not used in the code.Apply this diff:
-from typing import Optional, Union, List, Dict +from typing import Optional, Union🧰 Tools
🪛 Ruff (0.8.2)
12-12:
typing.List
imported but unusedRemove unused import
(F401)
12-12:
typing.Dict
imported but unusedRemove unused import
(F401)
backend/open_webui/utils/tools.py (2)
64-68
: Consider a more robust solution for OpenAI API compatibility.The current hack to convert "str" to "string" is fragile and might miss nested type definitions.
Consider using a recursive function to handle all levels of the schema:
+def convert_types_for_openai(obj): + if isinstance(obj, dict): + return {k: convert_types_for_openai(v) for k, v in obj.items()} + elif isinstance(obj, list): + return [convert_types_for_openai(v) for v in obj] + elif obj == "str": + return "string" + return obj # TODO: Fix hack for OpenAI API -for val in spec.get("parameters", {}).get("properties", {}).values(): - if val["type"] == "str": - val["type"] = "string" +spec["parameters"] = convert_types_for_openai(spec["parameters"])
83-88
: Improve docstring parsing.The current implementation has two issues:
- Uses positional arguments in
re.split
- Doesn't handle multiline docstrings well
Apply this diff:
- if callable.__doc__ and callable.__doc__.strip() != "": - s = re.split(":(param|return)", callable.__doc__, 1) - spec["description"] = s[0] - else: - spec["description"] = function_name + if callable.__doc__: + # Use keyword arguments for clarity + s = re.split(pattern=":(param|return)", string=callable.__doc__, maxsplit=1) + # Clean up multiline docstring + spec["description"] = s[0].strip().replace("\n", " ") + else: + spec["description"] = function_name🧰 Tools
🪛 Ruff (0.8.2)
84-84:
re.split
should passmaxsplit
andflags
as keyword arguments to avoid confusion due to unintuitive argument positions(B034)
src/lib/apis/users/index.ts (1)
286-289
: Consider enhancing error handling and logging.The current implementation silently handles errors by logging and returning null. This could make it difficult for callers to understand and handle error conditions appropriately.
Consider one of these approaches:
- Return a structured response that includes both the error and the result:
-const location = await getUserPosition().catch((err) => { - console.log(err); - return null; -}); +const location = await getUserPosition().catch((err) => { + console.error('Failed to get user position:', err); + return { error: err.message, location: null }; +}); -if (location) { +if (location?.location) { - await updateUserInfo(token, { location: location }); + await updateUserInfo(token, { location: location.location }); - return location; + return location.location; } else { - console.log('Failed to get user location'); + console.error('Failed to get user location'); - return null; + return { error: location?.error || 'Location not available', location: null }; }
- Or, if you prefer the current approach, at least improve the logging:
const location = await getUserPosition().catch((err) => { - console.log(err); + console.error('Failed to get user position:', err); return null; }); if (location) { await updateUserInfo(token, { location: location }); return location; } else { - console.log('Failed to get user location'); + console.error('Failed to get user location'); return null; }Also applies to: 295-297
backend/open_webui/routers/users.py (2)
72-76
: Consider more restrictive default chat permissions.All chat permissions default to
True
, which might be too permissive. Consider following the principle of least privilege as implemented inWorkspacePermissions
.Consider setting more restrictive defaults:
- controls: bool = True - file_upload: bool = True - delete: bool = True - edit: bool = True - temporary: bool = True + controls: bool = False + file_upload: bool = False + delete: bool = False + edit: bool = False + temporary: bool = False
79-82
: Consider more restrictive default feature permissions.All feature permissions default to
True
, which might be too permissive. Consider following the principle of least privilege.Consider setting more restrictive defaults:
- web_search: bool = True - image_generation: bool = True - code_interpreter: bool = True + web_search: bool = False + image_generation: bool = False + code_interpreter: bool = Falsesrc/lib/components/admin/Settings/CodeExecution.svelte (1)
66-72
: Consider adding a security notice component for Jupyter warnings.The security warning for Jupyter execution is repeated in multiple places. Consider extracting it into a reusable component.
+import SecurityWarning from '$lib/components/common/SecurityWarning.svelte'; {#if config.CODE_EXECUTION_ENGINE === 'jupyter'} - <div class="text-gray-500 text-xs"> - {$i18n.t( - 'Warning: Jupyter execution enables arbitrary code execution, posing severe security risks—proceed with extreme caution.' - )} - </div> + <SecurityWarning + message={$i18n.t('Warning: Jupyter execution enables arbitrary code execution, posing severe security risks—proceed with extreme caution.')} + /> {/if}backend/open_webui/socket/main.py (1)
327-343
: Consider adding type hints to improve code clarity.The function signature could benefit from type hints for better code maintainability and IDE support.
-def get_event_call(request_info): +def get_event_call(request_info: dict) -> Callable: - async def __event_caller__(event_data): + async def __event_caller__(event_data: dict) -> Any:backend/open_webui/utils/task.py (1)
226-242
: Add docstring to the new image prompt generation function.The new function should have a docstring explaining its purpose and parameters.
def image_prompt_generation_template( template: str, messages: list[dict], user: Optional[dict] = None ) -> str: + """ + Generate an image prompt based on a template and message history. + + Args: + template (str): The template string containing placeholders + messages (list[dict]): List of message dictionaries containing conversation history + user (Optional[dict]): Optional user information dictionary + + Returns: + str: The generated prompt with all placeholders replaced + """src/lib/components/admin/Evaluations/Leaderboard.svelte (1)
291-292
: Consider using semantic HTML for better accessibility.The search input should have appropriate ARIA labels and roles.
<input class="w-full text-sm pr-4 py-1 rounded-r-xl outline-hidden bg-transparent" + aria-label={$i18n.t('Search models by topic')} + role="searchbox" bind:value={query} placeholder={$i18n.t('Search')}src/lib/apis/ollama/index.ts (1)
363-363
: LGTM! Consider adding type definition for the payload.The change to use a generic payload object improves flexibility. However, using
object
type in TypeScript is not type-safe.Consider defining an interface for the payload:
-export const createModel = async (token: string, payload: object, urlIdx: string | null = null) => { +interface CreateModelPayload { + tagName: string; + content: string; + // Add other potential fields +} +export const createModel = async (token: string, payload: CreateModelPayload, urlIdx: string | null = null) => {Also applies to: 375-375
backend/open_webui/utils/misc.py (3)
13-19
: Add type hints and docstring for better code maintainability.The implementation is correct, but could benefit from better documentation.
Apply this diff to improve the function:
-def deep_update(d, u): +def deep_update(d: dict, u: dict) -> dict: + """ + Recursively update a dictionary with values from another dictionary. + + Args: + d: The target dictionary to update + u: The source dictionary containing updates + + Returns: + The updated dictionary + """ for k, v in u.items(): if isinstance(v, collections.abc.Mapping): d[k] = deep_update(d.get(k, {}), v) else: d[k] = v return d
146-162
: Fix parameter name mismatch in docstring.The docstring refers to parameter
msg
but the function usescontent
.Apply this diff to fix the docstring:
def add_or_update_user_message(content: str, messages: list[dict]): """ Adds a new user message at the end of the messages list or updates the existing user message at the end. - :param msg: The message to be added or appended. + :param content: The message content to be added or appended. :param messages: The list of message dictionaries. :return: The updated list of message dictionaries. """
165-181
: Fix parameter name mismatch in docstring.The docstring refers to parameter
msg
but the function usescontent
.Apply this diff to fix the docstring:
def append_or_update_assistant_message(content: str, messages: list[dict]): """ Adds a new assistant message at the end of the messages list or updates the existing assistant message at the end. - :param msg: The message to be added or appended. + :param content: The message content to be added or appended. :param messages: The list of message dictionaries. :return: The updated list of message dictionaries. """backend/open_webui/utils/chat.py (1)
13-14
: Remove unused imports.Several imports are not used in the code:
status
fromfastapi
Response
andJSONResponse
fromstarlette.responses
UserModel
fromopen_webui.models.users
Remove these unused imports to keep the code clean.
Also applies to: 17-17
🧰 Tools
🪛 Ruff (0.8.2)
13-13:
fastapi.status
imported but unusedRemove unused import:
fastapi.status
(F401)
14-14:
starlette.responses.Response
imported but unusedRemove unused import
(F401)
14-14:
starlette.responses.JSONResponse
imported but unusedRemove unused import
(F401)
backend/open_webui/test/apps/webui/storage/test_provider.py (1)
59-425
: Consider enhancing error case testing.While the test coverage is comprehensive, consider:
- Using more specific exceptions instead of broad Exception catches
- Adding assertions for specific error messages
- Testing edge cases like file permissions and network errors
🧰 Tools
🪛 Ruff (0.8.2)
116-116:
pytest.raises(Exception)
should be considered evil(B017)
218-218:
pytest.raises(Exception)
should be considered evil(B017)
255-255: Comparison to
None
should becond is None
Replace with
cond is None
(E711)
279-279: Comparison to
None
should becond is None
Replace with
cond is None
(E711)
280-280: Comparison to
None
should becond is None
Replace with
cond is None
(E711)
302-302: Undefined name
azure
(F821)
307-307: Undefined name
azure
(F821)
312-312: Undefined name
azure
(F821)
334-334:
pytest.raises(Exception)
should be considered evil(B017)
src/lib/apis/chats/index.ts (1)
462-462
: Consider preserving full error context.The change to only use
err.detail
might lose valuable error information. Consider keeping the full error object or at least logging it before reducing to detail.-error = err.detail; +error = err.detail || err; +console.error('Full error:', err);docker-compose.playwright.yaml (1)
1-10
: LGTM! Well-structured Playwright integration.The configuration:
- Correctly pins Playwright version
- Properly exposes the service
- Sets up required environment variables for integration
Add a newline at the end of the file to comply with YAML standards:
- 'RAG_WEB_LOADER_ENGINE=playwright' - 'PLAYWRIGHT_WS_URI=ws://playwright:3000' +
🧰 Tools
🪛 YAMLlint (1.35.1)
[error] 10-10: no new line character at the end of file
(new-line-at-end-of-file)
backend/requirements.txt (1)
50-51
: Dependency Addition Without Version Pinning (transformers
)
The dependencytransformers
is added without a specified version. It’s good practice to pin a version to avoid unexpected breaking changes. Consider specifying a version range.src/app.html (1)
98-110
: Commented Out Image Elements
There are commented-out<img>
tags (lines 98–110 and 125–131). If these images (such as the splash logo) are no longer required, consider removing them to clean up the markup. If they will be re-enabled later, a TODO comment might help clarify their purpose.README.md (1)
18-22
: Introduce Enterprise Plan Tip SectionThe new tip section promoting the Enterprise Plan is informative and eye-catching. It highlights benefits such as custom theming, branding, and SLA support. One minor note: consider hyphenating “Service-Level Agreement (SLA)” for consistency with common style guidelines.
🧰 Tools
🪛 LanguageTool
[uncategorized] ~21-~21: When ‘Service-Level’ is used as a modifier, it is usually spelled with a hyphen.
Context: ...ding custom theming and branding, Service Level Agreement (SLA) support, **Long-Term Support (L...(SERVICE_LEVEL_HYPHEN)
searxng/settings.yml (3)
1-32
: General and Branding Sections – Clarity and Defaults
The “general” and “brand” sections are well organized and clearly commented. Please verify that setting values such asprivacypolicy_url
,donation_url
, andcontact_url
tofalse
is intentional (i.e. used to disable these links by default).🧰 Tools
🪛 YAMLlint (1.35.1)
[error] 10-10: trailing spaces
(trailing-spaces)
10-10
: Style Issue: Trailing Whitespace Detected
There is a trailing space at the end of the line definingdonation_url: false
on line 10. Removing extra whitespace will help maintain file cleanliness and consistency.🧰 Tools
🪛 YAMLlint (1.35.1)
[error] 10-10: trailing spaces
(trailing-spaces)
340-2551
: Engine Definitions – Consider Modularization for Maintainability
The engines section is extremely comprehensive, listing a large number of search engine configurations. Although the extensive details provide flexibility, the section’s size could make future maintenance and updates challenging. Consider breaking these definitions into modular files or employing YAML merge keys/anchors to reduce repetition and improve readability. This will help keep the configuration manageable as more engines are added or modified over time.CHANGELOG.md (3)
14-27
: Well-Documented Additions for Version 0.5.15The new features added in version 0.5.15 are comprehensively listed under “### Added”. The descriptions—including features like full context mode for local document search, smarter web search with agentic workflows, experimental Playwright support, and more—are informative and employ consistent use of emojis for clarity. As a suggestion, verify that the style (such as punctuation and emoji usage) remains uniform with previous version entries.
189-189
: Avoid Bare URL FormattingStatic analysis flagged a bare URL used on line 189. For enhanced readability and to comply with markdown best practices, please replace any bare URL (for example, likely “https://github.com/open-webui/desktop” mentioned in the context of desktop app preparations) with proper markdown link syntax such as:
- Follow our progress and updates here: https://github.com/open-webui/desktop + Follow our progress and updates here: [Desktop App Progress](https://github.com/open-webui/desktop)This small change will help avoid MD034 warnings and improve the overall presentation.
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
189-189: Bare URL used
null(MD034, no-bare-urls)
1-1681
: Overall Changelog Consistency and ReadabilityThe changelog is extremely comprehensive, documenting a wide range of fixes, additions, and changes from version 0.5.16 down to the earliest releases. It adheres well to the “Keep a Changelog” format and provides both technical specifics and user-facing details. As the document grows in length, consider whether splitting major version milestones into separate sections or files might improve navigability and maintenance. Also, ensure uniformity in the use of formatting elements such as emojis, link formatting, and consistent phrasing for clarity.
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
189-189: Bare URL used
null(MD034, no-bare-urls)
227-227: Bare URL used
null(MD034, no-bare-urls)
276-276: Bare URL used
null(MD034, no-bare-urls)
552-552: Bare URL used
null(MD034, no-bare-urls)
1228-1228: Bare URL used
null(MD034, no-bare-urls)
1292-1292: Bare URL used
null(MD034, no-bare-urls)
1303-1303: Bare URL used
null(MD034, no-bare-urls)
1342-1342: Bare URL used
null(MD034, no-bare-urls)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
backend/open_webui/static/favicon.png
is excluded by!**/*.png
backend/open_webui/static/logo.png
is excluded by!**/*.png
package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (108)
.github/workflows/integration-test.disabled
(1 hunks).github/workflows/release-pypi.yml
(1 hunks)CHANGELOG.md
(1 hunks)Dockerfile
(1 hunks)README.md
(2 hunks)backend/open_webui/__init__.py
(1 hunks)backend/open_webui/config.py
(25 hunks)backend/open_webui/constants.py
(2 hunks)backend/open_webui/env.py
(5 hunks)backend/open_webui/functions.py
(1 hunks)backend/open_webui/internal/db.py
(2 hunks)backend/open_webui/main.py
(34 hunks)backend/open_webui/models/chats.py
(2 hunks)backend/open_webui/models/groups.py
(3 hunks)backend/open_webui/models/users.py
(3 hunks)backend/open_webui/retrieval/utils.py
(13 hunks)backend/open_webui/retrieval/vector/dbs/chroma.py
(1 hunks)backend/open_webui/retrieval/vector/dbs/milvus.py
(1 hunks)backend/open_webui/retrieval/vector/dbs/opensearch.py
(1 hunks)backend/open_webui/retrieval/vector/dbs/pgvector.py
(3 hunks)backend/open_webui/retrieval/web/bing.py
(1 hunks)backend/open_webui/retrieval/web/bocha.py
(1 hunks)backend/open_webui/retrieval/web/duckduckgo.py
(1 hunks)backend/open_webui/retrieval/web/exa.py
(1 hunks)backend/open_webui/retrieval/web/google_pse.py
(1 hunks)backend/open_webui/retrieval/web/jina_search.py
(1 hunks)backend/open_webui/retrieval/web/main.py
(2 hunks)backend/open_webui/retrieval/web/serpapi.py
(1 hunks)backend/open_webui/retrieval/web/tavily.py
(2 hunks)backend/open_webui/retrieval/web/utils.py
(4 hunks)backend/open_webui/routers/audio.py
(10 hunks)backend/open_webui/routers/auths.py
(20 hunks)backend/open_webui/routers/channels.py
(3 hunks)backend/open_webui/routers/chats.py
(1 hunks)backend/open_webui/routers/configs.py
(1 hunks)backend/open_webui/routers/files.py
(9 hunks)backend/open_webui/routers/groups.py
(2 hunks)backend/open_webui/routers/images.py
(14 hunks)backend/open_webui/routers/knowledge.py
(11 hunks)backend/open_webui/routers/memories.py
(4 hunks)backend/open_webui/routers/models.py
(2 hunks)backend/open_webui/routers/ollama.py
(32 hunks)backend/open_webui/routers/openai.py
(10 hunks)backend/open_webui/routers/pipelines.py
(2 hunks)backend/open_webui/routers/prompts.py
(2 hunks)backend/open_webui/routers/retrieval.py
(30 hunks)backend/open_webui/routers/tasks.py
(20 hunks)backend/open_webui/routers/tools.py
(4 hunks)backend/open_webui/routers/users.py
(2 hunks)backend/open_webui/routers/utils.py
(2 hunks)backend/open_webui/socket/main.py
(2 hunks)backend/open_webui/socket/utils.py
(1 hunks)backend/open_webui/static/swagger-ui/swagger-ui.css
(0 hunks)backend/open_webui/storage/provider.py
(2 hunks)backend/open_webui/test/apps/webui/storage/test_provider.py
(1 hunks)backend/open_webui/utils/access_control.py
(3 hunks)backend/open_webui/utils/auth.py
(2 hunks)backend/open_webui/utils/chat.py
(6 hunks)backend/open_webui/utils/code_interpreter.py
(1 hunks)backend/open_webui/utils/filter.py
(1 hunks)backend/open_webui/utils/images/comfyui.py
(1 hunks)backend/open_webui/utils/middleware.py
(25 hunks)backend/open_webui/utils/misc.py
(6 hunks)backend/open_webui/utils/models.py
(1 hunks)backend/open_webui/utils/oauth.py
(13 hunks)backend/open_webui/utils/payload.py
(4 hunks)backend/open_webui/utils/pdf_generator.py
(4 hunks)backend/open_webui/utils/plugin.py
(1 hunks)backend/open_webui/utils/response.py
(2 hunks)backend/open_webui/utils/task.py
(3 hunks)backend/open_webui/utils/tools.py
(2 hunks)backend/open_webui/utils/webhook.py
(2 hunks)backend/requirements.txt
(7 hunks)backend/start.sh
(1 hunks)backend/start_windows.bat
(1 hunks)docker-compose.playwright.yaml
(1 hunks)docker-compose.yaml
(2 hunks)docs/apache.md
(2 hunks)package.json
(5 hunks)postcss.config.js
(1 hunks)pyproject.toml
(4 hunks)run-compose.sh
(5 hunks)scripts/prepare-pyodide.js
(2 hunks)searxng/settings.yml
(1 hunks)searxng/uwsgi.ini
(1 hunks)src/app.css
(6 hunks)src/app.html
(5 hunks)src/lib/apis/chats/index.ts
(3 hunks)src/lib/apis/configs/index.ts
(1 hunks)src/lib/apis/index.ts
(3 hunks)src/lib/apis/models/index.ts
(1 hunks)src/lib/apis/ollama/index.ts
(2 hunks)src/lib/apis/openai/index.ts
(3 hunks)src/lib/apis/users/index.ts
(1 hunks)src/lib/apis/utils/index.ts
(4 hunks)src/lib/components/AddConnectionModal.svelte
(9 hunks)src/lib/components/ChangelogModal.svelte
(1 hunks)src/lib/components/NotificationToast.svelte
(1 hunks)src/lib/components/OnBoarding.svelte
(1 hunks)src/lib/components/admin/Evaluations/Feedbacks.svelte
(4 hunks)src/lib/components/admin/Evaluations/Leaderboard.svelte
(4 hunks)src/lib/components/admin/Functions.svelte
(15 hunks)src/lib/components/admin/Functions/FunctionEditor.svelte
(4 hunks)src/lib/components/admin/Functions/FunctionMenu.svelte
(3 hunks)src/lib/components/admin/Settings.svelte
(3 hunks)src/lib/components/admin/Settings/Audio.svelte
(24 hunks)src/lib/components/admin/Settings/CodeExecution.svelte
(1 hunks)src/lib/components/admin/Settings/Connections.svelte
(16 hunks)
💤 Files with no reviewable changes (1)
- backend/open_webui/static/swagger-ui/swagger-ui.css
✅ Files skipped from review due to trivial changes (6)
- src/lib/components/NotificationToast.svelte
- src/lib/components/admin/Functions/FunctionEditor.svelte
- src/lib/components/ChangelogModal.svelte
- searxng/uwsgi.ini
- src/lib/components/admin/Functions/FunctionMenu.svelte
- src/lib/components/admin/Evaluations/Feedbacks.svelte
🧰 Additional context used
🪛 LanguageTool
README.md
[uncategorized] ~21-~21: When ‘Service-Level’ is used as a modifier, it is usually spelled with a hyphen.
Context: ...ding custom theming and branding, Service Level Agreement (SLA) support, **Long-Term Support (L...
(SERVICE_LEVEL_HYPHEN)
🪛 YAMLlint (1.35.1)
docker-compose.playwright.yaml
[error] 10-10: no new line character at the end of file
(new-line-at-end-of-file)
searxng/settings.yml
[error] 10-10: trailing spaces
(trailing-spaces)
🪛 Ruff (0.8.2)
backend/open_webui/utils/tools.py
84-84: re.split
should pass maxsplit
and flags
as keyword arguments to avoid confusion due to unintuitive argument positions
(B034)
backend/open_webui/utils/access_control.py
75-75: Do not use mutable data structures for argument defaults
Replace with None
; initialize within function
(B006)
backend/open_webui/routers/knowledge.py
20-20: open_webui.storage.provider.Storage
imported but unused
Remove unused import: open_webui.storage.provider.Storage
(F401)
backend/open_webui/routers/tasks.py
305-305: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
355-355: Use form_data.get("chat_id")
instead of form_data.get("chat_id", None)
Replace form_data.get("chat_id", None)
with form_data.get("chat_id")
(SIM910)
361-361: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
579-579: Use form_data.get("chat_id")
instead of form_data.get("chat_id", None)
Replace form_data.get("chat_id", None)
with form_data.get("chat_id")
(SIM910)
backend/open_webui/test/apps/webui/storage/test_provider.py
10-10: azure.storage.blob.BlobServiceClient
imported but unused
Remove unused import
(F401)
10-10: azure.storage.blob.ContainerClient
imported but unused
Remove unused import
(F401)
10-10: azure.storage.blob.BlobClient
imported but unused
Remove unused import
(F401)
23-23: Found useless expression. Either assign it to a variable or remove it.
(B018)
24-24: Found useless expression. Either assign it to a variable or remove it.
(B018)
25-25: Found useless expression. Either assign it to a variable or remove it.
(B018)
26-26: Found useless expression. Either assign it to a variable or remove it.
(B018)
27-27: Found useless expression. Either assign it to a variable or remove it.
(B018)
28-28: Found useless expression. Either assign it to a variable or remove it.
(B018)
116-116: pytest.raises(Exception)
should be considered evil
(B017)
218-218: pytest.raises(Exception)
should be considered evil
(B017)
255-255: Comparison to None
should be cond is None
Replace with cond is None
(E711)
279-279: Comparison to None
should be cond is None
Replace with cond is None
(E711)
280-280: Comparison to None
should be cond is None
Replace with cond is None
(E711)
302-302: Undefined name azure
(F821)
307-307: Undefined name azure
(F821)
312-312: Undefined name azure
(F821)
334-334: pytest.raises(Exception)
should be considered evil
(B017)
backend/open_webui/utils/filter.py
74-75: Use a single if
statement instead of nested if
statements
(SIM102)
backend/open_webui/routers/chats.py
453-453: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
backend/open_webui/retrieval/vector/dbs/opensearch.py
141-141: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
backend/open_webui/routers/users.py
92-92: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
backend/open_webui/utils/chat.py
13-13: fastapi.status
imported but unused
Remove unused import: fastapi.status
(F401)
14-14: starlette.responses.Response
imported but unused
Remove unused import
(F401)
14-14: starlette.responses.JSONResponse
imported but unused
Remove unused import
(F401)
17-17: open_webui.models.users.UserModel
imported but unused
Remove unused import: open_webui.models.users.UserModel
(F401)
128-131: Use contextlib.suppress(Exception)
instead of try
-except
-pass
Replace with contextlib.suppress(Exception)
(SIM105)
130-130: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
226-226: Avoid equality comparisons to True
; use if form_data.get("stream"):
for truth checks
Replace with form_data.get("stream")
(E712)
backend/open_webui/retrieval/web/utils.py
447-450: Use ternary operator parser = "xml" if url.endswith(".xml") else self.default_parser
instead of if
-else
-block
Replace if
-else
-block with parser = "xml" if url.endswith(".xml") else self.default_parser
(SIM108)
backend/open_webui/routers/pipelines.py
95-95: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
102-102: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
144-144: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
backend/open_webui/routers/configs.py
49-49: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
59-59: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
90-90: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
111-111: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
backend/open_webui/utils/oauth.py
257-260: Use a single with
statement with multiple contexts instead of nested with
statements
(SIM117)
284-284: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
347-348: Use a single with
statement with multiple contexts instead of nested with
statements
(SIM117)
backend/open_webui/routers/auths.py
170-170: Local variable LDAP_SERVER_LABEL
is assigned to but never used
Remove assignment to unused variable LDAP_SERVER_LABEL
(F841)
backend/open_webui/utils/middleware.py
8-8: aiocache.cached
imported but unused
Remove unused import: aiocache.cached
(F401)
9-9: typing.Any
imported but unused
Remove unused import: typing.Any
(F401)
10-10: random
imported but unused
Remove unused import: random
(F401)
13-13: inspect
imported but unused
Remove unused import: inspect
(F401)
44-44: open_webui.routers.pipelines.process_pipeline_outlet_filter
imported but unused
Remove unused import: open_webui.routers.pipelines.process_pipeline_outlet_filter
(F401)
64-64: open_webui.utils.misc.deep_update
imported but unused
Remove unused import: open_webui.utils.misc.deep_update
(F401)
73-73: open_webui.utils.plugin.load_function_module_by_id
imported but unused
Remove unused import: open_webui.utils.plugin.load_function_module_by_id
(F401)
436-436: Local variable negative_prompt
is assigned to but never used
Remove assignment to unused variable negative_prompt
(F841)
461-461: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
499-499: f-string without any placeholders
Remove extraneous f
prefix
(F541)
696-696: Local variable variables
is assigned to but never used
Remove assignment to unused variable variables
(F841)
715-715: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
897-897: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
1180-1180: Loop control variable idx
not used within loop body
Rename unused idx
to _idx
(B007)
1373-1373: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
1568-1570: Use a single if
statement instead of nested if
statements
(SIM102)
backend/open_webui/routers/images.py
425-428: Use ternary operator r = requests.get(url, headers=headers) if headers else requests.get(url)
instead of if
-else
-block
Replace if
-else
-block with r = requests.get(url, headers=headers) if headers else requests.get(url)
(SIM108)
backend/open_webui/utils/auth.py
12-12: typing.List
imported but unused
Remove unused import
(F401)
12-12: typing.Dict
imported but unused
Remove unused import
(F401)
79-79: Do not call setattr
with a constant attribute value. It is not any safer than normal property access.
Replace setattr
with assignment
(B010)
81-81: Do not call setattr
with a constant attribute value. It is not any safer than normal property access.
Replace setattr
with assignment
(B010)
backend/open_webui/utils/payload.py
14-14: Use params.get("system")
instead of params.get("system", None)
Replace params.get("system", None)
with params.get("system")
(SIM910)
76-76: Local variable param
is assigned to but never used
(F841)
76-76: Use params.get(key)
instead of params.get(key, None)
Replace params.get(key, None)
with params.get(key)
(SIM910)
backend/open_webui/routers/audio.py
578-580: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
600-600: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
backend/open_webui/main.py
158-158: open_webui.config.WHISPER_MODEL_AUTO_UPDATE
imported but unused
Remove unused import
(F401)
159-159: open_webui.config.WHISPER_MODEL_DIR
imported but unused
Remove unused import
(F401)
162-162: open_webui.config.DEFAULT_RAG_TEMPLATE
imported but unused
Remove unused import
(F401)
961-961: Use form_data.get("model")
instead of form_data.get("model", None)
Replace form_data.get("model", None)
with form_data.get("model")
(SIM910)
989-989: Use form_data.get("variables")
instead of form_data.get("variables", None)
Replace form_data.get("variables", None)
with form_data.get("variables")
(SIM910)
1013-1016: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
1213-1213: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
backend/open_webui/routers/retrieval.py
797-799: Multiple isinstance
calls for value
, merge into a single call
Merge isinstance
calls for value
(SIM101)
backend/open_webui/routers/files.py
37-37: Do not perform function call File
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
38-38: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
39-39: Do not use mutable data structures for argument defaults
Replace with None
; initialize within function
(B006)
backend/open_webui/retrieval/utils.py
17-17: open_webui.utils.misc.get_last_user_message
imported but unused
Remove unused import
(F401)
17-17: open_webui.utils.misc.calculate_sha256_string
imported but unused
Remove unused import
(F401)
319-326: Do not assign a lambda
expression, use a def
Rewrite func
as a def
(E731)
416-416: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
backend/open_webui/routers/utils.py
22-22: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
31-31: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
38-38: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
43-43: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
76-76: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
88-88: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
backend/open_webui/routers/ollama.py
1476-1476: f-string without any placeholders
Remove extraneous f
prefix
(F541)
1500-1500: f-string without any placeholders
Remove extraneous f
prefix
(F541)
backend/open_webui/config.py
5-5: base64
imported but unused
Remove unused import: base64
(F401)
backend/open_webui/storage/provider.py
116-116: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
126-126: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
134-134: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
153-153: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
189-189: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
201-201: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
210-210: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
224-224: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
259-259: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
271-271: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
280-280: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
292-292: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
🪛 ESLint
src/lib/components/admin/Settings/CodeExecution.svelte
[error] 2-2: 'toast' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 14-14: Don't use Function
as a type. The Function
type accepts any function-like value.
It provides no type safety when calling the function, which can be a common source of bugs.
It also accepts things like class declarations, which will throw at runtime as they will not be called with new
.
If you are expecting the function to accept certain arguments, you should explicitly define the function shape.
(@typescript-eslint/ban-types)
[error] 21-21: 'res' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
src/lib/apis/index.ts
[error] 77-77: 'err' is defined but never used.
(@typescript-eslint/no-unused-vars)
src/lib/apis/utils/index.ts
[error] 4-4: 'error' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
[error] 95-95: 'error' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
[error] 122-122: 'error' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
🪛 markdownlint-cli2 (0.17.2)
CHANGELOG.md
189-189: Bare URL used
null
(MD034, no-bare-urls)
🪛 Gitleaks (8.21.2)
searxng/settings.yml
99-99: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🔇 Additional comments (244)
backend/open_webui/utils/webhook.py (2)
12-12
: LGTM! Function signature updated correctly.The addition of the
name
parameter enhances the flexibility of the webhook functionality.
42-42
: LGTM! Microsoft Teams payload updated correctly.The
name
parameter is properly integrated into theactivitySubtitle
field of the Microsoft Teams webhook payload.backend/open_webui/routers/channels.py (3)
195-195
: LGTM! Function signature updated correctly.The addition of the
name
parameter aligns with the changes in the webhook utility.
208-210
: LGTM! Webhook call updated correctly.The
name
parameter is properly passed to thepost_webhook
function.
306-306
: LGTM! Name parameter passed correctly.The
request.app.state.WEBUI_NAME
is appropriately used as the source for the name parameter.pyproject.toml (21)
9-9
: FastAPI Version Update
Thefastapi
dependency has been upgraded to version0.115.7
. Please confirm that any breaking changes introduced by this update have been addressed and that your API endpoints remain fully compatible.
11-11
: Pydantic Version Update
Upgradedpydantic
to2.10.6
. Ensure that all model validations and serialization logic in your project adapt correctly to any changes in the new version.
15-15
: Python-Jose Version Update
Thepython-jose
dependency is updated to3.4.0
. Verify that this version works smoothly with your JWT token handling and any related cryptographic operations.
19-19
: Aiohttp Version Update
aiohttp
has been updated to3.11.11
. Please ensure that asynchronous HTTP client/session behaviors throughout your application remain compatible with this change.
40-42
: New Dependency: RestrictedPython
AddedRestrictedPython==8.0
. Confirm that its integration meets your security and sandboxing requirements and that you have adequate tests covering its usage.
52-52
: Chromadb Update
Upgradedchromadb
to0.6.2
. Please test any database interactions that rely on chromadb to ensure they function as intended with the new version.
55-55
: Opensearch-py Update
opensearch-py
is now at2.8.0
. Verify that your search integration and any related functionalities remain stable after this update.
56-56
: New Dependency: Playwright
Addedplaywright==1.49.1
for end-to-end testing. Ensure that your test suites are updated accordingly and confirm that any necessary browser configurations are in place.
66-66
: Pymdown-extensions Update
Upgradedpymdown-extensions
to10.14.2
. Please ensure that markdown rendering features and any extension-specific behavior utilized in your project continue to work as expected.
69-69
: Unstructured Library Update
unstructured
has been updated to0.16.17
. Verify that any document parsing or processing functionalities that depend on this library remain compatible with the updated API.
80-80
: Soundfile Version Update
soundfile
is now at0.13.1
. Please check any audio processing features to ensure they behave correctly with the new version.
82-82
: Opencv-python-headless Update
Upgradedopencv-python-headless
to4.11.0.86
. Confirm that any image processing or computer vision tasks in your project function correctly after this update.
86-86
: Faster-Whisper Update
faster-whisper
has been updated to1.1.1
. Ensure that integrations relying on speech-to-text functionalities are thoroughly tested against this new version.
89-89
: Authlib Update
Upgradedauthlib
to1.4.1
. Please verify that any authentication or OAuth flows integrated into your application are fully compatible with this change.
98-98
: Duckduckgo-search Update
duckduckgo-search
has been updated to use the compatible version notation~=7.3.2
. Check that the search functionalities and any web scraping logic remain operational with this update.
107-107
: New Dependency: moto[s3]
Addedmoto[s3]>=5.0.26
for simulating AWS S3 in tests. Ensure that your test suites cover S3 interactions effectively.
110-110
: New Dependency: google-cloud-storage
Includedgoogle-cloud-storage==2.19.0
. Verify that any Cloud Storage integrations are compatible with this version.
112-112
: New Dependency: azure-identity
Addedazure-identity==1.20.0
to support Azure authentication. Confirm that this dependency integrates smoothly with your Azure workflows.
113-113
: New Dependency: azure-storage-blob
Addedazure-storage-blob==12.24.1
. Ensure that data storage and retrieval operations using Azure Blob storage are fully functional.
115-115
: New Dependency: ldap3
Addedldap3==2.9.1
. Please confirm that LDAP integrations, if used, adhere to current security best practices and requirements.
119-119
: New Dependency: gcp-storage-emulator
Includedgcp-storage-emulator>=2024.8.3
. Verify that this emulator is used appropriately (e.g., in testing or local development environments) without impacting production workflows.backend/open_webui/retrieval/web/jina_search.py (2)
24-29
: Use caution with raw API key as Authorization header.Currently, the code injects
api_key
directly under theAuthorization
header, which may be acceptable only if the Jina API requires a raw key. Otherwise, consider prefixing it with"Bearer "
or confirming that this is indeed the correct authentication scheme.Would you like to confirm this usage with Jina’s official documentation or by searching the web for best practices on Jina authentication?
39-39
: Validate the "data" structure in response.You're iterating
data["data"]
directly. Ifdata
or"data"
is missing for any reason, this could raise a KeyError. Consider using safer access patterns (e.g.,data.get("data", [])
).backend/open_webui/retrieval/web/google_pse.py (1)
60-61
: Check filtering approach for potential data loss.When applying
get_filtered_results
, confirm that vital data isn't mistakenly excluded. If the filter criteria are too broad, important results might get dropped.src/lib/apis/utils/index.ts (3)
9-10
: Header completeness.The
'Authorization': \
Bearer ${token}`header is set, but ensure calls do not silently fail if
token` is empty or invalid. You may want to validate the token before issuing the request.
66-68
: Confirm monitored security requirements.The use of
'Authorization': \
Bearer ${token}`` must match server logic. If your server expects a different scheme, you risk unexpected 401 errors.
121-129
: Graceful error handling with parse exceptions.If the response to
getHTMLFromMarkdown
isn’t valid JSON or doesn’t havehtml
, your code can break atreturn res.html;
. You might want to add a default fallback or extra checks.🧰 Tools
🪛 ESLint
[error] 122-122: 'error' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
backend/open_webui/utils/code_interpreter.py (1)
27-47
: Verify secure transport for password authentication.When sending a password to the Jupyter server, ensure that the connection is established over HTTPS or another secure channel to protect user credentials.
src/lib/apis/openai/index.ts (1)
274-276
: No issues found.Throwing an error when
url
is missing is appropriate to prevent silent failures.src/lib/components/admin/Settings/Connections.svelte (1)
174-184
: Avoid usingforEach
with async.Using
forEach
with async can lead to unawaited operations. If you want each iteration to run sequentially, consider a standardfor
-loop withawait
. If you need parallel execution, gather promises andawait Promise.all
. This ensures correct flow and error handling.backend/open_webui/routers/pipelines.py (3)
60-60
: Async migration check.
Changing toasync def process_pipeline_inlet_filter
is correct for non-blocking I/O. Confirm that all callers await this function; otherwise, the new async signature might be overlooked.
109-109
: Maintain naming convention.
Be consistent with function naming. You usedprocess_pipeline_inlet_filter
,process_pipeline_outlet_filter
, but some references might still use older naming conventions. Ensure all references are updated.
160-160
: Consider additional error handling.
When returningpayload
, confirm it’s valid after filter chaining. Detect partial modifications or empty results to avoid unpredictable states.backend/open_webui/utils/oauth.py (4)
73-77
: Runtime injection of app dependency.
Passingapp
intoOAuthManager
is helpful for config usage. Ensure the app state or config is always accessible and not overwritten in a different context.
215-288
: GitHub email retrieval flow.
This block adds robust fallback for email retrieval (lines 253–285). Good improvement! Consider caching or handling rate limits from GitHub to avoid repeated calls.🧰 Tools
🪛 Ruff (0.8.2)
235-235: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
257-260: Use a single
with
statement with multiple contexts instead of nestedwith
statements(SIM117)
284-284: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
374-377
: Ensure fallback name is correct.
Whenusername_claim
is missing, settingname = email
is fine. For privacy, confirm that sharing an email publicly (e.g., in logs) matches user expectations.
385-396
: Randomized password approach.
Generating a random password (line 383) is fine for OAuth users. Confirm that it’s never exposed to the user or used incorrectly in non-OAuth flows.backend/open_webui/routers/knowledge.py (4)
28-28
: New import usage check.
You importedModels, ModelForm
to handle referencing knowledge bases in the model’s meta. Ensure these imports are utilized fully and remain consistent with the rest of the codebase.
217-221
: Enhanced access control.
This block checks if the user is the owner or has write-group membership or is an admin. Good improvement; ensure alignment with other ACL checks for consistency.
444-451
: Deleting file collection.
Removing the file’s dedicated collection (444–448) and deleting it from the DB (450) is logical. Confirm no references remain in other knowledge bases or model metas for the same file.
500-505
: Cross-check knowledge removal preconditions.
When deleting a knowledge base, ensure all dependent references are updated. This check prevents partial deactivation scenarios.backend/open_webui/retrieval/utils.py (6)
69-71
: Unused parameter.
user
is not used withinquery_doc
. Consider removing or implementing usage if needed.
88-99
: Unused parameter.
user
is not used withinget_doc
. Consider removing or implementing usage if needed.
154-173
: Ensure safe key access when merging results.
merge_get_results
unconditionally expects each dictionary to contain"documents"
,"metadatas"
, and"ids"
. If any retrieved result is missing these keys, aKeyError
will occur. Consider adding checks or defaults to prevent runtime errors.
259-264
: Chroma ordering logic looks correct.Conditionally reversing results for non-Chroma vector DBs is consistent with your code comments. No issues spotted.
300-305
: Consistent hybrid search ordering logic.Mirroring the sort logic for Chroma in
query_collection_with_hybrid_search
maintains consistency withquery_collection
. Looks good.
501-522
: Potential PII leakage.Forwarding user information (name, email, role) as headers to external services may reveal sensitive data. Verify that this is intentional and that the external API handles PII responsibly.
backend/open_webui/retrieval/web/utils.py (2)
65-74
: Useful URL validation utility.
safe_validate_urls
effectively filters out invalid or private IP addresses. Looks good for preventing SSRF attempts.
504-539
: Loader instantiation logic is well-structured.
get_web_loader
elegantly chooses the loader class fromRAG_WEB_LOADER_ENGINES
and applies proxy/SSL settings. Nicely done.backend/open_webui/routers/tasks.py (4)
55-56
: New field for image prompt generation is clearly exposed.Including
IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE
in the GET config endpoint ensures it's visible to the client. Looks good.
72-74
: Consistent representation of new fields in the form.Defining
ENABLE_TITLE_GENERATION
andIMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE
here ensures UI parity and server sync.
147-151
: Warn about disabled title generation.The early return clarifies to the user that title generation is disabled. This is user-friendly.
303-367
: Image prompt endpoint.The new
/image_prompt/completions
route is structured similarly to the other tasks. Ensure you confirm user permissions if image generation APIs incur cost or handle sensitive data.🧰 Tools
🪛 Ruff (0.8.2)
305-305: Do not perform function call
Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
355-355: Use
form_data.get("chat_id")
instead ofform_data.get("chat_id", None)
Replace
form_data.get("chat_id", None)
withform_data.get("chat_id")
(SIM910)
361-361: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
backend/open_webui/routers/images.py (13)
3-3
: Consolidated new imports
These lines add new imports for 'io', 'UploadFile', environment variables, and theupload_file
function, along with pydantic. Implementation looks correct.Also applies to: 12-12, 15-15, 16-16, 23-23
40-40
: Include prompt_generation in get_config
Adding the 'prompt_generation' field to the returned config is consistent with existing patterns for exposing feature flags.
85-88
: New GeminiConfigForm
Defines a form model with the Gemini API parameters. Straightforward and coherent with existing config forms.
93-93
: Add prompt_generation field to ConfigForm
This boolean field captures whether prompt generation is enabled, aligning with other config parameters.
97-97
: Gemini config in ConfigForm
The newgemini
field references theGeminiConfigForm
, ensuring a typed structure for Gemini settings.
107-109
: Set ENABLE_IMAGE_PROMPT_GENERATION
Assigningform_data.prompt_generation
to the app state persists the user’s prompt generation preference.
116-120
: Set Gemini config in update_config
Storing Gemini API base URL and key in the app’s state is done correctly.
155-155
: Return prompt_generation in config update
Ensures the updated configuration JSON includes the prompt_generation state for accurate front-end consumption.
173-176
: Return Gemini config in updated response
Exposes the persisted Gemini parameters in the config response so that clients can retrieve and display them as needed.
408-419
: Refactor load_b64_image_data
Refined to parse base64 strings and return the decoded image data plus MIME type. This increases clarity and reusability.
445-455
: Implement upload_image
Usingio.BytesIO
to construct anUploadFile
for uploading the generated image. Straightforward and follows existing patterns.
575-602
: ComfyUI block enhancements
Retrieves images from URLs and uploads them. Clean integration that parallels other engine handlers.
646-655
: Automatic1111 block: b64 decode and upload
Consistent patterned approach to decode images viaload_b64_image_data
and then upload them.backend/open_webui/routers/openai.py (9)
78-92
: Modify openai_o1_o3_handler
Renamed to handle O1/O3 model parameters, removing or renaming incompatible fields. This is a clear, minimal fix.
148-155
: Refine removal of stale API configs
The dictionary comprehension neatly filtersOPENAI_API_CONFIGS
so only valid indices remain.
269-271
: Check legacy configs
Continues backward compatibility by allowing either string indices or URL keys for config references.
278-283
: Fallback to legacy key
Retrieves config using the index string or URL. Good approach for ensuring old configs remain accessible.
323-327
: Prefix ID usage
Handles the optionalprefix_id
for model naming. This helps unify naming across different sources.
555-556
: Pop metadata from payload
Separating out the "metadata" field from the main payload ensures the request body aligns with the API spec.
590-590
: Fetch all models
Ensures the newest model data is retrieved before proceeding.
601-606
: Retrieve API config
Falls back correctly to either index-based or URL-based keys for retrieving the config.
624-633
: Handle special cases for O1/O3
Convertsmax_tokens
tomax_completion_tokens
for O1/O3. This is a well-targeted fix for models that have different naming.🧰 Tools
🪛 Ruff (0.8.2)
628-630: Use a single
if
statement instead of nestedif
statements(SIM102)
backend/open_webui/routers/audio.py (6)
14-14
: Import mimetypes
Facilitates MIME type detection for audio files, which is essential for the new STT engine logic.
138-143
: Add DEEPGRAM_API_KEY
Introduces the field inSTTConfigForm
to support Deepgram transcription.
170-172
: Return DEEPGRAM_API_KEY in STT config
Sensitive credentials are returned. Verify whether open disclosure is acceptable or if partial masking is needed.
270-273
: OpenAI TTS request with custom timeout
Adds aClientTimeout
to help avoid indefinite blocking when calling the TTS endpoint.
330-333
: ElevenLabs request with custom timeout
Maintains consistency by applying the same timeout logic to ElevenLabs requests.
390-393
: Azure request with custom timeout
Uniformly sets a timeout for Azure TTS, preventing potential hanging requests.src/lib/apis/index.ts (2)
2-2
: Import appears valid and aligned with usage.
No issues found with this addition.
993-1000
: Bearer token authorization looks correct.
The newly added headers ensure the request is authenticated with the provided token.backend/open_webui/routers/auths.py (2)
28-29
: Cookie variable renaming is clear.
RenamingWEBUI_SESSION_COOKIE_*
toWEBUI_AUTH_COOKIE_*
better reflects their purpose.
167-167
: Confirm the impact of switching the response model.
Changing fromSigninResponse
toSessionUserResponse
may break clients expecting the old response structure. Verify that downstream code and UI are updated accordingly.backend/open_webui/main.py (1)
1213-1213
: Safe to ignore this Ruff warning.
In FastAPI, it’s idiomatic to useuser=Depends(get_verified_user)
in function signatures. This is not an actual error and can be safely ignored.🧰 Tools
🪛 Ruff (0.8.2)
1213-1213: Do not perform function call
Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
backend/open_webui/routers/ollama.py (20)
29-29
: Import appended
The addition ofConfigDict
andvalidator
from Pydantic looks aligned with the new validation logic below.
153-158
: Validate fallback logic
This modified helper function attempts to fetch configurations first byidx
, then bybase_url
as a legacy fallback. Confirm that both paths are tested, especially ifstr(idx)
orbase_url
entries are missing in theconfigs
.
241-248
: Confirm index bounds
The code prunesOLLAMA_API_CONFIGS
based on the enumeratedOLLAMA_BASE_URLS
. Ensure that the derivedkeys
list accurately reflects existing valid indices. If any mismatch occurs (e.g., accidental length changes), we might drop valid configs or keep stale ones.
262-264
: Check config existence
When bothstr(idx)
andurl
are absent inOLLAMA_API_CONFIGS
, this branch defaults tosend_get_request
without an API config. Verify that subsequent usage handles missing credentials gracefully.
366-366
: Usage check
Callingget_api_key
here follows the established pattern. No functional concerns.
397-397
: Filter assignment
Settingmodels["models"] = await get_filtered_models(...)
assumes"models"
is always a valid key in the originalmodels
dict. Consider verifying the structure if future modifications occur.
411-415
: Consistent inline fallback
The usage for key-based authentication remains consistent with earlier logic.
511-511
: Key retrieval usage
No issues. Matches the existing retrieval pattern.
551-551
: Optional model
Definingmodel
asOptional[str] = None
is fine. Ensure callers handle theNone
case properly to avoid unexpected errors.
556-556
: Allowing extra fields
ConfigDict(extra="allow")
is a good way to accommodate additional fields within this Pydantic model.
573-573
: Key retrieval
Fetching the API key here appears consistent with the rest of the module.
604-604
: Same retrieval logic
No specific issues with reusing theget_api_key
approach.
708-708
: Consistent usage
No concerns. This line is aligned with the existing pattern.
933-933
: Call toget_api_key
No issues detected.
939-953
: New validator ensures content or tool_calls
Requiring at least one ofcontent
ortool_calls
is a good way to prevent invalid messages. This helps maintain data integrity in chat usage.
965-965
: Optional tools
Adding an optional tools field broadens the model's flexibility without affecting existing logic.
980-980
: Explicit return
Returning(url, url_idx)
clarifies usage for downstream calls.
994-994
: Pop metadata
Extracting"metadata"
from the form data is a clean approach to handle optional fields.
1023-1023
: Apply system prompt
Ensure there's no conflict ifmetadata
isNone
. Otherwise, the approach is consistent.
1242-1242
: Consistent usage ofget_api_key
No concerns; usage aligns with the existing pattern.backend/open_webui/routers/retrieval.py (25)
24-24
: Use ofrun_in_threadpool
Introducingrun_in_threadpool
can help offload CPU-bound tasks, improving concurrency.
49-49
: New search engine import (Bocha)
Importingsearch_bocha
broadens supported search backends.
54-54
: SerpAPI import
This expands integration with thesearch_serpapi
function.
61-61
: Exa engine import
Similarly, this introduces another supported search engine.
395-397
: Additional keys in the config dictionary
Includingsearchapi_engine
,serpapi_api_key
, andserpapi_engine
in the JSON output is consistent with newly supported functionality. Ensure they’re set or default-handled if empty.
400-400
: New EXA API key
Storing theexa_api_key
in config allows integration with your custom EXA search engine.
403-403
: Domain filter list
ExposingRAG_WEB_SEARCH_DOMAIN_FILTER_LIST
in the output is a good approach for user-configurable domain restrictions.
440-440
: Optional Bocha search key
Designatingbocha_search_api_key
as optional is consistent with the approach for other search engines.
448-449
: SerpAPI fields
Makingserpapi_api_key
andserpapi_engine
optional remains consistent with existing optional search engine credentials.
453-453
: EXA API key
Configured as optional. No concerns.
456-456
: Optional trust_env
Allowing toggling environment-based trust is useful for advanced configurations.
457-457
: Optional domain_filter_list
Good approach to supply a default empty list, preventing potentialNoneType
issues.
462-462
: ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION
Indicating SSL verification is optional aligns with possible insecure or dev test scenarios.
463-463
: RAG_WEB_SEARCH_FULL_CONTEXT
Makes retrieving the entire context from web results switchable. This is a nice feature toggle.
467-467
: RAG_FULL_CONTEXT
Allowing a full context toggle at the global RAG level is consistent with your feature set.
488-492
: Updating RAG_FULL_CONTEXT
This snippet updatesRAG_FULL_CONTEXT
only if present inform_data
. The fallback to the existing value is logical.
555-557
: Bocha search API
AssigningBOCHA_SEARCH_API_KEY
ensures the config is up-to-date with user input.
570-571
: SerpAPI updates
Storingserpapi_api_key
andserpapi_engine
in the config is consistent with other search engines.
581-581
: EXA API key
EnsuringEXA_API_KEY
is saved. No concerns.
589-591
: RAG_WEB_SEARCH_TRUST_ENV
This extends user control over trusted environment variables for web searches.
592-594
: Set domain_filter_list
Assigning domain filters from user-provided data. Logical addition to search constraints.
629-629
: Expose bocha_search_api_key
Including the Bocha API key in the response. Looks consistent with the other search APIs.
637-638
: SerpAPI config
Returning these fields aligns with the rest of the optional search engine credentials.
643-643
: EXA API key
Including EXA credentials in the final output is consistent.
646-647
: Expose trust_env and domain_filter_list
Providing these values in the JSON output for front-end usage or debugging.postcss.config.js (1)
3-3
: Consolidate Tailwind configuration.Replacing separate
tailwindcss
andautoprefixer
entries with@tailwindcss/postcss
seems consistent with newer Tailwind workflows. This looks good.backend/open_webui/retrieval/web/duckduckgo.py (1)
36-46
: LGTM! Improved efficiency and readability.The changes improve both efficiency and readability by:
- Filtering results before constructing SearchResult objects
- Using list comprehension for cleaner result construction
backend/start_windows.bat (1)
9-18
: LGTM! Well-structured conditional block for Playwright setup.The implementation correctly:
- Checks RAG_WEB_LOADER_ENGINE case-insensitively
- Verifies PLAYWRIGHT_WS_URI is not set before installing browsers
- Downloads required NLTK tokenizer
backend/open_webui/retrieval/web/bing.py (1)
26-26
: LGTM! Parameter name aligned with Bing API.The change from "answerCount" to "count" correctly matches Bing API's expected parameter name.
backend/open_webui/retrieval/web/exa.py (1)
48-76
: LGTM! Well-implemented error handling and result transformation.The implementation:
- Properly handles API errors
- Transforms results to the common SearchResult format
- Includes informative logging
backend/open_webui/retrieval/web/bocha.py (1)
60-65
: LGTM! Well-implemented result transformation.The implementation correctly:
- Transforms results to the common SearchResult format
- Handles missing fields with get()
- Respects the requested result count
backend/open_webui/socket/utils.py (1)
29-29
: LGTM! Redundant decode removed.The change correctly removes the redundant
.decode('utf-8')
call since Redis client is already configured withdecode_responses=True
.backend/open_webui/routers/groups.py (2)
5-6
: LGTM: Import statement is correctly placed.The new import for the Users model is appropriately placed with other model imports.
85-86
: LGTM: User validation is properly implemented.The code now validates user IDs before updating group membership, which is a good security practice to prevent invalid user assignments.
scripts/prepare-pyodide.js (2)
26-50
: LGTM: Proxy configuration is well-implemented.The proxy configuration function:
- Correctly prioritizes lowercase environment variables
- Properly validates proxy URLs
- Has good error handling
- Includes helpful logging
12-15
:✅ Verification successful
Verify package compatibility with Pyodide.
Please ensure these new packages are compatible with Pyodide's WebAssembly environment.
🌐 Web query:
Are sympy, tiktoken, and pytz packages compatible with Pyodide?
💡 Result:
SymPy,
tiktoken
, andpytz
are compatible with Pyodide under certain conditions based on their dependencies and how they interact with WebAssembly constraints:SymPy
- Compatibility: Fully supported via manual installation using
micropip
[5].- Details:
SymPy isn't included by default in Pyodide but can be installed from PyPI using:The SymPy Live Shell demonstrates this by dynamically fetching the latest SymPy wheel during deployment[5]. Note that while older Pyodide releases might bundle outdated SymPy versions, manual installation ensures compatibility[5].await pyodide.loadPackage("micropip"); await micropip.install("sympy")
tiktoken
- Compatibility: Works as a pure Python package[2][10].
- Details:
tiktoken
(a Byte-Pair Encoding tokenizer) has no native dependencies and can be installed via:Testing confirms functionality in browser environments[10], though streaming downloads may require cross-origin isolation[1].await micropip.install("tiktoken")
pytz
- Compatibility: Supported via
micropip
[3][9].- Details:
As a pure Python timezone library,pytz
installs cleanly:For timezone data in the standard library’sawait micropip.install("pytz")zoneinfo
, loadtzdata
separately:await pyodide.loadPackage("tzdata") # For stdlib zoneinfo
Key Considerations
- Installation Method: Use
micropip
for PyPI packages[3][9]. Binary packages require explicit loading viapyodide.loadPackage()
[1][6].- Network Limitations: Browser security policies (CORS) may block remote resource fetching unless configured properly[1][3].
- Missing Modules: Avoid dependencies on unsupported modules like
multiprocessing
orssl
(requires explicit loading)[1][7].For all three packages, no fundamental incompatibilities exist with Pyodide’s WebAssembly runtime when installed correctly[1][3][9].
Citations:
- 1: https://pyodide.org/en/stable/usage/wasm-constraints.html
- 2: https://pypi.org/project/tiktoken/
- 3: https://pyodide.org/en/stable/usage/loading-packages.html
- 4: https://pyodide.org/en/stable/project/changelog.html
- 5: https://github.com/sympy/live
- 6: https://github.com/pyodide/pyodide/blob/main/docs/project/changelog.md
- 7: https://daobook.github.io/pyodide-book/docs/usage/03_wasm-constraints.html
- 8: https://pyodide.org/en/0.27.0/usage/packages-in-pyodide.html
- 9: https://pyodide.org/en/latest/index.html
- 10: openai/tiktoken#94
Verified Pyodide Compatibility for New Packages
Based on the latest web query results:
- Sympy: Compatible when manually installed via
micropip
; ensure you loadmicropip
and install Sympy explicitly.- Tiktoken: A pure-Python package that installs cleanly with
micropip
.- Pytz: Works as expected via
micropip
; if relying on standard library timezone support, consider loadingtzdata
as needed.The package additions in
scripts/prepare-pyodide.js
(lines 12–15) are fine provided these installation steps are followed. Also, verify that any additional packages (e.g., seaborn) adhere to similar compatibility guidelines if applicable.backend/open_webui/utils/response.py (1)
9-24
: LGTM! Well-structured tool call conversion function.The function properly handles missing data using
.get()
and provides default values. The UUID generation for missing IDs is a good practice.backend/open_webui/routers/prompts.py (1)
115-120
: LGTM! Enhanced access control logic.The updated condition properly checks for all three access scenarios: original creator, write access through groups, or admin role. The comment clearly explains the access requirements.
backend/open_webui/utils/pdf_generator.py (1)
45-52
: LGTM! Proper HTML escaping implementation.The code now properly escapes HTML special characters in all user-provided content, preventing potential HTML injection vulnerabilities. The newline to
<br/>
conversion maintains proper formatting.Also applies to: 57-57
backend/open_webui/routers/memories.py (1)
60-60
:❓ Verification inconclusive
Verify the impact of user-specific embeddings.
The addition of the
user
parameter toEMBEDDING_FUNCTION
calls suggests personalized embeddings. Ensure this change is compatible with the embedding model and verify its impact on memory retrieval accuracy.Also applies to: 85-85, 108-108, 163-165
🏁 Script executed:
#!/bin/bash # Check if the embedding function is imported and defined correctly rg -A 5 "EMBEDDING_FUNCTION.*=.*" backend/Length of output: 1250
Action: Verify compatibility of personalized embedding integration
The change in
backend/open_webui/routers/memories.py
(line 60, as well as lines 85, 108, and 163–165) now passes auser
parameter toEMBEDDING_FUNCTION
. However, our search results indicate thatEMBEDDING_FUNCTION
is initialized in bothbackend/open_webui/main.py
andbackend/open_webui/routers/retrieval.py
viaget_embedding_function
without any sign of handling an extra parameter. Please ensure that:
- The implementation of
get_embedding_function
(or the function it returns) is updated to accept and correctly process the additionaluser
parameter.- The embedding model in use supports and appropriately utilizes personalized embeddings without compromising memory retrieval accuracy.
- All usage sites are consistent in their parameter passing and that no side effects are introduced in the embedding calculations.
backend/open_webui/utils/access_control.py (1)
10-25
: LGTM! Well-structured recursive function for filling missing permissions.The implementation correctly handles nested dictionaries and ensures all default permissions are present.
src/lib/apis/models/index.ts (1)
222-222
: LGTM! Improved error handling specificity.Using
err.detail
instead of the full error object provides more focused error information to the user.backend/open_webui/routers/models.py (2)
158-166
: LGTM! Enhanced access control for model updates.The implementation correctly checks for user ownership, write access, and admin role before allowing model updates.
186-190
: LGTM! Improved access control for model deletion.The implementation properly verifies admin role, user ownership, and write access before allowing model deletion.
backend/open_webui/constants.py (2)
60-60
: LGTM! Improved error message clarity.The updated message is more user-friendly and avoids listing specific formats, making it more maintainable.
116-116
: LGTM! Added new task for image prompt generation.The new task constant follows the existing naming convention and integrates well with the TASKS enum.
backend/open_webui/models/groups.py (1)
83-83
: LGTM!The addition of the
permissions
field with appropriate typing and default value is well-implemented.backend/open_webui/utils/images/comfyui.py (1)
164-164
:❓ Verification inconclusive
Verify the reason for reducing the random seed range.
The upper limit for random seed generation has been reduced from
2^64-2
to2^50
. While this still provides a large range of possible seeds, please verify if this change is:
- Required for compatibility with external systems
- A performance optimization
- Has any specific reason
🌐 Web query:
What is the recommended range for random seeds in ComfyUI?
💡 Result:
ComfyUI's recommended seed ranges vary slightly depending on the specific nodes used, but generally follow these guidelines:
Standard Range
Most seed implementations use 64-bit unsigned integers ranging from:
0
to18,446,744,073,709,551,615
(hex:0xffffffffffffffff
) [1][6]. This allows approximately 18 quintillion unique possibilities.Special Values
Some nodes like rgthree's implementation accept extended ranges and special values:
-1
: Random seed per generation [2][5]-2
/-3
: Increment/decrement last used seed [2]- Extended signed range:
-1,125,899,906,842,624
to+1,125,899,906,842,624
in rgthree nodes [5]Key Implementation Details
- Seeds control reproducibility - identical seeds with matching settings produce identical outputs [3][4]
- Batch generation assigns sequential seeds automatically (first image uses input seed) [4]
- Special samplers like Euler may override seed behavior compared to DPM variants [4][7]
- Nodes like CR Seed and Seed Generator enforce unsigned 64-bit ranges by default [1][6]
For most workflows:
# Typical usage pattern seed = 42 # Any value between 0-18446744073709551615Use
-1
in compatible nodes for automatic randomization[2][5].Citations:
- 1: https://www.runcomfy.com/comfyui-nodes/ComfyUI_Comfyroll_CustomNodes/CR-Seed
- 2: https://www.comfydeploy.com/comfy-node/rgthree/rgthree-comfy
- 3: https://stablediffusion3.net/blog-Understanding-ComfyUI-Nodes-A-Comprehensive-Guide-40687
- 4: https://github.com/Creative-comfyUI/seed_eng
- 5: https://www.runcomfy.com/comfyui-nodes/rgthree-comfy/Seed--rgthree-
- 6: https://www.runcomfy.com/comfyui-nodes/comfy-image-saver/Seed-Generator
- 7: https://www.youtube.com/watch?v=IqgNPw1j8LQ
- 8: https://comfy.icu/node/NegiTools_SeedGenerator
- 9: comfyanonymous/ComfyUI#278
- 10: https://stable-diffusion-art.com/comfyui/
Seed range reduction may be intentionally set for compatibility with certain nodes (e.g. rgthree) that require seeds within a 50‑bit limit.
Based on the web reference, most ComfyUI seed implementations use the full 64‑bit range (0 to 2^64‑1). However, specific nodes—like those in rgthree’s implementation—appear to work with a signed range roughly between –2^50 and +2^50. Reducing the upper limit to 2^50 in
backend/open_webui/utils/images/comfyui.py
suggests a deliberate choice to ensure compatibility with such nodes.To proceed, please verify that:
- The limited 50‑bit range is expected by all downstream consumers (especially nodes that may enforce these limits).
- There are no performance implications or unintended side effects for nodes that might normally accept values in the full 64‑bit range.
- Documentation/comments are updated to clarify the reason for restricting the seed range for future maintainers.
backend/open_webui/utils/auth.py (1)
34-48
: LGTM! Secure implementation of HMAC signature verification.The implementation follows security best practices:
- Uses constant-time comparison with
hmac.compare_digest
- Properly handles exceptions
- Uses SHA-256 for hashing
.github/workflows/integration-test.disabled (1)
55-56
: LGTM! Good addition for CI environment.Setting
LIBGL_ALWAYS_SOFTWARE=1
is a good practice for running Cypress in CI environments where hardware acceleration may not be available.backend/open_webui/utils/models.py (1)
145-145
: LGTM! Good defensive programming.Using
model.get("owned_by", "unknown owner")
instead of direct dictionary access is a good practice to prevent KeyError exceptions.backend/open_webui/routers/users.py (2)
65-68
: LGTM! Good security practice.Setting default workspace permissions to
False
follows the principle of least privilege, which is a good security practice.
156-156
: LGTM! Good separation of concerns.Using
update_user_settings_by_id
instead ofupdate_user_by_id
follows the principle of least privilege by limiting the scope of the update to just settings.backend/open_webui/models/users.py (3)
274-291
: LGTM! The user settings update implementation is robust.The method properly handles null settings and uses appropriate error handling.
328-332
: LGTM! The implementation is efficient and focused.The method efficiently filters valid user IDs using SQL's IN clause.
292-309
: LGTM! The user deletion cleanup is comprehensive.The implementation properly cleans up user associations in the correct order: groups → chats → user.
backend/open_webui/retrieval/vector/dbs/milvus.py (2)
10-11
: LGTM! New configuration imports are properly organized.The imports are well-organized and follow the existing pattern.
18-21
: LGTM! Token-based authentication is properly implemented.The conditional initialization handles both token and non-token cases cleanly.
backend/open_webui/functions.py (1)
253-253
:✅ Verification successful
Verify the updated function signature.
The function call now includes metadata as a new parameter. Ensure that the
apply_model_system_prompt_to_body
function in the payload utils module has been updated to accept this parameter.
🏁 Script executed:
#!/bin/bash # Description: Verify the function signature of apply_model_system_prompt_to_body # Search for the function definition rg -A 5 "def apply_model_system_prompt_to_body"Length of output: 477
The updated function signature has been verified.
The call inbackend/open_webui/functions.py
now properly passes themetadata
parameter along withparams
,form_data
, anduser
, which aligns with the definition inbackend/open_webui/utils/payload.py
. No further changes are needed.src/lib/components/AddConnectionModal.svelte (3)
24-25
: LGTM! Props are properly declared.The new props follow Svelte conventions with appropriate default values.
42-43
: LGTM! Error handling is consistent.The error handling is improved with consistent string formatting.
Also applies to: 51-55
205-205
: LGTM! Layout classes improve responsiveness.The added flex and shrink utilities enhance the layout structure.
backend/open_webui/socket/main.py (1)
282-284
: Improve error handling for missing chat_id and message_id.Using
.get()
with a default value ofNone
is a good defensive programming practice to handle missing keys.backend/open_webui/utils/task.py (1)
25-25
: Improve error handling for model ownership check.Using
.get()
with a default value is a good defensive programming practice to handle missing keys.src/lib/components/admin/Evaluations/Leaderboard.svelte (2)
354-355
: Use consistent class naming.Changed from
flex-shrink-0
toshrink-0
for consistency with Tailwind's class naming conventions.
3-5
:❓ Verification inconclusive
Verify WASM paths configuration.
The WASM paths configuration needs to be verified to ensure the files are available at the specified location.
🏁 Script executed:
#!/bin/bash # Check if WASM files exist in the public directory fd -t f . public/wasm -e wasmLength of output: 130
Action Required: Confirm WASM Files Location
The current verification command indicates that the
public/wasm
directory does not exist (error: “Search path 'public/wasm' is not a directory”). Please manually verify that the WASM files are correctly deployed and that the runtime environment maps the/wasm/
URL to the proper directory. If your build or deployment setup places these files in a different location, update the configuration accordingly.backend/open_webui/routers/files.py (2)
233-245
: LGTM! Improved PDF file handling.The changes properly handle PDF files by setting the appropriate content disposition and content type headers, allowing PDFs to be displayed inline in the browser.
125-125
: Simplify error logging messages.The error logging has been simplified to use consistent messages across different functions.
Also applies to: 254-254, 285-285
backend/open_webui/env.py (3)
57-62
: LGTM! Improved device detection for Apple Silicon.The addition of MPS (Metal Performance Shaders) device detection improves performance on Apple Silicon devices.
359-375
: LGTM! Enhanced cookie security settings.The changes improve cookie security by:
- Separating session and auth cookie settings
- Making settings configurable via environment variables
- Maintaining backward compatibility
110-114
:✅ Verification successful
Verify the new configuration values.
The WebUI name, favicon URL, and trusted signature key have been updated with new default values.
🌐 Web query:
Is "Prediction Guard Chat" a valid default name for this application? This seems to be a significant branding change.
💡 Result:
The name "Prediction Guard Chat" appears consistently across multiple official contexts as part of Prediction Guard's product ecosystem:
LangChain Integration
The Python librarylangchain_predictionguard
explicitly usesChatPredictionGuard
as its chat interface class[1]. Documentation refers to it as "Prediction Guard Chat" when describing API endpoints for building chatbots[1].GitHub Implementation
Prediction Guard's guarded-chat repository describes itself as providing access to their "Chat endpoint" while displaying "Prediction Guard Chatbot" in the interface[3]. This suggests "Chat" is an accepted shorthand in developer contexts.API Documentation
Prediction Guard's API guides use "Chat API" as a standard term when explaining how to implement conversational features[4].While no explicit branding announcement appears in these sources, the pattern shows:
- Consistency: Used uniformly across technical implementations
- Differentiation: Separates chat functionality from other services like completions and embeddings[1]
- Developer Familiarity: Follows naming conventions seen in AI/ML frameworks (e.g., LangChain's chat models)
The name appears valid based on current technical documentation rather than indicating a recent rebranding effort.
Citations:
- 1: https://python.langchain.com/docs/integrations/providers/predictionguard/
- 2: https://business.purdue.edu/journal/24/s/stories/data4good.php
- 3: https://github.com/predictionguard/guarded-chat
- 4: https://docs.predictionguard.com/guides-and-concepts/guides/many-chat-with-ll-ms
Configuration Values Verified
The updated default for
WEBUI_NAME
("Prediction Guard Chat") has been confirmed against official documentation and appears consistently in Prediction Guard’s product ecosystem. In addition, the favicon URL and the signature key defaults seem appropriate given their usage context. No further actions are required.backend/open_webui/routers/tools.py (2)
72-74
: LGTM! Updated permission check.The permission check now correctly verifies "workspace.tools" instead of "workspace.knowledge".
168-173
: LGTM! Enhanced access control logic.The access control logic has been improved to:
- Check if the user is the original creator
- Verify write access through access control groups
- Allow admin access
- Use appropriate HTTP status codes (400 for prohibited access)
Also applies to: 230-234, 317-325
backend/open_webui/retrieval/vector/dbs/pgvector.py (1)
97-124
: LGTM! Improved error handling and robustness.The changes enhance the
check_vector_length
method by:
- Adding early return if table doesn't exist
- Providing clear error messages for different scenarios
- Properly checking vector column type and dimensions
backend/open_webui/utils/chat.py (1)
63-155
: LGTM! Well-structured direct chat completion implementation.The implementation:
- Properly handles streaming responses using asyncio.Queue
- Cleans up socket handlers in background tasks
- Provides clear error handling
However, consider using
contextlib.suppress
for cleaner error handling:- async def background(): - try: - del sio.handlers["/"][channel] - except Exception as e: - pass + from contextlib import suppress + async def background(): + with suppress(Exception): + del sio.handlers["/"][channel]🧰 Tools
🪛 Ruff (0.8.2)
128-131: Use
contextlib.suppress(Exception)
instead oftry
-except
-pass
Replace with
contextlib.suppress(Exception)
(SIM105)
130-130: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
src/lib/components/admin/Settings.svelte (1)
192-216
: LGTM! Consistent implementation of Code Execution settings.The changes:
- Follow existing button styling patterns
- Properly integrate the CodeExecution component
- Implement save handler consistently with other settings
Also applies to: 394-402
src/lib/components/admin/Functions.svelte (4)
6-6
: LGTM!The addition of
settings
import is necessary for the direct connections feature.
64-64
: LGTM: Consistent error message formatting.Error messages are now consistently formatted using template literals.
Also applies to: 91-91, 107-107, 121-121, 140-140, 437-437
54-57
: LGTM: Consistent model fetching with direct connections support.All model fetching calls have been updated to include the direct connections parameter, maintaining consistency across the codebase.
Also applies to: 372-378, 515-520, 541-546
183-183
:❓ Verification inconclusive
Verify the custom event name.
The event name 'blur-sm' is non-standard. Ensure this is intentional and the event is properly defined elsewhere in the codebase.
Also applies to: 188-188
🏁 Script executed:
#!/bin/bash # Search for other occurrences of 'blur-sm' event rg -A 5 "addEventListener\('blur-sm'"Length of output: 1913
Action Required: Verify 'blur-sm' Custom Event Usage
- The event
"blur-sm"
is used consistently in multiple components:
- src/lib/components/admin/Functions.svelte (lines 183 and 188)
- src/lib/components/layout/Sidebar.svelte
- src/lib/components/workspace/Models.svelte
- src/lib/components/workspace/Tools.svelte
- Since
"blur-sm"
is not a standard browser event, please confirm that it is an intentional custom event. If so, verify that it is correctly defined and dispatched (e.g., viaCustomEvent
) and consider adding documentation or inline comments to clarify its purpose.backend/open_webui/test/apps/webui/storage/test_provider.py (2)
1-12
: LGTM: Comprehensive test setup.The imports provide all necessary dependencies for testing various storage providers.
🧰 Tools
🪛 Ruff (0.8.2)
10-10:
azure.storage.blob.BlobServiceClient
imported but unusedRemove unused import
(F401)
10-10:
azure.storage.blob.ContainerClient
imported but unusedRemove unused import
(F401)
10-10:
azure.storage.blob.BlobClient
imported but unusedRemove unused import
(F401)
14-57
: LGTM: Well-structured test helpers and basic provider tests.The implementation includes:
- A reusable mock_upload_dir helper
- Comprehensive provider instantiation tests
- Good error case coverage
🧰 Tools
🪛 Ruff (0.8.2)
23-23: Found useless expression. Either assign it to a variable or remove it.
(B018)
24-24: Found useless expression. Either assign it to a variable or remove it.
(B018)
25-25: Found useless expression. Either assign it to a variable or remove it.
(B018)
26-26: Found useless expression. Either assign it to a variable or remove it.
(B018)
27-27: Found useless expression. Either assign it to a variable or remove it.
(B018)
28-28: Found useless expression. Either assign it to a variable or remove it.
(B018)
src/lib/components/admin/Settings/Audio.svelte (2)
42-42
: LGTM: Well-implemented Deepgram integration.The implementation includes:
- Secure API key handling
- Clear UI for model selection
- Helpful documentation links
Also applies to: 180-182, 220-250
54-57
: LGTM: Consistent model fetching implementation.The model fetching logic aligns with the direct connections feature implementation in Functions.svelte.
backend/open_webui/routers/chats.py (1)
447-449
: LGTM: Well-structured form class.The CloneForm class properly defines an optional title field.
src/lib/apis/chats/index.ts (1)
583-595
: LGTM! Clean implementation of optional title parameter.The implementation correctly:
- Adds optional title parameter to function signature
- Uses spread operator to conditionally include title in request body
- Maintains backward compatibility
backend/open_webui/models/chats.py (2)
473-473
: LGTM! Fixed typo in comment.Simple correction of "checkng" to "checking" in the comment.
396-396
:❓ Verification inconclusive
Verify impact of removing folder_id filter.
The removal of
.filter_by(folder_id=None)
means this method will now return all chats for a user, regardless of folder. Ensure this change is intentional and that all consuming code handles the expanded result set correctly.
🏁 Script executed:
#!/bin/bash # Search for direct usages of get_chat_list_by_user_id rg -A 5 "get_chat_list_by_user_id"Length of output: 2223
Impact of Updated Chat Query in get_chat_list_by_user_id
- The removal of the
folder_id
filter inget_chat_list_by_user_id
(backend/open_webui/models/chats.py, line 396) means that all chats for a given user will now be returned, regardless of folder association. Verify that downstream consumers—such as the calls in backend/open_webui/routers/chats.py—are intended to work with this broader result set.- The comment fix in
get_chat_by_share_id
is a straightforward typo correction with no functional impact..github/workflows/release-pypi.yml (1)
22-22
:✅ Verification successful
Consider using LTS version of Node.js.
Node.js 22 is currently in development and not yet an LTS release. This could potentially introduce stability issues in the build process.
Consider using the latest LTS version instead:
- node-version: 22 + node-version: 20
🌐 Web query:
What is the latest LTS version of Node.js?
💡 Result:
The latest Long Term Support (LTS) version of Node.js is v22.x (codename "Jod"), which entered Active LTS status on October 29, 2024[1][8]. This version will receive critical updates and security patches until April 2027[7][8], with:
- Active LTS support until October 2025
- Maintenance LTS support from October 2025 to April 2027
Key details about Node.js v22 LTS:
- Includes a built-in WebSocket client for native real-time communication[1]
- Ships with OpenSSL 3.0.x (quictls fork) for enhanced security[8]
- Provides stable APIs and performance improvements from previous versions[1]
The current recommended production version as of February 2025 is v22.14.0[6][10], which can be downloaded from the official Node.js website. Previous LTS versions like v20.x ("Iron") are now in Maintenance LTS until April 2026[4][7], but new projects should adopt v22.x for maximum support coverage.
For development environments needing cutting-edge features, Node.js v23.x remains in Current release status but isn't recommended for production use[3].
Citations:
- 1: http://nodesource.com/blog/Node.js-v22-Long-Term-Support-LTS/
- 2: https://www.npmjs.com/package/node-lts-versions
- 3: https://nodejs.org/en/about/previous-releases
- 4: https://nodejs.org/en/blog/release/v20.9.0
- 5: https://daily.dev/blog/nodejs-v20-lts-is-now-generally-available-and-its-awesome
- 6: https://nodejs.org/en/download
- 7: https://www.herodevs.com/blog-posts/node-js-end-of-life-dates-you-should-be-aware-of
- 8: https://nodejs.org/en/blog/release/v22.11.0
- 9: https://www.nearform.com/digital-community/node-js-release-schedule-explained
- 10: https://nodejs.org/en
Node.js v22 is now the proper LTS version
The update to
node-version: 22
is valid. Node.js v22.x entered Active LTS status in October 2024 and is the current recommended production version as of February 2025. No changes are needed, as using Node.js 22 aligns with the latest LTS recommendations.docker-compose.yaml (5)
1-3
: File Header and Version Declaration
The version declaration and service container are formatted correctly.
4-25
: New Servicesearxng
Added
The newsearxng
service is well configured with proper container name, image, ports, volume, environment file, restart policy, and security capabilities. Please verify that the environment file (.env
) contains the correct configuration forsearxng
and that all volume paths are accessible.
27-47
: Update toopen-webui
Service Dependencies and Environment
Theopen-webui
service now depends onsearxng
, which is consistent with the new changes. However, note that the environment variable on line 46 still points toOLLAMA_BASE_URL=http://ollama:11434
. Since theollama
service is removed, consider updating or removing this variable unless it is still used for legacy purposes.
52-57
: New Servicetika
Added
The addition of thetika
service with its container name, image, and port mapping is clear and follows the style of other service definitions.
59-63
: Volumes Configuration Review
A new volumefavicons
has been added appropriately for mounting assets. However, the volumeollama
is still declared (line 60) even though theollama
service was removed. Please verify ifollama
volume is still needed or if it should be removed to keep the configuration clean.backend/requirements.txt (6)
1-4
: Dependency Version Updates (FastAPI and Pydantic)
The updates forfastapi
andpydantic
to versions0.115.7
and2.10.6
respectively are clear. Ensure that these newer versions are compatible with your existing backend code and that all tests pass.
7-12
: Other Core Dependencies Updated
Version bump forpython-jose
to3.4.0
andaiohttp
to3.11.11
are noted. Please verify any breaking changes between the old and new versions in the context of your application.
32-34
: New DependencyRestrictedPython
Added
The addition ofRestrictedPython==8.0
looks appropriate; just ensure that its usage in the codebase is properly covered by tests and that security reviews have been conducted for sandboxing requirements.
48-51
: Dependency Updates for AI/ML and Browser Automation Tools
The updates forchromadb
,opensearch-py
, andplaywright
are consistent with modernizing the stack. Note the comment regarding the Playwright version—ensure that it matches the configuration in your Docker Compose setups.
55-64
: Other Dependency Version Updates and Additions
The remaining version updates (e.g.,pymdown-extensions
,unstructured
,soundfile
,opencv-python-headless
,faster-whisper
,authlib
, andduckduckgo-search
) are clearly listed. Please double-check that your integration tests validate compatibility after these updates.
104-108
: New Cloud and Identity Libraries
The additions and updates forgoogle-cloud-storage
,azure-identity
, andazure-storage-blob
are appropriate given the expanded cloud functionality. Verify that any new authentication or storage code interacts seamlessly with these libraries.backend/start.sh (2)
17-37
: Legacy Configuration for Secret Key and Conditional Service Starts
The remainder of the script (lines 17–37) remains unchanged and appears to handle key loading and legacy service starts (likeollama serve
) correctly. Ensure that any deprecated code (related to ollama) is revisited in line with other service removal updates.🧰 Tools
🪛 Shellcheck (0.10.0)
[warning] 27-27: Quote this to prevent word splitting.
(SC2046)
39-43
: CUDA Library Path Update
The update forUSE_CUDA_DOCKER
(lines 39–42) properly appends the necessary paths for CUDA libraries.package.json (5)
1-8
: Version Bump and New Script Addition
The project version has been updated from"0.5.4"
to"0.5.16"
, and a new development script"dev:5050"
has been added. Both changes improve clarity and offer additional development options.
28-29
: New DevDependencies for Tailwind Plugins
The addition of"@tailwindcss/container-queries": "^0.1.1"
and"@tailwindcss/postcss": "^4.0.0"
in the devDependencies helps enhance styling capabilities. Make sure these plugins are integrated into your PostCSS configuration.
46-51
: Dependency Updates for Build Tools
The upgrades for"tailwindcss"
,"vite"
, and"vitest"
are noted. Ensure that these updates are compatible with your SvelteKit configuration and that existing tests run as expected after these changes.
87-89
: Dependency Updates and Additions in Production Dependencies
Dependencies such as"katex"
,"kokoro-js"
, and"pyodide"
have been updated or added. Confirm that these dependencies work together seamlessly in your build process and that any breaking changes have been addressed.
109-112
: New Dependencies:undici
andvite-plugin-static-copy
The addition of"undici"
and"vite-plugin-static-copy"
should be reviewed in context—ensure that their usage in the codebase is as intended and that they are properly configured in your build pipeline.src/app.html (4)
8-10
: Rebranding: Updated Apple Mobile Web App Title
The<meta name="apple-mobile-web-app-title" content="Global Chat" />
tag now reflects the new branding. This is consistent with the overall rebranding effort.
17-23
: Rebranding: Updated Description and Search Metadata
The changes to the<meta name="description">
and<link rel="search">
tags now using "Global Chat" are appropriate for the rebranding.
24-25
: New Script Inclusion: Loader Script
The addition of the<script src="/static/loader.js" defer></script>
tag (line 24) is clear. Verify that the loader script exists at the specified location and that it does not introduce performance issues during page load.
80-81
: Updated Page Title for Rebranding
The<title>
tag is updated to "Global Chat", which aligns with the new branding direction.docs/apache.md (2)
19-21
: Add HTTP WebSocket Proxy ConfigurationThe new lines add WebSocket proxy configuration (with the comment "Needed after 0.5") immediately after the standard HTTP reverse proxy setup. This is clear and concise for enabling WebSocket support in the HTTP VirtualHost.
38-40
: Add HTTPS WebSocket Proxy ConfigurationSimilarly, the addition of WebSocket proxy configuration for the HTTPS VirtualHost is consistent with the HTTP setup. It’s properly documented with the “Needed after 0.5” comment and ensures that WebSocket requests over SSL are handled correctly.
Dockerfile (1)
33-35
: Increase Node.js Memory AllocationThe new environment variable
ENV NODE_OPTIONS="--max-old-space-size=4096"correctly increases the memory allocation for the Node.js build process. This change can help avoid potential out-of-memory issues during the build.
run-compose.sh (3)
77-78
: Document the Playwright Option in UsageThe usage message now includes the
--playwright
option with a clear description ("Enable Playwright support for web scraping."). This informs users about the new functionality right from the help output.
134-136
: Parse the Playwright FlagThe argument parsing correctly sets the
enable_playwright
flag when the--playwright
option is encountered:--playwright) enable_playwright=true ;;
This is clean and follows the style of the other flag parsing logic.
190-192
: Integrate Playwright into Docker Compose CommandThe conditional block appends the
docker-compose.playwright.yaml
configuration whenenable_playwright
is true:if [[ $enable_playwright == true ]]; then DEFAULT_COMPOSE_COMMAND+=" -f docker-compose.playwright.yaml" fiThis approach cleanly integrates Playwright support into the compose command.
src/app.css (9)
1-2
: Reference Tailwind CSSThe new
@reference "./tailwind.css";
at the top ensures that Tailwind’s utilities are included. This clear reference enhances modularity and consistency in styling.
57-59
: Enhance Markdown Prose StylingThe updated
.markdown-prose
class now applies additional utilities (like border styling for blockquotes and adjusted typography), which should improve the readability of markdown content.
61-63
: Update Smaller Markdown Prose StylingThe
.markdown-prose-xs
class now includes similar enhancements as the standard version, ensuring consistency across different text sizes.
73-82
: Introduce Drag-and-Drop Region ClassesThe additions of the
.drag-region
,.drag-region a
,.drag-region button
, and.no-drag-region
classes (with appropriate-webkit-app-region
settings) are well implemented. They provide clear control over draggable regions which is useful for desktop app interfaces.
119-121
: Adjust Select Element Background PositionChanging the
background-position
of theselect
element toright 0rem center
fine-tunes its appearance. Removing the previously commented-out padding adjustments also cleans up the code.
132-139
: Add Shimmer Keyframe AnimationThe new
@keyframes shimmer
definition provides a smooth background animation, which is then used in the.shimmer
class to create a visually appealing loading effect. The fallback color definition is also a nice touch.
141-149
: Implement the Shimmer ClassThe
.shimmer
class leverages the new keyframe animation effectively. This creates an engaging text effect and demonstrates attention to detail in UI feedback.
161-170
: Add Smooth Fade-In AnimationThe newly defined
@keyframes smoothFadeIn
and the accompanying.status-description
class introduce a subtle animated appearance, enhancing the user experience for status messages.
222-230
: Refine Scrollbar Visibility for Code ScrollerThe modifications to the
.cm-scroller
scrollbar styling now conditionally show/hide the scrollbar thumb. This update improves the usability of scrollable areas, especially during user interaction.README.md (1)
182-183
: Update Documentation Link for Updating GuideThe updated link replacing the old migration guide with the "Updating Guide" improves guidance for users. Ensure the URL is verified to match the latest documentation.
searxng/settings.yml (4)
82-112
: Server and Redis Sections – Environment Variable Integration
The “server” section is well documented with notes on environment variable overrides, and the inline comments help clarify the purpose of each setting (for example,base_url
andsecret_key
notes). Ensure that thebase_url
value (set to/
) meets your deployment requirements and is correctly interpreted as a string. Also, verify that settingredis.url
tofalse
correctly signals that no connection should be established or that it is intended to be overridden via environment variables.🧰 Tools
🪛 Gitleaks (8.21.2)
99-99: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
118-171
: UI Settings – Customization and Defaults
The UI section is detailed and offers a wide range of customization options (such as paths, themes, and behaviors). Ensure that the default values (for example, empty strings forstatic_path
andtemplates_path
) are intended, and consider adding more descriptive comments if users are expected to override these values.
186-221
: Outgoing Communication Settings – Timeouts and Connection Handling
The settings under “outgoing” are clearly defined and include sensible default values (e.g.request_timeout: 3.0
,pool_connections: 100
). Please double-check that these values meet your performance and reliability requirements, and that the additional configuration (like HTTP/2 support) is aligned with your environment.
2566-2575
: DOI Resolvers Configuration – Clear and Concise
The DOI resolvers section, along with thedefault_doi_resolver
setting, is clearly defined and appears consistent. Just ensure that the URLs provided for each resolver are current and that the default choice (oadoi.org
) aligns with your desired behavior for DOI resolution.CHANGELOG.md (2)
8-9
: Version Heading Update VerificationThe changelog now begins with the updated version header “## [0.5.16] - 2025-02-20”. This update clearly reflects the jump from version 0.5.4 to 0.5.16 as specified in the PR objectives. Please ensure that corresponding release notes and documentation are also updated to match this version change.
10-12
: Clear Documentation of Fixed Issues for Version 0.5.16The “### Fixed” section under version 0.5.16 documents the restoration of web search retrieval very clearly. The bullet point outlines the correction in reverting deduplication changes, which is both concise and comprehensible. This aids readers in quickly understanding the critical fix.
async def execute_code_jupyter( | ||
jupyter_url, code, token=None, password=None, timeout=10 | ||
): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider using an asynchronous HTTP client for concurrency.
The execute_code_jupyter
function is defined as async
yet uses requests
(a blocking HTTP client) which can block the event loop. To improve concurrency, consider switching to a non-blocking library like aiohttp
.
if (param := params.get(key, None)) is not None: | ||
form_data[value] = param | ||
# Copy the parameter to new name then delete it, to prevent Ollama warning of invalid option provided | ||
params[value] = params[key] | ||
del params[key] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove unused variable assignment.
(param := params.get(key, None))
is assigned but never used. Remove or refactor this assignment to avoid confusion and adhere to best practices.
- if (param := params.get(key, None)) is not None:
+ if params.get(key) is not None:
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (param := params.get(key, None)) is not None: | |
form_data[value] = param | |
# Copy the parameter to new name then delete it, to prevent Ollama warning of invalid option provided | |
params[value] = params[key] | |
del params[key] | |
if params.get(key) is not None: | |
# Copy the parameter to new name then delete it, to prevent Ollama warning of invalid option provided | |
params[value] = params[key] | |
del params[key] |
🧰 Tools
🪛 Ruff (0.8.2)
76-76: Local variable param
is assigned to but never used
(F841)
76-76: Use params.get(key)
instead of params.get(key, None)
Replace params.get(key, None)
with params.get(key)
(SIM910)
|
||
|
||
@router.get("/direct_connections", response_model=DirectConnectionsConfigForm) | ||
async def get_direct_connections_config(request: Request, user=Depends(get_admin_user)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid using Depends(...)
as a default parameter value [ruff B008].
FastAPI recommends assigning dependencies via function parameters (or router-level dependencies) instead of using them as default parameter values to comply with best practices and avoid potential pitfalls:
Use a pattern like:
-async def get_direct_connections_config(request: Request, user=Depends(get_admin_user)):
+async def get_direct_connections_config(request: Request, user: User = Depends(get_admin_user)):
...
-async def set_code_execution_config(
- request: Request, form_data: CodeInterpreterConfigForm, user=Depends(get_admin_user)
-):
+async def set_code_execution_config(
+ request: Request, form_data: CodeInterpreterConfigForm, user: User = Depends(get_admin_user)
+):
...
Also applies to: 59-59, 90-90, 111-111
🧰 Tools
🪛 Ruff (0.8.2)
49-49: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
except ClientError as e: | ||
raise RuntimeError(f"Error uploading file to S3: {e}") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use explicit exception chaining ([ruff B904]).
When re-raising an exception, provide from e
to clarify the cause and preserve the original traceback. Example fix:
-except ClientError as e:
- raise RuntimeError(f"Error uploading file to S3: {e}")
+except ClientError as e:
+ raise RuntimeError(f"Error uploading file to S3: {e}") from e
Repeating similarly for GCS and Azure exceptions will improve debugging and clarity of error origins.
Also applies to: 125-127, 133-135, 153-154, 189-190, 201-202, 210-211, 224-225, 259-260, 271-272, 280-281, 292-293
🧰 Tools
🪛 Ruff (0.8.2)
116-116: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
async with aiohttp.ClientSession() as session: | ||
for filter in sorted_filters: | ||
urlIdx = filter.get("urlIdx") | ||
if urlIdx is None: | ||
continue | ||
|
||
url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] | ||
key = request.app.state.config.OPENAI_API_KEYS[urlIdx] | ||
|
||
if key != "": | ||
r = requests.post( | ||
f"{url}/{filter['id']}/filter/outlet", | ||
headers={"Authorization": f"Bearer {key}"}, | ||
json={ | ||
"user": user, | ||
"body": payload, | ||
}, | ||
) | ||
if not key: | ||
continue | ||
|
||
r.raise_for_status() | ||
data = r.json() | ||
payload = data | ||
except Exception as e: | ||
# Handle connection error here | ||
print(f"Connection error: {e}") | ||
headers = {"Authorization": f"Bearer {key}"} | ||
request_data = { | ||
"user": user, | ||
"body": payload, | ||
} | ||
|
||
if r is not None: | ||
try: | ||
async with session.post( | ||
f"{url}/{filter['id']}/filter/outlet", | ||
headers=headers, | ||
json=request_data, | ||
) as response: | ||
response.raise_for_status() | ||
payload = await response.json() | ||
except aiohttp.ClientResponseError as e: | ||
try: | ||
res = r.json() | ||
res = ( | ||
await response.json() | ||
if "application/json" in response.content_type | ||
else {} | ||
) | ||
if "detail" in res: | ||
return Exception(r.status_code, res) | ||
raise Exception(response.status, res) | ||
except Exception: | ||
pass | ||
|
||
else: | ||
pass | ||
except Exception as e: | ||
print(f"Connection error: {e}") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused ClientResponseError
variable and concurrency caution.
- Variable
e
inexcept aiohttp.ClientResponseError as e
(line 144) isn’t used. Remove the variable or reference it if needed. - Ensure no data race on
payload
when shared across multiple coroutines. Ifpayload
is mutated, concurrency locks might be needed.
-except aiohttp.ClientResponseError as e:
+except aiohttp.ClientResponseError:
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
async with aiohttp.ClientSession() as session: | |
for filter in sorted_filters: | |
urlIdx = filter.get("urlIdx") | |
if urlIdx is None: | |
continue | |
url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] | |
key = request.app.state.config.OPENAI_API_KEYS[urlIdx] | |
if key != "": | |
r = requests.post( | |
f"{url}/{filter['id']}/filter/outlet", | |
headers={"Authorization": f"Bearer {key}"}, | |
json={ | |
"user": user, | |
"body": payload, | |
}, | |
) | |
if not key: | |
continue | |
r.raise_for_status() | |
data = r.json() | |
payload = data | |
except Exception as e: | |
# Handle connection error here | |
print(f"Connection error: {e}") | |
headers = {"Authorization": f"Bearer {key}"} | |
request_data = { | |
"user": user, | |
"body": payload, | |
} | |
if r is not None: | |
try: | |
async with session.post( | |
f"{url}/{filter['id']}/filter/outlet", | |
headers=headers, | |
json=request_data, | |
) as response: | |
response.raise_for_status() | |
payload = await response.json() | |
except aiohttp.ClientResponseError as e: | |
try: | |
res = r.json() | |
res = ( | |
await response.json() | |
if "application/json" in response.content_type | |
else {} | |
) | |
if "detail" in res: | |
return Exception(r.status_code, res) | |
raise Exception(response.status, res) | |
except Exception: | |
pass | |
else: | |
pass | |
except Exception as e: | |
print(f"Connection error: {e}") | |
async with aiohttp.ClientSession() as session: | |
for filter in sorted_filters: | |
urlIdx = filter.get("urlIdx") | |
if urlIdx is None: | |
continue | |
url = request.app.state.config.OPENAI_API_BASE_URLS[urlIdx] | |
key = request.app.state.config.OPENAI_API_KEYS[urlIdx] | |
if not key: | |
continue | |
headers = {"Authorization": f"Bearer {key}"} | |
request_data = { | |
"user": user, | |
"body": payload, | |
} | |
try: | |
async with session.post( | |
f"{url}/{filter['id']}/filter/outlet", | |
headers=headers, | |
json=request_data, | |
) as response: | |
response.raise_for_status() | |
payload = await response.json() | |
except aiohttp.ClientResponseError: | |
try: | |
res = ( | |
await response.json() | |
if "application/json" in response.content_type | |
else {} | |
) | |
if "detail" in res: | |
raise Exception(response.status, res) | |
except Exception: | |
pass | |
except Exception as e: | |
print(f"Connection error: {e}") |
🧰 Tools
🪛 Ruff (0.8.2)
144-144: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
self.Storage.delete_file(gcs_file_path) | ||
# check that deleting file from gcs will delete the local file as well | ||
assert not (upload_dir / self.filename).exists() | ||
assert self.Storage.bucket.get_blob(self.filename) == None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix None comparisons to follow Python idioms.
Use 'is None' instead of '== None' for proper Python idioms.
-assert self.Storage.bucket.get_blob(self.filename) == None
+assert self.Storage.bucket.get_blob(self.filename) is None
-assert self.Storage.bucket.get_blob(self.filename) == None
-assert self.Storage.bucket.get_blob(self.filename_extra) == None
+assert self.Storage.bucket.get_blob(self.filename) is None
+assert self.Storage.bucket.get_blob(self.filename_extra) is None
Also applies to: 279-280
🧰 Tools
🪛 Ruff (0.8.2)
255-255: Comparison to None
should be cond is None
Replace with cond is None
(E711)
@@ -166,13 +172,14 @@ | |||
<div class=" self-center text-xs font-medium">{$i18n.t('Speech-to-Text Engine')}</div> | |||
<div class="flex items-center relative"> | |||
<select | |||
class="dark:bg-gray-900 cursor-pointer w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right" | |||
class="dark:bg-gray-900 cursor-pointer w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-right" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix invalid Tailwind CSS classes.
Replace all instances of 'outline-hidden' with 'outline-none' as it's the correct Tailwind CSS class.
Example fix:
-class="dark:bg-gray-900 cursor-pointer w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-right"
+class="dark:bg-gray-900 cursor-pointer w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-none text-right"
Apply similar changes to all other instances.
Also applies to: 191-191, 209-209, 234-234, 258-258, 375-375, 388-388, 399-399, 405-405, 422-422, 446-446, 487-487, 507-507, 528-528, 547-547, 569-569, 596-596, 612-612
async def clone_chat_by_id( | ||
form_data: CloneForm, id: str, user=Depends(get_verified_user) | ||
): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix FastAPI dependency injection pattern.
Move the Depends call into the function signature to follow FastAPI best practices.
-async def clone_chat_by_id(
- form_data: CloneForm, id: str, user=Depends(get_verified_user)
-):
+async def clone_chat_by_id(
+ form_data: CloneForm,
+ id: str,
+ user: User = Depends(get_verified_user)
+):
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
async def clone_chat_by_id( | |
form_data: CloneForm, id: str, user=Depends(get_verified_user) | |
): | |
async def clone_chat_by_id( | |
form_data: CloneForm, | |
id: str, | |
user: User = Depends(get_verified_user) | |
): |
🧰 Tools
🪛 Ruff (0.8.2)
453-453: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
backend/start.sh
Outdated
# Add conditional Playwright browser installation | ||
if [[ "${RAG_WEB_LOADER_ENGINE,,}" == "playwright" ]]; then | ||
if [[ -z "${PLAYWRIGHT_WS_URI}" ]]; then | ||
echo "Installing Playwright browsers..." | ||
playwright install chromium | ||
playwright install-deps chromium | ||
fi | ||
|
||
python -c "import nltk; nltk.download('punkt_tab')" | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conditional Playwright Browser Installation and NLTK Resource Download
The newly added conditional block (lines 6–15) for installing Playwright browsers based on the RAG_WEB_LOADER_ENGINE
variable is clear. However, please double-check that the NLTK resource name 'punkt_tab'
is intentional. Typically, NLTK downloads the 'punkt'
tokenizer; if 'punkt_tab'
is a custom resource, ensure that it exists. Additionally, consider adding error handling for the Playwright installation commands.
# If your instance owns a /etc/searxng/settings.yml file, then set the following | ||
# values there. | ||
|
||
secret_key: "68c0af85bed7d563749c41a2b34b8c1634142620640d02e3c5953f722a37e1c0" # Is overwritten by ${SEARXNG_SECRET} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical Security: Hardcoded Secret Key
The secret_key
on line 99 is hardcoded in the configuration. Storing sensitive keys in version-controlled files poses a security risk. It is strongly recommended to remove the static key from the file and instead retrieve it from an environment variable or a secure secrets manager, especially for production deployments.
🧰 Tools
🪛 Gitleaks (8.21.2)
99-99: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
✅ Actions performedReview triggered.
|
@coderabbitai summary |
✅ Actions performedSummary regeneration triggered. |
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
🔭 Outside diff range comments (1)
backend/open_webui/routers/files.py (1)
314-357
: 🛠️ Refactor suggestionDuplicate function name.
There are two functions named
get_file_content_by_id
in this file (lines 231 and 314), which could cause confusion during maintenance.Rename one of the functions to better reflect its specific purpose, such as:
-@router.get("/{id}/content/{file_name}") -async def get_file_content_by_id(id: str, user=Depends(get_verified_user)): +@router.get("/{id}/content/{file_name}") +async def get_file_content_with_name(id: str, user=Depends(get_verified_user)):🧰 Tools
🪛 Ruff (0.8.2)
314-314: Redefinition of unused
get_file_content_by_id
from line 231(F811)
314-314: Do not perform function call
Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
342-342: Local variable
file_name
is assigned to but never usedRemove assignment to unused variable
file_name
(F841)
♻️ Duplicate comments (2)
backend/open_webui/retrieval/vector/dbs/chroma.py (1)
59-60
:⚠️ Potential issueLikely incorrect comparison when
list_collections()
returns collection objects.This pattern has been previously flagged. If
list_collections()
returns objects rather than simple strings, verifying membership withcollection_name in collection_names
might be incorrect. Ensure that you're comparing the correct attribute (e.g.,collection.name
) instead of the collection object.-collection_names = self.client.list_collections() -return collection_name in collection_names +collections = self.client.list_collections() +return collection_name in [c.name for c in collections]backend/open_webui/routers/files.py (1)
39-40
:⚠️ Potential issueFix function parameter defaults.
Using mutable default arguments and function calls in parameter defaults can lead to unexpected behavior.
-def upload_file( - request: Request, - file: UploadFile = File(...), - user=Depends(get_verified_user), - file_metadata: dict = {}, -): +def upload_file( + request: Request, + file: UploadFile = File(...), + user=Depends(get_verified_user), + file_metadata: dict | None = None, +): + if file_metadata is None: + file_metadata = {}🧰 Tools
🪛 Ruff (0.8.2)
39-39: Do not perform function call
Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
40-40: Do not use mutable data structures for argument defaults
Replace with
None
; initialize within function(B006)
🧹 Nitpick comments (65)
backend/open_webui/retrieval/vector/dbs/qdrant.py (1)
14-15
: Avoid setting log level in library code
Configuring the logger’s level here might override global logging configurations. Typically, libraries should defer log-level settings to the application-level entry point.log = logging.getLogger(__name__) -log.setLevel(SRC_LOG_LEVELS["RAG"]) +# Consider removing this line or checking for a default fallbackbackend/open_webui/utils/misc.py (6)
8-8
: Remove unused import
Static analysis indicates thattyping.Callable
is unused. Remove it to keep imports clean.-from typing import Callable, Optional +from typing import Optional🧰 Tools
🪛 Ruff (0.8.2)
8-8:
typing.Callable
imported but unusedRemove unused import:
typing.Callable
(F401)
14-15
: Avoid library-level log configuration
Setting a specific log level in a utility file may inadvertently override user-configured log levels. Consider removing or making it optional.
18-25
: Document in-place modification
Thedeep_update
function is helpful, but clarify in a docstring that it mutatesd
in-place to avoid surprises.def deep_update(d, u): + """ + Recursively update dictionary d with dictionary u and return d. + Note: This function mutates d in-place. + """ for k, v in u.items(): ...
151-168
: Docstring param mismatch
The docstring mentions:param msg:
but the function signature usescontent
. Update the docstring for consistency.def add_or_update_user_message(content: str, messages: list[dict]): """ - :param msg: The message to be added or appended. + :param content: The message text to be added or appended. ...
170-187
: Docstring param mismatch (assistant message)
Similarly, the docstring references:param msg:
; rename it to align withcontent
to avoid confusion.
260-265
: File-based hash computation
Introducing a chunk size for computing the file hash is more efficient for large files. Consider adding a docstring to clarify usage and default chunk size if any.pyproject.toml (1)
9-125
:❓ Verification inconclusive
Review dependency expansions
A large set of new or upgraded dependencies can introduce potential bloat or conflicts. Consider grouping some libraries under optional extras to minimize the default install overhead. Also, note that libraries likeplaywright
may require additional system dependencies and could impact CI.
🏁 Script executed:
#!/bin/bash # Verify potential dependency conflicts using pip’s resolver in a temporary environment # 1. Create a new virtualenv python -m venv /tmp/test_env source /tmp/test_env/bin/activate # 2. Install dependencies from pyproject.toml # Hatch is specified but let's try using pip for conflict detection pip install --upgrade pip setuptools wheel pip install tomli # Convert pyproject.toml to requirements via a script or a plugin if needed # Or parse and install them line-by-line # For demonstration, just do: pip install fastapi==0.115.7 pydantic==2.10.6 aiohttp==3.11.11 ... # 3. Check for conflicts pip checkLength of output: 2446
Attention: Dependency Grouping Recommendation
The dependency list installs without reported conflicts (aside from the demonstration placeholder “…”), but the expansion remains a potential source of bloat and unexpected CI impacts—especially for packages like
playwright
that may require extra system dependencies. Please consider these points:
- Optional Extras: Group related packages (e.g., web frameworks, database drivers, ML tools) under optional extras to minimize the default install overhead.
- CI Considerations: Be aware that libraries such as
playwright
might impact CI builds due to additional system dependencies.- Verification: Although the temporary pip conflict check (ignoring the placeholder “...”) reported no broken requirements, manually verify that all dependency groupings align with usage patterns and deployment needs.
Please review these recommendations and confirm that dependencies are organized optimally.
backend/open_webui/retrieval/vector/dbs/pgvector.py (5)
33-34
: Logger instantiation and configuration.Using
logging.getLogger(__name__)
and setting the log level from config fosters consistent logging. Consider verifying thatSRC_LOG_LEVELS["RAG"]
is always valid or handle missing keys.
91-91
: Initialization info log.Logging successful initialization is a helpful indicator. Adding more context (e.g., DB URL or partial config detail) might further assist in debugging.
94-94
: Exception logging during initialization.
log.exception
automatically includes the traceback, so thef"{e}"
in the message is somewhat redundant. You might omit it or repurpose it for additional context.- log.exception(f"Error during initialization: {e}") + log.exception("Error during initialization")
289-289
: Exception handling insearch
.Consider logging additional query context (e.g., collection_name, vector sizes) to expedite debugging if an error surfaces.
370-370
: Rollback on delete exception.Good practice. As with other exception blocks, consider adding more specific context to the log if needed.
backend/open_webui/utils/filter.py (2)
35-66
: Filter function loading logic.Loading function modules into a cached state object (
request.app.state.FUNCTIONS
) is a neat approach. Continue verifying advanced concurrency scenarios if multiple requests load the same filter simultaneously.
85-86
: Combine nested if statements.As flagged by static analysis, lines 85-86 can be refactored into a single check for readability:
- if "__user__" in sig.parameters: - if hasattr(function_module, "UserValves"): + if "__user__" in sig.parameters and hasattr(function_module, "UserValves"):🧰 Tools
🪛 Ruff (0.8.2)
85-86: Use a single
if
statement instead of nestedif
statements(SIM102)
backend/open_webui/utils/chat.py (3)
13-14
: Unused imports detected.There are several imports that aren't being used in the code.
-from fastapi import Request, status +from fastapi import Request -from starlette.responses import Response, StreamingResponse, JSONResponse +from starlette.responses import StreamingResponse🧰 Tools
🪛 Ruff (0.8.2)
13-13:
fastapi.status
imported but unusedRemove unused import:
fastapi.status
(F401)
14-14:
starlette.responses.Response
imported but unusedRemove unused import
(F401)
14-14:
starlette.responses.JSONResponse
imported but unusedRemove unused import
(F401)
17-17
: Unused import: UserModel.The UserModel import is not being used in this file.
-from open_webui.models.users import UserModel
🧰 Tools
🪛 Ruff (0.8.2)
17-17:
open_webui.models.users.UserModel
imported but unusedRemove unused import:
open_webui.models.users.UserModel
(F401)
128-131
: Use contextlib.suppress for cleaner exception handling.The try-except-pass pattern could be replaced with a more Pythonic approach.
- async def background(): - try: - del sio.handlers["/"][channel] - except Exception as e: - pass + async def background(): + from contextlib import suppress + with suppress(Exception): + del sio.handlers["/"][channel]🧰 Tools
🪛 Ruff (0.8.2)
128-131: Use
contextlib.suppress(Exception)
instead oftry
-except
-pass
Replace with
contextlib.suppress(Exception)
(SIM105)
130-130: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
CHANGELOG.md (1)
21-21
: Bare URLs in markdown.There are instances of bare URLs that should be properly formatted with markdown link syntax for better readability and accessibility.
For example, change:
- **🔎 "Stream" Hook for Real-Time Filtering**: The new "stream" hook allows dynamic real-time message filtering. Learn more in our documentation (https://docs.openwebui.com/features/plugin/functions/filter).to:
- **🔎 "Stream" Hook for Real-Time Filtering**: The new "stream" hook allows dynamic real-time message filtering. Learn more in our [documentation](https://docs.openwebui.com/features/plugin/functions/filter).Also applies to: 218-218
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
21-21: Bare URL used
null(MD034, no-bare-urls)
backend/open_webui/models/chats.py (1)
1-2
: Unused imports.There are imports that aren't being used in the code.
import logging -import json import time import uuid from typing import Optional from open_webui.internal.db import Base, get_db -from open_webui.models.tags import TagModel, Tag, Tags +from open_webui.models.tags import TagModel, Tags from open_webui.env import SRC_LOG_LEVELSAlso applies to: 8-9
🧰 Tools
🪛 Ruff (0.8.2)
2-2:
json
imported but unusedRemove unused import:
json
(F401)
backend/open_webui/routers/auths.py (3)
169-169
: Remove unused variable
LDAP_SERVER_LABEL
is never referenced after assignment. Consider removing it to avoid confusion.- LDAP_SERVER_LABEL = request.app.state.config.LDAP_SERVER_LABEL
🧰 Tools
🪛 Ruff (0.8.2)
169-169: Local variable
LDAP_SERVER_LABEL
is assigned to but never usedRemove assignment to unused variable
LDAP_SERVER_LABEL
(F841)
487-488
: Posting sign-up webhook
Consider handling potential network failures aroundpost_webhook
, e.g., retries or logging.
764-764
: Setting mail attribute from user input
Consider validating this new mail attribute name if your system supports only certain known attributes.backend/open_webui/routers/tasks.py (5)
23-26
: Unused filter imports
get_sorted_filter_ids
andprocess_filter_functions
appear unused. Kindly remove them to keep imports clean.-from open_webui.utils.filter import ( - get_sorted_filter_ids, - process_filter_functions, -) +# Remove or comment out if not used🧰 Tools
🪛 Ruff (0.8.2)
24-24:
open_webui.utils.filter.get_sorted_filter_ids
imported but unusedRemove unused import
(F401)
25-25:
open_webui.utils.filter.process_filter_functions
imported but unusedRemove unused import
(F401)
192-198
: Stripping
Your regex approach effectively removes reasoning details. Keep an eye on complexity for large inputs.
221-225
: Optional “chat_id” usage
Static analysis recommends dropping the default “None”.- "chat_id": form_data.get("chat_id", None), + "chat_id": form_data.get("chat_id"),🧰 Tools
🪛 Ruff (0.8.2)
224-224: Use
form_data.get("chat_id")
instead ofform_data.get("chat_id", None)
Replace
form_data.get("chat_id", None)
withform_data.get("chat_id")
(SIM910)
255-260
: Repeated direct-model check
Several endpoints checkgetattr(request.state, "direct", False)
andrequest.state.model
. Consider abstracting to a helper for maintainability.
319-389
: New image prompt generation endpoint
Implementation parallels existing completions. You may reduce code duplication by creating a shared workflow function.🧰 Tools
🪛 Ruff (0.8.2)
321-321: Do not perform function call
Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
371-371: Use
form_data.get("chat_id")
instead ofform_data.get("chat_id", None)
Replace
form_data.get("chat_id", None)
withform_data.get("chat_id")
(SIM910)
383-383: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
backend/open_webui/routers/pipelines.py (1)
102-102
: Raise exceptions with clearer context
When re-raising, consider usingraise ... from e
for clarity.🧰 Tools
🪛 Ruff (0.8.2)
102-102: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
backend/open_webui/utils/audit.py (1)
210-215
: Simplify the return
Static analysis suggests returning this condition directly for fewer branches.- if pattern.match(request.url.path): - return True - return False + return bool(pattern.match(request.url.path))🧰 Tools
🪛 Ruff (0.8.2)
212-215: Return the condition
bool(pattern.match(request.url.path))
directlyReplace with
return bool(pattern.match(request.url.path))
(SIM103)
backend/open_webui/routers/audio.py (3)
269-272
: Consider separate connect/read timeouts.
Specifyingconnect
andread
timeouts separately can provide finer control in case of partial slowdowns.
540-544
: Graceful fallback on undetectable MIME type.
Falling back to"audio/wav"
is sensible ifmimetypes
fails. Consider logging a warning to inform users about an unknown file extension.
575-579
: Include original exception context when re-raising.
Raising an exception withraise ... from e
helps preserve the original stack trace for debugging.except (KeyError, IndexError) as e: log.error(f"Malformed response from Deepgram: {str(e)}") - raise Exception("Failed to parse Deepgram response - unexpected response format") + raise Exception("Failed to parse Deepgram response - unexpected response format") from e🧰 Tools
🪛 Ruff (0.8.2)
577-579: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
backend/open_webui/env.py (1)
420-442
: Audit logging settings look good.
Consider validating the rotation size format (e.g., "10MB") in code if user input is untrusted.backend/open_webui/utils/auth.py (2)
24-24
: Remove or comment out unused imports.
Response
is not used, so you can remove it to streamline imports.-from fastapi import BackgroundTasks, Depends, HTTPException, Request, Response, status +from fastapi import BackgroundTasks, Depends, HTTPException, Request, status🧰 Tools
🪛 Ruff (0.8.2)
24-24:
fastapi.Response
imported but unusedRemove unused import:
fastapi.Response
(F401)
87-89
: Use direct attribute assignment instead ofsetattr
.
This is clearer and aligns with best practices.- setattr(app.state, "USER_COUNT", v) -elif k == "webui_name": - setattr(app.state, "WEBUI_NAME", v) + app.state.USER_COUNT = v +elif k == "webui_name": + app.state.WEBUI_NAME = v🧰 Tools
🪛 Ruff (0.8.2)
87-87: Do not call
setattr
with a constant attribute value. It is not any safer than normal property access.Replace
setattr
with assignment(B010)
89-89: Do not call
setattr
with a constant attribute value. It is not any safer than normal property access.Replace
setattr
with assignment(B010)
backend/open_webui/utils/oauth.py (2)
316-316
: Remove unused variable assignment.The
user_count
variable is assigned but never used in this code block.- user_count = Users.get_num_users()
🧰 Tools
🪛 Ruff (0.8.2)
316-316: Local variable
user_count
is assigned to but never usedRemove assignment to unused variable
user_count
(F841)
334-354
: Consider combining nested with statements.Similar to the earlier suggestion, the nested
with
statements here could be combined for better readability.- async with aiohttp.ClientSession() as session: - async with session.get(picture_url, **get_kwargs) as resp: + async with aiohttp.ClientSession() as session, session.get(picture_url, **get_kwargs) as resp:🧰 Tools
🪛 Ruff (0.8.2)
338-339: Use a single
with
statement with multiple contexts instead of nestedwith
statements(SIM117)
backend/open_webui/routers/images.py (1)
433-450
: Refactored URL image loading with improved error handling.The function now supports custom headers and returns image data and MIME type instead of saving files directly.
Consider simplifying the conditional logic using a ternary operator:
- if headers: - r = requests.get(url, headers=headers) - else: - r = requests.get(url) + r = requests.get(url, headers=headers) if headers else requests.get(url)🧰 Tools
🪛 Ruff (0.8.2)
435-438: Use ternary operator
r = requests.get(url, headers=headers) if headers else requests.get(url)
instead ofif
-else
-blockReplace
if
-else
-block withr = requests.get(url, headers=headers) if headers else requests.get(url)
(SIM108)
backend/open_webui/utils/middleware.py (3)
41-45
: Added imports for pipelines and improved modularity.The new imports support the pipeline filtering mechanism, enhancing the modularity of the code.
However, the static analysis indicates that
process_pipeline_outlet_filter
is imported but not used.- from open_webui.routers.pipelines import ( - process_pipeline_inlet_filter, - process_pipeline_outlet_filter, - ) + from open_webui.routers.pipelines import process_pipeline_inlet_filter🧰 Tools
🪛 Ruff (0.8.2)
44-44:
open_webui.routers.pipelines.process_pipeline_outlet_filter
imported but unusedRemove unused import:
open_webui.routers.pipelines.process_pipeline_outlet_filter
(F401)
1233-1378
: Complex content tag handler implementation.The
tag_content_handler
function is quite complex and handles multiple tag types with a lot of regex operations. Consider adding more detailed comments explaining the function's behavior or splitting it into smaller, more focused functions.
1763-1947
: Complex code interpreter execution logic.The code interpreter execution logic is comprehensive but very complex. Consider breaking this into smaller functions with clear responsibilities to improve maintainability.
backend/open_webui/routers/files.py (1)
369-370
: Add Chroma cleanup implementation.The comment indicates a needed feature but lacks implementation. Consider implementing the Chroma cleanup or creating a follow-up task.
Would you like me to help generate a basic implementation for cleaning up Chroma collections related to deleted files?
backend/open_webui/utils/payload.py (1)
14-14
: Avoid using default 'None' inparams.get("system", None)
This is a minor style improvement suggested by static analysis. You can safely remove the redundant
None
default value:- system = params.get("system", None) + system = params.get("system")🧰 Tools
🪛 Ruff (0.8.2)
14-14: Use
params.get("system")
instead ofparams.get("system", None)
Replace
params.get("system", None)
withparams.get("system")
(SIM910)
backend/open_webui/routers/utils.py (1)
27-27
: AvoidDepends(...)
calls in function parameter defaultsStatic analysis (Ruff B008) warns against calling
Depends
in function defaults. This is more a stylistic matter than a functional bug, but you might consider moving these dependency calls inside the function body to align with recommended FastAPI patterns.Also applies to: 36-36, 48-48, 81-81, 93-93
🧰 Tools
🪛 Ruff (0.8.2)
27-27: Do not perform function call
Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
backend/open_webui/retrieval/utils.py (4)
316-316
: Avoid assigning alambda
to a variable.Assigning lambdas to variables can reduce code readability and is flagged by linters. Prefer defining a named function or returning the lambda directly if functional style is desired.
-def func = lambda query, user=None: generate_embeddings(...) +def generate_single_embedding(query, user=None): + return generate_embeddings(...) ... -return lambda query, user=None: generate_multiple(query, user, func) +def generate_multiple_embeds(query, user=None): + return generate_multiple(query, user, generate_single_embedding)Also applies to: 337-337
🧰 Tools
🪛 Ruff (0.8.2)
316-323: Do not assign a
lambda
expression, use adef
Rewrite
func
as adef
(E731)
839-841
: Combine multipleisinstance
checks.Merging these checks into a single
isinstance
call improves readability and aligns with recommended best practices.-if ( - isinstance(value, datetime) - or isinstance(value, list) - or isinstance(value, dict) -): +if isinstance(value, (datetime, list, dict)):
925-930
: Use a context manager or specify exception types.Catching all exceptions with a bare
except:
and ignoring them might hide real problems. Usecontextlib.suppress
for known exceptions or handle specific exception types.-try: - VECTOR_DB_CLIENT.delete_collection(collection_name=f"file-{file.id}") -except: - pass +import contextlib +with contextlib.suppress(SomeExpectedException): + VECTOR_DB_CLIENT.delete_collection(collection_name=f"file-{file.id}")
1042-1042
: Refactor the conditional expression.This can be simplified to a boolean cast for better readability and to comply with lint checks.
-add=(True if form_data.collection_name else False), +add=bool(form_data.collection_name),backend/open_webui/routers/retrieval.py (1)
474-478
: Consider concurrency and resource usage in large-scale cases.The code now uses
run_in_threadpool
for asynchronous document loading and indexing. For high-volume queries, ensure that concurrency limits and potential memory constraints are properly handled to avoid overwhelming the system.backend/open_webui/routers/ollama.py (2)
1590-1590
: Remove extraneousf
prefixes.Both log statements use f-strings without placeholders. They can be replaced with standard string literals.
- log.info(f"Uploaded to /api/blobs") + log.info("Uploaded to /api/blobs") - log.info(f"API SUCCESS!") + log.info("API SUCCESS!")Also applies to: 1614-1614
🧰 Tools
🪛 Ruff (0.8.2)
1590-1590: f-string without any placeholders
Remove extraneous
f
prefix(F541)
1539-1635
: Improve handling of partial or interrupted uploads.While chunked uploads are effective for large files, consider adding a mechanism to handle partial uploads or network interruptions gracefully (e.g., resumable uploads or robust status checks) to minimize data corruption or repeated transfers.
🧰 Tools
🪛 Ruff (0.8.2)
1543-1543: Do not perform function call
File
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
1545-1545: Do not perform function call
Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
1590-1590: f-string without any placeholders
Remove extraneous
f
prefix(F541)
1614-1614: f-string without any placeholders
Remove extraneous
f
prefix(F541)
backend/open_webui/main.py (5)
108-121
: Introduce code execution and interpreter config.These environment variables (
CODE_EXECUTION_ENGINE
,CODE_EXECUTION_JUPYTER_URL
, etc.) bring powerful features. Verify that untrusted code cannot be executed by default. Consider sandboxing, timeouts, or containerization for security.
382-387
: ASCII banner display.This welcome banner is purely cosmetic and does not affect functionality. Ensure it does not spam logs in production.
661-669
: Configure code execution engine.Storing code execution parameters (engine, URL, auth details) directly in
app.state.config
offers clarity but carry out robust validation and strict timeouts (line 668) to prevent resource abuse.
697-698
: Gemini API parameters.Assigning
IMAGES_GEMINI_API_BASE_URL
andIMAGES_GEMINI_API_KEY
is helpful for alternative image generation sources. Confirm that secrets (API keys) aren’t leaked in logs.
901-913
: Audit logging setup.Configuring the
AuditLoggingMiddleware
withaudit_level
,excluded_paths
, andmax_body_size
is a strong addition. Mind that the logs don’t accidentally capture sensitive user data.backend/open_webui/config.py (5)
5-5
: Remove unused importbase64
.Static analysis indicates
base64
is unused. Consider removing it to keep the codebase lean.- import base64
🧰 Tools
🪛 Ruff (0.8.2)
5-5:
base64
imported but unusedRemove unused import:
base64
(F401)
366-389
: Add GitHub OAuth config parameters.Defining
GITHUB_CLIENT_ID
,GITHUB_CLIENT_SECRET
, etc. aligns with new OAuth providers. Verify they’re stored securely; rotation policies or secrets management might be necessary.
661-667
: New LICENSE_KEY persistent config.The
PersistentConfig
approach ensures the license is saved in the database. Confirm the UI or API properly notifies users if the key is invalid, and avoid storing it without encryption if it’s sensitive.
1142-1158
: Default title generation prompt template.This instructs models to produce a short title with optional emoji. Implementation is conceptually clear. Confirm the JSON structure is enforced in your prompt parsing logic.
1382-1413
: Code execution config (interpreter).Similar to lines 661–669, this chunk sets up environment for code interpreter. The logic largely repeats for the specialized code interpreter fields. Ensure duplication is intentional and well documented.
backend/open_webui/storage/provider.py (3)
102-129
: S3StorageProvider upload and get_file.Uploading starts by storing locally, then uploading that file to S3.
- Consider using memory-only streams if large disk writes are unnecessary.
- Within
except ClientError
blocks (lines 131, 141, 149, 168), follow best practices to chain exceptions for improved traceback:- except ClientError as e: - raise RuntimeError(f"Error uploading file to S3: {e}") + except ClientError as e: + raise RuntimeError(f"Error uploading file to S3: {e}") from e
143-153
: S3 delete logic.Deletes from S3, then calls local removal. This order is sensible. Again, consider explicit exception chaining in the
except
blocks for clarity.🧰 Tools
🪛 Ruff (0.8.2)
149-149: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
154-172
: Delete all files from S3.Lists objects, removes those matching
key_prefix
. Then removes local. Good approach—just be wary of bucket with large object counts. Consider pagination or concurrency as optimization if needed.🧰 Tools
🪛 Ruff (0.8.2)
168-168: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.json
is excluded by!**/package-lock.json
📒 Files selected for processing (50)
CHANGELOG.md
(1 hunks)backend/open_webui/config.py
(31 hunks)backend/open_webui/env.py
(6 hunks)backend/open_webui/functions.py
(3 hunks)backend/open_webui/main.py
(38 hunks)backend/open_webui/models/chats.py
(8 hunks)backend/open_webui/models/feedbacks.py
(1 hunks)backend/open_webui/models/files.py
(1 hunks)backend/open_webui/models/folders.py
(1 hunks)backend/open_webui/models/functions.py
(4 hunks)backend/open_webui/models/models.py
(2 hunks)backend/open_webui/models/tags.py
(1 hunks)backend/open_webui/models/tools.py
(4 hunks)backend/open_webui/retrieval/loaders/main.py
(3 hunks)backend/open_webui/retrieval/models/colbert.py
(1 hunks)backend/open_webui/retrieval/utils.py
(11 hunks)backend/open_webui/retrieval/vector/dbs/chroma.py
(4 hunks)backend/open_webui/retrieval/vector/dbs/milvus.py
(3 hunks)backend/open_webui/retrieval/vector/dbs/pgvector.py
(12 hunks)backend/open_webui/retrieval/vector/dbs/qdrant.py
(3 hunks)backend/open_webui/routers/audio.py
(15 hunks)backend/open_webui/routers/auths.py
(21 hunks)backend/open_webui/routers/files.py
(10 hunks)backend/open_webui/routers/functions.py
(6 hunks)backend/open_webui/routers/groups.py
(7 hunks)backend/open_webui/routers/images.py
(17 hunks)backend/open_webui/routers/knowledge.py
(11 hunks)backend/open_webui/routers/ollama.py
(50 hunks)backend/open_webui/routers/openai.py
(18 hunks)backend/open_webui/routers/pipelines.py
(11 hunks)backend/open_webui/routers/retrieval.py
(33 hunks)backend/open_webui/routers/tasks.py
(20 hunks)backend/open_webui/routers/tools.py
(10 hunks)backend/open_webui/routers/utils.py
(3 hunks)backend/open_webui/storage/provider.py
(1 hunks)backend/open_webui/utils/audit.py
(1 hunks)backend/open_webui/utils/auth.py
(4 hunks)backend/open_webui/utils/chat.py
(5 hunks)backend/open_webui/utils/filter.py
(1 hunks)backend/open_webui/utils/logger.py
(1 hunks)backend/open_webui/utils/middleware.py
(28 hunks)backend/open_webui/utils/misc.py
(7 hunks)backend/open_webui/utils/models.py
(3 hunks)backend/open_webui/utils/oauth.py
(13 hunks)backend/open_webui/utils/payload.py
(4 hunks)backend/open_webui/utils/plugin.py
(2 hunks)backend/open_webui/utils/response.py
(2 hunks)backend/requirements.txt
(7 hunks)package.json
(5 hunks)pyproject.toml
(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- backend/open_webui/utils/plugin.py
- backend/open_webui/utils/models.py
- backend/open_webui/functions.py
- backend/open_webui/routers/tools.py
- backend/requirements.txt
- package.json
🧰 Additional context used
🪛 Ruff (0.8.2)
backend/open_webui/routers/knowledge.py
20-20: open_webui.storage.provider.Storage
imported but unused
Remove unused import: open_webui.storage.provider.Storage
(F401)
backend/open_webui/routers/auths.py
169-169: Local variable LDAP_SERVER_LABEL
is assigned to but never used
Remove assignment to unused variable LDAP_SERVER_LABEL
(F841)
backend/open_webui/routers/tasks.py
24-24: open_webui.utils.filter.get_sorted_filter_ids
imported but unused
Remove unused import
(F401)
25-25: open_webui.utils.filter.process_filter_functions
imported but unused
Remove unused import
(F401)
224-224: Use form_data.get("chat_id")
instead of form_data.get("chat_id", None)
Replace form_data.get("chat_id", None)
with form_data.get("chat_id")
(SIM910)
299-299: Use form_data.get("chat_id")
instead of form_data.get("chat_id", None)
Replace form_data.get("chat_id", None)
with form_data.get("chat_id")
(SIM910)
321-321: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
371-371: Use form_data.get("chat_id")
instead of form_data.get("chat_id", None)
Replace form_data.get("chat_id", None)
with form_data.get("chat_id")
(SIM910)
383-383: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
454-454: Use form_data.get("chat_id")
instead of form_data.get("chat_id", None)
Replace form_data.get("chat_id", None)
with form_data.get("chat_id")
(SIM910)
541-541: Use form_data.get("chat_id")
instead of form_data.get("chat_id", None)
Replace form_data.get("chat_id", None)
with form_data.get("chat_id")
(SIM910)
613-613: Use form_data.get("chat_id")
instead of form_data.get("chat_id", None)
Replace form_data.get("chat_id", None)
with form_data.get("chat_id")
(SIM910)
681-681: Use form_data.get("chat_id")
instead of form_data.get("chat_id", None)
Replace form_data.get("chat_id", None)
with form_data.get("chat_id")
(SIM910)
backend/open_webui/utils/middleware.py
8-8: aiocache.cached
imported but unused
Remove unused import: aiocache.cached
(F401)
9-9: typing.Any
imported but unused
Remove unused import: typing.Any
(F401)
10-10: random
imported but unused
Remove unused import: random
(F401)
13-13: inspect
imported but unused
Remove unused import: inspect
(F401)
44-44: open_webui.routers.pipelines.process_pipeline_outlet_filter
imported but unused
Remove unused import: open_webui.routers.pipelines.process_pipeline_outlet_filter
(F401)
64-64: open_webui.utils.misc.deep_update
imported but unused
Remove unused import: open_webui.utils.misc.deep_update
(F401)
73-73: open_webui.utils.plugin.load_function_module_by_id
imported but unused
Remove unused import: open_webui.utils.plugin.load_function_module_by_id
(F401)
437-437: Local variable negative_prompt
is assigned to but never used
Remove assignment to unused variable negative_prompt
(F841)
462-462: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
500-500: f-string without any placeholders
Remove extraneous f
prefix
(F541)
548-548: Do not use bare except
(E722)
699-699: Local variable variables
is assigned to but never used
Remove assignment to unused variable variables
(F841)
718-718: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
899-899: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
1197-1197: Loop control variable idx
not used within loop body
Rename unused idx
to _idx
(B007)
1392-1392: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
1627-1629: Use a single if
statement instead of nested if
statements
(SIM102)
backend/open_webui/utils/audit.py
212-215: Return the condition bool(pattern.match(request.url.path))
directly
Replace with return bool(pattern.match(request.url.path))
(SIM103)
backend/open_webui/utils/auth.py
12-12: typing.List
imported but unused
Remove unused import
(F401)
12-12: typing.Dict
imported but unused
Remove unused import
(F401)
24-24: fastapi.Response
imported but unused
Remove unused import: fastapi.Response
(F401)
87-87: Do not call setattr
with a constant attribute value. It is not any safer than normal property access.
Replace setattr
with assignment
(B010)
89-89: Do not call setattr
with a constant attribute value. It is not any safer than normal property access.
Replace setattr
with assignment
(B010)
backend/open_webui/routers/pipelines.py
95-95: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
102-102: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
144-144: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
backend/open_webui/routers/images.py
435-438: Use ternary operator r = requests.get(url, headers=headers) if headers else requests.get(url)
instead of if
-else
-block
Replace if
-else
-block with r = requests.get(url, headers=headers) if headers else requests.get(url)
(SIM108)
backend/open_webui/utils/chat.py
13-13: fastapi.status
imported but unused
Remove unused import: fastapi.status
(F401)
14-14: starlette.responses.Response
imported but unused
Remove unused import
(F401)
14-14: starlette.responses.JSONResponse
imported but unused
Remove unused import
(F401)
17-17: open_webui.models.users.UserModel
imported but unused
Remove unused import: open_webui.models.users.UserModel
(F401)
128-131: Use contextlib.suppress(Exception)
instead of try
-except
-pass
Replace with contextlib.suppress(Exception)
(SIM105)
130-130: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
226-226: Avoid equality comparisons to True
; use if form_data.get("stream"):
for truth checks
Replace with form_data.get("stream")
(E712)
backend/open_webui/storage/provider.py
131-131: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
141-141: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
149-149: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
168-168: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
204-204: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
216-216: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
225-225: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
239-239: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
274-274: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
286-286: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
295-295: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
307-307: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
backend/open_webui/routers/ollama.py
1590-1590: f-string without any placeholders
Remove extraneous f
prefix
(F541)
1614-1614: f-string without any placeholders
Remove extraneous f
prefix
(F541)
backend/open_webui/retrieval/utils.py
18-18: open_webui.utils.misc.get_last_user_message
imported but unused
Remove unused import
(F401)
18-18: open_webui.utils.misc.calculate_sha256_string
imported but unused
Remove unused import
(F401)
316-323: Do not assign a lambda
expression, use a def
Rewrite func
as a def
(E731)
459-459: Local variable e
is assigned to but never used
Remove assignment to unused variable e
(F841)
backend/open_webui/utils/misc.py
8-8: typing.Callable
imported but unused
Remove unused import: typing.Callable
(F401)
backend/open_webui/routers/retrieval.py
839-841: Multiple isinstance
calls for value
, merge into a single call
Merge isinstance
calls for value
(SIM101)
925-930: Use contextlib.suppress(Exception)
instead of try
-except
-pass
(SIM105)
928-928: Do not use bare except
(E722)
1042-1042: Use bool(...)
instead of True if ... else False
Replace with `bool(...)
(SIM210)
backend/open_webui/main.py
162-162: open_webui.config.WHISPER_MODEL_AUTO_UPDATE
imported but unused
Remove unused import
(F401)
163-163: open_webui.config.WHISPER_MODEL_DIR
imported but unused
Remove unused import
(F401)
166-166: open_webui.config.DEFAULT_RAG_TEMPLATE
imported but unused
Remove unused import
(F401)
225-225: Redefinition of unused ONEDRIVE_CLIENT_ID
from line 101
Remove definition: ONEDRIVE_CLIENT_ID
(F811)
227-227: open_webui.config.ENABLE_RAG_LOCAL_WEB_FETCH
imported but unused
Remove unused import
(F401)
993-993: Use form_data.get("model")
instead of form_data.get("model", None)
Replace form_data.get("model", None)
with form_data.get("model")
(SIM910)
1021-1021: Use form_data.get("variables")
instead of form_data.get("variables", None)
Replace form_data.get("variables", None)
with form_data.get("variables")
(SIM910)
1045-1048: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
1247-1247: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
backend/open_webui/config.py
5-5: base64
imported but unused
Remove unused import: base64
(F401)
backend/open_webui/models/chats.py
2-2: json
imported but unused
Remove unused import: json
(F401)
8-8: open_webui.models.tags.Tag
imported but unused
Remove unused import: open_webui.models.tags.Tag
(F401)
backend/open_webui/retrieval/vector/dbs/chroma.py
110-110: Do not use bare except
(E722)
backend/open_webui/routers/audio.py
577-579: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
599-599: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
backend/open_webui/routers/files.py
38-38: Do not perform function call File
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
39-39: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
40-40: Do not use mutable data structures for argument defaults
Replace with None
; initialize within function
(B006)
backend/open_webui/routers/groups.py
46-46: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
backend/open_webui/routers/utils.py
27-27: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
36-36: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
43-43: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
48-48: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
81-81: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
93-93: Do not perform function call Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable
(B008)
backend/open_webui/utils/filter.py
85-86: Use a single if
statement instead of nested if
statements
(SIM102)
backend/open_webui/utils/oauth.py
257-260: Use a single with
statement with multiple contexts instead of nested with
statements
(SIM117)
284-284: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
316-316: Local variable user_count
is assigned to but never used
Remove assignment to unused variable user_count
(F841)
338-339: Use a single with
statement with multiple contexts instead of nested with
statements
(SIM117)
backend/open_webui/utils/payload.py
14-14: Use params.get("system")
instead of params.get("system", None)
Replace params.get("system", None)
with params.get("system")
(SIM910)
76-76: Local variable param
is assigned to but never used
(F841)
76-76: Use params.get(key)
instead of params.get(key, None)
Replace params.get(key, None)
with params.get(key)
(SIM910)
🪛 markdownlint-cli2 (0.17.2)
CHANGELOG.md
21-21: Bare URL used
null
(MD034, no-bare-urls)
218-218: Bare URL used
null
(MD034, no-bare-urls)
🔇 Additional comments (198)
backend/open_webui/retrieval/models/colbert.py (1)
8-11
: LGTM: Good logging configuration.Properly setting up logging with configurable log levels is a good practice. This helps with debugging and monitoring while allowing centralized control over verbosity.
backend/open_webui/retrieval/vector/dbs/qdrant.py (4)
2-2
: Use of logging library
Importing thelogging
module is a good practice that aligns with structured logging throughout the codebase.
10-10
: Ensure environment variable usage
ImportingSRC_LOG_LEVELS
is correct, but verify that the environment variable or configuration is properly set to avoid potential runtime errors.
57-57
: Replacing print with log
Usinglog.info
here is a great improvement over print statements for better log management.
128-128
: Structured error handling
Replacing print withlog.exception
greatly improves traceability of errors by including stack traces.backend/open_webui/utils/misc.py (7)
5-5
: Structured logging adoption
Good choice to switch to the logging library for consistent log management.
11-11
: Check usage ofcollections.abc
This import is valid since it’s used for mapping checks indeep_update
.
12-12
: Reliance on environment-based log levels
EnsureSRC_LOG_LEVELS["MAIN"]
is consistently defined for all modules to prevent KeyErrors or mismatched logging levels.
40-40
: ReturnNone
consistency
ReturningNone
if a message is not found matches typical Python conventions.
199-218
: Enhanced template parameters
Addingcontent
andtool_calls
foropenai_chat_chunk_message_template
provides flexibility. Verify all callers pass these arguments or handleNone
gracefully.
224-238
: Consistency with chunk message template
The modifications foropenai_chat_completion_message_template
mirror the chunk template changes. Ensure both are used consistently.
420-420
: Improved exception logging
Usinglog.exception
here captures stack trace details for debugging parameter parsing.backend/open_webui/models/files.py (1)
122-122
: Improved error loggingReplacing print statements with structured logging is a good practice. Using
log.exception()
instead of a simple print statement not only logs the error message but also captures the full traceback, which is crucial for debugging.backend/open_webui/models/feedbacks.py (1)
121-121
: Enhanced error reportingGood improvement replacing the print statement with proper logging. The
log.exception()
method provides more context and captures the full traceback compared to simple print statements.backend/open_webui/models/tags.py (1)
64-64
: Better error handling with structured loggingUsing
log.exception()
provides a more comprehensive error report than print statements by capturing the full exception traceback. This is part of a consistent improvement across the codebase.backend/open_webui/models/tools.py (4)
134-134
: Improved error logging with contextGood switch from print statement to structured logging with
log.exception()
, which captures the full traceback for better debugging.
178-178
: Enhanced error reporting with method contextThe error message now includes both the method context (getting tool valves) and the specific ID, which will make troubleshooting much easier.
207-209
: Better error reporting with detailed contextGood improvement in error reporting by providing both the tool ID and user ID in the error message. The multi-line formatting also improves readability of the complex string.
232-234
: Comprehensive error logging with operation detailsError message now clearly indicates which operation failed (updating user valves) and includes both IDs needed for troubleshooting, making debugging much more efficient.
backend/open_webui/models/folders.py (1)
85-85
: Use of structured logging is a good practice.Replacing a print statement with
log.exception
is an improvement as it provides better clarity and stack traces for debugging.backend/open_webui/retrieval/vector/dbs/chroma.py (1)
2-3
: Structured logger initialization looks good.Initializing a logger here and setting it to a configured log level is a solid approach for consistent, centralized logging.
Also applies to: 20-23
backend/open_webui/models/models.py (2)
169-169
: Switched to structured logging.Using
log.exception
improves error visibility over a plain print.
249-249
: Consistent exception logging.Replacing
log.exception
aligns with the project's enhanced error handling strategy.backend/open_webui/retrieval/loaders/main.py (4)
7-7
: New loader import recognized.Importing
AzureAIDocumentIntelligenceLoader
paves the way for enhanced document parsing from Azure’s services.
80-80
: Adding "json" to known source extensions is beneficial.Properly covering JSON ensures that the loader can handle or differentiate JSON files.
152-167
: Conditional check for Azure Document Intelligence Loader.The condition ensures that the necessary endpoint, key, and file types are provided. This is a good approach to controlling loader behavior.
168-172
: AzureAIDocumentIntelligenceLoader usage is correct.This instantiation passes essential credentials and file path to the loader. Remember to verify secure handling of the key.
backend/open_webui/retrieval/vector/dbs/milvus.py (3)
4-4
: Good addition of structured logging.Replacing print statements with proper logging is a great improvement for maintainability and observability.
Also applies to: 13-16
22-25
: Improved client initialization with conditional token handling.The conditional initialization based on MILVUS_TOKEN presence provides better flexibility and security.
175-175
: Enhanced error logging with better context.Replacing print statements with appropriate logging levels and adding detailed error context will help with debugging and monitoring.
Also applies to: 202-202, 205-207
backend/open_webui/routers/functions.py (4)
2-2
: Good addition of structured logging.Replacing print statements with proper logging is a great improvement for maintainability and observability.
Also applies to: 17-20
88-88
: Enhanced exception logging.Improved error handling with structured logging to capture function creation failures.
192-192
: Added debug logging for function updates.This helps with troubleshooting by logging the updated function data.
308-308
: Improved error context in exception logging.Adding function and ID information to the exception logs will make troubleshooting easier.
Also applies to: 397-397
backend/open_webui/models/functions.py (2)
108-108
: Enhanced error logging.Improved error reporting for function creation failures.
173-173
: Improved error context in exception logging.Adding function and user ID information to the exception logs will make troubleshooting easier.
Also applies to: 205-207, 230-232
backend/open_webui/routers/groups.py (3)
46-46
: Fixed function name to match its purpose.Renamed from
create_new_function
tocreate_new_group
, which correctly reflects the function's purpose.Note: The static analysis warning about using
Depends
in the argument default is a false positive, as this is the standard pattern in FastAPI.🧰 Tools
🪛 Ruff (0.8.2)
46-46: Do not perform function call
Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
91-93
: Added user validation before updating groups.Good addition of user validation to ensure only valid user IDs are added to groups.
57-57
: Enhanced error logging with better context.Replacing print statements with exception logging and adding context about the specific group ID will help with debugging.
Also applies to: 103-103, 127-127
backend/open_webui/retrieval/vector/dbs/pgvector.py (12)
2-2
: Switching to structured logging is beneficial.Importing the
logging
module is appropriate here. Ensure that print statements across the module are fully replaced with logging calls for consistency.
13-13
: Good use of SQLAlchemy'sTable
.By using
Table
directly, the reflection approach becomes more flexible. Just ensure you’ve tested table reflection with partial or missing schemas if that’s a possibility in your environment.
23-23
: CatchingNoSuchTableError
is sensible.This is effective for handling missing tables gracefully. Keep an eye out for any additional exception classes if multiple table checks are introduced later.
28-29
: Proper usage ofSRC_LOG_LEVELS
.Importing environment-based log levels ensures consistent logging configurations across modules. This is a good approach for centralized log-level management.
103-111
: Reflection logic fordocument_chunk
table.This approach to reflect the table is correct, and the
NoSuchTableError
handling is properly placed. Ensure that any future migrations or table renames are also accounted for.
112-130
: Detailed checks on thevector
column.The dimension consistency checks look robust. Using clear exception messages for mismatches helps devs understand the necessary migration process.
321-321
: Exception logging inquery
.Everything looks good. As with other methods, providing relevant contextual info (e.g., filter values) could be beneficial in logs.
345-345
: Exception logging inget
.Same pattern here—solid usage of
log.exception
.
367-367
: Informational logging for deletion.Logging the number of items deleted gives insight into DB operations. This is helpful for auditing.
377-379
: Ensuring file reprocessing withprocess_file
.Be mindful of concurrency. If the same file is processed concurrently, ensure race conditions or partial updates won’t corrupt metadata or DB state.
398-398
: Exception logging forhas_collection()
.Return of
False
in error scenarios is consistent, but be certain no call sites need to differentiate between errors and a missing collection.
403-403
: Cleanup log message on collection deletion.This info-level log is good for monitoring, especially if you have to trace usage or removal frequency of knowledge collections.
backend/open_webui/utils/filter.py (6)
1-2
: Imports for inspection and logging.Using
inspect
can be powerful for dynamically assembling handler arguments. Ensure performance remains acceptable when used repeatedly.
4-6
: Appropriate environment-based logging.
load_function_module_by_id
andSRC_LOG_LEVELS
references are consistent with your new logging approach. Good job centralizing configuration.
8-9
: Logger setup.The logger is created and leveled with
"MAIN"
. Confirm"MAIN"
is a defined key inSRC_LOG_LEVELS
to avoid runtime issues.
12-32
:get_sorted_filter_ids
: Priority-based sorting.The logic correctly extracts and sorts filter IDs by a configurable priority. Consider adding warnings or logs if some filters can’t be found or remain inactive.
67-106
: Parameter assembly and dynamic call.Combining user valves with the function signature is well structured. Watch out for large
form_data
objects to avoid performance hits.🧰 Tools
🪛 Ruff (0.8.2)
85-86: Use a single
if
statement instead of nestedif
statements(SIM102)
107-110
: File skipping logic.Removing file metadata from
form_data
can prevent unintended processing. This is a good example of providing an “escape hatch” for certain filter operations.backend/open_webui/routers/knowledge.py (8)
28-28
:Models, ModelForm
import.Used later for referencing model data. Ensure that circular-import issues are handled if knowledge references models while models reference knowledge.
216-221
: Write-access checks for knowledge updating.Nicely ensures only original creators, group members with write privileges, or admins can modify knowledge. The role-based check is correct.
267-271
: Access checks before file addition.Consistent with your approach in other routes. This ensures data consistency and user isolation.
351-355
: Updating an existing file within knowledge.The vector DB removal followed by reprocessing ensures updated content is reflected accurately. Validate that partial reprocesses don’t lead to mismatch states.
423-426
: Removal access checks.Again, consistent with your overall knowledge base permission model. Good approach.
501-504
: Delete knowledge permission check.Same pattern as other knowledge modifications. Maintaining consistency is helpful for maintainability.
510-539
: Model references cleanup on knowledge deletion.Updating all models to remove references to this knowledge base ensures no orphan references remain. This is a thorough approach; well done.
617-617
: Bulk file additions logging.Logging the count of files helps track usage. This block properly ensures only valid files are processed.
backend/open_webui/utils/logger.py (1)
1-141
: New structured logging utility.
- Blending Loguru with Python’s standard logging is powerful.
InterceptHandler
ensures all logs come through a unified pipeline.file_format
method with JSON is excellent for downstream analytics.start_logger
function provides a clear, centralized init.Overall, the module is well-organized and significantly improves logging consistency.
backend/open_webui/utils/response.py (6)
9-24
: Well-structured conversion utility for tool calls.The new function
convert_ollama_tool_call_to_openai
provides a clean way to transform Ollama tool calls to OpenAI format. The function properly handles missing fields with sensible defaults and generates UUIDs for calls without IDs.
27-80
: Comprehensive usage metrics conversion with proper error handling.This function provides a thorough transformation of Ollama usage metrics to OpenAI-compatible format, with appropriate handling of edge cases (like division by zero) and clear documentation of equivalent fields.
86-90
: Clean implementation of tool calls processing.The code now properly detects and handles tool calls in responses, using the new conversion utility function for consistent formatting.
94-94
: Modularized usage metrics conversion.Good refactoring to use the dedicated conversion function rather than inline calculation, improving maintainability.
107-112
: Consistent handling of streaming tool calls.The streaming response handler now properly processes tool calls using the same conversion logic as the non-streaming handler, ensuring consistency.
118-118
: Unified usage metrics handling.Using the same conversion function for both streaming and non-streaming responses ensures consistent behavior.
backend/open_webui/utils/chat.py (2)
63-156
: Well-implemented direct chat completion function.The new
generate_direct_chat_completion
function introduces a robust mechanism for handling direct model connections with proper WebSocket communication. The implementation correctly handles both streaming and non-streaming responses, with appropriate error handling.🧰 Tools
🪛 Ruff (0.8.2)
128-131: Use
contextlib.suppress(Exception)
instead oftry
-except
-pass
Replace with
contextlib.suppress(Exception)
(SIM105)
130-130: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
158-195
: Enhanced chat completion with direct connection support.The modified
generate_chat_completion
function now checks for direct connections and delegates to the new direct chat completion function when appropriate. This provides a clean integration path for the new functionality.CHANGELOG.md (2)
8-14
: Comprehensive documentation of important fixes in 0.5.18.The changelog properly documents the critical fixes in this version, providing clear information about what issues were resolved.
16-36
: Detailed feature documentation for version 0.5.17.The changelog provides comprehensive information about new features, fixes and changes in version 0.5.17, making it easy for users to understand what's new.
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
21-21: Bare URL used
null(MD034, no-bare-urls)
backend/open_webui/models/chats.py (4)
20-21
: Proper logging setup.Adding a logger with appropriate log level configuration is a good practice for structured logging.
400-400
: Query simplification in get_chat_list_by_user_id.Removing the filter for folder_id allows retrieving all chats for a user regardless of folder association, which appears to be a deliberate change to expand the query's scope.
477-477
: Improved comment clarity.The updated comment better explains the logic for checking if a chat is still shared.
677-677
: Replaced print statements with proper logging.Converting print statements to structured logging is a good practice for better observability and log management.
Also applies to: 738-738, 759-759, 817-817
backend/open_webui/routers/auths.py (21)
28-29
: Use environment-based cookie settings
Great to see these environment variables in use for cookie configuration. This approach is more secure and flexible.
34-34
: Import for LDAP and OAuth
Straightforward import addition. No issues here.
52-54
: Conditional import for LDAP modules
UsingENABLE_LDAP.value
to guard LDAP imports prevents unnecessary overhead when LDAP is disabled. Looks good.
97-98
: Secure cookie parameters
Includinghttponly=True
,samesite
, andsecure
is a best practice to protect session cookies.
163-166
: Updated response model for LDAP authentication
The endpoint now returnsSessionUserResponse
. Verify your frontend and any other consumers expect this shape.
172-172
: Environment variable for LDAP mail attribute
EnsureLDAP_ATTRIBUTE_FOR_MAIL
is properly set in all environments.
221-225
: Expanded LDAP search attributes
Including the mail attribute is necessary for identifying user emails. This is a sensible addition.
233-235
: Blocking LDAP sign-in without an email
Throwing an exception when mail is missing prevents ambiguous user records and is good practice.
253-254
: Retrieving user count
UsingUsers.get_num_users()
is fine here. Monitor performance on very large user stores.
257-257
: First LDAP user as admin
Assigning admin rights on the first user is a design choice—confirm this is desired for production.
292-294
: Fetching user permissions
Looks good. This code cleanly centralizes permission retrieval.
304-304
: Include permissions in response
Consistent with the rest of your response structure. No issues.
387-388
: Cookie security on sign-in
Again, usingsamesite
andsecure
for session cookies is commendable.
432-432
: LDAP sign-up user count
Same user counting approach. No concerns at this point.
442-442
: Assigning default role
Double-check that your workflow demands making the first user an admin for all signups.
482-483
: Secure cookie on signup
Ensuring session cookies have secure attributes is fundamental for production security.
709-709
: Default mail attribute
A sane default (“mail”) helps standardize LDAP mail lookups.
726-726
: Retrieve mail attribute in server config
No issue. This complements the new LDAP configuration logic.
738-738
: New admin route for LDAP server config
Providing an endpoint for LDAP server configuration changes is handy and straightforward.
745-745
: Mail attribute as required
Good job enforcing mail as part of the required fields.
780-780
: Returning “attribute_for_mail”
Nice to expose the updated field in the response for clarity.backend/open_webui/routers/tasks.py (11)
7-7
: Regex import
Direct usage ofre
is clear for the upcoming text transformations.
13-13
: Added template import
Importingimage_prompt_generation_template
aligns with the new image prompt endpoint.
32-32
: New default image prompt template
AddingDEFAULT_IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE
ensures consistent fallback logic.
60-60
: Expose image prompt template
SurfacingIMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE
in config matches your new feature.
65-65
: Enable title generation
Likewise, exposingENABLE_TITLE_GENERATION
in the config endpoint keeps the UI in sync.
76-76
: New boolean field
ENABLE_TITLE_GENERATION
inTaskConfigForm
is straightforward and well-typed.
78-78
: String field for image prompt template
A strong addition for custom image prompt formatting.
95-95
: Apply new config
AssigningENABLE_TITLE_GENERATION
from the form data correctly updates the config.
100-102
: Apply custom image prompt generation template
Implementation is consistent with other config fields.
132-134
: Confirming new config fields
ReturningENABLE_TITLE_GENERATION
andIMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE
helps ensure the UI shows updated values.
150-155
: Disable title generation
This early return clarifies that title generation is off, preventing unnecessary processing.backend/open_webui/routers/pipelines.py (3)
12-12
: Async I/O
Switching toaiohttp
fosters non-blocking flows for the pipeline. Good improvement.
95-95
: Unused exception variable
You previously flagged this in older commits; removinge
is best to avoid confusion.-except aiohttp.ClientResponseError as e: +except aiohttp.ClientResponseError:🧰 Tools
🪛 Ruff (0.8.2)
95-95: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
144-144
: Unused variable in outlet filter
Same scenario as before: removee
if unused.-except aiohttp.ClientResponseError as e: +except aiohttp.ClientResponseError:🧰 Tools
🪛 Ruff (0.8.2)
144-144: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
backend/open_webui/utils/audit.py (3)
1-35
: New module for audit logging
Introduces structured auditing classes and context managers. The design is clear and well-documented.
36-91
:AuditLogEntry
andAuditLogger
Data classes and logger binding are well-structured and should help produce consistent audit records.
92-250
: Audit logging middleware
This middleware effectively intercepts requests and captures relevant data. Carefully consider the overhead of storing request/response bodies for large payloads, but it appears you have a cap withMAX_BODY_LOG_SIZE
.🧰 Tools
🪛 Ruff (0.8.2)
212-215: Return the condition
bool(pattern.match(request.url.path))
directlyReplace with
return bool(pattern.match(request.url.path))
(SIM103)
backend/open_webui/routers/audio.py (7)
14-14
: Import usage looks good.
Themimetypes
import is correctly used later to guess file types for Deepgram support.
40-40
: Importing the new timeout configuration is fine.
No further remarks on this addition.
74-74
: Clearer logging for missing files.
Logging an error here can help identify misconfigurations or unexpected audio paths.
91-91
: Useful conversion log message.
This log statement helps track audio conversions; no issues found.
329-332
: Same suggestion regarding timeouts.
The mention about separate connect/read timeouts also applies here.
389-392
: Same suggestion regarding timeouts.
The recommendation to specify more granular timeouts applies here as well.
469-469
: Informative log statement looks good.
This helps trace audio transcription requests succinctly.backend/open_webui/env.py (7)
57-57
: CUDA to MPS fallback block usage looks fine.
This import under atry
is consistent with checking for device availability.
95-95
: New log source "OAUTH" is fine.
No issues—just be sure it is used where relevant.
110-110
: Default name change is straightforward.
It’s acceptable to rename the application in this way.
112-112
: Favicon URL default looks good.
No concerns regarding the updated default.
114-114
: Verify that the signature key is properly encoded.
Be aware that environment variables are typically strings, and downstream code may need to encode it into bytes for HMAC usage.
279-279
: Database schema variable introduced.
No issues, ensures flexible schema usage if multiple schemas are needed.
359-375
: Confirm secure cookie settings in production.
UsingSecure=True
and strictSameSite
can prevent session hijacking, but double-check that these reflect the intended environment.backend/open_webui/utils/auth.py (4)
4-8
: Imports are used, except note the static analysis for unused references below.
Base modules appear relevant for new functions like signature verification.
31-32
: Fine-grained log level usage.
Redirecting auth-specific logs to "OAUTH" source can help isolate security events.
58-69
: Path check is partial.
If the environment includes Windows backslashes or other edge cases, this might be bypassed. Please see past reviewer suggestions regarding normalizing paths to avoid directory traversal.
153-153
: Asynchronous user update is well-implemented.
AddingBackgroundTasks
to refresh last active timestamps without blocking the request is a good design choice.backend/open_webui/utils/oauth.py (5)
4-5
: Import additions and environment variables look good.The added imports for
sys
and additional environment variables for cookie security settings enhance the functionality and configuration options.Also applies to: 38-43
73-77
: Good enhancement with app parameter in the constructor.Storing the app as an instance variable and refactoring the provider registration process to use a
register
method simplifies the initialization logic.
109-113
: Enhanced debugging with detailed log statements.The additional logging for OAuth roles provides better visibility into the authorization process, which is helpful for troubleshooting.
154-159
: Improved debugging in group management.The additional log statements help track OAuth group processing, making it easier to debug group-related issues.
415-417
: Good security enhancement with configurable cookie settings.Using environment variables for cookie security settings allows for better security configuration across different environments.
backend/open_webui/routers/images.py (11)
58-61
: Good addition of Gemini configuration to API response.Adding Gemini configuration to the config endpoint response makes it accessible to the client.
85-88
: Clean implementation of GeminiConfigForm.The new Gemini configuration form follows the established pattern of other provider forms.
93-93
: Updated ConfigForm with new properties.The ConfigForm has been appropriately updated to include the new prompt_generation flag and Gemini configuration.
Also applies to: 97-97
107-109
: Added support for image prompt generation configuration.This configuration option will allow enabling/disabling automatic prompt generation for images.
116-120
: Added Gemini API configuration handling.The implementation properly stores Gemini API configuration in the application state.
256-261
: Good addition of Gemini model support.The implementation follows the pattern established for other image generation models.
418-430
: Refactored image loading from base64.The function has been improved to return image data and MIME type instead of saving files directly, enhancing modularity.
453-465
: Good implementation of image upload utility.This function centralizes the image upload logic, making the code more maintainable and reusable.
525-557
: Well-implemented Gemini image generation support.The Gemini API integration follows the pattern of other image generation engines and includes proper error handling.
597-612
: Added headers support and improved image upload for ComfyUI.The changes allow for authentication headers when accessing ComfyUI generated images and use the centralized upload function.
656-664
: Consolidated image upload for Automatic1111.Using the centralized upload_image function makes the code more consistent across different image generation engines.
backend/open_webui/utils/middleware.py (9)
15-16
: New imports for enhanced functionality.The addition of
re
andast
modules support the new parsing and processing capabilities in the middleware.
102-103
: Updated tools handler signature.The function now accepts a
tools
parameter instead ofextra_params
, making the parameter name more semantically meaningful.
179-245
: Well-implemented async tool call handler.The refactoring using an inner async function for tool call handling improves code organization and readability. The tool output processing logic is also well-structured.
422-513
: Strong implementation of image generation in chat.The new
chat_image_generation_handler
adds support for generating images based on user messages, with appropriate error handling and user feedback.🧰 Tools
🪛 Ruff (0.8.2)
437-437: Local variable
negative_prompt
is assigned to but never usedRemove assignment to unused variable
negative_prompt
(F841)
462-462: Local variable
e
is assigned to but never usedRemove assignment to unused variable
e
(F841)
500-500: f-string without any placeholders
Remove extraneous
f
prefix(F541)
554-574
: Improved file source retrieval with async execution.The refactoring to use a ThreadPoolExecutor for
get_sources_from_files
improves performance by offloading the potentially expensive operation to a separate thread.
611-613
: Added support for reasoning effort parameter.This enhancement provides more control over the reasoning process.
1080-1089
: Added helper function for content processing.The
split_content_and_whitespace
function cleanly separates content from trailing whitespace, which is useful for preservation during transformations.
1090-1094
: Added code block detection function.The
is_opening_code_block
function uses a clever approach to detect if the current string is opening a new code block by counting backtick segments.
748-748
:❓ Verification inconclusive
Consider including a check for empty files.
The code assumes files is not None after popping it, but it could be empty. Consider adding an explicit check.
🏁 Script executed:
#!/bin/bash # Look for any places where files is checked for None vs. empty rg -A 3 "files = form_data\.pop\(\"files\", None\)" --include "*.py" rg -A 5 "if files:" --include "*.py"Length of output: 991
Below is a revised review comment that reflects the need to address an empty list even when the popped value isn’t None. (Note that since our initial rg-based search didn’t produce useful results due to incorrect flag usage, please manually verify the exact locations where—if at all—an empty files list is handled.)
Action Item: Ensure explicit handling of empty file lists
It appears that while the code pops "files" from the request data with a default of None, there isn’t a check for the case where "files" is an empty collection. Even if "files" isn’t None, an empty list might lead to unexpected behavior later on. Consider adding an explicit conditional, for example:
files = form_data.pop("files", None) if not files: # Handle the empty files case explicitly, # e.g., by returning an error response or taking an alternate code path.This additional check will make the code more robust in handling edge cases.
backend/open_webui/routers/files.py (5)
64-64
: Good enhancement with file metadata inclusion.Including the provided metadata in the file's meta object allows for rich context to be associated with uploaded files.
71-86
: Excellent addition of audio transcription support.Detecting audio file types and automatically transcribing them before processing is a valuable enhancement that improves the user experience.
209-210
: Added user context to process_file.Passing the user to process_file provides better context for file processing operations.
244-261
: Improved content type handling for file responses.The enhanced logic to handle PDF files with inline display improves the user experience when viewing document files.
292-292
: Informative logging for file paths.Adding this log statement helps with debugging file path issues.
backend/open_webui/utils/payload.py (1)
76-76
: Local variableparam
is assigned but never used
Referencing the previous comment about removing or refactoring this unused variable.🧰 Tools
🪛 Ruff (0.8.2)
76-76: Local variable
param
is assigned to but never used(F841)
76-76: Use
params.get(key)
instead ofparams.get(key, None)
Replace
params.get(key, None)
withparams.get(key)
(SIM910)
backend/open_webui/routers/openai.py (2)
101-110
: Verify handling of multiple “system” messagesCurrently,
openai_o1_o3_handler
modifies only the first message if it has asystem
role. If there can be multiple system messages in the payload, consider whether they should be handled similarly.
55-73
: Confirm user data safety in forwarded headersSensitive user information is added to custom headers. If “username,” “email,” or other fields can contain special or untrusted characters, consider sanitizing them before appending to HTTP headers.
backend/open_webui/routers/utils.py (1)
46-72
: Revisit the code execution timeout handlingA previous review suggested adding tighter exception handling (e.g., catching
asyncio.TimeoutError
) to gracefully handle timeouts during code execution. Consider reintroducing that logic to improve fault tolerance.🧰 Tools
🪛 Ruff (0.8.2)
48-48: Do not perform function call
Depends
in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable(B008)
backend/open_webui/retrieval/utils.py (3)
18-18
: Remove unused imports.Both
get_last_user_message
andcalculate_sha256_string
are not referenced anywhere in this file. Removing unused imports reduces clutter and prevents confusion.- from open_webui.utils.misc import get_last_user_message, calculate_sha256_string
🧰 Tools
🪛 Ruff (0.8.2)
18-18:
open_webui.utils.misc.get_last_user_message
imported but unusedRemove unused import
(F401)
18-18:
open_webui.utils.misc.calculate_sha256_string
imported but unusedRemove unused import
(F401)
72-72
: Verify necessity of the newuser
parameter.The
user
parameter was introduced but is never utilized in this function. Confirm whether it’s intended for future expansions like audit logging or access control. If not, consider removing it to keep the signature clean.
86-88
: Exception handling looks good.Using
log.exception
is a solid approach for recording stack traces. These lines properly re-raise the exception to avoid silent failures.backend/open_webui/routers/retrieval.py (1)
49-49
: Validate new search engine API credentials.These newly imported search engines (
bocha
,serpapi
,exa
) rely on associated API keys. Ensure you check for missing or invalid environment variables to prevent runtime errors.Also applies to: 54-54, 61-61
backend/open_webui/main.py (9)
48-50
: Add logging and audit imports.These imports bring in structured logging, auditing levels, and the logger initialization function. They seem properly utilized below (e.g.,
start_logger
at line 399 and audit middleware around line 908).
94-94
: Verify proper handling of LICENSE_KEY.While loading
LICENSE_KEY
from config is straightforward, ensure the logic around license checks (lines 403–405) gracefully handles invalid or missing keys and does not block application startup unexpectedly.
105-105
: Minor inline comment.No issues found; this is just a comment marker for the new "Direct Connections" section.
106-106
: Enable direct connections configuration.The addition of
ENABLE_DIRECT_CONNECTIONS
aligns with allowing direct model usage (e.g., lines 992–1008). Ensure thorough testing of any security implications.
399-399
: Initialize logger on application lifespan start.Good call to
start_logger()
early in the lifecycle. Verify that repeated calls do not reconfigure the logger multiple times inadvertently.
403-405
: Load license data if available.Retrieves license data only if
LICENSE_KEY
is present. This logic is consistent—just confirm robust error handling if service calls fail.
450-455
: Comment block for direct connections.These lines merely structure the file. No actionable items needed.
456-457
: Set direct connections config state.Assigning
app.state.config.ENABLE_DIRECT_CONNECTIONS
is straightforward and consistent with the new feature. Looks good.
692-692
: Enable image prompt generation.Check whether image prompt generation needs additional rate-limiting or external call controls if large volumes of prompt generation are possible.
backend/open_webui/config.py (6)
538-550
: GitHub OAuth registration block.The
github_oauth_register
function properly sets up endpoints. Confirm you handle potential userinfo mismatch or GitHub scope changes gracefully (lines 541–548).
606-613
: Attempting to copyloader.js
.These lines handle copying an additional static asset. Handle exceptions carefully (as done with try/except). No issues noted.
974-993
: Default user permissions for new features.Including web search, image generation, and code interpreter flags for user roles is a neat approach. Just ensure these new permissions (lines 959–971) integrate seamlessly with your role-based checks.
1100-1102
: Error loading WEBUI_BANNERS.Wrapped in an exception; logs the error with
log.exception()
. This is fine—just confirm it’s not too verbose if environment variables are missing.
1187-1212
: Image prompt generation template.Descriptive instructions for generating images from chat context. This template references a JSON output format. Again, ensure callers robustly parse the JSON since user models can deviate.
1219-1224
: Enable title generation.Key-based toggle to turn this feature on/off. Looks consistent with the other toggles.
backend/open_webui/storage/provider.py (9)
3-10
: New imports and reorganized dependencies.Grouping AWS, GCS, and Azure libraries indicates a multi-provider approach. Verify dependencies are pinned to secure versions in your requirements.
41-57
: Abstract StorageProvider class.Defining an interface with
upload_file
,get_file
,delete_file
, anddelete_all_files
is a clean approach. Encourages consistent usage across providers.
59-98
: LocalStorageProvider implementation.The local provider writes files into
UPLOAD_DIR
.
- Raises a
ValueError
if empty (line 64).- Logs any failures to delete.
Everything looks correct for local usage.
133-142
: S3 download logic.Your approach
_extract_s3_key
→_get_local_file_path
thendownload_file
is straightforward. Confirm that partial or large downloads handle network disruptions.🧰 Tools
🪛 Ruff (0.8.2)
141-141: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
174-179
: Helpers for S3 keys and local path.Extracting the S3 key from an “s3://” style path and forming the local path is fine. Confirm correct behavior with subfolders, if supported.
181-243
: GCSStorageProvider.Similar pattern as S3:
- Upload saves locally first, then uploads to GCS.
- For
NotFound
handling (lines 215, 225, 239), considerraise ... from e
for clarity.🧰 Tools
🪛 Ruff (0.8.2)
204-204: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
216-216: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
225-225: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
239-239: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
245-311
: AzureStorageProvider.Implements the same interface. Notably uses
upload_blob(contents, overwrite=True)
.
- In
except
blocks (lines 274, 286, 295, 307), ensuring we chain or re-raise from the original error improves debugging.🧰 Tools
🪛 Ruff (0.8.2)
274-274: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
286-286: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
295-295: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
307-307: Within an
except
clause, raise exceptions withraise ... from err
orraise ... from None
to distinguish them from errors in exception handling(B904)
313-325
: Factory method for selecting storage provider.
get_storage_provider
returns the correct provider based on config. RaiseRuntimeError
for unsupported providers. This is a clean design.
327-327
: Global Storage instance.Instantiates the chosen provider once. Looks good—just confirm concurrency safety if multiple threads/processes.
|
||
class ColBERT: | ||
def __init__(self, name, **kwargs) -> None: | ||
print("ColBERT: Loading model", name) | ||
log.info("ColBERT: Loading model", name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the logging format.
The current logging statement uses incorrect formatting for Python's logging module. When passing variables to logging methods, you should use string formatting with placeholders rather than passing them as additional arguments.
- log.info("ColBERT: Loading model", name)
+ log.info("ColBERT: Loading model %s", name)
Alternatively, you could use an f-string:
- log.info("ColBERT: Loading model", name)
+ log.info(f"ColBERT: Loading model {name}")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
log.info("ColBERT: Loading model", name) | |
log.info("ColBERT: Loading model %s", name) |
@@ -102,8 +107,7 @@ def query( | |||
} | |||
) | |||
return None | |||
except Exception as e: | |||
print(e) | |||
except: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid bare except
.
Catching all exceptions without specifying the exception type can mask errors and complicate debugging.
- except:
+ except Exception:
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
except: | |
except Exception: |
🧰 Tools
🪛 Ruff (0.8.2)
110-110: Do not use bare except
(E722)
@@ -17,14 +17,15 @@ | |||
process_files_batch, | |||
BatchProcessFilesForm, | |||
) | |||
|
|||
from open_webui.storage.provider import Storage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove unused import.
from open_webui.storage.provider import Storage
is not used in this file. Removing it avoids confusion and meets linting guidelines.
- from open_webui.storage.provider import Storage
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
from open_webui.storage.provider import Storage |
🧰 Tools
🪛 Ruff (0.8.2)
20-20: open_webui.storage.provider.Storage
imported but unused
Remove unused import: open_webui.storage.provider.Storage
(F401)
except Exception as e: | ||
log.exception(e) | ||
detail = None | ||
if r is not None: | ||
try: | ||
res = r.json() | ||
if "error" in res: | ||
detail = f"External: {res['error'].get('message', '')}" | ||
except Exception: | ||
detail = f"External: {e}" | ||
raise Exception(detail if detail else "Open WebUI: Server Connection Error") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure r
is defined before usage and preserve exception trace.
If requests.post
fails before assigning r
, referencing r
in the except
clause may cause an UnboundLocalError
. Also consider using raise ... from e
to maintain original context.
try:
+ r = None
r = requests.post(
...
)
r.raise_for_status()
except Exception as e:
log.exception(e)
detail = None
if r is not None:
try:
res = r.json()
...
- raise Exception(detail if detail else "Open WebUI: Server Connection Error")
+ raise Exception(detail if detail else "Open WebUI: Server Connection Error") from e
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
except Exception as e: | |
log.exception(e) | |
detail = None | |
if r is not None: | |
try: | |
res = r.json() | |
if "error" in res: | |
detail = f"External: {res['error'].get('message', '')}" | |
except Exception: | |
detail = f"External: {e}" | |
raise Exception(detail if detail else "Open WebUI: Server Connection Error") | |
try: | |
+ r = None | |
r = requests.post( | |
... | |
) | |
r.raise_for_status() | |
except Exception as e: | |
log.exception(e) | |
detail = None | |
if r is not None: | |
try: | |
res = r.json() | |
if "error" in res: | |
detail = f"External: {res['error'].get('message', '')}" | |
except Exception: | |
detail = f"External: {e}" | |
- raise Exception(detail if detail else "Open WebUI: Server Connection Error") | |
+ raise Exception(detail if detail else "Open WebUI: Server Connection Error") from e |
🧰 Tools
🪛 Ruff (0.8.2)
599-599: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
def verify_signature(payload: str, signature: str) -> bool: | ||
""" | ||
Verifies the HMAC signature of the received payload. | ||
""" | ||
try: | ||
expected_signature = base64.b64encode( | ||
hmac.new(TRUSTED_SIGNATURE_KEY, payload.encode(), hashlib.sha256).digest() | ||
).decode() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure the HMAC key is in bytes.
TRUSTED_SIGNATURE_KEY
is likely a string, so consider encoding it before calling hmac.new
. Otherwise, it may throw a TypeError
.
expected_signature = base64.b64encode(
- hmac.new(TRUSTED_SIGNATURE_KEY, payload.encode(), hashlib.sha256).digest()
+ hmac.new(TRUSTED_SIGNATURE_KEY.encode(), payload.encode(), hashlib.sha256).digest()
).decode()
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def verify_signature(payload: str, signature: str) -> bool: | |
""" | |
Verifies the HMAC signature of the received payload. | |
""" | |
try: | |
expected_signature = base64.b64encode( | |
hmac.new(TRUSTED_SIGNATURE_KEY, payload.encode(), hashlib.sha256).digest() | |
).decode() | |
def verify_signature(payload: str, signature: str) -> bool: | |
""" | |
Verifies the HMAC signature of the received payload. | |
""" | |
try: | |
expected_signature = base64.b64encode( | |
hmac.new(TRUSTED_SIGNATURE_KEY.encode(), payload.encode(), hashlib.sha256).digest() | |
).decode() |
# If the provider is GitHub,and public email is not provided, we can use the access token to fetch the user's email | ||
if provider == "github": | ||
try: | ||
access_token = token.get("access_token") | ||
headers = {"Authorization": f"Bearer {access_token}"} | ||
async with aiohttp.ClientSession() as session: | ||
async with session.get( | ||
"https://api.github.com/user/emails", headers=headers | ||
) as resp: | ||
if resp.ok: | ||
emails = await resp.json() | ||
# use the primary email as the user's email | ||
primary_email = next( | ||
(e["email"] for e in emails if e.get("primary")), | ||
None, | ||
) | ||
if primary_email: | ||
email = primary_email | ||
else: | ||
log.warning( | ||
"No primary email found in GitHub response" | ||
) | ||
raise HTTPException( | ||
400, detail=ERROR_MESSAGES.INVALID_CRED | ||
) | ||
else: | ||
log.warning("Failed to fetch GitHub email") | ||
raise HTTPException( | ||
400, detail=ERROR_MESSAGES.INVALID_CRED | ||
) | ||
except Exception as e: | ||
log.warning(f"Error fetching GitHub email: {e}") | ||
raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) | ||
else: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Good addition of GitHub email retrieval fallback.
The implementation to fetch email from GitHub when not provided in the initial authentication response is a robust enhancement, particularly for users with private email settings.
However, there's an issue with exception handling:
- except Exception as e:
- log.warning(f"Error fetching GitHub email: {e}")
- raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)
+ except Exception as e:
+ log.warning(f"Error fetching GitHub email: {e}")
+ raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) from e
Also, consider combining the nested with
statements for better readability:
- async with aiohttp.ClientSession() as session:
- async with session.get(
- "https://api.github.com/user/emails", headers=headers
- ) as resp:
+ async with aiohttp.ClientSession() as session, session.get(
+ "https://api.github.com/user/emails", headers=headers
+ ) as resp:
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
# If the provider is GitHub,and public email is not provided, we can use the access token to fetch the user's email | |
if provider == "github": | |
try: | |
access_token = token.get("access_token") | |
headers = {"Authorization": f"Bearer {access_token}"} | |
async with aiohttp.ClientSession() as session: | |
async with session.get( | |
"https://api.github.com/user/emails", headers=headers | |
) as resp: | |
if resp.ok: | |
emails = await resp.json() | |
# use the primary email as the user's email | |
primary_email = next( | |
(e["email"] for e in emails if e.get("primary")), | |
None, | |
) | |
if primary_email: | |
email = primary_email | |
else: | |
log.warning( | |
"No primary email found in GitHub response" | |
) | |
raise HTTPException( | |
400, detail=ERROR_MESSAGES.INVALID_CRED | |
) | |
else: | |
log.warning("Failed to fetch GitHub email") | |
raise HTTPException( | |
400, detail=ERROR_MESSAGES.INVALID_CRED | |
) | |
except Exception as e: | |
log.warning(f"Error fetching GitHub email: {e}") | |
raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) | |
else: | |
# If the provider is GitHub,and public email is not provided, we can use the access token to fetch the user's email | |
if provider == "github": | |
try: | |
access_token = token.get("access_token") | |
headers = {"Authorization": f"Bearer {access_token}"} | |
async with aiohttp.ClientSession() as session, session.get( | |
"https://api.github.com/user/emails", headers=headers | |
) as resp: | |
if resp.ok: | |
emails = await resp.json() | |
# use the primary email as the user's email | |
primary_email = next( | |
(e["email"] for e in emails if e.get("primary")), | |
None, | |
) | |
if primary_email: | |
email = primary_email | |
else: | |
log.warning( | |
"No primary email found in GitHub response" | |
) | |
raise HTTPException( | |
400, detail=ERROR_MESSAGES.INVALID_CRED | |
) | |
else: | |
log.warning("Failed to fetch GitHub email") | |
raise HTTPException( | |
400, detail=ERROR_MESSAGES.INVALID_CRED | |
) | |
except Exception as e: | |
log.warning(f"Error fetching GitHub email: {e}") | |
raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED) from e | |
else: |
🧰 Tools
🪛 Ruff (0.8.2)
257-260: Use a single with
statement with multiple contexts instead of nested with
statements
(SIM117)
284-284: Within an except
clause, raise exceptions with raise ... from err
or raise ... from None
to distinguish them from errors in exception handling
(B904)
app.state.config.ENABLE_CODE_INTERPRETER = ENABLE_CODE_INTERPRETER | ||
app.state.config.CODE_INTERPRETER_ENGINE = CODE_INTERPRETER_ENGINE | ||
app.state.config.CODE_INTERPRETER_PROMPT_TEMPLATE = CODE_INTERPRETER_PROMPT_TEMPLATE | ||
|
||
app.state.config.CODE_INTERPRETER_JUPYTER_URL = CODE_INTERPRETER_JUPYTER_URL | ||
app.state.config.CODE_INTERPRETER_JUPYTER_AUTH = CODE_INTERPRETER_JUPYTER_AUTH | ||
app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_TOKEN = ( | ||
CODE_INTERPRETER_JUPYTER_AUTH_TOKEN | ||
) | ||
app.state.config.CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = ( | ||
CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD | ||
) | ||
app.state.config.CODE_INTERPRETER_JUPYTER_TIMEOUT = CODE_INTERPRETER_JUPYTER_TIMEOUT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enable code interpreter.
Allowing a code interpreter inside the application can pose significant security risks. Recommend verifying user roles, implementing safe execution sandboxes, and restricting file system access.
# Ollama | ||
ENABLE_OLLAMA_API, | ||
OLLAMA_BASE_URLS, | ||
OLLAMA_API_CONFIGS, | ||
# OpenAI | ||
ENABLE_OPENAI_API, | ||
ONEDRIVE_CLIENT_ID, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Redundant ONEDRIVE_CLIENT_ID import.
Static analysis suggests a redefinition of ONEDRIVE_CLIENT_ID
. Verify it's genuinely needed here. If not, consider removing this import to avoid confusion.
- ONEDRIVE_CLIENT_ID,
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
ONEDRIVE_CLIENT_ID, |
@gemini conduct ane extremely granular review of the PR, additionally, provide a full walkthrough, including an evaluation (worse or better) of the proposed changes. |
Okay, I will conduct an extremely granular review of the PR and provide a full walkthrough, including an evaluation of the proposed changes. Granular Code ReviewI have reviewed the pull request in detail, focusing on correctness, efficiency, maintainability, and security. Here's a breakdown of the key changes and some suggestions for improvement.
Full WalkthroughThis pull request introduces a wide range of new features, improvements, and bug fixes. The changes span across the entire codebase, from the frontend to the backend, and include updates to the build system, documentation, and dependencies. New Features
Improvements
Bug Fixes
Evaluation of Proposed ChangesOverall, the proposed changes significantly improve the functionality, stability, and user experience of Open WebUI. The addition of new features such as Gemini image generation, OneDrive storage integration, and Elasticsearch Vector DB support expands the platform's capabilities and provides users with more flexibility. The numerous bug fixes address critical issues and enhance the reliability of the software. The rebranding of the interface from "Open WebUI" to "Global Chat" may be a good change, but it depends on the target audience and the overall branding strategy. Worse or Better? These changes are definitively better for the project. The new features and improvements outweigh any potential drawbacks, and the bug fixes address critical issues that were affecting the user experience. |
@coderrabitai review the code to determine if we have a dash card and landing page now |
chore: Fix dependabot configuration
…urls fix: only keep URLs as sources for which the content was actually retrieved
i18n: update zh-TW
i18n language pack vietnamese
i18n: update zh-CN
This commit fixes an issue created on commit 2e7a01f. Ldap object is type <class 'ldap3.abstract.attribute.Attribute'>. So we need to return the value and verify if it's null, string or list. Fixes open-webui#12813
fix: Properly handle ldap3.abstract.attribute.Attribute value
[i18n] Russian locale update
feat/Enable vad_filter to improve quality of transcription in faster-whisper
Fix: Robust Handling of LDAP Email Attribute Types
Co-Authored-By: Sebastian Whincop <[email protected]>
Pull Request Checklist
Note to first-time contributors: Please open a discussion post in Discussions and describe your changes before submitting a pull request.
Before submitting, make sure you've checked the following:
dev
branch.Changelog Entry
Description
Added
Changed
Deprecated
Removed
Fixed
Security
Breaking Changes
Additional Information
Screenshots or Videos