Commit graph

9440 commits

Author SHA1 Message Date
G30
ffe6ab9869
fix: stop the note editor date reading as a button (#29708) 2026-09-06 15:31:47 -04:00
Classic298
a3c90e5aac
fix: blank chat messages on iOS home screen apps and in-app browsers (#29734)
Chat messages are virtualized with content-visibility: auto, which WebKit paints incorrectly and can leave blank. #26805 skipped that on Safari by looking for the Safari token in the user agent, but iOS in-app browsers, home screen apps and iPadOS desktop-class standalone windows send no such token, so those users still get empty assistant responses.

Check the navigator vendor string as well, which every WebKit surface reports regardless of user agent. The user agent check stays, because non-Apple WebKit ports can compile a different vendor string while shipping the same paint bug.

That earlier fix also withheld the message-listitem class entirely, and the class doubles as the styling hook the sidebar hover preview reaches through, so hover previews have rendered at full chat spacing and width on Safari since v0.11.0. Only the content-visibility rule is gated now, on its own class, and the hook stays on every message. Safari hover previews become compact like every other engine.

Verified across fourteen engine cases: virtualization is off on every Apple WebKit surface, unchanged on Chromium, Firefox and Android, the hover preview overrides apply again on Safari, and the screenshot export still captures every message on both.

Refs #26712, #29688
2026-09-06 15:21:09 -04:00
Timothy Jaeryang Baek
85b11a4f35 refac
Some checks failed
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args: free_disk:false name:main suffix:]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_CUDA=true USE_CUDA_VER=cu126 free_disk:true name:cuda126 suffix:-cuda126]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_CUDA=true free_disk:true name:cuda suffix:-cuda]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_OLLAMA=true free_disk:false name:ollama suffix:-ollama]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_SLIM=true free_disk:false name:slim suffix:-slim]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args: free_disk:false name:main suffix:]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_CUDA=true USE_CUDA_VER=cu126 free_disk:true name:cuda126 suffix:-cuda126]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_CUDA=true free_disk:true name:cuda suffix:-cuda]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_OLLAMA=true free_disk:false name:ollama suffix:-ollama]) (push) Has been cancelled
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_SLIM=true free_disk:false name:slim suffix:-slim]) (push) Has been cancelled
Python CI / Ruff Format (3.11) (push) Has been cancelled
Python CI / Ruff Format (3.12) (push) Has been cancelled
Frontend Build / Format & Build (push) Has been cancelled
Frontend Build / Unit Tests (push) Has been cancelled
Create and publish Docker images with specific build args / merge (map[name:cuda suffix:-cuda]) (push) Has been cancelled
Create and publish Docker images with specific build args / merge (map[name:cuda126 suffix:-cuda126]) (push) Has been cancelled
Create and publish Docker images with specific build args / merge (map[name:ollama suffix:-ollama]) (push) Has been cancelled
Create and publish Docker images with specific build args / notify-helm-charts (push) Has been cancelled
Create and publish Docker images with specific build args / copy-to-dockerhub (, main) (push) Has been cancelled
Create and publish Docker images with specific build args / copy-to-dockerhub (-cuda, cuda) (push) Has been cancelled
Create and publish Docker images with specific build args / copy-to-dockerhub (-cuda126, cuda126) (push) Has been cancelled
Create and publish Docker images with specific build args / copy-to-dockerhub (-ollama, ollama) (push) Has been cancelled
Create and publish Docker images with specific build args / copy-to-dockerhub (-slim, slim) (push) Has been cancelled
Create and publish Docker images with specific build args / merge (map[name:main suffix:]) (push) Has been cancelled
Create and publish Docker images with specific build args / merge (map[name:slim suffix:-slim]) (push) Has been cancelled
2026-09-04 23:34:32 -04:00
Timothy Jaeryang Baek
54a7a7a7ce refac 2026-09-04 22:56:00 -04:00
Timothy Jaeryang Baek
3facfa61d4 refac 2026-09-04 22:53:37 -04:00
Classic298
c2e6766ed8
Move the vitest tests to the open-webui/tests suite (#29677)
The colocated vitest files (shortcuts, the colon fence marked extension) now
live in open-webui/tests under frontend/, next to the rest of the regression
suite, where they run against the source of any ref through the shared
regression workflow. This removes the copies here; the unit-tests workflow job
and the test:frontend script stay and pass with no tests.

src/lib/utils/_template_old.ts goes as well: it imports vitest but its name
never matched the test glob, so those tests have not run since they were added.
2026-09-04 19:43:48 -04:00
Timothy Jaeryang Baek
7bf898f461 refac 2026-09-04 19:21:49 -04:00
Timothy Jaeryang Baek
67ac1a4e93 refac 2026-09-04 19:12:41 -04:00
Timothy Jaeryang Baek
858ab727d2 refac 2026-09-04 18:31:59 -04:00
Timothy Jaeryang Baek
7b6562e335 refac 2026-09-04 17:39:34 -04:00
Classic298
323f8da202
fix: show relevance badge for single-source citations (#29647)
A response with exactly one citation never showed its relevance badge, even though the source carried a perfectly valid score. Adding a second citation made the badge appear for that same source, so the score looked like it came and went at random.

calculateShowRelevance hides relevance when a result set mixes distance metrics (cosine in -1..1 next to unbounded L2), since those numbers are not comparable. With a single distance that check degenerates: distances.length - 1 is 0, so the "all but one are out of range" clause matches whatever the value is, and the score is hidden. A lone distance cannot be a mix of two metrics, so it now returns before the outlier check runs.

Sets of two or more distances behave exactly as before, mixed-metric sets are still suppressed.

Fixes #29646
2026-09-04 17:17:14 -04:00
G30
4f419627f8
fix: remove the stray background band from the Attach Webpage modal footer (#29664) 2026-09-04 17:16:47 -04:00
G30
b49db6f287
fix: stop the browser back button creating extra notes (#29645) 2026-09-04 15:54:10 -04:00
G30
bd0b3875ba
i18n: blank redundant en-US translation values (#29318) 2026-09-04 11:58:50 -04:00
spoofy
bfed5f8950
i18n: unify es-ES terminology on common loanwords (#29593)
Adopts the loanwords normally used in Spanish-language developer and AI
interfaces for three terms the locale currently calques, and applies each
one consistently across the file.

- prompt:   Indicador -> Prompt   (74 strings)
- pipeline: Tubería   -> Pipeline (14 strings)
- delete:   Borrar    -> Eliminar (62 strings), matching the rendering the
            locale already uses for "remove" and closing the Borrar /
            Eliminar split that applied both words to the same action
- Admin -> Administrador, Email -> Correo electrónico (3 strings)

"Indicador" means indicator or gauge and is not how Spanish-language AI
tools refer to a prompt. "Tubería" is a physical pipe; the file already
hedged once with "Tuberías (Pipelines)". Gender agreement is updated where
it changes, since Pipeline is masculine and Tubería feminine.

Before this change the locale rendered "delete" as Borrar in 34 strings and
Eliminar in 28, with no distinction in meaning between them.

This changes wording contributed by the Spanish community rather than
fixing defects, so it is a terminology decision rather than a correctness
fix, and is kept separate from the translation work for that reason.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 11:51:51 -04:00
Alexey Shabalin
ffd4c48b94
i18n: fix incorrect Russian translations (#29625)
Two entries lost their interpolation placeholder, so they render
literally instead of being substituted:

- "{{ models }}" had the placeholder name itself translated
- the 50-word summary prompt replaced {{topic}} with a bracketed note

The rest change the meaning or contradict neighbouring strings:

- "Enter Key Behavior" was read as the verb "enter", turning the label
  for how the Enter key behaves into "type in the behaviour key", while
  its own description already explains the setting correctly
- "Regenerate Menu" was read as "refresh the menu" rather than the menu
  of regenerate actions its description describes
- "Enter reasoning effort" was not meaningful Russian
- "Enter Bing Search V7 Subscription Key" mentioned an endpoint that the
  source string does not
- "Web Search in Chat" called the feature a search engine
- "Enter Application DN" said ND; "Enter Bocha Search API Key" said APi
- "Toast Notifications for New Updates" dropped "new" and used the wrong
  form of the preposition
- "Enter Top K Reranker" used a term its own label does not, and
  "Select a reranking model engine" differed from every other reranking
  string
- two of the four iframe sandbox switches did not follow the wording of
  the other two
- "Follow-Up Auto-Generation" capitalised a word mid-phrase

Only values changed; the keys and their order are untouched.
2026-09-04 11:49:24 -04:00
G30
cc14f3dac0
fix: report version check failures instead of claiming latest (#29626)
GET /api/version/updates returned the running version as latest whenever
the GitHub request failed, so an instance that cannot reach GitHub
reported itself up to date however far behind it was. The exception was
logged at debug, below the default level, so nothing recorded that the
check never happened.

The failure path now returns latest: None and logs at warning.

A null latest cannot be passed to compareVersion as it stood.
current.localeCompare(null) coerces to the string "null", and "0.10.2"
sorts before it, so the function returned true. The backend change alone
would have turned a false (latest) into a false update-available plus a
toast, so the guard is part of the fix.

The three callers stop substituting the running version in their catch,
and the two badge surfaces gain a third state. When latest is unknown
the badge is plain text, since there is no release to link to.

Admin Settings > General was wrong in a worse way than reported: it
initialised updateAvailable false with latest set to the running
version, and never checked on mount, so it claimed (latest) having made
no request at all. It now matches About.svelte, which starts unknown and
checks on mount.

Closes #29580
2026-09-04 11:39:52 -04:00
G30
0b804c5316
feat: shift quick delete for notes in list and grid views (#29635) 2026-09-04 11:27:57 -04:00
spoofy
18a48cffba
i18n: add Russian and Ukrainian translations for new UI strings (#29601) 2026-09-04 00:57:21 -04:00
spoofy
eb870cd9e1
i18n: translate newly added Spanish UI strings (#29599) 2026-09-04 00:57:09 -04:00
Classic298
59f9502240
fix: install black's transitive deps in the pyodide code formatter (#29503)
Saving any tool or function in the admin UI threw "ModuleNotFoundError:
No module named 'click'" in the browser, even on a fresh tool with no
custom code, because the click name never appears in user code at all.

The in-browser formatter runs black through a Pyodide/micropip worker.
black needs click, mypy_extensions, pathspec, platformdirs and pytokens
at import time, but the vendored pyodide-lock.json records none of
these as black's dependencies, and micropip only walks a locked
package's declared deps when install() is given explicit constraints,
which this worker never does. So only black itself ever got installed.

Requesting the five packages explicitly alongside black fixes it
without touching the worker or the lock file.
2026-09-04 00:45:58 -04:00
Timothy Jaeryang Baek
8aa25dd358 chore: i18n 2026-09-03 20:36:27 -04:00
Timothy Jaeryang Baek
237b11c6d9 refac 2026-09-03 20:26:40 -04:00
Classic298
7ab8b76449
i18n: complete the German (de-DE) translation (#29590)
Ten strings were still untranslated in de-DE, so German users saw raw English keys in the settings sidebar and in the interface settings. The settings group headings (Basics, Services, Preferences, Data, AI, Quality, Experience) all rendered in English above otherwise German tab names, plus the font family label and its description, and the multi-file upload failure toast in a knowledge base.

All ten now have German values, chosen to match the terminology the catalog already uses: AI as KI, Services as Dienste (matching Dienstkonto and the existing service endpoint strings), Interface as Benutzeroberfläche in the font description, and the third-person descriptive voice the neighbouring setting descriptions use. Experience is rendered as Benutzererlebnis rather than Darstellung because that group covers audio as well as interface and images. Both interpolation placeholders in the upload toast are preserved.

Only de-DE is touched. No key was added, removed or reordered, and no already-translated string was changed. The catalog now has no empty values left.
2026-09-03 20:23:38 -04:00
spoofy
63c61b7d39
i18n: complete es-ES translation and fix defective strings (#29592)
Fills the 917 empty strings in the es-ES locale and repairs 94 existing
entries that rendered incorrectly. No keys are added or removed, and the
terminology chosen by the Spanish community is preserved throughout: new
strings reuse the glossary already present in the file.

Filled strings:
- Reuse existing renderings so each English term keeps one Spanish form
  (chunk -> Fragmento, knowledge base -> Base de Conocimiento,
  workspace -> Espacio de Trabajo, skill -> Habilidad).
- Include the settings sidebar group headers added in 006f95ee5
  (Basics, Services, Preferences, Data, AI, Quality, Experience), which
  were otherwise falling back to English in the settings modal.
- Add real grammatical plural forms for every one/many/other variant.
  Spanish requires the `many` CLDR category, which English does not have.
- Preserve every {{placeholder}}, backtick, URL, HTML tag and CLI flag.

Repaired strings:
- 4 broken interpolations, including "Deleted {{name}}", whose placeholder
  had itself been translated to {{nombre}} and so rendered literally.
- 6 plural groups whose values carried the i18next key suffix as visible
  text (e.g. "{{count}} seleccionados_únicos"), and one where "_one" had
  been translated as the adjective "únicas".
- "Reset" now reads Restablecer rather than Reiniciar ("restart"), which
  misdescribed destructive actions such as Reset Vector Storage/Knowledge.
- "Access" (Acceso) separated from "Permissions" (Permisos); the *Access
  family was previously split between the two.
- "Chats Public Sharing" and "Chats Open Sharing" no longer render
  identically in the group permissions panel.
- "You" corrected to "Tú"; unaccented "Tu" is the possessive "your", and
  this string labels every user message bubble.
- "Channels" corrected from the singular "Canal".
- ~49 misspellings and missing accents (Conexxión, Interprete, Publicamente,
  Busqueda, Incrustración, Añador, Wev, actualiada, mantentrá).

Verified: 0 empty strings, key set identical to dev, 0 placeholder
mismatches, prettier --check passes, and all strings render correctly
through i18next 23.16.8 using the application's own options.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 20:23:24 -04:00
Timothy Jaeryang Baek
f677fdbf50 refac 2026-09-03 20:22:32 -04:00
spoofy
ca26632a2a
i18n: translate settings sidebar group headers (ru-RU, uk-UA) (#29591)
The settings navigation group labels added in 006f95ee5 (Basics,
Services, Preferences, Data, Experience, AI, Quality) were left
empty in every locale, so ru-RU and uk-UA fell back to the English
key text. Fill them for both locales.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 16:06:37 -05:00
Timothy Jaeryang Baek
006f95ee59 chore: i18n 2026-09-03 16:18:59 -04:00
Timothy Jaeryang Baek
cffd734a18 refac 2026-09-03 16:18:39 -04:00
spoofy
065002b49e
i18n: complete ru-RU and uk-UA translations (#29586)
Fill all remaining untranslated strings so both locales reach full
coverage:
- ru-RU: 967 strings translated
- uk-UA: 2110 strings translated

ru-RU also aligns terminology with the existing translations
(webhook -> вебхук, sub-agent -> субагент, reranker -> реранкер,
chunk -> чанк, parsing -> розбір/разбор) and standardizes "web search"
to «Поисковая система» across the whole file.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 15:27:03 -04:00
Anthony Chen
2831207d40
i18n: update Traditional Chinese entries - #29514 (#29549)
* add: new translations

* Update translations in zh-TW locale
2026-09-03 14:57:14 -04:00
Cyp
a9408ede42
i18n: update Korean translations - #29555 (#29556)
* i18n: update Korean translations

* Update Korean translation

---------

Co-authored-by: bglee <bglee@hct.co.kr>
2026-09-03 14:55:06 -04:00
Kylapaallikko
38cf156849
Update fi-FI translation.json (#29584)
Added missing translations.
2026-09-03 14:54:47 -04:00
Anthony Chen
dfc24dfb43
add: new translations (#29514) 2026-09-01 22:11:10 -04:00
Badar Rahman
a3a72068c2
i18n: add missing Indonesian (id-ID) translations for v0.11.1 aligned with en-US catalog (#29294)
Co-authored-by: DarRahman <darrahman@users.noreply.github.com>
2026-08-31 10:27:38 -04:00
Timothy Jaeryang Baek
1457000ba6 refac 2026-08-31 10:27:01 -04:00
Timothy Jaeryang Baek
471b5cbbb1 refac 2026-08-31 01:41:17 -04:00
Timothy Jaeryang Baek
a6f9751401 refac 2026-08-31 01:37:36 -04:00
Timothy Jaeryang Baek
2daa610cba refac 2026-08-31 01:28:40 -04:00
Classic298
89716ea880
perf: stop scanning every socket.io payload for binary data (#28180)
* perf: stop scanning every socket.io payload for binary data

Every socket.io event the backend sends was first walked recursively to check whether any value was a bytes object needing binary attachment framing. Open WebUI never emits binary, so the walk always came back empty and the work was thrown away. It has no early exit and allocates at every level, so it scaled with the full size of the message, and the messages are the big ones: chat streaming re-emits the whole assistant message on every update, note collaboration sends document state as a JSON array with one entry per byte. With the Redis manager it ran once per instance per emit on top of that, since every instance builds its own copy of the packet.

The server now installs a Packet subclass with binary events off, through python-socketio's own serializer hook, the same mechanism its msgpack serializer uses. Inbound binary attachments are decoded to int lists rather than refused, so the one frontend path that sends a raw Uint8Array keeps working and handlers can still echo client data straight back out. One scan remains in multi-instance setups: python-socketio's Redis manager calls it on the base Packet class directly, where the serializer hook cannot reach.

Measured per encode:

| payload | before | after |
|---|---|---|
| chat completion re-emit (7.5 KB JSON) | 30 us | 13 us |
| collaborative document state (292 KB JSON) | 9.0 ms | 1.7 ms |

With ENABLE_ORJSON=true, where the scan is nearly the whole encode cost: 20 us to 2.3 us, and 7.8 ms to 0.14 ms.

Closes #28164

* fix: match the other Yjs emits and send the full state as an array

Collaboration.ts sent the initial full-document state as a raw Uint8Array while the other two Yjs emit sites convert with Array.from first. socket.io framed that one as a binary attachment, so with the JSON-only packet class the server turns it into a list of ints and re-broadcasts it as JSON: a 10240-byte state update becomes 36561 JSON characters. Converting at the emit site keeps the wire form uniform across all three sites.

Also trims the JSONOnlyPacket docstring, which claimed attachments already arrive as int lists when the override is what converts them, and annotates the new reconstruct_binary parameters.
2026-08-31 01:22:06 -04:00
Timothy Jaeryang Baek
5d74df95ed chore: format 2026-08-31 01:11:41 -04:00
Classic298
b75e2670b7
fix: keep a custom recurrence rule when the editor reopens it (#29260)
Loading an automation whose rule the visual controls cannot represent switched the schedule to Custom but left the bookkeeping the seeding block reads on the previous value, so that block immediately replaced the rule with a freshly built default. The rule was lost when the editor opened, before anything was saved, and cloning carried the default across as well. Recording the switch alongside it leaves the stored rule in place.

Verified in a browser against the same build without this line: a minutely rule and a yearly rule now survive reopen and save byte for byte, cloning keeps the original, and every schedule the editor itself produces, along with switching to Custom by hand, behaves exactly as before.
2026-08-31 00:08:28 -05:00
TOM
949876f9c0
fix(i18n): disable key/ns separator splitting at runtime to match i18next-parser config (#29161) 2026-08-31 00:54:08 -04:00
Classic298
188fc83a79
fix: surface files the browser cannot read during a knowledge base directory sync (#29135)
* fix: surface files the browser cannot read during a knowledge base directory sync

Syncing a local folder into a knowledge base could fail with nothing but "Error accessing directory": no failing file name, no network request, no server log, and no console output either, because production builds strip console.error. On Windows this happens once the absolute path of a file passes the platform limit, at which point the browser refuses to open a file it just listed.

The directory scan now handles that per file. It names the first failing path and how many files are affected, and stops before anything is uploaded. Stopping is the point: a file missing from the manifest is treated as deleted by the sync, so continuing would remove the knowledge base copy of a file that still exists on disk.

Dragging a folder in hit the same failure and reported nothing at all, and the Firefox picker path returned its promise without awaiting it, so a rejection escaped the error handler and surfaced only as an unhandled rejection. Both report through the existing handler now, and production builds keep console.error so the underlying exception stays visible.

* fix: narrow the change to the silent drag-and-drop folder failure

Dropping a folder onto a knowledge base did nothing at all when the browser refused to open one of the files inside it: the rejection escaped the async drop listener, so the user got no toast, no upload and no clue why. The listener now routes that failure through the same error handler the directory picker already uses, so one path and one message cover both ways of adding a folder.

The rest of the branch is reverted. Dropping `console.error` from the esbuild `pure` list un-stripped 597 call sites across 103 files from every production bundle, which is a repo-wide logging policy change that needs its own argument. The picker-side collect-and-count machinery only reworded a toast the existing catch already showed, and the Firefox `return await` fix is a different bug in a different path.
2026-08-31 00:45:26 -04:00
Timothy Jaeryang Baek
e8bdbd716b refac 2026-08-31 00:33:43 -04:00
Timothy Jaeryang Baek
7a11154182 refac 2026-08-31 00:32:46 -04:00
G30
95032b6c61
fix: let the model defaults capability and prompt suggestion sections scroll (#29235) 2026-08-31 00:11:34 -04:00
Timothy Jaeryang Baek
84d0940da1 refac 2026-08-31 00:11:04 -04:00
G30
9a669197c8
fix: let setting row controls shrink so long values do not squeeze the label (#29229) 2026-08-31 00:06:37 -04:00
Timothy Jaeryang Baek
09163ccc73 refac 2026-08-31 00:06:05 -04:00