Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.11.3] - 2026-08-31

### Added

- ♿ **Accessibility mode reaches the menus.** Accessibility mode now marks the menu entry you are pointing at and the model already chosen with a stronger background, across the dropdown menus, their submenus, and the model picker together with its filter and compare controls, so those cues carry the contrast the accessibility guidelines ask for in both themes. [Commit](https://github.com/open-webui/open-webui/commit/a6f9751401589ee73208295b6f6a7f6eae9c1b44), [Commit](https://github.com/open-webui/open-webui/commit/471b5cbbb16c3996c32e68808dde6f8898f64ecd)
- 🔄 **General improvements.** Various improvements were implemented across the application to enhance performance, stability, and security.
- 🌐 **Translation updates.** Translations for Indonesian were enhanced and expanded.

### Fixed

- 💥 **Chat branches stay connected after reloads.** A reply saved under an earlier message now stays listed under that message, so branch arrows, exports, reloads, and later edits keep the whole conversation in view, and chats already saved with that link missing are repaired when opened. [#29299](https://github.com/open-webui/open-webui/issues/29299)
- 🧱 **Upgrades fail clearly instead of starting half updated.** A failed database upgrade now stops at the migration error that caused it, instead of starting anyway and reporting a missing table or column such as 'chat.timer_at' later, which is the upgrade failure seen after moving from 0.11.0, 0.11.1, or 0.11.2. [#29280](https://github.com/open-webui/open-webui/issues/29280)
- 🔤 **Custom interface fonts reach more of the app.** The font chosen in interface settings now applies to dropdowns and other interface text that previously fell back to the standard font. [Commit](https://github.com/open-webui/open-webui/commit/1457000ba66547b24bd98012aa35ac16fd4bc696)
- 🔌 **Disconnect OAuth only where there is OAuth.** The disconnect control on a tool server reached over MCP now appears only where that server signs in through OAuth and an account is connected, rather than on servers that use no sign-in at all. [#29296](https://github.com/open-webui/open-webui/issues/29296)

## [0.11.2] - 2026-08-31

### Added
Expand Down
1 change: 1 addition & 0 deletions backend/open_webui/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def run_migrations():
command.upgrade(alembic_cfg, 'head')
except Exception as e:
log.exception(f'Error running migrations: {e}')
raise


if ENABLE_DB_MIGRATIONS:
Expand Down
5 changes: 4 additions & 1 deletion backend/open_webui/models/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from open_webui.models.access_grants import AccessGrantModel, AccessGrants
from open_webui.models.groups import Groups
from open_webui.models.users import User, UserModel, UserResponse
from open_webui.utils.automations import rrule_interval_seconds
from pydantic import BaseModel, ConfigDict, Field, field_validator
from sqlalchemy import (
JSON,
Expand Down Expand Up @@ -198,6 +197,8 @@ class CalendarEventForm(BaseModel):
@classmethod
def reject_sub_daily_rrule(cls, value: Optional[str]) -> Optional[str]:
if value:
from open_webui.utils.automations import rrule_interval_seconds

try:
interval = rrule_interval_seconds(value)
except ValueError:
Expand Down Expand Up @@ -228,6 +229,8 @@ class CalendarEventUpdateForm(BaseModel):
@classmethod
def reject_sub_daily_rrule(cls, value: Optional[str]) -> Optional[str]:
if value:
from open_webui.utils.automations import rrule_interval_seconds

try:
interval = rrule_interval_seconds(value)
except ValueError:
Expand Down
29 changes: 27 additions & 2 deletions backend/open_webui/models/chats.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,23 @@ def _last_descendant_id(messages: dict, message_id: str) -> str:
message_id = next_id
return message_id

@staticmethod
def _add_child_id_to_parent(messages: dict, parent_id: str | None, child_id: str) -> bool:
parent = messages.get(parent_id) if parent_id else None
if not isinstance(parent, dict):
return False

child_ids = parent.get('childrenIds')
if not isinstance(child_ids, list):
child_ids = []
parent['childrenIds'] = child_ids

if child_id in child_ids:
return False

child_ids.append(child_id)
return True

def _repair_chat_current_id(self, chat: dict) -> bool:
history = chat.get('history')
if not isinstance(history, dict):
Expand All @@ -465,6 +482,12 @@ def _repair_chat_current_id(self, chat: dict) -> bool:
if not isinstance(messages, dict):
return False

changed = False
for message_id, message in messages.items():
if not isinstance(message, dict):
continue
changed = self._add_child_id_to_parent(messages, message.get('parentId'), message_id) or changed

current_id = history.get('currentId')
current_message = messages.get(current_id)
output = []
Expand Down Expand Up @@ -494,7 +517,7 @@ def _repair_chat_current_id(self, chat: dict) -> bool:
history['currentId'] = last_descendant_id
return True

return False
return changed

latest_leaf_id = None
latest_timestamp = -1
Expand All @@ -509,7 +532,7 @@ def _repair_chat_current_id(self, chat: dict) -> bool:
latest_timestamp = timestamp

if not latest_leaf_id or latest_leaf_id == current_id:
return False
return changed

history['currentId'] = latest_leaf_id
return True
Expand Down Expand Up @@ -998,6 +1021,8 @@ def upsert_message_to_history(history: dict, message_id: str, message: dict) ->
'timestamp': message.get('timestamp') or int(time.time()),
}
history['currentId'] = message_id

ChatTable._add_child_id_to_parent(messages, messages[message_id].get('parentId'), message_id)
return messages[message_id]

async def backfill_messages_by_chat_id(self, chat_id: str, user_id: str, messages: dict[str, dict]) -> None:
Expand Down
8 changes: 8 additions & 0 deletions backend/open_webui/routers/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,14 @@ async def load_url_image(data):
return data

if data.startswith('http://') or data.startswith('https://'):
parsed = urlparse(data)
if (
parsed.netloc == urlparse(str(request.base_url)).netloc
and parsed.path.startswith('/api/v1/files/')
and '/content' in parsed.path
):
return await load_url_image(parsed.path)

# Validate URL to prevent SSRF attacks against local/private networks.
# allow_redirects=False prevents redirect-based SSRF: validate_url() is
# called only on the originally-submitted URL; following 3xx redirects
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "open-webui",
"version": "0.11.2",
"version": "0.11.3",
"private": true,
"scripts": {
"dev": "npm run pyodide:fetch && vite dev --host",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@
</div>
</div>

{#if (tools?.[toolId]?.authenticated ?? true) && toolId.startsWith('server:mcp:')}
{#if tools?.[toolId]?.authenticated === true && toolId.startsWith('server:mcp:')}
<div class="shrink-0">
<Tooltip content={$i18n.t('Disconnect OAuth')}>
<button
Expand Down
14 changes: 14 additions & 0 deletions src/lib/i18n/locales/id-ID/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,25 @@
"{{COUNT}} Available Tools": "",
"{{COUNT}} characters": "",
"{{COUNT}} extracted lines": "",
"{{count}} files_one": "{{count}} berkas",
"{{count}} files_other": "",
"{{COUNT}} files": "",
"{{count}} files selected. Only new and modified files will be uploaded. Deleted files will be removed. The folder structure will be mirrored. Continue?_one": "{{count}} berkas dipilih. Hanya berkas baru dan yang dimodifikasi yang akan diunggah. Berkas yang dihapus akan disingkirkan. Struktur folder akan disinkronkan. Lanjutkan?",
"{{count}} files selected. Only new and modified files will be uploaded. Deleted files will be removed. The folder structure will be mirrored. Continue?_other": "",
"{{count}} filters_one": "{{count}} filter",
"{{count}} filters_other": "",
"{{count}} groups_one": "{{count}} grup",
"{{count}} groups_other": "",
"{{COUNT}} hidden lines": "",
"{{COUNT}} members": "",
"{{count}} of {{total}} accessible_one": "{{count}} dari {{total}} dapat diakses",
"{{count}} of {{total}} accessible_other": "",
"{{COUNT}} Replies": "",
"{{COUNT}} Rows": "",
"{{count}} selected_one": "{{count}} dipilih",
"{{count}} selected_other": "",
"{{COUNT}} Sources": "",
"{{count}} users_one": "{{count}} pengguna",
"{{count}} users_other": "",
"{{COUNT}} words": "",
"{{COUNT}}d_time_ago": "",
Expand Down Expand Up @@ -574,6 +581,7 @@
"Completions": "",
"Compress Images in Channels": "",
"Compress uploaded images before sending or storage.": "",
"Computing checksums ({{count}} files)_one": "Menghitung checksum ({{count}} berkas)",
"Computing checksums ({{count}} files)_other": "",
"Concurrent Requests": "Permintaan Bersamaan",
"Config": "",
Expand Down Expand Up @@ -1123,7 +1131,9 @@
"Event title": "",
"Event updated": "",
"Events": "",
"Every {{count}} hours_one": "Setiap {{count}} jam",
"Every {{count}} hours_other": "",
"Every {{count}} minutes_one": "Setiap {{count}} menit",
"Every {{count}} minutes_other": "",
"Every minute": "",
"Exa API Key": "",
Expand Down Expand Up @@ -2201,6 +2211,7 @@
"Reduces the probability of generating nonsense. A higher value (e.g. 100) will give more diverse answers, while a lower value (e.g. 10) will be more conservative.": "",
"Reference Chats": "",
"Refresh": "",
"Refresh requested: {{count}} terminal(s)_one": "Permintaan muat ulang: {{count}} terminal",
"Refresh requested: {{count}} terminal(s)_other": "",
"Refresh Terminals": "",
"Refresh the account email from OAuth on sign-in.": "",
Expand Down Expand Up @@ -2236,6 +2247,7 @@
"Remove Pinned Model": "",
"Remove prompt suggestion": "",
"Remove Selected Model": "",
"Removing {{count}} stale files..._one": "Menghapus {{count}} berkas usang...",
"Removing {{count}} stale files..._other": "",
"Rename": "Ganti nama",
"Renamed to {{name}}": "",
Expand Down Expand Up @@ -2281,6 +2293,7 @@
"Retrieval": "",
"Retrieval Query Generation": "",
"Retrieved {{count}} sources": "",
"Retrieved {{count}} sources_one": "Mengambil {{count}} sumber",
"Retrieved {{count}} sources_other": "",
"Retrieved 1 source": "",
"Retry": "",
Expand Down Expand Up @@ -2581,6 +2594,7 @@
"Start of the channel": "Awal saluran",
"Start Tag": "",
"Start the chat to use this terminal.": "",
"Starting in {{count}} minutes_one": "Mulai dalam {{count}} menit",
"Starting in {{count}} minutes_other": "",
"Starting in 1 minute": "",
"Starting kernel...": "",
Expand Down
20 changes: 15 additions & 5 deletions src/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
@config '../tailwind.config.js';

@theme {
--font-sans:
var(--app-font-family, -apple-system), BlinkMacSystemFont, 'Inter', 'Vazirmatn', ui-sans-serif,
system-ui, 'Segoe UI', Roboto, Ubuntu, Cantarell, 'Noto Sans', sans-serif, 'Helvetica Neue',
Arial, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
--font-primary: var(--font-sans);
--font-secondary: var(--font-sans);

--color-gray-50: oklch(0.98 0 0);
--color-gray-100: oklch(0.94 0 0);
--color-gray-200: oklch(0.92 0 0);
Expand Down Expand Up @@ -37,11 +44,7 @@

@layer base {
html {
font-family:
var(--app-font-family, -apple-system), BlinkMacSystemFont, 'Inter', 'Vazirmatn',
ui-sans-serif, system-ui, 'Segoe UI', Roboto, Ubuntu, Cantarell, 'Noto Sans', sans-serif,
'Helvetica Neue', Arial, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
font-family: var(--font-sans);
}

pre {
Expand Down Expand Up @@ -97,4 +100,11 @@
}
}

@layer utilities {
.font-primary,
.font-secondary {
font-family: var(--font-sans);
}
}

@custom-variant hover (&:hover);
Loading