diff --git a/docs/features/extensibility/plugin/development/events.mdx b/docs/features/extensibility/plugin/development/events.mdx index cad37472..03a2620c 100644 --- a/docs/features/extensibility/plugin/development/events.mdx +++ b/docs/features/extensibility/plugin/development/events.mdx @@ -667,6 +667,134 @@ async function myToolHandler(req) { --- +## πŸ”’ Persistence & Browser Disconnection + +A common question is: **what happens if the browser tab is closed while a tool, action, or pipe is still running?** + +### Server-Side Execution Continues + +When you send a chat request, Open WebUI creates a background `asyncio` task that is **not tied to your HTTP connection or Socket.IO session**. If you close the tab: + +1. The WebSocket disconnects and the Socket.IO disconnect handler fires +2. The disconnect handler cleans up session data but **does not cancel any running tasks** +3. The background task continues running to completion on the server +4. `sio.emit()` calls succeed silently β€” events are sent to an empty room and discarded +5. **Database writes still happen** for persisted event types (see below) +6. The task runs until the function returns, raises an error, or is manually cancelled + +:::info No Execution Timeout +There is **no timeout** on pipe, tool, or action execution. Your code can run for minutes or hours β€” nothing in Open WebUI will kill it automatically. The only things that can stop a running task are: +- The function itself returning or raising an exception +- Manual cancellation via `POST /api/tasks/stop/{task_id}` (the stop button in the UI) +- The Open WebUI server process restarting +::: + +### Which Event Types Are Persisted to the Database? + +The event emitter writes certain event types directly to the database **regardless of whether a browser is connected**. These writes are independent of the `ENABLE_REALTIME_CHAT_SAVE` setting. + +#### βœ… Persisted (survive tab close) + +| Type | What's saved | +|------|-------------| +| `status` | Appended to the message's `statusHistory` array | +| `message` | Appended to the message's `content` field | +| `replace` | Overwrites the message's `content` field | +| `embeds` | Appended to the message's `embeds` array (Rich UI HTML) | +| `files` | Appended to the message's `files` array | +| `source` / `citation` | Appended to the message's `sources` array | + +These 6 types always write to the database inside the event emitter function itself, completely independent of `ENABLE_REALTIME_CHAT_SAVE`. + +:::warning Use Short Names for Persistence +The backend event emitter only recognizes the short names above for DB writes. If you emit `"chat:message:embeds"` instead of `"embeds"`, the frontend handles it identically, but the **backend won't persist it**. Always use the short names (`"status"`, `"message"`, `"replace"`, `"embeds"`, `"files"`, `"source"`) if you need persistence. +::: + +#### ❌ Not persisted (lost on tab close) + +| Type | Why it's lost | +|------|--------------| +| `chat:completion` | Streaming LLM deltas β€” Socket.IO only | +| `chat:message:delta` | Frontend alias, backend doesn't persist | +| `chat:message` | Frontend alias, backend doesn't persist | +| `chat:message:files` | Frontend alias, backend doesn't persist | +| `chat:message:embeds` | Frontend alias, backend doesn't persist | +| `chat:message:error` | Socket.IO only | +| `chat:message:follow_ups` | Socket.IO only | +| `chat:message:favorite` | Socket.IO only (updates frontend state) | +| `chat:title` | Socket.IO only | +| `chat:tags` | Socket.IO only | +| `notification` | Toast popup β€” Socket.IO only | + +:::tip Alternative for Streaming LLM Output +If your pipe or tool needs to call an LLM and have the result persist even when the browser is closed, you can import and use `generate_chat_completion` from Open WebUI's internals instead of emitting `chat:completion` events. The completion flows through the normal chat pipeline and its result is saved to the database like any other assistant message. +::: + +#### ⚠️ Requires live connection (will error on tab close) + +| Type | Why | +|------|-----| +| `confirmation` | Uses `sio.call()` β€” waits for client response, will timeout | +| `input` | Uses `sio.call()` β€” waits for client response, will timeout | +| `execute` | Uses `sio.call()` β€” waits for client response, will timeout | + +These `__event_call__` types fundamentally require a live browser connection. If the tab is closed, `sio.call()` will timeout and raise an exception in your function code. + +### Return Value Persistence + +The final return value of your function is **always saved to the database** when the task completes, regardless of browser state. + +#### Pipes + +When a pipe's `pipe()` method returns (or its generator finishes yielding), the streaming handler saves the final result at completion: +- If `ENABLE_REALTIME_CHAT_SAVE` is **on**: intermediate chunks are saved during streaming +- If `ENABLE_REALTIME_CHAT_SAVE` is **off**: the full final content is saved in one write at completion + +Either way, the final assistant message is always persisted. When you reopen the chat, it will be there. + +#### Tools + +| Return type | What happens | Persisted? | +|-------------|-------------|-----------| +| `HTMLResponse` (with `Content-Disposition: inline`) | HTML body extracted β†’ added to `embeds` β†’ emitted as `"embeds"` event | βœ… Yes | +| `HTMLResponse` (without inline) | Body decoded as plain text tool result | βœ… Yes | +| `str` / `dict` | Used as tool result text | βœ… Yes | +| `list` (MCP) | Text items joined, images converted to files | βœ… Yes | + +#### Actions + +Actions go through the same return handling as tools. The same persistence rules apply: + +| Return type | What happens | Persisted? | +|-------------|-------------|-----------| +| `HTMLResponse` (with `Content-Disposition: inline`) | HTML body extracted β†’ added to `embeds` β†’ emitted as `"embeds"` event | βœ… Yes | +| `HTMLResponse` (without inline) | Body decoded as plain text result | βœ… Yes | +| `str` / `dict` | Used as action result text | βœ… Yes | + +#### Filters + +Filters transform `form_data` in the pipeline β€” they don't return results to the user directly. However, filters **do receive `__event_emitter__`** and can emit persisted event types like `"status"`, `"embeds"`, `"message"`, etc. + +### Function Type Capabilities Matrix + +| Capability | Tools | Actions | Pipes | Filters | +|-----------|-------|---------|-------|---------| +| `__event_emitter__` | βœ… | βœ… | βœ… | βœ… | +| `__event_call__` | βœ… | βœ… | βœ… | βœ… | +| Return value β†’ user response | βœ… | βœ… | βœ… | ❌ (modifies `form_data`) | +| `HTMLResponse` β†’ Rich UI embed | βœ… | βœ… | ❌ | ❌ | + +### Practical Summary + +If you want your function's output to **survive a closed browser tab**, follow these rules: + +1. **Always return your final answer** from your `pipe()`, tool, or action function β€” the return value is always saved +2. **Use short event type names** (`"status"`, `"message"`, `"embeds"`, `"files"`, `"source"`) for DB persistence +3. **Avoid relying on** `"notification"`, `"confirmation"`, `"input"`, or `"execute"` for critical workflows β€” these require a live browser connection +4. Rich UI HTML embeds (`"embeds"` type or `HTMLResponse` return) **are persisted** and will render when the user reopens the chat + +--- + ## πŸ“ Conclusion **Events** give you real-time, interactive superpowers inside Open WebUI. They let your code update content, trigger notifications, request user input, stream results, handle code, and much moreβ€”seamlessly plugging your backend intelligence into the chat UI. diff --git a/docs/getting-started/quick-start/tab-docker/ManualDocker.md b/docs/getting-started/quick-start/tab-docker/ManualDocker.md index 835737f1..e0d469d1 100644 --- a/docs/getting-started/quick-start/tab-docker/ManualDocker.md +++ b/docs/getting-started/quick-start/tab-docker/ManualDocker.md @@ -23,7 +23,7 @@ docker pull ghcr.io/open-webui/open-webui:main-slim You can also pull a specific Open WebUI release version directly by using a versioned image tag. This is recommended for production environments to ensure stable and reproducible deployments. ```bash -docker pull ghcr.io/open-webui/open-webui:v0.8.4 +docker pull ghcr.io/open-webui/open-webui:v0.8.5 ``` ## Step 2: Run the Container diff --git a/docs/getting-started/updating.mdx b/docs/getting-started/updating.mdx index 5a2f9c6d..6c4958f7 100644 --- a/docs/getting-started/updating.mdx +++ b/docs/getting-started/updating.mdx @@ -76,9 +76,9 @@ Without a persistent `WEBUI_SECRET_KEY`, a new key is generated each time the co By default the `:main` tag always points to the latest build. For production, pin a specific release: ``` -ghcr.io/open-webui/open-webui:v0.8.4 -ghcr.io/open-webui/open-webui:v0.8.4-cuda -ghcr.io/open-webui/open-webui:v0.8.4-ollama +ghcr.io/open-webui/open-webui:v0.8.5 +ghcr.io/open-webui/open-webui:v0.8.5-cuda +ghcr.io/open-webui/open-webui:v0.8.5-ollama ``` ### Rolling Back diff --git a/docs/intro.mdx b/docs/intro.mdx index 94b0283c..d158f597 100644 --- a/docs/intro.mdx +++ b/docs/intro.mdx @@ -108,9 +108,9 @@ openwebui/open-webui:- Examples (pinned versions for illustration purposes only): ``` -ghcr.io/open-webui/open-webui:v0.8.4 -ghcr.io/open-webui/open-webui:v0.8.4-ollama -ghcr.io/open-webui/open-webui:v0.8.4-cuda +ghcr.io/open-webui/open-webui:v0.8.5 +ghcr.io/open-webui/open-webui:v0.8.5-ollama +ghcr.io/open-webui/open-webui:v0.8.5-cuda ``` ### Using the Dev Branch πŸŒ™ diff --git a/docs/reference/env-configuration.mdx b/docs/reference/env-configuration.mdx index a29cf6b2..dbdb39bf 100644 --- a/docs/reference/env-configuration.mdx +++ b/docs/reference/env-configuration.mdx @@ -12,7 +12,7 @@ As new variables are introduced, this page will be updated to reflect the growin :::info -This page is up-to-date with Open WebUI release version [v0.8.4](https://github.com/open-webui/open-webui/releases/tag/v0.8.4), but is still a work in progress to later include more accurate descriptions, listing out options available for environment variables, defaults, and improving descriptions. +This page is up-to-date with Open WebUI release version [v0.8.5](https://github.com/open-webui/open-webui/releases/tag/v0.8.5), but is still a work in progress to later include more accurate descriptions, listing out options available for environment variables, defaults, and improving descriptions. ::: diff --git a/docs/tutorials/tips/sqlite-database.md b/docs/tutorials/tips/sqlite-database.md index 2301df60..4f221394 100644 --- a/docs/tutorials/tips/sqlite-database.md +++ b/docs/tutorials/tips/sqlite-database.md @@ -10,7 +10,7 @@ This tutorial is a community contribution and is not supported by the Open WebUI ::: > [!WARNING] -> This documentation was created/updated based on version 0.8.4 and updated for recent migrations. +> This documentation was created/updated based on version 0.8.5 and updated for recent migrations. ## Open-WebUI Internal SQLite Database