Skip to content

Commit 66a17e4

Browse files
authored
Merge pull request #674 from open-webui/dev
merge dev to main
2 parents 8adc771 + d809f4d commit 66a17e4

File tree

7 files changed

+523
-98
lines changed

7 files changed

+523
-98
lines changed

docs/features/code-execution/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ Open WebUI offers powerful code execution capabilities directly within your chat
77

88
## Key Features
99

10-
- **Python Code Execution**: Run Python scripts directly in your browser using Pyodide, with support for popular libraries like pandas and matplotlib no setup required.
10+
- **Python Code Execution**: Run Python scripts directly in your browser using Pyodide, with support for popular libraries like pandas and matplotlib with no setup required.
1111

1212
- **MermaidJS Rendering**: Create and visualize flowcharts, diagrams, and other visual representations with MermaidJS syntax that automatically renders in your chat.
1313

1414
- **Interactive Artifacts**: Generate and interact with rich content like HTML websites, SVG graphics, and JavaScript visualizations directly within your conversations.
1515

16-
These execution capabilities bridge the gap between conversation and implementation, allowing you to explore ideas, analyze data, and create visual content seamlessly while chatting with AI models.
16+
These execution capabilities bridge the gap between conversation and implementation, allowing you to explore ideas, analyze data, and create visual content seamlessly while chatting with AI models.

docs/features/plugin/functions/action.mdx

Lines changed: 269 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ sidebar_position: 3
33
title: "🎬 Action Function"
44
---
55

6-
Action functions allow you to write custom buttons to the message toolbar for end users to interact
7-
with. This feature enables more interactive messaging, enabling users to grant permission before a
8-
task is performed, generate visualizations of structured data, download an audio snippet of chats,
9-
and many other use cases.
6+
Action functions allow you to write custom buttons that appear in the message toolbar for end users to interact with. This feature enables more interactive messaging, allowing users to grant permission before a task is performed, generate visualizations of structured data, download an audio snippet of chats, and many other use cases.
107

