diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 10802def2a..721c890407 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -2599,8 +2599,7 @@ def oauth_client_kwargs(scope: str, **kwargs): client_kwargs['code_challenge_method'] = 'S256' elif OAUTH_CODE_CHALLENGE_METHOD: raise Exception( - 'Code challenge methods other than "%s" not supported. Given: "%s"' - % ('S256', OAUTH_CODE_CHALLENGE_METHOD) + 'Code challenge methods other than "%s" not supported. Given: "%s"' % ('S256', OAUTH_CODE_CHALLENGE_METHOD) ) return client_kwargs diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 171d5b2d7b..6462a60625 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -837,7 +837,9 @@ async def get_models(request: Request, refresh: bool = False, user=Depends(get_v all_models = await get_all_models(request, refresh=refresh, user=user) # Filter out filter pipelines - models = [model for model in all_models if not ('pipeline' in model and model['pipeline'].get('type', None) == 'filter')] + models = [ + model for model in all_models if not ('pipeline' in model and model['pipeline'].get('type', None) == 'filter') + ] # Chat requests resolve models by ID from request.app.state.MODELS, where # duplicate IDs collapse to the last model. Return the same effective list. @@ -1142,11 +1144,7 @@ async def chat_completion( chat_id = form_data.get('chat_id') or '' chat_variables = form_data.pop('chat_variables', None) if chat_variables is None: - existing_chat = ( - await Chats.get_chat_by_id(chat_id) - if is_saved_chat_id(chat_id) - else None - ) + existing_chat = await Chats.get_chat_by_id(chat_id) if is_saved_chat_id(chat_id) else None chat_variables = existing_chat.variables if existing_chat else {} chat_variables = normalize_chat_variables(chat_variables) diff --git a/backend/open_webui/migrations/versions/959eaac8f909_add_automation_folder_id.py b/backend/open_webui/migrations/versions/959eaac8f909_add_automation_folder_id.py index 3eafd1a246..1298abd41d 100644 --- a/backend/open_webui/migrations/versions/959eaac8f909_add_automation_folder_id.py +++ b/backend/open_webui/migrations/versions/959eaac8f909_add_automation_folder_id.py @@ -5,6 +5,7 @@ Revises: 55f1302ac17c Create Date: 2026-07-26 19:19:31.345756 """ + from collections.abc import Sequence import sqlalchemy as sa diff --git a/backend/open_webui/migrations/versions/b0018471bbbe_add_user_variables.py b/backend/open_webui/migrations/versions/b0018471bbbe_add_user_variables.py index 73d3687c1f..d8e94ca60b 100644 --- a/backend/open_webui/migrations/versions/b0018471bbbe_add_user_variables.py +++ b/backend/open_webui/migrations/versions/b0018471bbbe_add_user_variables.py @@ -5,6 +5,7 @@ Revises: c49178636c78 Create Date: 2026-07-24 01:21:46.457057 """ + from typing import Sequence, Union import sqlalchemy as sa diff --git a/backend/open_webui/migrations/versions/c49178636c78_add_chat_variables.py b/backend/open_webui/migrations/versions/c49178636c78_add_chat_variables.py index 7823f3867c..c4d4aaf355 100644 --- a/backend/open_webui/migrations/versions/c49178636c78_add_chat_variables.py +++ b/backend/open_webui/migrations/versions/c49178636c78_add_chat_variables.py @@ -5,6 +5,7 @@ Revises: 9a1b2c3d4e5f Create Date: 2026-07-23 23:33:45.497453 """ + from typing import Sequence, Union import sqlalchemy as sa diff --git a/backend/open_webui/models/access_grants.py b/backend/open_webui/models/access_grants.py index eb23740273..7cca23546c 100644 --- a/backend/open_webui/models/access_grants.py +++ b/backend/open_webui/models/access_grants.py @@ -174,9 +174,7 @@ def normalize_access_grants(access_grants: Optional[list]) -> list[dict]: continue if not isinstance(principal_id, str) or not principal_id: continue - if principal_type == PRINCIPAL_TYPE_ANYONE and ( - principal_id != WILDCARD_PRINCIPAL_ID or permission != 'read' - ): + if principal_type == PRINCIPAL_TYPE_ANYONE and (principal_id != WILDCARD_PRINCIPAL_ID or permission != 'read'): continue key = (principal_type, principal_id, permission) diff --git a/backend/open_webui/models/calendar.py b/backend/open_webui/models/calendar.py index b9be370f31..4faad1a456 100644 --- a/backend/open_webui/models/calendar.py +++ b/backend/open_webui/models/calendar.py @@ -777,9 +777,7 @@ class CalendarEventAttendeeTable: existing_status = { row.user_id: row.status for row in ( - await db.execute( - select(CalendarEventAttendee).filter(CalendarEventAttendee.event_id == event_id) - ) + await db.execute(select(CalendarEventAttendee).filter(CalendarEventAttendee.event_id == event_id)) ).scalars() } diff --git a/backend/open_webui/retrieval/web/openserp.py b/backend/open_webui/retrieval/web/openserp.py index dde8d90d32..a9276cb1a0 100644 --- a/backend/open_webui/retrieval/web/openserp.py +++ b/backend/open_webui/retrieval/web/openserp.py @@ -21,25 +21,25 @@ async def search_openserp( No API key is required -- only a reachable OpenSERP base URL. """ - url = f"{base_url.rstrip('/')}/mega/search" - params = {"text": query, "limit": count} + url = f'{base_url.rstrip("/")}/mega/search' + params = {'text': query, 'limit': count} - log.debug("searching OpenSERP at %s", url) + log.debug('searching OpenSERP at %s', url) session = await get_session() async with session.get(url, params=params) as response: response.raise_for_status() payload = await response.json() - results = payload.get("results", []) + results = payload.get('results', []) if filter_list: results = get_filtered_results(results, filter_list) return [ SearchResult( - link=item.get("url", ""), - title=item.get("title"), - snippet=item.get("snippet"), + link=item.get('url', ''), + title=item.get('title'), + snippet=item.get('snippet'), ) for item in results[:count] ] diff --git a/backend/open_webui/routers/chats.py b/backend/open_webui/routers/chats.py index dfef6e332d..35dbf70abd 100644 --- a/backend/open_webui/routers/chats.py +++ b/backend/open_webui/routers/chats.py @@ -995,7 +995,10 @@ async def get_user_chats(user=Depends(get_verified_user)): @router.get('/all/archived', response_model=list[ChatResponse]) async def get_user_archived_chats(user=Depends(get_verified_user), db: AsyncSession = Depends(get_async_session)): - return [ChatResponse.model_validate(chat, from_attributes=True) for chat in await Chats.get_archived_chats_by_user_id(user.id, db=db)] + return [ + ChatResponse.model_validate(chat, from_attributes=True) + for chat in await Chats.get_archived_chats_by_user_id(user.id, db=db) + ] ############################ @@ -1357,12 +1360,15 @@ async def update_chat_by_id( touch = 'history' in form_data.chat or 'messages' in form_data.chat chat = await Chats.update_chat_by_id(id, updated_chat, db=db, touch=touch) if form_data.variables is not None: - chat = await Chats.update_chat_variables_by_id( - id, - form_data.variables, - db=db, - touch=False, - ) or chat + chat = ( + await Chats.update_chat_variables_by_id( + id, + form_data.variables, + db=db, + touch=False, + ) + or chat + ) # Reconcile chat_message rows without inferring deletes from missing IDs. # Message deletion has its own endpoint below. diff --git a/backend/open_webui/routers/models.py b/backend/open_webui/routers/models.py index 8af1afbdce..b2ed9e9531 100644 --- a/backend/open_webui/routers/models.py +++ b/backend/open_webui/routers/models.py @@ -50,7 +50,7 @@ router = APIRouter() def add_chat_variables_schema(model_dict: dict) -> dict: - system = ((model_dict.get('params') or {}).get('system') if isinstance(model_dict.get('params'), dict) else None) + system = (model_dict.get('params') or {}).get('system') if isinstance(model_dict.get('params'), dict) else None schema = get_chat_variables_schema(system) if schema: model_dict.setdefault('meta', {})['chat_variables_schema'] = schema diff --git a/backend/open_webui/utils/access_control/__init__.py b/backend/open_webui/utils/access_control/__init__.py index a81aac812a..f7e6806bc9 100644 --- a/backend/open_webui/utils/access_control/__init__.py +++ b/backend/open_webui/utils/access_control/__init__.py @@ -378,9 +378,7 @@ async def check_model_access( raise HTTPException(status_code=403, detail='Model not found') # Enforce access on chained base models - if not await has_base_model_access( - user.id, model_info, user_role=user.role, user_group_ids=user_group_ids - ): + if not await has_base_model_access(user.id, model_info, user_role=user.role, user_group_ids=user_group_ids): raise HTTPException(status_code=403, detail='Model not found') else: if user.role != 'admin': diff --git a/backend/open_webui/utils/automations.py b/backend/open_webui/utils/automations.py index 9ce8084358..50a61909ef 100644 --- a/backend/open_webui/utils/automations.py +++ b/backend/open_webui/utils/automations.py @@ -477,7 +477,7 @@ async def execute_automation(app, automation: AutomationModel) -> None: {'role': 'user', 'content': prompt}, ], 'meta': {'automation_id': automation.id}, - } + }, ), ) diff --git a/backend/open_webui/utils/context_compaction.py b/backend/open_webui/utils/context_compaction.py index a06f7c3c41..3509b00a12 100644 --- a/backend/open_webui/utils/context_compaction.py +++ b/backend/open_webui/utils/context_compaction.py @@ -205,9 +205,7 @@ async def _load_config() -> dict: 'enable': bool(values.get('chat.context_compaction.enable', False)), 'token_threshold': token_threshold, 'token_cap': _parse_positive_int(values.get('chat.context_compaction.token_cap')) or token_threshold, - 'retention_percentage': _clamp_retention_percentage( - values.get('chat.context_compaction.retention_percentage') - ), + 'retention_percentage': _clamp_retention_percentage(values.get('chat.context_compaction.retention_percentage')), 'prompt_template': values.get('chat.context_compaction.prompt_template', '') or '', } @@ -261,14 +259,9 @@ async def get_chat_context_usage(chat: Any, model_id: str | None = None) -> dict for idx in range(len(messages) - 1, -1, -1): usage = messages[idx].get('usage') or (messages[idx].get('info') or {}).get('usage') - input_tokens = ( - (usage or {}).get('prompt_tokens') - or (usage or {}).get('input_tokens') - ) + input_tokens = (usage or {}).get('prompt_tokens') or (usage or {}).get('input_tokens') if isinstance(usage, dict) and input_tokens: - tokens = int(input_tokens or 0) + int( - usage.get('completion_tokens') or usage.get('output_tokens') or 0 - ) + tokens = int(input_tokens or 0) + int(usage.get('completion_tokens') or usage.get('output_tokens') or 0) tokens += _estimate_messages_tokens(messages[idx + 1 :]) return _build_context_usage(tokens, threshold) diff --git a/backend/open_webui/utils/headers.py b/backend/open_webui/utils/headers.py index a847be4243..2f23879c8a 100644 --- a/backend/open_webui/utils/headers.py +++ b/backend/open_webui/utils/headers.py @@ -70,7 +70,9 @@ def custom_headers_require_user_groups(custom_headers: Optional[dict]) -> bool: ) -async def get_user_groups_for_custom_headers(custom_headers: Optional[dict], user: Optional[Any] = None) -> Optional[list]: +async def get_user_groups_for_custom_headers( + custom_headers: Optional[dict], user: Optional[Any] = None +) -> Optional[list]: """Fetch the user's groups only when a header value actually references a groups placeholder.""" if user is None or not custom_headers_require_user_groups(custom_headers): return None diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index cc9357200d..c1b8455bd4 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -3567,11 +3567,7 @@ async def non_streaming_chat_response_handler(response, ctx): } ) - title = ( - await Chats.get_chat_title_by_id(metadata['chat_id']) - if save_to_chat - else '' - ) + title = await Chats.get_chat_title_by_id(metadata['chat_id']) if save_to_chat else '' # Use output from backend if provided (OR-compliant backends), # otherwise generate from response content @@ -3648,11 +3644,7 @@ async def non_streaming_chat_response_handler(response, ctx): except Exception as e: log.debug(f'Error occurred while processing request: {e}') chat_id = metadata.get('chat_id') - if ( - getattr(request.state, 'internal', False) is not True - and chat_id - and is_saved_chat_id(chat_id) - ): + if getattr(request.state, 'internal', False) is not True and chat_id and is_saved_chat_id(chat_id): webui_url = await Config.get('webui.url') await publish_event( request, @@ -5337,11 +5329,7 @@ async def streaming_chat_response_handler(response, ctx): if item.get('status') == 'in_progress': item['status'] = 'completed' - title = ( - await Chats.get_chat_title_by_id(metadata['chat_id']) - if save_to_chat - else '' - ) + title = await Chats.get_chat_title_by_id(metadata['chat_id']) if save_to_chat else '' data = { 'done': True, 'output': output, diff --git a/backend/open_webui/utils/misc.py b/backend/open_webui/utils/misc.py index cff3ad6e40..8e84a1a47c 100644 --- a/backend/open_webui/utils/misc.py +++ b/backend/open_webui/utils/misc.py @@ -194,9 +194,7 @@ def get_output_text(output: list | None) -> str: continue text = ''.join( - str(part.get('text')) - for part in parts - if isinstance(part, dict) and part.get('text') is not None + str(part.get('text')) for part in parts if isinstance(part, dict) and part.get('text') is not None ) if text.strip(): texts.append(text) diff --git a/src/lib/components/calendar/CalendarEventModal.svelte b/src/lib/components/calendar/CalendarEventModal.svelte index 50d96cdccd..e95c30d6e6 100644 --- a/src/lib/components/calendar/CalendarEventModal.svelte +++ b/src/lib/components/calendar/CalendarEventModal.svelte @@ -214,11 +214,23 @@