Commit Graph
800 Commits
Author SHA1 Message Date
Timothy Jaeryang Baek 21366fa1b1 refac 2026-08-25 14:19:58 -04:00
Timothy Jaeryang Baek 20f35d157b refac 2026-08-25 14:14:13 -04:00
Timothy Jaeryang Baek a9a802d95f refac 2026-08-24 19:48:12 -04:00
Timothy Jaeryang Baek 06e7aac219 refac 2026-08-24 19:05:21 -04:00
G30 2978a03c68 fix: restore the model avatar reset option in the model editor (#29007) 2026-08-24 19:02:22 -04:00
G30 f2313d0c72 fix: keep the workspace tab counts in sync with each section's list (#28983) 2026-08-24 17:36:12 -04:00
Timothy Jaeryang Baek a914868e3c refac 2026-08-24 17:25:33 -04:00
G30 16b20c651d fix: restore per-item retrieval settings in the model editor knowledge section (#27686) 2026-08-24 07:34:30 -04:00
G30 528259695c fix: key selected item lists in model editor selectors to stop checkbox state reuse (#28837) 2026-08-20 12:57:39 -07:00
Timothy Jaeryang Baek 33dff414e8 refac 2026-08-19 16:35:49 -07:00
Classic298 3df485582d fix: reject skill IDs that are not URL path safe (#27660)
A skill ID goes straight into the path of every mutating skill endpoint (/api/v1/skills/id/{id}/...), but create only replaced spaces with hyphens. An ID containing a "/" was stored verbatim as the primary key, so the route never matched, the request fell through to the SPA static mount and the client got 405 Method Not Allowed. The skill could not be opened, edited, toggled or deleted, by admins either, and since skill.name is UNIQUE it could not be recreated under a corrected ID. Percent-encoding does not help: uvicorn decodes the path before Starlette routes it, so the only remaining fix was a direct database write.

Create now rejects any ID outside [a-z0-9_-] with 400 instead of silently storing an unreachable one. Two frontend paths that fed unsanitized IDs into it are fixed as well: the manual "Skill ID" field, which was bound with no sanitization at all and is the path that reproduces on every version, and the markdown import, which put the raw frontmatter name into the ID before opening the editor in clone mode, where the reactive slugify is disabled.

Existing rows with an unreachable ID are not repaired here; rewriting a primary key would also have to re-point the access grants keyed on it.

Fixes #27655
2026-08-17 00:52:16 -06:00
Classic298 1756c9d5d2 fix: default pinned models stop applying after a user's first page load (#28069)
Changing "Default Pinned Models" in admin settings had no effect for anyone who had already opened Open WebUI once. The sidebar copied the admin default into that user's own settings the first time it rendered and saved it to the server, which marked them as having customized their pins, so every later change to the default was ignored for them. Merely loading the page was enough, the user never had to touch a pin.

The default is now resolved for display only, through a shared store that falls back to the admin list while the user has no pins of their own, the same way default models already work. Nothing is written to the user's settings until they actually pin, unpin or reorder something, at which point their choice takes over for good. Unpinning everything still persists an empty list rather than snapping back to the default.

Users whose settings were already overwritten by the old behaviour keep that copy, since a stored pin list cannot be told apart from a deliberate one.

Fixes a drag-reorder path that mixed sidebar positions with stored ones, and stops the sidebar section reopening itself after any unrelated settings change.
2026-08-17 00:22:51 -06:00
Timothy Jaeryang Baek 0f821398ca refac 2026-08-14 23:52:13 -06:00
Timothy Jaeryang Baek 1b39ff352a refac 2026-08-14 23:50:34 -06:00
Timothy Jaeryang Baek 4465f52a3e refac 2026-08-13 18:13:43 -06:00
Timothy Jaeryang Baek 2649e3305c refac 2026-08-13 16:42:10 -06:00
G30 e58245d5b4 fix: place model editor capability checkboxes directly before their labels (#27788) 2026-08-11 11:13:04 -06:00
Timothy Jaeryang BaekandClassic298 c8f8fa451a a11y
Co-Authored-By: Classic298 <27028174+Classic298@users.noreply.github.com>
2026-08-11 01:25:20 -06:00
Timothy Jaeryang Baek 385d08bea5 refac 2026-08-10 19:42:05 -06:00
Timothy Jaeryang Baek d4461bd6f3 refac 2026-08-10 18:52:18 -06:00
Timothy Jaeryang Baek 8fbfd14a8b refac 2026-08-10 01:38:32 -06:00
Timothy Jaeryang Baek 810378c0b8 refac 2026-07-27 19:39:36 -04:00
Timothy Jaeryang Baek 75e54bf46b refac 2026-07-27 01:21:00 -04:00
Classic298 7e96c53a20 feat: multiselect valve input type with static or dynamic options (#26884)
Adds a multiselect input type for Valves and UserValves so plugin authors can let users pick multiple values from static or runtime-resolved options instead of maintaining comma-separated text fields with hardcoded allowed-value lists in the description.

ENABLED_ITEMS: list[str] = Field(
    default=["foo"],
    json_schema_extra={"input": {"type": "multiselect", "options": "get_item_options"}},
)

@classmethod
def get_item_options(cls):
    return [{"value": "foo", "label": "Foo"}, {"value": "bar", "label": "Bar"}]

Options accept the same shapes as the existing select input: either a static list (strings or {value, label} dicts) or a classmethod name resolved at request time (including __user__ context for UserValves). No backend changes are needed because resolve_valves_schema_options already resolves options independently of the input type.

The new MultiSelect component follows the existing Select portal dropdown pattern and renders checkbox rows that stay open while toggling, with the selected labels shown in the trigger. Values bind as a real string array end to end: the array-to-comma-string conversions in the chat controls valves panel and the valves modal are skipped for multiselect fields, so the stored valve is a native list[str] validated by Pydantic.

Requested in #26848.
2026-07-27 01:11:38 -04:00
Timothy Jaeryang Baek 6732852ce6 refac 2026-07-27 01:05:52 -04:00
Timothy Jaeryang Baek 57e60423b9 refac 2026-07-27 00:27:38 -04:00
Timothy Jaeryang Baek 20647bd2d5 chore: format 2026-07-27 00:12:47 -04:00
G30 771540f3de feat: sortable title and updated at columns on the knowledge workspace page (#27457) 2026-07-26 18:19:31 -04:00
Timothy Jaeryang Baek 1f0dc90abe refac 2026-07-26 18:06:03 -04:00
Classic298 2725ae6d6c fix: expose Checkbox as a checkbox with a name and state (WCAG 4.1.2) (#27494)
On latest `dev`, `common/Checkbox.svelte` renders a `<button type="button">` containing only `aria-hidden="true"` SVGs. It has no `role`, no `aria-checked` and no accessible name, and the component has no `$$restProps` spread, so a caller cannot supply a name either.

Assistive technology announces every one of these as an unnamed "button". A screen reader user cannot tell that the control is a checkbox, cannot tell whether it is on or off, and cannot tell what it toggles. The visible label is always an unassociated sibling element, for example `Capabilities.svelte` puts it in a preceding `<div>` with no `id`, and `Groups/Users.svelte` puts it in a different table cell from the checkbox.

Breaks WCAG 4.1.2 Name, Role, Value (Level A) on all three counts at once.

Fix: expose `role="checkbox"` and `aria-checked` on the control, add an `ariaLabel` prop, and pass the label text that is already in scope at each call site. `aria-checked` mirrors the component's existing icon logic exactly, so the indeterminate dash reports `mixed` rather than `false`. The `ariaLabel={ariaLabel || undefined}` shape matches the sibling `common/Switch.svelte`. Every label expression is the same one that renders the visible text next to the checkbox, so the accessible name always matches what is on screen.

Three call sites are deliberately left out of this PR, because they nest `Checkbox` inside another `<button>`, which is invalid HTML and independently broken:

- `workspace/Knowledge/KnowledgeBase.svelte` — the Checkbox's `on:change` sets `includeContent = true` and then the same click bubbles to the outer button, which flips it back with `includeContent = !includeContent`. Clicking the checkbox square is a no-op today, only the text label works. Giving it a confident name would advertise a control that does nothing.
- `workspace/common/MemberSelector.svelte` (two instances) — the inner Checkbox has no `on:change` at all and only works because its click bubbles to the row button. Naming it would create two focusable controls per row with the same name.

Both need the nesting resolved first, so that the row button carries the checkbox semantics. That is a behavioural fix and belongs in its own PR.

Severity: Serious. Affects model capabilities, default features, builtin tools, tool/filter/skill/action selectors and group membership.

### Contributor License Agreement

<!--
🚨 DO NOT DELETE THE TEXT BELOW 🚨
Keep the "Contributor License Agreement" confirmation text intact.
Deleting it will trigger the CLA-Bot to INVALIDATE your PR.

Your PR will NOT be reviewed or merged until you check the box below confirming that you have read and agree to the terms of the CLA.
-->

- [x] By submitting this pull request, I confirm that I have read and fully agree to the [Contributor License Agreement (CLA)](https://github.com/open-webui/open-webui/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT), and I am providing my contributions under its terms.

> [!NOTE]
> Deleting the CLA section will lead to immediate closure of your PR and it will not be merged in.
2026-07-26 17:37:06 -04:00
Timothy Jaeryang Baek 212eec408c refac 2026-07-24 01:44:30 -04:00
Timothy Jaeryang Baek ce831f7b85 refac 2026-07-24 01:25:52 -04:00
Timothy Jaeryang Baek 8cbb7f765c refac 2026-07-24 00:47:12 -04:00
Timothy Jaeryang Baek 381ababeba refac 2026-07-24 00:40:21 -04:00
Timothy Jaeryang Baek 49abfbdd15 refac 2026-07-23 13:18:04 -04:00
Timothy Jaeryang Baek 48625e657f refac 2026-07-23 03:54:19 -04:00
Timothy Jaeryang Baek 1428a4ddce refac 2026-07-20 21:44:12 -04:00
Timothy Jaeryang Baek f192657dc9 refac 2026-07-17 06:35:24 -04:00
Timothy Jaeryang Baek 9281adc564 refac 2026-07-17 06:34:17 -04:00
Timothy Jaeryang Baek fd07e3a8e3 refac 2026-07-17 06:30:04 -04:00
Timothy Jaeryang Baek ff49217206 refac 2026-07-17 06:22:15 -04:00
Timothy Jaeryang Baek 1bf05ebc7d refac 2026-07-17 06:06:23 -04:00
Timothy Jaeryang Baek cda5bdb9d4 refac 2026-07-17 05:51:39 -04:00
Timothy Jaeryang Baek ea2e3d0afc refac 2026-07-17 05:48:41 -04:00
Timothy Jaeryang Baek 437c06c479 refac 2026-07-17 05:46:09 -04:00
Timothy Jaeryang Baek d027a32ed1 refac 2026-07-17 05:40:40 -04:00
Timothy Jaeryang Baek 21e180182a refac 2026-07-17 05:34:00 -04:00
Timothy Jaeryang Baek d0bea60581 refac 2026-07-17 05:31:32 -04:00
Timothy Jaeryang Baek 421da67446 refac 2026-07-17 05:15:09 -04:00
Timothy Jaeryang Baek 5424ac5891 refac 2026-07-17 05:09:29 -04:00