11-
A scaffold of Action code can be found [in the community section](https://openwebui.com/f/hub/custom_action/).
8+
Actions are admin-managed functions that extend the chat interface with custom interactive capabilities. When a message is generated by a model that has actions configured, these actions appear as clickable buttons beneath the message.
9+
10+
A scaffold of Action code can be found [in the community section](https://openwebui.com/f/hub/custom_action/). For more Action Function examples built by the community, visit [https://openwebui.com/functions](https://openwebui.com/functions).
1211

1312
An example of a graph visualization Action can be seen in the video below.
1413

@@ -21,46 +20,195 @@ An example of a graph visualization Action can be seen in the video below.
2120
</a>
2221
</p>
2322

24-
### Action
23+
## Action Function Architecture
2524

26-
Actions are used to create a button in the Message UI (the small buttons found directly underneath individual chat messages).
25+
Actions are Python-based functions that integrate directly into the chat message toolbar. They execute server-side and can interact with users through real-time events, modify message content, and access the full Open WebUI context.
2726

28-
Actions have a single main component called an action function. This component takes an object defining the type of action and the data being processed.
27+
### Function Structure
2928

30-
<details>
31-
<summary>Example</summary>
29+
Actions follow a specific class structure with an `action` method as the main entry point:
3230

3331
```python
34-
async def action(
35-
self,
36-
body: dict,
37-
__user__=None,
38-
__event_emitter__=None,
39-
__event_call__=None,
40-
) -> Optional[dict]:
41-
print(f"action:{__name__}")
32+
class Action:
33+
def __init__(self):
34+
self.valves = self.Valves()
35+
36+
class Valves(BaseModel):
37+
# Configuration parameters
38+
parameter_name: str = "default_value"
39+
40+
async def action(self, body: dict, __user__=None, __event_emitter__=None, __event_call__=None):
41+
# Action implementation
42+
return {"content": "Modified message content"}
43+
```
44+
45+
### Action Method Parameters
46+
47+
The `action` method receives several parameters that provide access to the execution context:
48+
49+
- **`body`** - Dictionary containing the message data and context
50+
- **`__user__`** - Current user object with permissions and settings
51+
- **`__event_emitter__`** - Function to send real-time updates to the frontend
52+
- **`__event_call__`** - Function for bidirectional communication (confirmations, inputs)
53+
- **`__model__`** - Model information that triggered the action
54+
- **`__request__`** - FastAPI request object for accessing headers, etc.
55+
- **`__id__`** - Action ID (useful for multi-action functions)
56+
57+
## Event System Integration
58+
59+
Actions can utilize Open WebUI's real-time event system for interactive experiences:
60+
61+
### Event Emitter (`__event_emitter__`)
62+
63+
**For more information about Events and Event emitters, [see here](https://docs.openwebui.com/features/plugin/events/).**
64+
65+
Send real-time updates to the frontend during action execution:
66+
67+
```python
68+
async def action(self, body: dict, __event_emitter__=None):
69+
# Send status updates
70+
await __event_emitter__({
71+
"type": "status",
72+
"data": {"description": "Processing request..."}
73+
})
74+
75+
# Send notifications
76+
await __event_emitter__({
77+
"type": "notification",
78+
"data": {"type": "info", "content": "Action completed successfully"}
79+
})
80+
```
81+
82+
### Event Call (`__event_call__`)
83+
Request user input or confirmation during execution:
84+
85+
```python
86+
async def action(self, body: dict, __event_call__=None):
87+
# Request user confirmation
88+
response = await __event_call__({
89+
"type": "confirmation",
90+
"data": {
91+
"title": "Confirm Action",
92+
"message": "Are you sure you want to proceed?"
93+
}
94+
})
95+
96+
# Request user input
97+
user_input = await __event_call__({
98+
"type": "input",
99+
"data": {
100+
"title": "Enter Value",
101+
"message": "Please provide additional information:",
102+
"placeholder": "Type your input here..."
103+
}
104+
})
105+
```
106+
107+
## Action Types and Configurations
108+
109+
### Single Actions
110+
Standard actions with one `action` method:
111+
112+
```python
113+
async def action(self, body: dict, **kwargs):
114+
# Single action implementation
115+
return {"content": "Action result"}
116+
```
117+
118+
### Multi-Actions
119+
Functions can define multiple sub-actions through an `actions` array:
120+
121+
```python
122+
actions = [
123+
{
124+
"id": "summarize",
125+
"name": "Summarize",
126+
"icon_url": "data:image/svg+xml;base64,..."
127+
},
128+
{
129+
"id": "translate",
130+
"name": "Translate",
131+
"icon_url": "data:image/svg+xml;base64,..."
132+
}
133+
]
134+
135+
async def action(self, body: dict, __id__=None, **kwargs):
136+
if __id__ == "summarize":
137+
# Summarization logic
138+
return {"content": "Summary: ..."}
139+
elif __id__ == "translate":
140+
# Translation logic
141+
return {"content": "Translation: ..."}
142+
```
143+
144+
### Global vs Model-Specific Actions
145+
- **Global Actions** - Turn on the toggle in the Action's settings, to globally enable it for all users and all models.
146+
- **Model-Specific Actions** - Configure enabled actions for specific models in the model settings.
147+
148+
## Advanced Capabilities
42149

43-
response = await __event_call__(
150+
### Background Task Execution
151+
For long-running operations, actions can integrate with the task system:
152+
153+
```python
154+
async def action(self, body: dict, __event_emitter__=None):
155+
# Start long-running process
156+
await __event_emitter__({
157+
"type": "status",
158+
"data": {"description": "Starting background processing..."}
159+
})
160+
161+
# Perform time-consuming operation
162+
result = await some_long_running_function()
163+
164+
return {"content": f"Processing completed: {result}"}
165+
```
166+
167+
### File and Media Handling
168+
Actions can work with uploaded files and generate new media:
169+
170+
```python
171+
async def action(self, body: dict):
172+
message = body
173+
174+
# Access uploaded files
175+
if message.get("files"):
176+
for file in message["files"]:
177+
# Process file based on type
178+
if file["type"] == "image":
179+
# Image processing logic
180+
pass
181+
182+
# Return new files
183+
return {
184+
"content": "Analysis complete",
185+
"files": [
44186
{
45-
"type": "input",
46-
"data": {
47-
"title": "write a message",
48-
"message": "here write a message to append",
49-
"placeholder": "enter your message",
50-
},
187+
"type": "image",
188+
"url": "generated_chart.png",
189+
"name": "Analysis Chart"
51190
}
52-
)
53-
print(response)
191+
]
192+
}
54193
```
55194

56-
</details>
195+
### User Context and Permissions
196+
Actions can access user information and respect permissions:
197+
198+
```python
199+
async def action(self, body: dict, __user__=None):
200+
if __user__["role"] != "admin":
201+
return {"content": "This action requires admin privileges"}
202+
203+
user_name = __user__["name"]
204+
return {"content": f"Hello {user_name}, admin action completed"}
205+
```
57206

58-
### Example - Specifying Action Frontmatter
207+
## Example - Specifying Action Frontmatter
59208

60209
Each Action function can include a docstring at the top to define metadata for the button. This helps customize the display and behavior of your Action in Open WebUI.
61210

62211
Example of supported frontmatter fields:
63-
64212
- `title`: Display name of the Action.
65213
- `author`: Name of the creator.
66214
- `version`: Version number of the Action.
@@ -69,13 +217,100 @@ Example of supported frontmatter fields:
69217

70218
**Base64-Encoded Example:**
71219

220+
<details>
221+
<summary>Example</summary>
222+
72223
```python
73224
"""
74-
title: Summarize Text
75-
author: @you
76-
version: 1.0.0
225+
title: Enhanced Message Processor
226+
author: @admin
227+
version: 1.2.0
77228
required_open_webui_version: 0.5.0
78-
icon_url: data:image/svg+xml;base64,<IMAGE STRING>...
229+
icon_url: data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDJMMTMuMDkgOC4yNkwyMCA5TDEzLjA5IDE1Ljc0TDEyIDIyTDEwLjkxIDE1Ljc0TDQgOUwxMC45MSA4LjI2TDEyIDJaIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHN2Zz4K
230+
requirements: requests,beautifulsoup4
79231
"""
80232

233+
from pydantic import BaseModel
234+
235+
class Action:
236+
def __init__(self):
237+
self.valves = self.Valves()
238+
239+
class Valves(BaseModel):
240+
api_key: str = ""
241+
processing_mode: str = "standard"
242+
243+
async def action(
244+
self,
245+
body: dict,
246+
__user__=None,
247+
__event_emitter__=None,
248+
__event_call__=None,
249+
):
250+
# Send initial status
251+
await __event_emitter__({
252+
"type": "status",
253+
"data": {"description": "Processing message..."}
254+
})
255+
256+
# Get user confirmation
257+
response = await __event_call__({
258+
"type": "confirmation",
259+
"data": {
260+
"title": "Process Message",
261+
"message": "Do you want to enhance this message?"
262+
}
263+
})
264+
265+
if not response:
266+
return {"content": "Action cancelled by user"}
267+
268+
# Process the message
269+
original_content = body.get("content", "")
270+
enhanced_content = f"Enhanced: {original_content}"
271+
272+
return {"content": enhanced_content}
81273
```
274+
275+
</details>
276+
277+
## Best Practices
278+
279+
### Error Handling
280+
Always implement proper error handling in your actions:
281+
282+
```python
283+
async def action(self, body: dict, __event_emitter__=None):
284+
try:
285+
# Action logic here
286+
result = perform_operation()
287+
return {"content": f"Success: {result}"}
288+
except Exception as e:
289+
await __event_emitter__({
290+
"type": "notification",
291+
"data": {"type": "error", "content": f"Action failed: {str(e)}"}
292+
})
293+
return {"content": "Action encountered an error"}
294+
```
295+
296+
### Performance Considerations
297+
- Use async/await for I/O operations
298+
- Implement timeouts for external API calls
299+
- Provide progress updates for long-running operations
300+
- Consider using background tasks for heavy processing
301+
302+
### User Experience
303+
- Always provide clear feedback through event emitters
304+
- Use confirmation dialogs for destructive actions
305+
- Include helpful error messages
306+
307+
## Integration with Open WebUI Features
308+
309+
Actions integrate seamlessly with other Open WebUI features:
310+
- **Models** - Actions can be model-specific or global
311+
- **Tools** - Actions can invoke external tools and APIs
312+
- **Files** - Actions can process uploaded files and generate new ones
313+
- **Memory** - Actions can access conversation history and context
314+
- **Permissions** - Actions respect user roles and access controls
315+
316+
For more examples and community-contributed actions, visit [https://openwebui.com/functions](https://openwebui.com/functions) where you can discover, download, and explore custom functions built by the Open WebUI community.

docs/getting-started/advanced-topics/development.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Before you begin, ensure your system meets these minimum requirements:
1414
- **Operating System:** Linux (or WSL on Windows), Windows 11, or macOS. *(Recommended for best compatibility)*
1515
- **Python:** Version **3.11 or higher**. *(Required for backend services)*
1616
- **Node.js:** Version **22.10 or higher**. *(Required for frontend development)*
17-
- **IDE (Recommended):** We recommend using an IDE like [VSCode](https://code.visualstudio.com/) for code editing, debugging, and integrated terminal access. Feel free to use your favorite IDE if you have one!
17+
- **IDE (Recommended):** We recommend using an IDE like [VS Code](https://code.visualstudio.com/) for code editing, debugging, and integrated terminal access. Feel free to use your favorite IDE if you have one!
1818
- **[Optional] GitHub Desktop:** For easier management of the Git repository, especially if you are less familiar with command-line Git, consider installing [GitHub Desktop](https://desktop.github.com/).
1919

2020
## Setting Up Your Local Environment
@@ -49,7 +49,7 @@ Let's get the user interface (what you see in your browser) up and running first
4949

5050
This command copies the `.env.example` file to a new file named `.env`. The `.env` file is where you'll configure environment variables for the frontend.
5151
52-
- **Customize `.env`**: Open the `.env` file in your code editor (like VSCode). This file contains configuration variables for the frontend, such as API endpoints and other settings. For local development, the default settings in `.env.example` are usually sufficient to start with. However, you can customize them if needed.
52+
- **Customize `.env`**: Open the `.env` file in your code editor (like VS Code). This file contains configuration variables for the frontend, such as API endpoints and other settings. For local development, the default settings in `.env.example` are usually sufficient to start with. However, you can customize them if needed.
5353
5454
**Important:** Do not commit sensitive information to `.env` if you are contributing back to the repository.
5555
@@ -107,17 +107,17 @@ npm run build
107107

108108
We **require** you to use separate terminal instances for your frontend and backend processes. This keeps your workflows organized and makes it easier to manage each part of the application independently.
109109

110-
**Using VSCode Integrated Terminals:**
110+
**Using VS Code Integrated Terminals:**
111111

112-
VSCode's integrated terminal feature makes managing multiple terminals incredibly easy. Here's how to leverage it for frontend and backend separation:
112+
VS Code's integrated terminal feature makes managing multiple terminals incredibly easy. Here's how to leverage it for frontend and backend separation:
113113

114-
1. **Frontend Terminal (You likely already have this):** If you followed the Frontend Setup steps, you probably already have a terminal open in VSCode at the project root (`open-webui` directory). This is where you'll run your frontend commands (`npm run dev`, etc.). Ensure you are in the `open-webui` directory for the next steps if you are not already.
114+
1. **Frontend Terminal (You likely already have this):** If you followed the Frontend Setup steps, you probably already have a terminal open in VS Code at the project root (`open-webui` directory). This is where you'll run your frontend commands (`npm run dev`, etc.). Ensure you are in the `open-webui` directory for the next steps if you are not already.
115115
116116
2. **Backend Terminal (Open a New One):**
117-
- In VSCode, go to **Terminal > New Terminal** (or use the shortcut `Ctrl+Shift+` on Windows/Linux or `Cmd+Shift+` on macOS). This will open a new integrated terminal panel.
117+
- In VS Code, go to **Terminal > New Terminal** (or use the shortcut `Ctrl+Shift+` on Windows/Linux or `Cmd+Shift+` on macOS). This will open a new integrated terminal panel.
118118
- **Navigate to the `backend` directory:** In this *new* terminal, use the `cd backend` command to change the directory to the `backend` folder within your project. This ensures all backend-related commands are executed in the correct context.
119119
120-
Now you have **two separate terminal instances within VSCode**: one for the frontend (likely in the `open-webui` directory) and one specifically for the backend (inside the `backend` directory). You can easily switch between these terminals within VSCode to manage your frontend and backend processes independently. This setup is highly recommended for a cleaner and more efficient development workflow.
120+
Now you have **two separate terminal instances within VS Code**: one for the frontend (likely in the `open-webui` directory) and one specifically for the backend (inside the `backend` directory). You can easily switch between these terminals within VS Code to manage your frontend and backend processes independently. This setup is highly recommended for a cleaner and more efficient development workflow.
121121
122122
**Backend Setup Steps (in your *backend* terminal):**
123123

0 commit comments

Comments
 (0)