mirror of
https://github.com/open-webui/docs.git
synced 2026-01-04 02:36:55 +07:00
refac: reorg
This commit is contained in:
7
docs/features/plugin/development/_category_.json
Normal file
7
docs/features/plugin/development/_category_.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"label": "Development",
|
||||
"position": 800,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
||||
424
docs/features/plugin/development/events.mdx
Normal file
424
docs/features/plugin/development/events.mdx
Normal file
@@ -0,0 +1,424 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
title: "Events"
|
||||
---
|
||||
|
||||
# 🔔 Events: Using `__event_emitter__` and `__event_call__` in Open WebUI
|
||||
|
||||
Open WebUI's plugin architecture is not just about processing input and producing output—**it's about real-time, interactive communication with the UI and users**. To make your Tools, Functions, and Pipes more dynamic, Open WebUI provides a built-in event system via the `__event_emitter__` and `__event_call__` helpers.
|
||||
|
||||
This guide explains **what events are**, **how you can trigger them** from your code, and **the full catalog of event types** you can use (including much more than just `"input"`).
|
||||
|
||||
---
|
||||
|
||||
## 🌊 What Are Events?
|
||||
|
||||
**Events** are real-time notifications or interactive requests sent from your backend code (Tool, or Function) to the web UI. They allow you to update the chat, display notifications, request confirmation, run UI flows, and more.
|
||||
|
||||
- Events are sent using the `__event_emitter__` helper for one-way updates, or `__event_call__` when you need user input or a response (e.g., confirmation, input, etc.).
|
||||
|
||||
**Metaphor:**
|
||||
Think of Events like push notifications and modal dialogs that your plugin can trigger, making the chat experience richer and more interactive.
|
||||
|
||||
---
|
||||
|
||||
## 🧰 Basic Usage
|
||||
|
||||
### Sending an Event
|
||||
|
||||
You can trigger an event anywhere inside your Tool, or Function by calling:
|
||||
|
||||
```python
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "status", # See the event types list below
|
||||
"data": {
|
||||
"description": "Processing started!",
|
||||
"done": False,
|
||||
"hidden": False,
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
You **do not** need to manually add fields like `chat_id` or `message_id`—these are handled automatically by Open WebUI.
|
||||
|
||||
### Interactive Events
|
||||
|
||||
When you need to pause execution until the user responds (e.g., confirm/cancel dialogs, code execution, or input), use `__event_call__`:
|
||||
|
||||
```python
|
||||
result = await __event_call__(
|
||||
{
|
||||
"type": "input", # Or "confirmation", "execute"
|
||||
"data": {
|
||||
"title": "Please enter your password",
|
||||
"message": "Password is required for this action",
|
||||
"placeholder": "Your password here",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
# result will contain the user's input value
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📜 Event Payload Structure
|
||||
|
||||
When you emit or call an event, the basic structure is:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "event_type", // See full list below
|
||||
"data": { ... } // Event-specific payload
|
||||
}
|
||||
```
|
||||
|
||||
Most of the time, you only set `"type"` and `"data"`. Open WebUI fills in the routing automatically.
|
||||
|
||||
---
|
||||
|
||||
## 🗂 Full List of Event Types
|
||||
|
||||
Below is a comprehensive table of **all supported `type` values** for events, along with their intended effect and data structure. (This is based on up-to-date analysis of Open WebUI event handling logic.)
|
||||
|
||||
| type | When to use | Data payload structure (examples) |
|
||||
| -------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| `status` | Show a status update/history for a message | `{description: ..., done: bool, hidden: bool}` |
|
||||
| `chat:completion` | Provide a chat completion result | (Custom, see Open WebUI internals) |
|
||||
| `chat:message:delta`,<br/>`message` | Append content to the current message | `{content: "text to append"}` |
|
||||
| `chat:message`,<br/>`replace` | Replace current message content completely | `{content: "replacement text"}` |
|
||||
| `chat:message:files`,<br/>`files` | Set or overwrite message files (for uploads, output) | `{files: [...]}` |
|
||||
| `chat:title` | Set (or update) the chat conversation title | Topic string OR `{title: ...}` |
|
||||
| `chat:tags` | Update the set of tags for a chat | Tag array or object |
|
||||
| `source`,<br/>`citation` | Add a source/citation, or code execution result | For code: See [below.](/features/plugin/development/events#source-or-citation-and-code-execution) |
|
||||
| `notification` | Show a notification ("toast") in the UI | `{type: "info" or "success" or "error" or "warning", content: "..."}` |
|
||||
| `confirmation` <br/>(needs `__event_call__`) | Ask for confirmation (OK/Cancel dialog) | `{title: "...", message: "..."}` |
|
||||
| `input` <br/>(needs `__event_call__`) | Request simple user input ("input box" dialog) | `{title: "...", message: "...", placeholder: "...", value: ...}` |
|
||||
| `execute` <br/>(needs `__event_call__`) | Request user-side code execution and return result | `{code: "...javascript code..."}` | |
|
||||
|
||||
**Other/Advanced types:**
|
||||
|
||||
- You can define your own types and handle them at the UI layer (or use upcoming event-extension mechanisms).
|
||||
|
||||
### ❗ Details on Specific Event Types
|
||||
|
||||
### `status`
|
||||
|
||||
Show a status/progress update in the UI:
|
||||
|
||||
```python
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "status",
|
||||
"data": {
|
||||
"description": "Step 1/3: Fetching data...",
|
||||
"done": False,
|
||||
"hidden": False,
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `chat:message:delta` or `message`
|
||||
|
||||
**Streaming output** (append text):
|
||||
|
||||
```python
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "chat:message:delta", # or simply "message"
|
||||
"data": {
|
||||
"content": "Partial text, "
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
# Later, as you generate more:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "chat:message:delta",
|
||||
"data": {
|
||||
"content": "next chunk of response."
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `chat:message` or `replace`
|
||||
|
||||
**Set (or replace) the entire message content:**
|
||||
|
||||
```python
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "chat:message", # or "replace"
|
||||
"data": {
|
||||
"content": "Final, complete response."
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `files` or `chat:message:files`
|
||||
|
||||
**Attach or update files:**
|
||||
|
||||
```python
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "files", # or "chat:message:files"
|
||||
"data": {
|
||||
"files": [
|
||||
# Open WebUI File Objects
|
||||
]
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `chat:title`
|
||||
|
||||
**Update the chat's title:**
|
||||
|
||||
```python
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "chat:title",
|
||||
"data": {
|
||||
"title": "Market Analysis Bot Session"
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `chat:tags`
|
||||
|
||||
**Update the chat's tags:**
|
||||
|
||||
```python
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "chat:tags",
|
||||
"data": {
|
||||
"tags": ["finance", "AI", "daily-report"]
|
||||
},
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `source` or `citation` (and code execution)
|
||||
|
||||
**Add a reference/citation:**
|
||||
|
||||
```python
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "source", # or "citation"
|
||||
"data": {
|
||||
# Open WebUI Source (Citation) Object
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**For code execution (track execution state):**
|
||||
|
||||
```python
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "source",
|
||||
"data": {
|
||||
# Open WebUI Code Source (Citation) Object
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `notification`
|
||||
|
||||
**Show a toast notification:**
|
||||
|
||||
```python
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {
|
||||
"type": "info", # "success", "warning", "error"
|
||||
"content": "The operation completed successfully!"
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `confirmation` (**requires** `__event_call__`)
|
||||
|
||||
**Show a confirm dialog and get user response:**
|
||||
|
||||
```python
|
||||
result = await __event_call__(
|
||||
{
|
||||
"type": "confirmation",
|
||||
"data": {
|
||||
"title": "Are you sure?",
|
||||
"message": "Do you really want to proceed?"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if result: # or check result contents
|
||||
await __event_emitter__({
|
||||
"type": "notification",
|
||||
"data": {"type": "success", "content": "User confirmed operation."}
|
||||
})
|
||||
else:
|
||||
await __event_emitter__({
|
||||
"type": "notification",
|
||||
"data": {"type": "warning", "content": "User cancelled."}
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `input` (**requires** `__event_call__`)
|
||||
|
||||
**Prompt user for text input:**
|
||||
|
||||
```python
|
||||
result = await __event_call__(
|
||||
{
|
||||
"type": "input",
|
||||
"data": {
|
||||
"title": "Enter your name",
|
||||
"message": "We need your name to proceed.",
|
||||
"placeholder": "Your full name"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
user_input = result
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {"type": "info", "content": f"You entered: {user_input}"}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `execute` (**requires** `__event_call__`)
|
||||
|
||||
**Run code dynamically on the user's side:**
|
||||
|
||||
```python
|
||||
result = await __event_call__(
|
||||
{
|
||||
"type": "execute",
|
||||
"data": {
|
||||
"code": "print(40 + 2);",
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {
|
||||
"type": "info",
|
||||
"content": f"Code executed, result: {result}"
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ When & Where to Use Events
|
||||
|
||||
- **From any Tool, or Function** in Open WebUI.
|
||||
- To **stream responses**, show progress, request user data, update the UI, or display supplementary info/files.
|
||||
- `await __event_emitter__` is for one-way messages (fire and forget).
|
||||
- `await __event_call__` is for when you need a response from the user (input, execute, confirmation).
|
||||
|
||||
---
|
||||
|
||||
## 💡 Tips & Advanced Notes
|
||||
|
||||
- **Multiple types per message:** You can emit several events of different types for one message—for example, show `status` updates, then stream with `chat:message:delta`, then complete with a `chat:message`.
|
||||
- **Custom event types:** While the above list is the standard, you may use your own types and detect/handle them in custom UI code.
|
||||
- **Extensibility:** The event system is designed to evolve—always check the [Open WebUI documentation](https://github.com/open-webui/open-webui) for the most current list and advanced usage.
|
||||
|
||||
---
|
||||
|
||||
## 🧐 FAQ
|
||||
|
||||
### Q: How do I trigger a notification for the user?
|
||||
Use `notification` type:
|
||||
```python
|
||||
await __event_emitter__({
|
||||
"type": "notification",
|
||||
"data": {"type": "success", "content": "Task complete"}
|
||||
})
|
||||
```
|
||||
|
||||
### Q: How do I prompt the user for input and get their answer?
|
||||
Use:
|
||||
```python
|
||||
response = await __event_call__({
|
||||
"type": "input",
|
||||
"data": {
|
||||
"title": "What's your name?",
|
||||
"message": "Please enter your preferred name:",
|
||||
"placeholder": "Name"
|
||||
}
|
||||
})
|
||||
|
||||
# response will be: {"value": "user's answer"}
|
||||
```
|
||||
|
||||
### Q: What event types are available for `__event_call__`?
|
||||
- `"input"`: Input box dialog
|
||||
- `"confirmation"`: Yes/No, OK/Cancel dialog
|
||||
- `"execute"`: Run provided code on client and return result
|
||||
|
||||
### Q: Can I update files attached to a message?
|
||||
Yes—use the `"files"` or `"chat:message:files"` event type with a `{files: [...]}` payload.
|
||||
|
||||
### Q: Can I update the conversation title or tags?
|
||||
Absolutely: use `"chat:title"` or `"chat:tags"` accordingly.
|
||||
|
||||
### Q: Can I stream responses (partial tokens) to the user?
|
||||
Yes—emit `"chat:message:delta"` events in a loop, then finish with `"chat:message"`.
|
||||
|
||||
---
|
||||
|
||||
## 📝 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.
|
||||
|
||||
- Use `__event_emitter__` for one-way status/content updates.
|
||||
- Use `__event_call__` for interactions that require user follow-up (input, confirmation, execution).
|
||||
|
||||
Refer to this document for common event types and structures, and explore Open WebUI source code or docs for breaking updates or custom events!
|
||||
|
||||
---
|
||||
|
||||
**Happy event-driven coding in Open WebUI! 🚀**
|
||||
340
docs/features/plugin/development/reserved-args.mdx
Normal file
340
docs/features/plugin/development/reserved-args.mdx
Normal file
@@ -0,0 +1,340 @@
|
||||
---
|
||||
sidebar_position: 999
|
||||
title: "Reserved Arguments"
|
||||
---
|
||||
|
||||
:::warning
|
||||
|
||||
This tutorial is a community contribution and is not supported by the Open WebUI team. It serves only as a demonstration on how to customize Open WebUI for your specific use case. Want to contribute? Check out the contributing tutorial.
|
||||
|
||||
:::
|
||||
|
||||
# 🪄 Special Arguments
|
||||
|
||||
When developping your own `Tools`, `Functions` (`Filters`, `Pipes` or `Actions`), `Pipelines` etc, you can use special arguments explore the full spectrum of what Open-WebUI has to offer.
|
||||
|
||||
This page aims to detail the type and structure of each special argument as well as provide an example.
|
||||
|
||||
### `body`
|
||||
|
||||
A `dict` usually destined to go almost directly to the model. Although it is not strictly a special argument, it is included here for easier reference and because it contains itself some special arguments.
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```json
|
||||
|
||||
{
|
||||
"stream": true,
|
||||
"model": "my-cool-model",
|
||||
# lowercase string with - separated words: this is the ID of the model
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "What is in this picture?"
|
||||
},
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAdYAAAGcCAYAAABk2YF[REDACTED]"
|
||||
# Images are passed as base64 encoded data
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "The image appears to be [REDACTED]"
|
||||
},
|
||||
],
|
||||
"features": {
|
||||
"image_generation": false,
|
||||
"code_interpreter": false,
|
||||
"web_search": false
|
||||
},
|
||||
"stream_options": {
|
||||
"include_usage": true
|
||||
},
|
||||
"metadata": "[The exact same dict as __metadata__]",
|
||||
"files": "[The exact same list as __files__]"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `__user__`
|
||||
|
||||
A `dict` with user information.
|
||||
|
||||
Note that if the `UserValves` class is defined, its instance has to be accessed via `__user__["valves"]`. Otherwise, the `valves` keyvalue is missing entirely from `__user__`.
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"email": "cheesy_dude@openwebui.com",
|
||||
"name": "Patrick",
|
||||
"role": "user",
|
||||
# role can be either `user` or `admin`
|
||||
"valves": "[the UserValve instance]"
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `__metadata__`
|
||||
|
||||
A `dict` with wide ranging information about the chat, model, files, etc.
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"chat_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"message_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"session_id": "xxxxxxxxxxxxxxxxxxxx",
|
||||
"tool_ids": null,
|
||||
# tool_ids is a list of str.
|
||||
"tool_servers": [],
|
||||
"files": "[Same as in body['files']]",
|
||||
# If no files are given, the files key exists in __metadata__ and its value is []
|
||||
"features": {
|
||||
"image_generation": false,
|
||||
"code_interpreter": false,
|
||||
"web_search": false
|
||||
},
|
||||
"variables": {
|
||||
"{{USER_NAME}}": "cheesy_username",
|
||||
"{{USER_LOCATION}}": "Unknown",
|
||||
"{{CURRENT_DATETIME}}": "2025-02-02 XX:XX:XX",
|
||||
"{{CURRENT_DATE}}": "2025-02-02",
|
||||
"{{CURRENT_TIME}}": "XX:XX:XX",
|
||||
"{{CURRENT_WEEKDAY}}": "Monday",
|
||||
"{{CURRENT_TIMEZONE}}": "Europe/Berlin",
|
||||
"{{USER_LANGUAGE}}": "en-US"
|
||||
},
|
||||
"model": "[The exact same dict as __model__]",
|
||||
"direct": false,
|
||||
"function_calling": "native",
|
||||
"type": "user_response",
|
||||
"interface": "open-webui"
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `__model__`
|
||||
|
||||
A `dict` with information about the model.
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "my-cool-model",
|
||||
"name": "My Cool Model",
|
||||
"object": "model",
|
||||
"created": 1746000000,
|
||||
"owned_by": "openai",
|
||||
# either openai or ollama
|
||||
"info": {
|
||||
"id": "my-cool-model",
|
||||
"user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"base_model_id": "gpt-4o",
|
||||
# this is the name of model that the model endpoint serves
|
||||
"name": "My Cool Model",
|
||||
"params": {
|
||||
"system": "You are my best assistant. You answer [REDACTED]",
|
||||
"function_calling": "native"
|
||||
# custom options appear here, for example "Top K"
|
||||
},
|
||||
"meta": {
|
||||
"profile_image_url": "/static/favicon.png",
|
||||
"description": "Description of my-cool-model",
|
||||
"capabilities": {
|
||||
"vision": true,
|
||||
"usage": true,
|
||||
"citations": true
|
||||
},
|
||||
"position": 17,
|
||||
"tags": [
|
||||
{
|
||||
"name": "for_friends"
|
||||
},
|
||||
{
|
||||
"name": "vision_enabled"
|
||||
}
|
||||
],
|
||||
"suggestion_prompts": null
|
||||
},
|
||||
"access_control": {
|
||||
"read": {
|
||||
"group_ids": [],
|
||||
"user_ids": []
|
||||
},
|
||||
"write": {
|
||||
"group_ids": [],
|
||||
"user_ids": []
|
||||
}
|
||||
},
|
||||
"is_active": true,
|
||||
"updated_at": 1740000000,
|
||||
"created_at": 1740000000
|
||||
},
|
||||
"preset": true,
|
||||
"actions": [],
|
||||
"tags": [
|
||||
{
|
||||
"name": "for_friends"
|
||||
},
|
||||
{
|
||||
"name": "vision_enabled"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `__messages__`
|
||||
|
||||
A `list` of the previous messages.
|
||||
|
||||
See the `body["messages"]` value above.
|
||||
|
||||
### `__chat_id__`
|
||||
|
||||
The `str` of the `chat_id`.
|
||||
|
||||
See the `__metadata__["chat_id"]` value above.
|
||||
|
||||
### `__session_id__`
|
||||
|
||||
The `str` of the `session_id`.
|
||||
|
||||
See the `__metadata__["session_id"]` value above.
|
||||
|
||||
### `__message_id__`
|
||||
|
||||
The `str` of the `message_id`.
|
||||
|
||||
See the `__metadata__["message_id"]` value above.
|
||||
|
||||
### `__event_emitter__`
|
||||
|
||||
A `Callable` used to display event information to the user.
|
||||
|
||||
### `__event_call__`
|
||||
|
||||
A `Callable` used for `Actions`.
|
||||
|
||||
### `__files__`
|
||||
|
||||
A `list` of files sent via the chat. Note that images are not considered files and are sent directly to the model as part of the `body["messages"]` list.
|
||||
|
||||
The actual binary of the file is not part of the arguments for performance reason, but the file remain nonetheless accessible by its path if needed. For example using `docker` the python syntax for the path could be:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
|
||||
the_file = Path(f"/app/backend/data/uploads/{__files__[0]["files"]["id"]}_{__files__[0]["files"]["filename"]}")
|
||||
assert the_file.exists()
|
||||
```
|
||||
|
||||
Note that the same files dict can also be accessed via `__metadata__["files"]` (and its value is `[]` if no files are sent) or via `body["files"]` (but the `files` key is missing entirely from `body` if no files are sent).
|
||||
|
||||
<details>
|
||||
<summary>Example</summary>
|
||||
|
||||
```json
|
||||
|
||||
[
|
||||
{
|
||||
"type": "file",
|
||||
"file": {
|
||||
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"filename": "Napoleon - Wikipedia.pdf",
|
||||
"user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"hash": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||
"data": {
|
||||
"content": "Napoleon - Wikipedia\n\n\nNapoleon I\n\nThe Emperor Napoleon in His Study at the\nTuileries, 1812\n\nEmperor of the French\n\n1st reign 18 May 1804 – 6 April 1814\n\nSuccessor Louis XVIII[a]\n\n2nd reign 20 March 1815 – 22 June 1815\n\nSuccessor Louis XVIII[a]\n\nFirst Consul of the French Republic\n\nIn office\n13 December 1799 – 18 May 1804\n\nBorn Napoleone Buonaparte\n15 August 1769\nAjaccio, Corsica, Kingdom of\nFrance\n\nDied 5 May 1821 (aged 51)\nLongwood, Saint Helena\n\nBurial 15 December 1840\nLes Invalides, Paris\n\nNapoleon\nNapoleon Bonaparte[b] (born Napoleone\nBuonaparte;[1][c] 15 August 1769 – 5 May 1821), later\nknown [REDACTED]",
|
||||
# The content value is the output of the document parser, the above example is with Tika as a document parser
|
||||
},
|
||||
"meta": {
|
||||
"name": "Napoleon - Wikipedia.pdf",
|
||||
"content_type": "application/pdf",
|
||||
"size": 10486578,
|
||||
# in bytes, here about 10Mb
|
||||
"data": {},
|
||||
"collection_name": "file-96xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
# always begins by 'file'
|
||||
},
|
||||
"created_at": 1740000000,
|
||||
"updated_at": 1740000000
|
||||
},
|
||||
"id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"url": "/api/v1/files/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"name": "Napoleon - Wikipedia.pdf",
|
||||
"collection_name": "file-96xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
"status": "uploaded",
|
||||
"size": 10486578,
|
||||
"error": "",
|
||||
"itemId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
# itemId is not the same as file["id"]
|
||||
}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `__request__`
|
||||
|
||||
An instance of `fastapi.Request`. You can read more in the [migration page](/docs/features/plugin/migration/index.mdx) or in [fastapi's documentation](https://fastapi.tiangolo.com/reference/request/).
|
||||
|
||||
### `__task__`
|
||||
|
||||
A `str` for the type of task. Its value is just a shorthand for `__metadata__["task"]` if present, otherwise `None`.
|
||||
|
||||
<details>
|
||||
<summary>Possible values</summary>
|
||||
|
||||
```json
|
||||
|
||||
[
|
||||
"title_generation",
|
||||
"tags_generation",
|
||||
"emoji_generation",
|
||||
"query_generation",
|
||||
"image_prompt_generation",
|
||||
"autocomplete_generation",
|
||||
"function_calling",
|
||||
"moa_response_generation"
|
||||
]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### `__task_body__`
|
||||
|
||||
A `dict` containing the `body` needed to accomplish a given `__task__`. Its value is just a shorthand for `__metadata__["task_body"]` if present, otherwise `None`.
|
||||
|
||||
Its structure is the same as `body` above, with modifications like using the appropriate model and system message etc.
|
||||
|
||||
### `__tools__`
|
||||
|
||||
A `list` of `ToolUserModel` instances.
|
||||
|
||||
For details the attributes of `ToolUserModel` instances, the code can be found in [tools.py](https://github.com/open-webui/open-webui/blob/main/backend/open_webui/models/tools.py).
|
||||
|
||||
77
docs/features/plugin/development/valves.mdx
Normal file
77
docs/features/plugin/development/valves.mdx
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
title: "Valves"
|
||||
---
|
||||
|
||||
## Valves
|
||||
|
||||
Valves and UserValves are used to allow users to provide dynamic details such as an API key or a configuration option. These will create a fillable field or a bool switch in the GUI menu for the given function. They are always optional, but HIGHLY encouraged.
|
||||
|
||||
Hence, Valves and UserValves class can be defined in either a `Pipe`, `Pipeline`, `Filter` or `Tools` class.
|
||||
|
||||
Valves are configurable by admins alone via the Tools or Functions menus. On the other hand UserValves are configurable by any users directly from a chat session.
|
||||
|
||||
<details>
|
||||
<summary>Commented example</summary>
|
||||
|
||||
```python
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Literal
|
||||
|
||||
# Define and Valves
|
||||
class Filter:
|
||||
# Notice the current indentation: Valves and UserValves must be declared as
|
||||
# attributes of a Tools, Filter or Pipe class. Here we take the
|
||||
# example of a Filter.
|
||||
class Valves(BaseModel):
|
||||
# Valves and UserValves inherit from pydantic's BaseModel. This
|
||||
# enables complex use cases like model validators etc.
|
||||
test_valve: int = Field( # Notice the type hint: it is used to
|
||||
# choose the kind of UI element to show the user (buttons,
|
||||
# texts, etc).
|
||||
default=4,
|
||||
description="A valve controlling a numberical value"
|
||||
# required=False, # you can enforce fields using True
|
||||
)
|
||||
# To give the user the choice between multiple strings, you can use Literal from typing:
|
||||
choice_option: Literal["choiceA", "choiceB"] = Field(
|
||||
default="choiceA",
|
||||
description="An example of a multi choice valve",
|
||||
)
|
||||
priority: int = Field(
|
||||
default=0,
|
||||
description="Priority level for the filter operations. Lower values are passed through first"
|
||||
)
|
||||
# The priority field is optional but if present will be used to
|
||||
# order the Filters.
|
||||
pass
|
||||
# Note that this 'pass' helps for parsing and is recommended.
|
||||
|
||||
# UserValves are defined the same way.
|
||||
class UserValves(BaseModel):
|
||||
test_user_valve: bool = Field(
|
||||
default=False, description="A user valve controlling a True/False (on/off) switch"
|
||||
)
|
||||
pass
|
||||
|
||||
def __init__(self):
|
||||
self.valves = self.Valves()
|
||||
# Because they are set by the admin, they are accessible directly
|
||||
# upon code execution.
|
||||
pass
|
||||
|
||||
# The inlet method is only used for Filter but the __user__ handling is the same
|
||||
def inlet(self, body: dict, __user__: dict):
|
||||
# Because UserValves are defined per user they are only available
|
||||
# on use.
|
||||
# Note that although __user__ is a dict, __user__["valves"] is a
|
||||
# UserValves object. Hence you can access values like that:
|
||||
test_user_valve = __user__["valves"].test_user_valve
|
||||
# Or:
|
||||
test_user_valve = dict(__user__["valves"])["test_user_valve"]
|
||||
# But this will return the default value instead of the actual value:
|
||||
# test_user_valve = __user__["valves"]["test_user_valve"] # Do not do that!
|
||||
```
|
||||
|
||||
</details>
|
||||
Reference in New Issue
Block a user