Releases: Classic298/open-webui-plugins
Release list
v1.0.27
v1.0.27
Inline Visualizer v2.2.0
Important
THE BIG ONE:
Your text is back — and a new Offline mode
On Open WebUI 0.10.x the visualization rendered fine but everything you wrote around it vanished — intro, explanation, all of it (#60). That's fixed, the hiding engine was rebuilt around one rule: never sacrifice your text. And for air-gapped and privacy-focused instances there's a new offline security level: zero outgoing connections, with a README tutorial for self-hosting the chart libraries on your own server. 🚀
Added
- New
offlinesecurity level — zero outgoing connections, period. Like Strict, but even the three chart-library CDNs are blocked: the visualization can only load scripts from your own Open WebUI server. External images, fonts, and media stay blocked too. Made for air-gapped networks and privacy-focused setups. - Performance Improvement: 🚀 The Strict and Balanced security headers are assembled once at startup instead of on every render — same output, less work per visualization.
- Self-hosting tutorial in the README — how to keep Chart.js, D3, ECharts & friends working in
offlinemode: download the library files once, drop them into Open WebUI's/static/iv-libs/folder (Docker recipe included), and pointSKILL.mdat the local copies. Visualizations that don't use a library work inofflinemode with zero setup. - Accidental hiding now fixes itself. Whatever the plugin hides in the chat is re-checked on every update and brought back the moment it no longer needs to be hidden — after message edits, re-renders, or a wrong guess about an incoming marker. Previously, once something was hidden it stayed hidden for good.
Fixed
- Entire response hidden on Open WebUI 0.10.x (#60). The visualization rendered fine, but all the text around it — the intro before and the explanation after — disappeared. Cause: Open WebUI 0.10 places the raw visualization source and your prose inside the same container, and the old logic hid that whole container. Happened every time, including when reopening finished chats. Thanks to @NC-Channel-Coder for the report and the perfect repro.
- Second visualization in the same message failing to render. Multiple visualizations in one response now coordinate with each other instead of tripping each other up.
- Text on the same line as a marker being destroyed.
Here is the chart: @@@VIZ-STARTand@@@VIZ-END And that's the takeaway.now keep their words — only the marker itself disappears. - A code example hijacking the visualization. A documentation snippet containing a marker pair used to get rendered in the iframe instead of the real visualization — which was then hidden and never shown anywhere. A marker mentioned in inline code could even hide the rest of the message.
- Sentences legitimately ending in
@@@disappearing forever. - Two visualizations back-to-back leaking raw source. When one block ended and the next began without text in between, the second one's source code could show up as plain text in the chat.
Changed
- Hiding rewritten around one rule: never sacrifice your text. The plugin now only hides something outright when everything inside it belongs to the visualization; anything that also contains your text is cleaned up more carefully instead. Images, dividers, and form elements sitting near a visualization are never touched.
- Markers inside code are treated as documentation, not instructions. If a message talks about
@@@VIZ-START … @@@VIZ-ENDin a code block or inline code, that's now simply displayed as code — it no longer triggers hiding or rendering. - Smarter handling of a trailing
@@@. Text ending in@@@is only treated as a possible incoming marker right at the live stream's tail, while the visualization is still being written. Everywhere else it's just text — and a wrong guess un-hides itself right away. - Late re-renders can no longer bring hidden source code back. The cleanup that runs after a visualization finishes now stays active and re-hides anything the chat restores afterwards.
Prune v0.10.10
Added
- See exactly what a Preview would delete. Every nonzero category on the
/prunepage now expands into a paginated list of the actual records behind the number — ids, owners, and titles, 50 or 100 per page — and the whole list can be exported as JSON for an audit trail. Exports larger than 10,000 items ask for confirmation first. Contributed by @FBH93 (#61) — thank you! - Cancel a running pass. A Cancel button appears on the manual page while a Preview or Execute is running (with a matching API endpoint). Cancellation is deliberately gentle: the pass stops at the next batch boundary, never mid-transaction — anything already deleted stays deleted, nothing is left half-done, and simply re-running finishes the job. A stale cancel can never abort a later run.
Fixed
- The JSON export could silently miss records on PostgreSQL. Detail pages had no fixed ordering, so page boundaries could shift between requests and drop rows from an export. Pages are now ordered by primary key — a full export walk is complete and duplicate-free.
- Full exports were painfully slow on big tables. Each page used to re-walk the table from row zero and re-fetch the whole user list. Sequential pages now resume where the previous one stopped, and the heavy classification work is reused for the duration of an export.
- The audio-cache scan could freeze the instance for a moment and even error out if another cleanup removed files mid-scan. It now runs off the main loop and shrugs off vanishing files.
- Whole-database detail listings now require the same authentication as Preview and Execute — they were reachable with cookie-only auth before. Nothing changes for the admin page itself.
Changed
- Faster vector-collection scans (Milvus/Qdrant), a leaner PGVector memory scan, and the
/prunepage is served from a pre-built template instead of being reassembled on every load. All output is byte-for-byte identical — these are pure speed-ups.
Inline Visualizer (v1 - Legacy) v1.5.0
Added
- Performance Improvement: The Strict and Balanced security headers are assembled once at startup instead of on every render — same output, less work per visualization. No functional changes.
v1.0.26
v1.0.26
Prune v0.10.7
Important
NEW:
The Prune Event Function
New plugin. Automatic, throttled database and storage cleanup driven by system events. Old chats, inactive accounts, orphaned records, uploads and vector collections are cleaned up in the background, slowly on purpose, so a live instance never feels it. Requires Open WebUI 0.10.2. Automated deletions. On demand deletions. Both. Full UI inside Open WebUI. Whatever you prefer!
Added
- Event-driven cleanup, no cron. Startup triggers a full sweep, chat activity ages out old chats, logins and signups catch dead accounts, and destruction events (
user.deleted,knowledge.deleted,file.deleted_all) trigger a reconciliation. Deletion stays off until you flip the master switch; dry-run Preview is always safe. - Purposefully slow deletion. A
deletion_rows_per_secondthrottle (default 50) trickles deletes with the write path free between rows and commits each batch before sleeping; it applies live to a running pass. Optionalscan_rows_per_secondcaps the read side. - Fast, resource-bounded scans. JSON columns are scanned as raw text with one compiled regex instead of json-decoding every chat (an order of magnitude faster on large databases), yielding the event loop between batches.
- Live progress. Preview, Execute and automatic passes report a stage plus a counted percentage.
- Multi-worker safe. Redis
SET NX EXclaims plus a heartbeat-renewed global run lock (in-process fallback without Redis; Valkey works) mean exactly one worker prunes fleet-wide and passes never overlap. - Reference-based file safety. A file is deleted only when nothing references it (no chat, KB, note, folder, channel or model);
orphan_file_grace_hours(default 24) protects fresh uploads. - Shared data of departed users survives. Orphaned knowledge bases, models, prompts, tools, notes and skills are kept when a living user, an existing group or a public grant can still reach them (per-category exempt toggles, on by default).
- Complete account cleanup. Inactive-user deletion removes the account and its login credentials through Open WebUI's own admin-delete path, plus automations and stored memories; admins and pending users are exempt by default.
- Manual admin page at
/prune. Session-gated Preview (per-category counts) and Execute (typedDELETEconfirm) with a live run log, resumable if the page is closed, plus an explicit VACUUM checkbox. - Vector database coverage: ChromaDB, PGVector, Milvus and Qdrant, including both multitenancy modes; other stores are skipped safely.
- Orphaned-memory cleanup is opt-in. Off by default: per-user vector probing is slow without dedicated DB indexes (roughly 1 minute per user on a constrained database), so it stays off with an in-UI warning until you enable it deliberately.
Interface Defaults v1.1.0
Added
- Floating Quick Action Buttons (JSON) valve: set the text-selection popup actions (the Ask/Explain style buttons) instance-wide from a JSON array of
{id, label, input, prompt}, with{{SELECTED_CONTENT}},{{CONTENT}}and{{INPUT_CONTENT}}placeholders. Invalid JSON is ignored. Includes a copy-paste README tutorial and admin ideas. - Manage only what you set. Only options switched to Custom are written; anything left on Default is never pushed, so each user keeps their own choice for it.
Fixed
- Factory reset no longer wipes unrelated settings.
settings.uiholds a user's whole store (system prompt, default model, audio, notification webhook, pinned models), so reset now clears only the interface keys this function manages instead of the entire store. - Image-compression pixel inputs no longer crash on
0, non-numeric junk or non-ASCII digits. - A trigger ticked while the function is disabled, or left ticked by a crash before it ran, is discarded on the next enable or startup instead of firing late.
Changed
- Writes deep-merge into each user's existing
settings.uiinstead of replacing it, and the shared snapshot is deep-copied per user so one user's write can't reach another's. - Apply to all and Reset all walk users in keyset-paginated chunks, so no user is skipped or double-processed when accounts are created or deleted mid-run; no-op writes are skipped.
- New-user seeding now also covers LDAP and admin-created accounts (alongside signup, OAuth and SCIM).
- Raised the minimum supported Open WebUI version to 0.10.2 (README previously stated 0.10.0).
Email Composer v1.0.2
Fixed
- The interactive email card now renders inline under Open WebUI 0.10 native tool calling (#54). The card is delivered on the message-level
embedschannel instead of only appearing inside the collapsed tool-call details, with a fallback to the previous return on older Open WebUI. Existing users must re-pastetool.pyto pick up the fix.
Documentation
Changed
- Corrected the function-calling setup wording for Open WebUI 0.10+ (#58) in Email Composer, Inline Visualizer and Inline Visualizer v2:
DefaultandNativeboth work andDefaulthas been native since0.10.0, onlyLegacyis legacy. - Inline Visualizer v2: corrected the skill install path to Workspace → Knowledge → Create Skill.
v1.0.25
v1.0.25
Interface Defaults v1.0.2
Added
- Bulk speed (users per second) valve (default
20) that rate-limits the two one-shot bulk actions, so applying to or resetting thousands of users never saturates the single database writer (0= no limit). - Human-readable titles on every valve, plus section-header hints (Chat behavior, Input, Artifacts, Voice & calls, Files & search, One-shot actions) so the native Valves form reads cleanly.
Fixed
- Bulk apply/reset on large instances no longer risks freezing the instance: the tight per-user write loop is throttled.
Changed
- Apply to all and Reset all now trickle through users at the configured rate instead of looping as fast as possible, keeping a live instance responsive while the bulk op runs.
- Reworded both button descriptions: new users are always seeded automatically while the function is enabled, with or without the apply button. The apply button only exists to catch up users created before install.
- Corrected the iframe-sandbox toggle wording to explain it lets sandboxed artifacts, previews and embeds render.
- Raised the minimum supported Open WebUI version to 0.10.2 (was 0.10.0).
v1.0.24
v1.0.24
Interface Defaults v1.0.1
Added
- Added more interface settings to configure
v1.0.23
v1.0.23
Inline Visualizer v2.1.3
Added
- 🖼️ SVG and PNG export in the download menu. The download button now opens a format picker (HTML / SVG / PNG). SVG serializes the visualization's SVG with theme styles inlined; PNG rasterizes it (crisp vector when the view is SVG-dominant, a native
foreignObjectscreenshot for HTML or mixed layouts, with an html2canvas fallback).
Fixed
- 🧩 Inline visualizations render under native tool calling (Open WebUI
0.10+). Embeds now go through the message-level channel so they paint regardless of the tool-calling path.
Vision Bridge v1.0.0
Added
- 👁️ New Filter + Tool pair that gives a text-only model the ability to work with images, with no core changes. ⭐💫
- 🖼️ Images stripped to a marker. The filter's
strip_onlymode replaces each image in the request with a marker naming its file id, so a text-only model never receives an image it cannot accept (no more 404), while the image stays in the chat untouched. - 🔍 On-demand vision through a tool. The model calls
analyze_image(file_id, query)to send an image to a configured vision model and get the answer back as text. It can call again with a different question about the same untouched image at any point in the conversation. - 🔁 Describe-and-replace fallback. For models that cannot tool-call,
strip_only = falseruns one vision pass up front and swaps the image for a text description (optionally deleting the file afterward). - ✅ Verified end-to-end against OpenRouter: text-only
deepseek-v4-flashreceives the marker, then re-queries one image twice viaminimax-m3("what colors?" and "any text?") with correct, distinct answers.
v1.0.22
v1.0.22
Interface Defaults v1.0.0
Added
- ❤️🔥 New Event function that manages your instance's Settings → Interface defaults from a single function's Valves. Requires Open WebUI
0.10.0or newer. ⭐💫 - 🔧 Instance-wide interface defaults from Valves. Every Settings → Interface toggle (title auto-generation, auto-tags, rich text input, chat bubble, widescreen, landing page mode, chat direction, text scale, default web search, and the rest) is configurable in one place. Defaults match Open WebUI's own factory values, so nothing changes until you change it.
- ⚙️ Automatic seeding of new users. Subscribes to
user.created, so every account created via signup, OAuth, or SCIM inherits the configured settings on registration. No action needed per user. - "Apply to all existing users" button. A one-shot Valve toggle that pushes the configured defaults to everyone already on the instance. Normally needed only once, right after install. Reverts itself once done.
- "Reset all users to factory" button. A one-shot Valve toggle that clears every user's interface overrides and resets the function's own config back to defaults. Reverts itself once done.
- No re-fire loop. Triggers untick themselves through the model layer, which does not re-publish the event.
v1.0.21
v1.0.21
Keep reasoning_content v2.0.0
Added
- ❤️🔥 Initial release ⭐💫
- 🧠 Keeps
reasoning_contentalive within a turn's tool-call loop and across follow-up turns, so reasoning models can see their own prior chain of thought - 🩹 Kills the
reasoning_content is missing in assistant tool call message at index N400s that hit mid tool-call - 🔧 Process-wide monkey-patch of
get_reasoning_format— catches the pre-inlet cross-turn history rebuild and the in-turn tool-call rebuilds in one shot - ⚙️
excluded_model_idsvalve to opt out models that must not get reasoning replayed (Gemma family, reasoning-summary models like the o-series) - 🤝 Works with any OpenAI-compatible reasoning model emitting
delta.reasoning_content— DeepSeek, Kimi, MiMo, vLLM, OpenRouter passthrough
v1.0.20
v1.0.20
Inline Visualizer v2.1.2
Changed
- Slightly improved SKILL token efficiency
- Major rework of tool prompt and Skill guidance to avoid unwanted visualizations. Entirely reworked HOW the model perceives the tool and what it is for.
v1.0.19
v1.0.19
Inline Visualizer v2.1.1
Added
- README: document drag-drop
SKILL.mdimport via Workspace → Skills - Add Azerbaijani (
az) translations across loader, error, done, copied, and download strings - Replace 3-shot finalize-artifact strip schedule with a 1s interval that runs for 30s, so late Svelte re-hydration flushes get cleaned up within a second
v1.0.18
v1.0.18
Inline Visualizer v2.1.0
Added
Pre-styled bare tags — write less, get more
Drop in a vanilla <button>, <input>, <select>, <table>, <details>, <kbd>, and friends, and they come out looking native to the host UI — theme-aware colors, focus rings, hover states, the works. Adding class or style opts you out, so the model can still go fully custom when the design calls for it.
The full list:
- Forms —
<button>,<textarea>,<select>,<label>,<fieldset>,<legend>, plus every common<input>type (text,email,number,range,date,checkbox,radio, …). - Content —
<kbd>keyboard-cap pills,<hr>flat dividers,<details>/<summary>collapsible sections with a rotating chevron,<blockquote>accent-colored callouts,<mark>highlights. - Tables —
<table>and friends with header pill, row hover, and tabular-num alignment for numeric columns. - Definition lists —
<dl>in three layouts: stacked glossary, two-column grid card (data-layout="grid"), and inline pill row (data-layout="inline").
This means smaller visualization payloads, faster rendering, and a consistent look across visualizations — without the model having to re-style the same primitives every time.
Nine-color accent palette
Set data-accent="teal" (or coral, pink, gray, blue, green, amber, red) on any element and the focus rings, checkboxes, radio buttons, and any custom uses of var(--accent) recolor to match. Names line up with the chart color ramps, so a finance dashboard with green accents reads naturally next to its green chart. Default stays purple. Light and dark themes handled automatically.
More chart types & patterns in the skill
The model now has guidance for stacked bars / areas, radar charts, KPI cards with sparklines, progress bars, ranking strips, KPI donuts, and custom-shape charts (thermometers, batteries, fuel gauges). Plus new component patterns for comparison cards, slider-driven explainers, tabs, and step-through walkthroughs.
More CDN libraries supported
ECharts, Plotly, vis-network, and Tone.js / Wavesurfer now have first-class entries in the skill catalog with vetted CDN URLs.
Accessibility
aria-invalid="true"paints a red border on text inputs / textareas / selects to flag validation errors.- Keyboard users get a clear accent-colored outline on focused controls; mouse focus stays subtle.
Changed
- Smarter handling of providers that wrap responses in reasoning blocks — Bedrock-hosted Haiku 4.5 (and any future provider doing the same) now renders correctly instead of staying blank.
- More resilient script chain. A single broken inline script (bad syntax, throw on insertion) used to stall every later script in the visualization. Each script is now isolated, so one failure doesn't bring down the rest of the chart.
- Hidden-tab charts have a documented fix. The skill now spells out the 0×0 init trap for Plotly, ECharts, and vis-network when their container starts inside a
display:nonetab, with the right resize call for each library. - Visualizations no longer feedback-loop on
100vh/100vwlayouts — the iframe used to grow taller every measurement cycle when the model used viewport units. Now it stays put. <style>blocks survive Open WebUI's chat sanitizer. Some builds were stripping the wrapping tags and breaking layout. The iframe re-inflates the rules automatically.- Better Svelte compatibility — message detection updated so visualizations behave correctly across regenerate / edit / branch flows in newer Open WebUI versions.
- Marker debris cleanup — leftover
@@@VIZ-START/@@@VIZ-ENDtext and stray closing tags occasionally bled into chat after a long visualization finished streaming. Multi-pass cleanup catches them.
Fixed
- Visualizations stayed blank when the model's "Thinking" / reasoning section was expanded. The wrapper now recovers correctly whether the response sits inside or outside the reasoning subtree. (#22)
- HTML export was missing chart data. Downloaded files now run the embedded charts properly when opened standalone — imported library scripts are relocated so they execute after their target divs exist. (#20)
- Visualization sometimes ate the prose around it, hiding text from before
@@@VIZ-STARTand after@@@VIZ-END. The marker detection and post-finalize cleanup are now much harder to confuse, including when a model emits broken markup inside the block. (#24) text.charCodeAt is not a functionconsole error blocking render for some setups (notably Claude through LiteLLM, but reported across multiple providers). Defensive guards through the streaming pipeline keep the iframe alive even when an upstream message arrives in an unexpected shape. (#23)- Charts no longer vanish at the end of streaming. D3 (
d3.select(...).append('svg')), vis-network, and ECharts charts used to lose their rendered SVG / canvas during the final paint pass. They now stay put. new vis.DataSet(...)throwingvis is not defined— the recommended CDN URL was pointing at the build that needsvis-dataloaded separately. Now points at the standalone bundle that just works.- Plugin failing silently when an internal script accidentally contained certain HTML literals (
<!--,<script>, etc., even inside JS comments). The plugin now refuses to load with a clear error message instead, so a regression like this can't ship. - Iframe going dormant if any one bootstrap step failed — the polling timer wasn't installed and the visualization stayed blank forever. Each step is now independently guarded.