diff --git a/docs/contributing.mdx b/docs/contributing.mdx
index 23c1c3ae1f..d8d7392b5a 100644
--- a/docs/contributing.mdx
+++ b/docs/contributing.mdx
@@ -11,6 +11,12 @@ import { TopBanners } from "@site/src/components/TopBanners";
Your interest in contributing to Open WebUI is greatly appreciated. This document is here to guide you through the process, ensuring your contributions enhance the project effectively. Let's make Open WebUI even better, together!
+## 📜 Code of Conduct
+
+All contributors and community participants are expected to follow our **[Code of Conduct](https://github.com/open-webui/open-webui/blob/main/CODE_OF_CONDUCT.md)**. We operate under a **zero-tolerance policy** — disrespectful, demanding, or hostile behavior will result in immediate action without prior warning.
+
+Our community is built on the work of volunteers who dedicate their free time to this project. Please treat every interaction with professionalism and respect.
+
## 💡 Contributing
Looking to contribute? Great! Here's how you can help:
@@ -79,7 +85,7 @@ Let's make Open WebUI usable for *everyone*.
### 🤔 Questions & Feedback
-Got questions or feedback? Join our [Discord community](https://discord.gg/5rJgQTnV4s) or open an issue. We're here to help!
+Got questions or feedback? Join our [Discord community](https://discord.gg/5rJgQTnV4s), visit our [Reddit](https://www.reddit.com/r/OpenWebUI/), or open an issue. We're here to help!
### 🚨 Reporting Issues
@@ -91,6 +97,8 @@ Noticed something off? Have an idea? Check our [Issues tab](https://github.com/o
- **Detail is Key:** To ensure your issue is understood and can be effectively addressed, it's imperative to include comprehensive details. Descriptions should be clear, including steps to reproduce, expected outcomes, and actual results. Lack of sufficient detail may hinder our ability to resolve your issue.
+- **Respectful Communication:** All interactions — including issue reports and discussions — fall under our **[Code of Conduct](https://github.com/open-webui/open-webui/blob/main/CODE_OF_CONDUCT.md)**. Hostile, entitled, or demanding behavior toward contributors will not be tolerated.
+
:::
### 🧭 Scope of Support
diff --git a/docs/faq.mdx b/docs/faq.mdx
index b8c9d70859..81467d59d9 100644
--- a/docs/faq.mdx
+++ b/docs/faq.mdx
@@ -7,6 +7,26 @@ import { TopBanners } from "@site/src/components/TopBanners";
+### Q: How can I get support or ask for help?
+
+**A:** Open WebUI is a community-driven, open-source project. Support is provided by **volunteers** who contribute their time and expertise for free — there is no dedicated support team, and no one is obligated to provide personalized or on-demand assistance.
+
+**To get the best help:**
+1. **Search first.** Check these docs, [Discord](https://discord.gg/5rJgQTnV4s), [Reddit](https://www.reddit.com/r/OpenWebUI/), [GitHub Discussions](https://github.com/open-webui/open-webui/discussions), and [Issues](https://github.com/open-webui/open-webui/issues) — your question may already be answered.
+2. **Try the Discord bot.** In our [Discord server](https://discord.gg/5rJgQTnV4s)'s **#questions** channel, we have an experimental bot that has access to all issues, all discussions, and the entire documentation. Simply ping the bot with your question in the same message, wait a few seconds, and it will answer you. As our documentation improves, so does the bot.
+3. **Provide details.** When asking for help, always include: your Open WebUI version, deployment method (Docker/pip), model provider and model name, relevant settings (screenshots of the Admin Panel section are ideal), and steps to reproduce the issue.
+4. **Be respectful.** Contributors are volunteers. Demanding, entitled, or hostile behavior is not tolerated and will result in immediate enforcement under our **[Code of Conduct](https://github.com/open-webui/open-webui/blob/main/CODE_OF_CONDUCT.md)**.
+
+**Where to ask:**
+- 🤖 **Quick Answers**: [Discord #questions channel](https://discord.gg/5rJgQTnV4s) — try the bot first, it can answer most Open WebUI questions
+- 🐛 **Bugs**: [GitHub Issues](https://github.com/open-webui/open-webui/issues) — you **must** use the issue template and provide all requested information (Open WebUI version, browser, deployment method, expected vs. actual behavior, and logs). Most importantly, your report **must include clear steps to reproduce the issue along with all relevant settings** to replicate the situation. If we cannot reproduce it, we will not investigate it. Reports that skip the template or omit key details will be closed without investigation or converted to discussions. Our contributors are volunteers — incomplete reports waste their limited time.
+- 💬 **Questions & Help**: [Discord](https://discord.gg/5rJgQTnV4s) (most active community), [Reddit](https://www.reddit.com/r/OpenWebUI/), or [GitHub Discussions](https://github.com/open-webui/open-webui/discussions)
+- 💡 **Feature Requests**: [GitHub Discussions](https://github.com/open-webui/open-webui/discussions/new/choose)
+
+:::important
+All participants in the Open WebUI community are expected to follow our **[Code of Conduct](https://github.com/open-webui/open-webui/blob/main/CODE_OF_CONDUCT.md)**, which operates under a **zero-tolerance policy**. Unacceptable behavior — including hostility, entitlement, or persistent negativity toward contributors — will result in immediate action without prior warning.
+:::
+
### Q: How do I customize the logo and branding?
**A:** You can customize the theme, logo, and branding with our **[Enterprise License](https://docs.openwebui.com/enterprise)**, which unlocks exclusive enterprise features.
@@ -17,6 +37,14 @@ For more details on enterprise solutions and branding customizations, [click her
**A:** No, your data is never sent anywhere unless you explicitly choose to share it or you connect an external model provider. Everything inside Open WebUI runs and is stored locally on your machine or server, giving you full control over your data at all times. We encourage you not to simply take our word for it: our entire codebase is hosted publicly, so you can inspect exactly how everything works, and if you ever notice anything concerning, please report it to us on our repo immediately.
+### Q: How can I see a list of all the chats I've ever shared?
+
+**A:** Open WebUI provides a centralized **Shared Chats** dashboard where you can see every link you've generated. This is available to all users via **Settings > Data Controls > Shared Chats > Manage**. From there, you can search through your shared history, re-copy links, or revoke (unshare) access to any conversation instantly.
+
+### Q: How can I manage or delete files I've uploaded?
+
+**A:** You can access the **File Manager** by going to **Settings > Data Controls > Manage Files > Manage**. This dashboard allows you to search through all your uploaded documents, view their details, and delete them. Deleting a file here also automatically cleans up any associated Knowledge Base entries and vector embeddings.
+
### Q: Can I use Open WebUI in outer space (e.g., Mars and beyond) or other extreme environments?
**A:** **Yes.** Open WebUI is fully self-hosted and does not rely on persistent internet connectivity, making it suitable for environments where cloud-based systems are impractical or impossible. As long as the underlying hardware can run a supported runtime, Open WebUI will function normally regardless of location.
@@ -165,7 +193,7 @@ def wait_for_processing(token, file_id):
time.sleep(2) # Wait before checking again
```
-For complete workflow examples, see the **[API Endpoints documentation](/getting-started/api-endpoints#checking-file-processing-status)** and the **[RAG Troubleshooting guide](/troubleshooting/rag#9-api-file-upload-the-content-provided-is-empty-error-)**.
+For complete workflow examples, see the **[API Endpoints documentation](/getting-started/api-endpoints#checking-file-processing-status)** and the **[RAG Troubleshooting guide](/troubleshooting/rag#9-api-file-upload-the-content-provided-is-empty-error)**.
### Q: I asked the model what it is and it gave the wrong answer. Is Open WebUI routing to the wrong model?
@@ -217,15 +245,64 @@ For more optimization tips, see the **[Performance Tips Guide](troubleshooting/p
### Q: Is MCP (Model Context Protocol) supported in Open WebUI?
-**A:** Yes, Open WebUI now includes **native support for MCP Streamable HTTP**, enabling direct, first-class integration with MCP tools that communicate over the standard HTTP transport. For any **other MCP transports or non-HTTP implementations**, you should use our official proxy adapter, **MCPO**, available at 👉 [https://github.com/open-webui/mcpo](https://github.com/open-webui/mcpo). MCPO provides a unified OpenAPI-compatible layer that bridges alternative MCP transports into Open WebUI safely and consistently. This architecture ensures maximum compatibility, strict security boundaries, and predictable tool behavior across different environments while keeping Open WebUI backend-agnostic and maintainable.
+**A:** Yes, Open WebUI includes **native support for MCP Streamable HTTP**, enabling direct, first-class integration with MCP tools that communicate over the standard HTTP transport. For any **other MCP transports or non-HTTP implementations**, you should use our official proxy adapter, **MCPO**, available at 👉 [https://github.com/open-webui/mcpo](https://github.com/open-webui/mcpo). MCPO provides a unified OpenAPI-compatible layer that bridges alternative MCP transports into Open WebUI safely and consistently. This architecture ensures maximum compatibility, strict security boundaries, and predictable tool behavior across different environments while keeping Open WebUI backend-agnostic and maintainable.
+
+### Q: Why doesn't Open WebUI natively support [Provider X]'s proprietary API?
+
+**A:** Open WebUI is highly modular with a plugin system including tools, functions, and most notably **[pipes](/features/plugin/functions/pipe)**. These modular pipes allow you to add support for virtually any provider you want—you can build your own or choose from the many [community-built](https://openwebui.com/) and usually well-maintained ones already available.
+
+That said, Open WebUI's core is built around **universal protocols**, not specific providers. Our stance is to support standard, widely-adopted APIs like the **OpenAI Chat Completions protocol**.
+
+This protocol-centric design ensures that Open WebUI remains backend-agnostic and compatible with dozens of providers simultaneously. We avoid implementing proprietary, provider-specific APIs in the core to prevent unsustainable architectural bloat and to maintain a truly open ecosystem.
-### Q: Why doesn't Open WebUI support [Specific Provider]'s latest API (e.g. OpenAI Responses API)?
+:::note Experimental: Open Responses
+As new standards emerge that gain broad adoption, we may add experimental support. Connections can now optionally be configured to use **[Open Responses](https://www.openresponses.org/)**—an open specification for multi-provider interoperability with consistent streaming events and tool use patterns.
+:::
+
+We understand this request comes up frequently, especially for major providers. Here's why we've made this deliberate architectural decision:
+
+#### 1. The Cascading Demand Problem
+
+Supporting one proprietary API sets a precedent. Once that precedent exists, every other major provider becomes a reasonable request. What starts as "just one provider" quickly becomes many integrations, each with their own quirks, authentication schemes, and breaking changes.
+
+#### 2. Maintenance is the Real Burden
+
+Adding integration code is the easy part. **Maintaining it forever** is where the real cost lies:
+- Each provider updates their API independently—when a provider changes something, we must update and test immediately
+- Changes in one integration can break compatibility with others
+- Every integration requires ongoing testing across multiple scenarios
+- Bug reports flood in for each provider whenever they make changes
+
+Contributors are **volunteers with full-time jobs**. Asking them to maintain 10+ provider integrations indefinitely is not sustainable.
-**A:** Open WebUI is built around **universal protocols**, not specific providers. Our core philosophy is to support standard, widely-adopted APIs like the **OpenAI Chat Completions protocol**.
+#### 3. Technical Complexity
-This protocol-centric design ensures that Open WebUI remains backend-agnostic and compatible with dozens of providers (like OpenRouter, LiteLLM, vLLM, and Groq) simultaneously. We avoid implementing proprietary, provider-specific APIs (such as OpenAI's stateful Responses API or Anthropic's Messages API) to prevent unsustainable architectural bloat and to maintain a truly open ecosystem.
+Each provider has different approaches to:
+- Reasoning/thinking content format and structure
+- Tool calling schemas and response formats
+- Authentication and request signing
+- Error handling and rate limiting
-If you need functionality exclusive to a proprietary API (like OpenAI's hidden reasoning traces), we recommend using a proxy like **LiteLLM** or **OpenRouter**, which translate those proprietary features into the standard Chat Completions protocol that Open WebUI supports.
+This requires provider-specific logic throughout both the backend and frontend, significantly increasing the codebase complexity and tech debt.
+
+#### 4. Scale and Stability Requirements
+
+Open WebUI is used by major organizations worldwide. At this scale, stability is paramount—extensive testing and backwards compatibility guarantees become exponentially harder with each added provider.
+
+#### 5. Pipes are the Modular Solution
+
+The pipes architecture exists precisely to solve this problem. One-click install a community pipe and you get full provider API support. This is exactly the modularity that allows:
+- Community members to maintain provider-specific integrations
+- Users to choose only what they need
+- The core project to remain stable and maintainable
+
+:::tip The Recommended Path
+For providers that don't follow widely adopted API standards, use:
+- **[Open WebUI community](https://openwebui.com/)**: Community-maintained provider integrations (one-click install)
+- **Middleware proxies**: Tools like LiteLLM or OpenRouter can translate proprietary APIs to widely adopted API formats
+
+These solutions exist specifically to bridge the gap, and they're maintained by teams dedicated to that purpose.
+:::
### Q: Why is the frontend integrated into the same Docker image? Isn't this unscalable or problematic?
@@ -272,4 +349,4 @@ We review every report in good faith and handle all submissions discreetly. Prot
### Need Further Assistance?
-If you have any further questions or concerns, please reach out to our [GitHub Issues page](https://github.com/open-webui/open-webui/issues) or our [Discord channel](https://discord.gg/5rJgQTnV4s) for more help and information.
+If you have any further questions or concerns, please reach out on our [Discord server](https://discord.gg/5rJgQTnV4s), [Reddit community](https://www.reddit.com/r/OpenWebUI/), [GitHub Issues](https://github.com/open-webui/open-webui/issues), or [GitHub Discussions](https://github.com/open-webui/open-webui/discussions) for more help and information. Please remember that all community interactions are governed by our **[Code of Conduct](https://github.com/open-webui/open-webui/blob/main/CODE_OF_CONDUCT.md)**.
diff --git a/docs/features/analytics/index.mdx b/docs/features/analytics/index.mdx
new file mode 100644
index 0000000000..3a23fad9fc
--- /dev/null
+++ b/docs/features/analytics/index.mdx
@@ -0,0 +1,407 @@
+---
+sidebar_position: 1050
+title: "Analytics"
+---
+
+# Analytics
+
+The **Analytics** feature in Open WebUI provides administrators with comprehensive insights into usage patterns, token consumption, and model performance across their instance. This powerful tool helps you understand how your users are interacting with AI models and make data-driven decisions about resource allocation and model selection.
+
+:::info Admin-Only Feature
+Analytics is only accessible to users with **admin** role. Access it via **Admin Panel > Analytics**.
+:::
+
+## Overview
+
+The Analytics dashboard gives you a bird's-eye view of your Open WebUI instance's activity, including:
+
+- **Message volume** across different models and time periods
+- **Token usage** tracking for cost estimation and resource planning
+- **User activity** patterns to understand engagement
+- **Time-series data** showing trends over hours, days, or months
+
+All analytics data is derived from the message history stored in your instance's database. When the Analytics feature is enabled, Open WebUI automatically tracks and indexes messages to provide fast, queryable insights.
+
+---
+
+## Accessing Analytics
+
+1. Log in with an **admin** account
+2. Navigate to **Admin Panel** (click your profile icon → Admin Panel)
+3. Click on the **Analytics** tab in the admin navigation
+
+---
+
+## Dashboard Features
+
+### Time Period Selection
+
+At the top right of the Analytics dashboard, you can filter all data by time period:
+
+- **Last 24 hours** - Hourly granularity for real-time monitoring
+- **Last 7 days** - Daily overview of the past week
+- **Last 30 days** - Monthly snapshot
+- **Last 90 days** - Quarterly trends
+- **All time** - Complete historical data
+
+Your selected time period is **automatically saved** and persists across browser sessions.
+
+### Group Filtering
+
+If you have [user groups](/features/rbac/groups) configured, the Analytics dashboard allows filtering by group:
+
+- Use the **group dropdown** next to the time period selector
+- Select a specific group to view analytics **only for users in that group**
+- Choose "All Users" to see instance-wide analytics
+
+This is useful for:
+- **Department-level reporting** - Track usage for specific teams
+- **Cost allocation** - Attribute token consumption to business units
+- **Pilot programs** - Monitor adoption within test groups
+
+All metrics on the page update automatically when you change the time period or group filter.
+
+### Summary Statistics
+
+The dashboard header displays key metrics for the selected time period:
+
+- **Total Messages** - Number of assistant responses generated
+- **Total Tokens** - Sum of all input and output tokens processed
+- **Total Chats** - Number of unique conversations
+- **Total Users** - Number of users who sent messages
+
+:::note Message Counting
+Analytics counts **assistant responses** rather than user messages. This provides a more accurate measure of AI model usage and token consumption.
+:::
+
+### Message Timeline Chart
+
+The interactive timeline chart visualizes message volume over time, broken down by model. Key features:
+
+- **Hourly or Daily granularity** - Automatically adjusts based on selected time period
+- **Multi-model visualization** - Shows up to 8 models with distinct colors
+- **Hover tooltips** - Display exact counts and percentages for each model at any point in time
+- **Trend identification** - Quickly spot usage patterns, peak hours, and model adoption
+
+This chart helps you:
+- Identify busy periods for capacity planning
+- Track model adoption after deployment
+- Detect unusual activity spikes
+- Monitor the impact of changes or announcements
+
+### Model Usage Table
+
+A detailed breakdown of how each model is being used:
+
+| Column | Description |
+|--------|-------------|
+| **#** | Rank by message count |
+| **Model** | Model name with icon |
+| **Messages** | Total assistant responses generated |
+| **Tokens** | Total tokens (input + output) consumed |
+| **%** | Percentage share of total messages |
+
+**Features:**
+- **Sortable columns** - Click column headers to sort by name or message count
+- **Model icons** - Visual identification with profile images
+- **Token tracking** - See which models consume the most resources
+- **Clickable rows** - Click any model to open the [Model Details Modal](#model-details-modal)
+
+**Use cases:**
+- Identify your most popular models
+- Calculate cost per model (by multiplying tokens by provider rates)
+- Decide which models to keep or remove
+- Plan infrastructure upgrades based on usage
+
+### Model Details Modal
+
+Clicking on any model row opens a detailed modal with two tabs:
+
+#### Overview Tab
+
+The Overview tab provides:
+
+- **Feedback Activity Chart** - Visual history of user feedback (thumbs up/down) over time
+ - Toggle between **30 days**, **1 year**, or **All time** views
+ - Weekly aggregation for longer time ranges
+- **Tags** - Most common chat tags associated with this model (top 10)
+
+This helps you understand:
+- How users perceive model quality over time
+- Which topics/use cases the model is handling
+- Trends in user satisfaction
+
+#### Chats Tab
+
+:::info Admin Chat Access Required
+The Chats tab is only visible when **Admin Chat Access** is enabled in your instance settings.
+:::
+
+The Chats tab shows conversations that used this model:
+
+- **User info** - Who started each chat
+- **Preview** - First message of each conversation
+- **Timestamp** - When the chat was last updated
+- **Click to open** - Navigate directly to the shared chat view
+
+This is useful for:
+- Understanding how users interact with specific models
+- Auditing model usage for quality assurance
+- Finding example conversations for training or documentation
+
+### User Activity Table
+
+Track user engagement and token consumption per user:
+
+| Column | Description |
+|--------|-------------|
+| **#** | Rank by activity |
+| **User** | Username with profile picture |
+| **Messages** | Total messages sent by this user |
+| **Tokens** | Total tokens consumed by this user |
+
+**Features:**
+- **Sortable columns** - Organize by name or activity level
+- **User identification** - Profile pictures and display names
+- **Token attribution** - See resource consumption per user
+
+**Use cases:**
+- Monitor power users and their token consumption
+- Identify inactive or low-usage accounts
+- Plan user quotas or rate limits
+- Calculate per-user costs for billing purposes
+
+---
+
+## Token Usage Tracking
+
+### What Are Tokens?
+
+Tokens are the units that language models use to process text. Both the **input** (your prompt) and **output** (the model's response) consume tokens. Most AI providers charge based on token usage, making token tracking essential for cost management.
+
+### How Token Tracking Works
+
+Open WebUI automatically captures token usage from model responses and stores it with each message. The Analytics feature aggregates this data to show:
+
+- **Input tokens** - Tokens in user prompts and context
+- **Output tokens** - Tokens in model responses
+- **Total tokens** - Sum of input and output
+
+Token data is normalized across different model providers (OpenAI, Ollama, llama.cpp, etc.) to provide consistent metrics regardless of which backend you're using.
+
+### Token Usage Metrics
+
+The **Token Usage** section (accessible via the Tokens endpoint or dashboard) provides:
+
+- **Per-model token breakdown** - Input, output, and total tokens for each model
+- **Total token consumption** - Instance-wide token usage
+- **Message count correlation** - Tokens per message for efficiency analysis
+
+:::tip Cost Estimation
+To estimate costs, multiply the token counts by your provider's pricing:
+```
+Cost = (input_tokens × input_price) + (output_tokens × output_price)
+```
+
+Example for GPT-4:
+- Input: 1,000,000 tokens × $0.03/1K = $30
+- Output: 500,000 tokens × $0.06/1K = $30
+- **Total: $60**
+:::
+
+---
+
+## Use Cases
+
+### 1. Resource Planning
+
+**Scenario:** You're running Open WebUI for a team and need to plan infrastructure capacity.
+
+**How Analytics helps:**
+- View the **Message Timeline** to identify peak usage hours
+- Check **Model Usage** to see which models need more resources
+- Monitor **Token Usage** to estimate future costs
+- Track **User Activity** to plan for team growth
+
+### 2. Model Evaluation
+
+**Scenario:** You've deployed several models and want to know which ones your users prefer.
+
+**How Analytics helps:**
+- Compare **message counts** across models to see adoption rates
+- Check **token efficiency** (tokens per message) to identify verbose models
+- Monitor **trends** in the timeline chart after introducing new models
+- Combine with the [Evaluation feature](../evaluation/index.mdx) for quality insights
+
+### 3. Cost Management
+
+**Scenario:** You're using paid API providers and need to control costs.
+
+**How Analytics helps:**
+- Track **total token consumption** by model and user
+- Identify **high-usage users** for quota discussions
+- Compare **token costs** across different model providers
+- Set up regular reviews using time-period filters
+
+### 4. User Engagement
+
+**Scenario:** You want to understand how your team is using AI tools.
+
+**How Analytics helps:**
+- Monitor **active users** vs. registered accounts
+- Identify **power users** who might need support or training
+- Track **adoption trends** over time
+- Correlate usage with team initiatives or training sessions
+
+### 5. Compliance & Auditing
+
+**Scenario:** Your organization requires usage reporting for compliance.
+
+**How Analytics helps:**
+- Generate **activity reports** for specific time periods
+- Track **user attribution** for all AI interactions
+- Monitor **model usage** for approved vs. unapproved models
+- Export data via API for external reporting tools
+
+---
+
+## Technical Details
+
+### Data Storage
+
+Analytics data is stored in the `chat_message` table, which contains:
+
+- **Message content** - User and assistant messages
+- **Metadata** - Model ID, user ID, timestamps
+- **Token usage** - Input, output, and total tokens
+- **Relationships** - Links to parent messages and chats
+
+When you enable Analytics (via migration), Open WebUI:
+1. Creates the `chat_message` table with optimized indexes
+2. **Backfills existing messages** from your chat history
+3. **Dual-writes** new messages to both the chat JSON and the message table
+
+This dual-write approach ensures:
+- **Backward compatibility** - Existing features continue working
+- **Fast queries** - Analytics doesn't impact chat performance
+- **Data consistency** - All messages are captured
+
+### Database Indexes
+
+The following indexes optimize analytics queries:
+
+- `chat_id` - Fast lookup of all messages in a chat
+- `user_id` - Quick user activity reports
+- `model_id` - Efficient model usage queries
+- `created_at` - Time-range filtering
+- Composite indexes for common query patterns
+
+### API Endpoints
+
+For advanced users and integrations, Analytics provides REST API endpoints:
+
+**Dashboard Endpoints:**
+```
+GET /api/v1/analytics/summary
+GET /api/v1/analytics/models
+GET /api/v1/analytics/users
+GET /api/v1/analytics/messages
+GET /api/v1/analytics/daily
+GET /api/v1/analytics/tokens
+```
+
+**Model Detail Endpoints:**
+```
+GET /api/v1/analytics/models/{model_id}/chats # Get chats using this model
+GET /api/v1/analytics/models/{model_id}/overview # Get feedback history and tags
+```
+
+**Common Query Parameters:**
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `start_date` | int | Unix timestamp (epoch seconds) - start of range |
+| `end_date` | int | Unix timestamp (epoch seconds) - end of range |
+| `group_id` | string | Filter to a specific user group (optional) |
+
+:::tip API Access
+All Analytics endpoints require admin authentication. Include your admin bearer token:
+```bash
+curl -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
+ "https://your-instance.com/api/v1/analytics/summary?group_id=abc123"
+```
+:::
+
+---
+
+## Privacy & Data Considerations
+
+### What Gets Tracked?
+
+Analytics tracks:
+- ✅ Message timestamps and counts
+- ✅ Token usage per message
+- ✅ Model IDs and user IDs
+- ✅ Chat IDs and message relationships
+
+Analytics **does not** track:
+- ❌ Message content display in the dashboard (only metadata)
+- ❌ External sharing or exports
+- ❌ Individual message content outside the database
+
+### Data Retention
+
+Analytics data follows your instance's chat retention policy. When you delete:
+- **A chat** - All associated messages are removed from analytics
+- **A user** - All their messages are disassociated
+- **Message history** - Analytics data is also cleared
+
+---
+
+## Frequently Asked Questions
+
+### Why are message counts different from what I expected?
+
+Analytics counts **assistant responses**, not user messages. If a chat has 10 user messages and 10 assistant responses, the count is 10. This provides a more accurate measure of AI usage and token consumption.
+
+### How accurate is token tracking?
+
+Token accuracy depends on your model provider:
+- **OpenAI/Anthropic** - Exact counts from API responses
+- **Ollama** - Accurate for models with token reporting
+- **llama.cpp** - Reports tokens when available
+- **Custom providers** - Depends on implementation
+
+Missing token data appears as 0 in analytics.
+
+### Can I export analytics data?
+
+Yes, via the API endpoints. Use tools like `curl`, Python scripts, or BI tools to fetch and export data:
+
+```bash
+curl -H "Authorization: Bearer TOKEN" \
+ "https://instance.com/api/v1/analytics/summary?start_date=1704067200&end_date=1706745600" \
+ > analytics_export.json
+```
+
+---
+
+## Summary
+
+Open WebUI's Analytics feature transforms your instance into a data-driven platform by providing:
+
+- 📊 **Real-time insights** into model and user activity
+- 💰 **Token tracking** for cost management and optimization
+- 📈 **Trend analysis** to understand usage patterns over time
+- 👥 **User engagement** metrics for community building
+- 🔒 **Privacy-focused** design keeping all data on your instance
+
+Whether you're managing a personal instance or a large organizational deployment, Analytics gives you the visibility needed to optimize performance, control costs, and better serve your users.
+
+---
+
+## Related Features
+
+- [**Evaluation**](../evaluation/index.mdx) - Measure model quality through user feedback
+- [**RBAC**](../rbac/index.mdx) - Control access to models and features per user
+- [**Data Controls**](../data-controls/index.mdx) - Manage chat history and exports
diff --git a/docs/features/auth/sso/index.mdx b/docs/features/auth/sso/index.mdx
index aff93fb023..4b58eb89a6 100644
--- a/docs/features/auth/sso/index.mdx
+++ b/docs/features/auth/sso/index.mdx
@@ -39,6 +39,7 @@ You cannot have Microsoft **and** Google as OIDC providers simultaneously.
| `OAUTH_SESSION_TOKEN_ENCRYPTION_KEY` | `WEBUI_SECRET_KEY` | A secret key for encrypting OAuth tokens stored on the server. Must be shared across all instances in a cluster. |
| `OAUTH_CLIENT_INFO_ENCRYPTION_KEY` | `WEBUI_SECRET_KEY` | A secret key for encrypting OAuth client information stored on the server - used for OAuth 2.1 authentication for MCP servers. |
| `ENABLE_OAUTH_ID_TOKEN_COOKIE` | `true` | For backward compatibility. Controls if the legacy `oauth_id_token` cookie is set. Recommended to set to `false`. |
+| `ENABLE_OAUTH_TOKEN_EXCHANGE` | `false` | Enables the token exchange endpoint for external apps to exchange OAuth tokens for Open WebUI JWTs. |
:::warning
@@ -69,6 +70,14 @@ This system is enabled by default but can be fine-tuned with the environment var
For more information, check out the [environment variable docs page](https://docs.openwebui.com/getting-started/env-configuration/).
+### OAuth Token Exchange for External Applications
+
+Open WebUI also supports **OAuth Token Exchange**, allowing external applications to authenticate with Open WebUI by exchanging an OAuth provider's access token for an Open WebUI JWT session token. This is useful for programmatic access from scripts, CLI tools, or services that already have OAuth tokens from your identity provider.
+
+**Example use case:** A CLI tool that has obtained an OAuth access token from your identity provider can exchange it for an Open WebUI token to make API calls to Open WebUI.
+
+To enable this feature, set `ENABLE_OAUTH_TOKEN_EXCHANGE=true`. See the [`ENABLE_OAUTH_TOKEN_EXCHANGE`](/getting-started/env-configuration#enable_oauth_token_exchange) environment variable documentation for details on usage, request/response examples, and security considerations.
+
### Google
To configure a Google OAuth client, please refer to [Google's documentation](https://support.google.com/cloud/answer/6158849) on how to create a Google OAuth client for a **web application**.
diff --git a/docs/features/chat-features/chatshare.md b/docs/features/chat-features/chatshare.md
index 619162d070..e20bf03ba5 100644
--- a/docs/features/chat-features/chatshare.md
+++ b/docs/features/chat-features/chatshare.md
@@ -110,3 +110,9 @@ Once deleted, the shared link will no longer be valid, and users will not be abl
4. Click on the chat you wish to change permission access for.
5. Scroll to the bottom of the chat and update its permission level.
6. Click the **Update Chat** button.
+
+### Managing Shared Chats
+
+Open WebUI provides a centralized dashboard to manage every chat conversation you have shared. From there you can search through your shared history, re-copy links, or revoke access instantly.
+
+For details on the management dashboard, see [Shared Chats Management](/features/data-controls/shared-chats).
diff --git a/docs/features/chat-features/code-execution/index.md b/docs/features/chat-features/code-execution/index.md
index 74d2660ee0..3468f506cf 100644
--- a/docs/features/chat-features/code-execution/index.md
+++ b/docs/features/chat-features/code-execution/index.md
@@ -7,7 +7,9 @@ Open WebUI offers powerful code execution capabilities directly within your chat
## Key Features
-- **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.
+- **Code Interpreter Capability**: Enable models to autonomously write and execute Python code as part of their responses. Works with both Default Mode (XML-based) and Native Mode (tool calling via `execute_code`).
+
+- **Python Code Execution**: Run Python scripts directly in your browser using Pyodide, or on a server using Jupyter. Supports popular libraries like pandas and matplotlib with no setup required.
- **MermaidJS Rendering**: Create and visualize flowcharts, diagrams, and other visual representations with MermaidJS syntax that automatically renders in your chat.
diff --git a/docs/features/chat-features/code-execution/python.md b/docs/features/chat-features/code-execution/python.md
index 8c5bbc6173..35d663f771 100644
--- a/docs/features/chat-features/code-execution/python.md
+++ b/docs/features/chat-features/code-execution/python.md
@@ -50,6 +50,20 @@ These settings can be configured at **Admin Panel → Settings → Code Executio
For Jupyter configuration, see the [Jupyter Notebook Integration](/tutorials/integrations/jupyter) tutorial.
+### Native Function Calling (Native Mode)
+
+When using **Native function calling mode** with a capable model (e.g., GPT-5, Claude 4.5, MiniMax M2.1), the code interpreter is available as a builtin tool called `execute_code`. This provides a more integrated experience:
+
+- **No XML tags required**: The model calls `execute_code(code)` directly
+- **Same image handling**: Base64 image URLs in output are replaced with file URLs; model embeds via markdown
+
+**Requirements:**
+1. `ENABLE_CODE_INTERPRETER` must be enabled globally
+2. Model must have `code_interpreter` capability enabled
+3. Model must use **Native** function calling mode (set in model's advanced params)
+
+For more details on builtin tools and native mode, see the [Tool Development Guide](/features/plugin/tools#built-in-system-tools-nativeagentic-mode).
+
## Displaying Images Inline (matplotlib, etc.)
When using matplotlib or other visualization libraries, images can be displayed directly in the chat. For this to work correctly, the code must output the image as a **base64 data URL**.
@@ -92,9 +106,7 @@ If you see raw base64 text appearing in chat responses, the model is incorrectly
### Example Prompt
-> Create a bar chart showing quarterly sales: Q1: 150, Q2: 230, Q3: 180, Q4: 310.
-> Use matplotlib, save the figure to a BytesIO buffer, encode it as base64, and print the data URL.
-> After the code runs, use the resulting file URL from the output to display the image in your response.
+> Create a bar chart showing quarterly sales: Q1: 150, Q2: 230, Q3: 180, Q4: 310.
**Expected model behavior:**
1. Model writes Python code using the base64 pattern above
@@ -175,6 +187,32 @@ plt.close()
The image will be automatically uploaded and displayed inline in your chat.
+## Browser Compatibility
+
+### Microsoft Edge: Pyodide Crashes
+
+If Pyodide-based code execution causes Microsoft Edge to crash with a `STATUS_ACCESS_VIOLATION` error, this is caused by Edge's enhanced security mode.
+
+**Symptom:** The browser tab or entire browser crashes when attempting to run Python code, with no useful error message.
+
+**Cause:** Edge's "Enhance your security on the web" setting (found at `edge://settings/privacy/security`) enables stricter security mitigations that are incompatible with WebAssembly-based runtimes like Pyodide.
+
+**Solutions:**
+
+1. **Disable enhanced security in Edge:**
+ - Go to `edge://settings/privacy/security`
+ - Turn off **"Enhance your security on the web"**
+
+2. **Use a different browser:**
+ - Chrome and Firefox do not have this issue
+
+3. **Use Jupyter backend:**
+ - Switch `CODE_INTERPRETER_ENGINE` to `jupyter` to avoid browser-based execution entirely
+
+:::note
+This is a known compatibility issue between Edge's enhanced security mode and WebAssembly. The same crash occurs on the official [Pyodide console](https://pyodide.org/en/stable/console.html) when this setting is enabled.
+:::
+
## Tips for Better Results
- **Mention the environment**: Tell the LLM it's running in a "Pyodide environment" or "code interpreter" for better code generation
diff --git a/docs/features/chat-features/follow-up-prompts.md b/docs/features/chat-features/follow-up-prompts.md
new file mode 100644
index 0000000000..d2af865fe3
--- /dev/null
+++ b/docs/features/chat-features/follow-up-prompts.md
@@ -0,0 +1,47 @@
+---
+sidebar_position: 9
+title: "Follow-Up Prompts"
+---
+
+# Follow-Up Prompts
+
+Open WebUI can automatically generate follow-up question suggestions after each model response. These suggestions appear as clickable chips below the response, helping you explore topics further without typing new prompts.
+
+## Settings
+
+Configure follow-up prompt behavior in **Settings > Interface** under the **Chat** section:
+
+### Follow-Up Auto-Generation
+
+**Default: On**
+
+Automatically generates follow-up question suggestions after each response. These suggestions are generated by the [task model](/getting-started/env-configuration#task_model) based on the conversation context.
+
+- **On**: Follow-up prompts are generated after each model response
+- **Off**: No follow-up suggestions are generated
+
+### Keep Follow-Up Prompts in Chat
+
+**Default: Off**
+
+By default, follow-up prompts only appear for the most recent message and disappear when you continue the conversation.
+
+- **On**: Follow-up prompts are preserved and remain visible for all messages in the chat history
+- **Off**: Only the last message shows follow-up prompts
+
+:::tip Perfect for Knowledge Exploration
+Enable this setting when exploring a knowledge base. You can see all the suggested follow-ups from previous responses, making it easy to revisit and explore alternative paths through the information.
+:::
+
+### Insert Follow-Up Prompt to Input
+
+**Default: Off**
+
+Controls what happens when you click a follow-up prompt.
+
+- **On**: Clicking a follow-up inserts the text into the input field, allowing you to edit it before sending
+- **Off**: Clicking a follow-up immediately sends it as your next message
+
+## Regenerating Follow-Ups
+
+If you want to regenerate follow-up suggestions for a specific response, you can use the [Regenerate Followups](https://openwebui.com/f/silentoplayz/regenerate_followups) action button from the community.
diff --git a/docs/features/chat-features/index.mdx b/docs/features/chat-features/index.mdx
index 93f191b8b5..9ac8814f5b 100644
--- a/docs/features/chat-features/index.mdx
+++ b/docs/features/chat-features/index.mdx
@@ -24,3 +24,5 @@ Open WebUI provides a comprehensive set of chat features designed to enhance you
- **[🕒 Temporal Awareness](./temporal-awareness.mdx)**: How models understand time and date, including native tools for precise time calculations.
- **[🧠 Reasoning & Thinking Models](./reasoning-models.mdx)**: Specialized support for models that generate internal chains of thought using thinking tags.
+
+- **[💬 Follow-Up Prompts](./follow-up-prompts.md)**: Automatic generation of suggested follow-up questions after model responses.
diff --git a/docs/features/chat-features/message-queue.mdx b/docs/features/chat-features/message-queue.mdx
new file mode 100644
index 0000000000..93e9e356c8
--- /dev/null
+++ b/docs/features/chat-features/message-queue.mdx
@@ -0,0 +1,111 @@
+---
+sidebar_position: 10
+title: "Message Queue"
+---
+
+# Message Queue
+
+The **Message Queue** feature allows you to continue composing and sending messages while the AI is still generating a response. Instead of blocking your input until the current response completes, your messages are queued and automatically sent in sequence.
+
+---
+
+## How It Works
+
+When you send a message while the AI is generating a response:
+
+1. **Your message is queued** - It appears in a compact queue area just above the input box
+2. **You can continue working** - Add more messages, edit queued messages, or delete them
+3. **Automatic processing** - Once the current response finishes, all queued messages are combined and sent together
+
+This creates a seamless workflow where you can capture thoughts as they come without waiting for the AI to finish.
+
+---
+
+## Queue Management
+
+Each queued message shows three action buttons:
+
+| Action | Icon | Description |
+|--------|------|-------------|
+| **Send Now** | ↑ | Interrupts the current generation and sends this message immediately |
+| **Edit** | ✏️ | Removes the message from the queue and puts it back in the input field |
+| **Delete** | 🗑️ | Removes the message from the queue without sending |
+
+### Combining Messages
+
+When the AI finishes generating, all queued messages are **combined into a single prompt** (separated by blank lines) and sent together. This means:
+
+- Multiple quick thoughts become one coherent message
+- Context flows naturally between your queued inputs
+- The AI receives everything at once for better understanding
+
+---
+
+## Persistence
+
+The message queue is preserved when you navigate between chats within the same browser session:
+
+- **Leaving a chat** - Queue is saved to session storage
+- **Returning to the chat** - Queue is restored and processed
+- **Closing the browser** - Queue is cleared (session storage only)
+
+This means you can start a thought, switch to another chat to check something, and return to find your queued messages waiting.
+
+---
+
+## Settings
+
+You can disable the Message Queue feature if you prefer the traditional behavior:
+
+1. Go to **Settings** → **Interface**
+2. Find **Enable Message Queue** under the Chat section
+3. Toggle it off
+
+When disabled, sending a message while the AI is generating will:
+- **Interrupt** the current generation
+- **Send** your new message immediately
+
+:::tip Default Behavior
+Message Queue is **enabled by default**. The toggle allows you to choose between:
+- **Queue mode** (default) - Messages queue up until generation completes
+- **Interrupt mode** - New messages stop current generation immediately
+:::
+
+---
+
+## Use Cases
+
+### 1. Stream of Consciousness
+
+You're reading an AI response and have follow-up questions. Instead of waiting:
+- Queue your first follow-up
+- Queue a clarification
+- Queue another thought
+
+All are sent together when the AI finishes.
+
+### 2. Adding Context
+
+The AI is working on a complex response, but you remember additional context:
+- Queue the extra information
+- The AI receives it as part of the next message
+
+### 3. Multitasking
+
+You're in a long conversation and need to capture quick notes:
+- Queue messages as reminders
+- Edit or delete before they're sent
+- Use "Send Now" for urgent interruptions
+
+---
+
+## Summary
+
+| Feature | Behavior |
+|---------|----------|
+| **Enabled** | Messages queue during generation, sent together when complete |
+| **Disabled** | New messages interrupt current generation immediately |
+| **Persistence** | Queue survives navigation within session |
+| **Actions** | Send Now, Edit, Delete for each queued item |
+
+The Message Queue helps you maintain your flow of thought without the friction of waiting for AI responses to complete.
diff --git a/docs/features/chat-features/reasoning-models.mdx b/docs/features/chat-features/reasoning-models.mdx
index 5233cf596c..a39a49127d 100644
--- a/docs/features/chat-features/reasoning-models.mdx
+++ b/docs/features/chat-features/reasoning-models.mdx
@@ -347,7 +347,7 @@ Open WebUI serializes reasoning as text wrapped in tags (e.g., `... Data Controls**.
+
+## Resources
+
+- [📁 File Management](./files.md) - Centralized management for all your uploaded documents
+- [🔗 Shared Chats](./shared-chats.md) - Manage and revoke access to your shared chat links
+- [📦 Archived Chats](./archived-chats.md) - Restore or permanently delete archived conversations
+- [💾 Import & Export](./import-export.md) - Backup and restore your chat history
diff --git a/docs/features/data-controls/shared-chats.md b/docs/features/data-controls/shared-chats.md
new file mode 100644
index 0000000000..3382beffa5
--- /dev/null
+++ b/docs/features/data-controls/shared-chats.md
@@ -0,0 +1,44 @@
+---
+sidebar_position: 2
+title: "🔗 Shared Chats"
+---
+
+Open WebUI provides a centralized dashboard to manage every chat conversation you have shared. This feature allows users to audit their shared content and quickly revoke access if needed.
+
+:::info
+This page documents the **management dashboard** for shared chats. For information on how to share chats, see [Chat Sharing](/features/chat-features/chatshare).
+:::
+
+## Accessing the Management Dashboard
+
+1. Click on your **profile name** or avatar in the bottom-left corner of the sidebar.
+2. Select **Settings** from the menu.
+3. Navigate to the **Data Controls** tab.
+4. Locate the **Shared Chats** row and click the **Manage** button.
+
+## Dashboard Features
+
+The **Shared Chats** modal provides a unified interface for your public content:
+
+- **Centralized List**: View all conversations that have an active share link.
+- **Search & Filter**: Quickly find specific shared chats by title. The search bar includes a **500ms debounce** to ensure smooth performance while typing.
+- **Advanced Sorting**: Organize your shared history by:
+ - **Updated At** (Default)
+ - **Title**
+- **Copy Link**: Use the **Clipboard icon** next to any entry to instantly copy the share URL back to your clipboard.
+- **Revoke Access (Unshare)**: Use the **Unshare icon** (represented by a slashed link) to deactivate a share link.
+ - :::warning
+ Revoking access immediately invalidates the link. Anyone attempting to visit the URL will receive a "Not Found" error. This action is permanent, though you can generate a *new* unique link by sharing the chat again from the main interface.
+ :::
+- **Pagination**: Efficiently browse through your history using the "Load More" functionality at the bottom of the list.
+
+## FAQ
+
+**Q: Does unsharing a chat delete the original conversation?**
+**A:** No. Unsharing only deletes the public link. Your original chat history remains completely intact.
+
+**Q: Can I manage chats I've shared on the community platform here?**
+**A:** No. This dashboard manages links generated on your local instance. For community-shared content, see [Deleting Shared Chats](/features/chat-features/chatshare#deleting-shared-chats).
+
+**Q: If I delete my original chat, what happens to the shared link?**
+**A:** Deleting a chat also immediately invalidates and deletes any associated share links.
diff --git a/docs/features/image-generation-and-editing/usage.md b/docs/features/image-generation-and-editing/usage.md
index 4a132db1db..aea079cc5b 100644
--- a/docs/features/image-generation-and-editing/usage.md
+++ b/docs/features/image-generation-and-editing/usage.md
@@ -18,9 +18,12 @@ Before you can use image generation, you must ensure that the **Image Generation
If your model is configured with **Native Function Calling** (see the [**Central Tool Calling Guide**](/features/plugin/tools#tool-calling-modes-default-vs-native)), it can invoke image generation directly as a tool.
### How it works:
-- **Requirement**: The **Image Generation** feature must be toggled **ON** for the chat or model. This grants the model "permission" to use the tool.
+- **Requirements**:
+ - **Image Generation** must be enabled globally in **Admin Panel → Settings → Images**
+ - The model must have the **Image Generation** capability enabled
+- **No Chat Toggle Needed**: With Native Mode, the `generate_image` tool is automatically included when the model has the `image_generation` capability. You don't need to manually toggle it on per chat.
- **Natural Language**: You can simply ask the model: *"Generate an image of a cybernetic forest."*
-- **Action**: If **Native Mode** is active and the feature is enabled, the model will invoke the `generate_image` tool.
+- **Action**: If **Native Mode** is active and the model has the capability, it will invoke the `generate_image` tool.
- **Display**: The generated image is displayed directly in the chat interface.
- **Editing**: This also supports **Image Editing** (inpainting) via the `edit_image` tool (e.g., *"Make the sky in this image red"*).
diff --git a/docs/features/index.mdx b/docs/features/index.mdx
index d757b5673b..b7f44d1498 100644
--- a/docs/features/index.mdx
+++ b/docs/features/index.mdx
@@ -19,6 +19,10 @@ import { TopBanners } from "@site/src/components/TopBanners";
- 🔐 **SCIM 2.0 Provisioning**: Enterprise-grade user and group provisioning through SCIM 2.0 protocol, enabling seamless integration with identity providers like Okta, Azure AD, and Google Workspace for automated user lifecycle management. [Read the SCIM Guide](/features/auth/scim).
+- 📂 **Centralized File Management**: A unified dashboard to search, view, and manage all your uploaded documents in one place. Includes automated cleanup of Knowledge Base associations and vector embeddings when deleting files. [Learn about File Management](/features/data-controls/files).
+
+- 💬 **Shared Chat Management**: A centralized interface to audit every conversation you've ever shared. Easily search through your shared history, re-copy links, or revoke (unshare) access instantly from a single location. [Learn about Shared Chats](/features/data-controls/shared-chats).
+
- 📱 **Responsive Design**: Enjoy a seamless experience across desktop PCs, laptops, and mobile devices.
- 📱 **Progressive Web App for Mobile**: Enjoy a native progressive web application experience on your mobile device with offline access on `localhost` or a personal domain, and a smooth user interface. In order for our PWA to be installable on your device, it must be delivered in a secure context. This usually means that it must be served over HTTPS.
@@ -164,6 +168,8 @@ import { TopBanners } from "@site/src/components/TopBanners";
- 🔔 **Chat Completion Notifications**: Stay updated with instant in-UI notifications when a chat finishes in a non-active tab, ensuring you never miss a completed response.
+- 📝 **Message Queue**: Continue composing messages while the AI is generating a response. Your messages are queued and automatically sent together when the current response completes. Edit, delete, or send queued messages immediately. [Learn about Message Queue](/features/chat-features/message-queue).
+
- 🌐 **Notification Webhook Integration**: Receive timely updates for long-running chats or external integration needs with configurable webhook notifications, even when your tab is closed. [Learn more about Webhooks](/features/interface/webhooks).
- 📚 **Channels (Beta)**: Explore real-time collaboration between users and AIs with Discord/Slack-style chat rooms, build bots for channels, and unlock asynchronous communication for proactive multi-agent workflows. [See Channels](/features/channels).
@@ -276,13 +282,13 @@ import { TopBanners } from "@site/src/components/TopBanners";
- 🍻 **TavernAI Character Card Integration**: Experience enhanced visual storytelling with TavernAI Character Card Integration in our model builder. Users can seamlessly incorporate TavernAI character card PNGs directly into their model files, creating a more immersive and engaging user experience.
-- 🎲 **Model Playground (Beta)**: Try out models with the model playground area (`beta`), which enables users to test and explore model capabilities and parameters with ease in a sandbox environment before deployment in a live chat environment.
+- 🎲 **Model Playground (Beta)**: Try out models with the model playground area (`beta`), which enables users to test and explore model capabilities and parameters with ease in a sandbox environment before deployment in a live chat environment. Export your playground conversations in JSON format (compatible with Open WebUI chat import) or as plain text for easy sharing and documentation.
---
### 👥 Collaboration
-- 🗨️ **Local Chat Sharing**: Generate and share chat links between users in an efficient and seamless manner, thereby enhancing collaboration and communication.
+- 🗨️ **Local Chat Sharing**: Generate and share chat links between users in an efficient and seamless manner. Includes a **centralized management interface** in Settings to view, copy links, or unshare conversations at any time. [Learn more about Chat Sharing](/features/chat-features/chatshare).
- 👍👎 **RLHF Annotation**: Enhance the impact of your messages by rating them with either a thumbs up or thumbs down AMD provide a rating for the response on a scale of 1-10, followed by the option to provide textual feedback, facilitating the creation of datasets for Reinforcement Learning from Human Feedback (`RLHF`). Utilize your messages to train or fine-tune models, all while ensuring the confidentiality of locally saved data.
@@ -422,8 +428,12 @@ import { TopBanners } from "@site/src/components/TopBanners";
- 👥 **Active Users Indicator**: Monitor the number of active users and which models are being utilized by whom to assist in gauging when performance may be impacted due to a high number of users.
+- 📊 **Analytics Dashboard**: Comprehensive usage insights for administrators including message volume, token consumption, user activity, and model performance metrics with interactive time-series charts and detailed breakdowns. Track costs, identify trends, and make data-driven decisions about resource allocation. [Learn more about Analytics](/features/analytics).
+
- 🔒 **Default Sign-Up Role**: Specify the default role for new sign-ups to `pending`, `user`, or `admin`, providing flexibility in managing user permissions and access levels for new users.
+- 🤖 **Bulk Model Management & Filtering**: Administrators can effortlessly manage large model collections from external providers with tools to bulk enable/disable models and filter the admin list by status (Enabled, Disabled, Hidden, etc.) to maintain a clean workspace. [Learn about Admin Models](/features/workspace/models#global-model-management-admin).
+
- 🔒 **Prevent New Sign-Ups**: Enable the option to disable new user sign-ups, restricting access to the platform and maintaining a fixed number of users.
- 🔒 **Prevent Chat Deletion**: Ability for admins to toggle a setting that prevents all users from deleting their chat messages, ensuring that all chat messages are retained for audit or compliance purposes.
diff --git a/docs/features/memory.mdx b/docs/features/memory.mdx
index 24748ff73f..a26b4d9738 100644
--- a/docs/features/memory.mdx
+++ b/docs/features/memory.mdx
@@ -45,6 +45,7 @@ Autonomous memory management works best with frontier models (GPT-5, Claude 4.5+
1. **Administrative Enablement**: Ensure the Memory feature is [enabled globally](#administrative-controls) by an administrator and that you have the required permissions.
2. **Native Mode (Agentic Mode)**: Enable **Native Function Calling** in the model's advanced parameters (**Admin Panel > Settings > Models > Model Specific Settings > Advanced Parameters**).
3. **Quality Models Required**: To unlock these features effectively, use frontier models with strong reasoning capabilities (e.g., GPT-5, Claude 4.5 Sonnet, Gemini 3 Flash, MiniMax M2.1) for the best experience. Small local models may not effectively manage memories autonomously.
+4. **Per-Model Category Toggle**: Ensure the **Memory** category is enabled for the model in **Workspace > Models > Edit > Builtin Tools** (enabled by default).
:::info Central Tool Documentation
For complete details on all built-in agentic tools (including memory, web search, and knowledge bases) and how to configure them, see the [**Native/Agentic Mode Tools Guide**](/features/plugin/tools#built-in-system-tools-nativeagentic-mode).
diff --git a/docs/features/pipelines/index.mdx b/docs/features/pipelines/index.mdx
index 354ba4b62d..d27376ae12 100644
--- a/docs/features/pipelines/index.mdx
+++ b/docs/features/pipelines/index.mdx
@@ -53,9 +53,9 @@ Integrating Pipelines with any OpenAI API-compatible UI client is simple. Launch
## ⚡ Quick Start with Docker
-:::warning
+:::danger ⚠️ Security Warning
-Pipelines are a plugin system with arbitrary code execution — **don't fetch random pipelines from sources you don't trust**.
+Pipelines are a plugin system with arbitrary code execution — **don't fetch random pipelines from sources you don't trust**. A malicious Pipeline could access your file system, exfiltrate data, mine cryptocurrency, or compromise your system. Always review Pipeline source code before installing. See the [Security Policy](/security) for more details.
:::
diff --git a/docs/features/plugin/development/events.mdx b/docs/features/plugin/development/events.mdx
index 53ccdf6fc3..31b141e9a0 100644
--- a/docs/features/plugin/development/events.mdx
+++ b/docs/features/plugin/development/events.mdx
@@ -24,15 +24,26 @@ Think of Events like push notifications and modal dialogs that your plugin can t
## 🏁 Availability
-:::important
-Events are **only available for native Python Tools and Functions** defined directly in Open WebUI.
+### Native Python Tools & Functions
-Events are **NOT supported** for:
-- **OpenAPI tool servers** (external REST APIs)
-- **MCP tool servers** (Model Context Protocol)
+Events are **fully available** for native Python Tools and Functions defined directly in Open WebUI using the `__event_emitter__` and `__event_call__` helpers.
-These external tools communicate via HTTP request/response and cannot emit real-time UI events.
-:::
+### External Tools (OpenAPI & MCP)
+
+External tools can emit events via a **dedicated REST endpoint**. Open WebUI passes the following headers to all external tool requests:
+
+| Header | Description |
+|--------|-------------|
+| `X-Open-WebUI-Chat-Id` | The chat ID where the tool was invoked |
+| `X-Open-WebUI-Message-Id` | The message ID associated with the tool call |
+
+Your external tool can use these headers to emit events back to the UI via:
+
+```
+POST /api/v1/chats/{chat_id}/messages/{message_id}/event
+```
+
+See [External Tool Events](#-external-tool-events) below for details.
---
@@ -452,6 +463,117 @@ Yes—emit `"chat:message:delta"` events in a loop, then finish with `"chat:mess
---
+## 🌐 External Tool Events
+
+External tools (OpenAPI and MCP servers) can emit events to the Open WebUI UI via a REST endpoint. This enables features like status updates, notifications, and streaming content from tools running on external servers.
+
+### Headers Provided by Open WebUI
+
+When Open WebUI calls your external tool, it includes these headers:
+
+| Header | Description |
+|--------|-------------|
+| `X-Open-WebUI-Chat-Id` | The chat ID where the tool was invoked |
+| `X-Open-WebUI-Message-Id` | The message ID associated with the tool call |
+
+### Event Endpoint
+
+**Endpoint:** `POST /api/v1/chats/{chat_id}/messages/{message_id}/event`
+
+**Authentication:** Requires a valid Open WebUI API key or session token.
+
+**Request Body:**
+
+```json
+{
+ "type": "status",
+ "data": {
+ "description": "Processing your request...",
+ "done": false
+ }
+}
+```
+
+### Supported Event Types
+
+External tools can emit the same event types as native tools:
+- `status` – Show progress/status updates
+- `notification` – Display toast notifications
+- `chat:message:delta` / `message` – Append content to the message
+- `chat:message` / `replace` – Replace message content
+- `files` / `chat:message:files` – Attach files
+- `source` / `citation` – Add citations
+
+:::note
+Interactive events (`input`, `confirmation`, `execute`) require `__event_call__` and are **not supported** for external tools as they need bidirectional WebSocket communication.
+:::
+
+### Example: Python External Tool
+
+```python
+import httpx
+
+def my_tool_handler(request):
+ # Extract headers from incoming request
+ chat_id = request.headers.get("X-Open-WebUI-Chat-Id")
+ message_id = request.headers.get("X-Open-WebUI-Message-Id")
+ api_key = "your-open-webui-api-key"
+
+ # Emit a status event
+ httpx.post(
+ f"http://your-open-webui-host/api/v1/chats/{chat_id}/messages/{message_id}/event",
+ headers={"Authorization": f"Bearer {api_key}"},
+ json={
+ "type": "status",
+ "data": {"description": "Working on it...", "done": False}
+ }
+ )
+
+ # ... do work ...
+
+ # Emit completion status
+ httpx.post(
+ f"http://your-open-webui-host/api/v1/chats/{chat_id}/messages/{message_id}/event",
+ headers={"Authorization": f"Bearer {api_key}"},
+ json={
+ "type": "status",
+ "data": {"description": "Complete!", "done": True}
+ }
+ )
+
+ return {"result": "success"}
+```
+
+### Example: JavaScript/Node.js External Tool
+
+```javascript
+async function myToolHandler(req) {
+ const chatId = req.headers['x-open-webui-chat-id'];
+ const messageId = req.headers['x-open-webui-message-id'];
+ const apiKey = 'your-open-webui-api-key';
+
+ // Emit a notification
+ await fetch(
+ `http://your-open-webui-host/api/v1/chats/${chatId}/messages/${messageId}/event`,
+ {
+ method: 'POST',
+ headers: {
+ 'Authorization': `Bearer ${apiKey}`,
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({
+ type: 'notification',
+ data: { type: 'info', content: 'Tool is processing...' }
+ })
+ }
+ );
+
+ return { result: 'success' };
+}
+```
+
+---
+
## 📝 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/features/plugin/development/reserved-args.mdx b/docs/features/plugin/development/reserved-args.mdx
index 8b36d2f631..133381ed73 100644
--- a/docs/features/plugin/development/reserved-args.mdx
+++ b/docs/features/plugin/development/reserved-args.mdx
@@ -132,6 +132,27 @@ A `dict` with wide ranging information about the chat, model, files, etc.
+:::tip Detecting Request Source
+
+The `interface` field indicates where the request originated:
+- **`"open-webui"`** - Request came from the web interface
+- **Other/missing** - Request likely came from a direct API call
+
+For direct API calls, some fields like `chat_id`, `message_id`, and `session_id` may be absent or `null` if not explicitly provided by the API client. You can use this to distinguish between WebUI and API requests in your filters:
+
+```python
+def inlet(self, body: dict, __metadata__: dict = None) -> dict:
+ if __metadata__ and __metadata__.get("interface") == "open-webui":
+ # Request from WebUI
+ pass
+ else:
+ # Direct API request
+ pass
+ return body
+```
+
+:::
+
### `__model__`
A `dict` with information about the model.
diff --git a/docs/features/plugin/development/valves.mdx b/docs/features/plugin/development/valves.mdx
index b91ff07016..22c3ccf149 100644
--- a/docs/features/plugin/development/valves.mdx
+++ b/docs/features/plugin/development/valves.mdx
@@ -75,3 +75,156 @@ class Filter:
```
+
+## Input Types
+
+Valves support special input types that change how fields are rendered in the UI. You can configure these using `json_schema_extra` with the `input` key in your Pydantic `Field` definitions.
+
+### Password Input (Masked Fields)
+
+For sensitive fields like passwords, API keys, or secrets, you can use the password input type to mask the value in the UI. This prevents the password from being visible on screen (protecting against shoulder surfing).
+
+```python
+from pydantic import BaseModel, Field
+
+class Tools:
+ class UserValves(BaseModel):
+ service_password: str = Field(
+ default="",
+ description="Your service password",
+ json_schema_extra={"input": {"type": "password"}}
+ )
+```
+
+When rendered, this field will appear as a masked input (dots instead of characters) with a toggle to reveal the value if needed, using Open WebUI's `SensitiveInput` component.
+
+:::tip
+Use password input types for any credential or secret that users configure in their Valves or UserValves. This is especially important for UserValves since they are configurable by end users directly from the chat interface.
+:::
+
+### Select Dropdown Input
+
+For fields where users should choose from a predefined list of options, use the select input type to render a dropdown menu. Options can be either static (hardcoded list) or dynamic (generated at runtime by a method).
+
+#### Static Options
+
+Use a list directly for options that don't change:
+
+```python
+from pydantic import BaseModel, Field
+
+class Tools:
+ class Valves(BaseModel):
+ priority: str = Field(
+ default="medium",
+ description="Processing priority level",
+ json_schema_extra={
+ "input": {
+ "type": "select",
+ "options": ["low", "medium", "high"]
+ }
+ }
+ )
+```
+
+You can also use label/value pairs for more descriptive options:
+
+```python
+from pydantic import BaseModel, Field
+
+class Tools:
+ class Valves(BaseModel):
+ log_level: str = Field(
+ default="info",
+ description="Logging verbosity",
+ json_schema_extra={
+ "input": {
+ "type": "select",
+ "options": [
+ {"value": "debug", "label": "Debug (Verbose)"},
+ {"value": "info", "label": "Info (Standard)"},
+ {"value": "warn", "label": "Warning (Minimal)"},
+ {"value": "error", "label": "Error (Critical Only)"}
+ ]
+ }
+ }
+ )
+```
+
+#### Dynamic Options
+
+For options that need to be generated at runtime (e.g., fetching available models, databases, or user-specific resources), specify a method name as a string. The method will be called when the configuration UI is rendered:
+
+```python
+from pydantic import BaseModel, Field
+
+class Tools:
+ class Valves(BaseModel):
+ selected_model: str = Field(
+ default="",
+ description="Choose a model to use",
+ json_schema_extra={
+ "input": {
+ "type": "select",
+ "options": "get_model_options" # Method name as string
+ }
+ }
+ )
+
+ @classmethod
+ def get_model_options(cls, __user__=None) -> list[dict]:
+ """
+ Dynamically fetch available models.
+ Called when the Valves configuration UI is opened.
+ """
+ # Example: Return options based on runtime state
+ return [
+ {"value": "gpt-4", "label": "GPT-4"},
+ {"value": "gpt-3.5-turbo", "label": "GPT-3.5 Turbo"},
+ {"value": "claude-3-opus", "label": "Claude 3 Opus"}
+ ]
+```
+
+The method can accept an optional `__user__` parameter to generate user-specific options:
+
+```python
+from pydantic import BaseModel, Field
+
+class Tools:
+ class UserValves(BaseModel):
+ workspace: str = Field(
+ default="",
+ description="Select your workspace",
+ json_schema_extra={
+ "input": {
+ "type": "select",
+ "options": "get_user_workspaces"
+ }
+ }
+ )
+
+ @classmethod
+ def get_user_workspaces(cls, __user__=None) -> list[dict]:
+ """
+ Return workspaces available to the current user.
+ __user__ contains the user's information as a dict.
+ """
+ if not __user__:
+ return []
+
+ user_id = __user__.get("id")
+ # Fetch user-specific workspaces from your data source
+ return [
+ {"value": "ws-1", "label": "Personal Workspace"},
+ {"value": "ws-2", "label": "Team Workspace"}
+ ]
+```
+
+:::tip
+Dynamic options are particularly useful for:
+- Fetching available API models from connected providers
+- Loading database or file options based on current system state
+- Presenting user-specific resources like projects or workspaces
+- Any scenario where options change based on runtime context
+:::
+
diff --git a/docs/features/plugin/functions/filter.mdx b/docs/features/plugin/functions/filter.mdx
index aa365f3ec9..c1815e8822 100644
--- a/docs/features/plugin/functions/filter.mdx
+++ b/docs/features/plugin/functions/filter.mdx
@@ -243,10 +243,15 @@ Understanding the difference between these two types is key to using the filter
- Do **not** show up in the chat integrations menu (⚙️ icon)
**Use Cases:**
-- Content moderation (always filter inappropriate content)
-- PII scrubbing (always remove sensitive data)
-- System-level transformations (always apply certain formatting)
-- Security/compliance filters
+- **Content moderation** - Filter profanity, hate speech, or inappropriate content
+- **PII scrubbing** - Automatically redact emails, phone numbers, SSNs, credit card numbers
+- **Prompt injection detection** - Block attempts to manipulate the system prompt
+- **Input/output logging** - Track all conversations for audit or analytics
+- **Cost tracking** - Estimate and log token usage for billing
+- **Rate limiting** - Enforce request limits per user or globally
+- **Language enforcement** - Ensure responses are in a specific language
+- **Company policy enforcement** - Inject legal disclaimers or compliance notices
+- **Model routing** - Redirect requests to different models based on content
**Example:**
```python
@@ -271,12 +276,16 @@ class ContentModerationFilter:
- `defaultFilterIds` controls their initial state (ON or OFF)
**Use Cases:**
-- Web search integration (user decides when to search)
-- Citation mode (user controls when to require sources)
-- Verbose output mode (user toggles detailed responses)
-- Translation filters (user enables when needed)
-- Code formatting (user chooses when to apply)
-- Thinking/reasoning toggle (user controls whether to show model reasoning)
+- **Web search integration** - User decides when to search the web for context
+- **Citation mode** - User controls when to require sources in responses
+- **Verbose/detailed mode** - User toggles between concise and detailed responses
+- **Translation filters** - User enables translation to/from specific languages
+- **Code formatting** - User chooses when to apply syntax highlighting or linting
+- **Thinking/reasoning toggle** - Show or hide model's chain-of-thought reasoning
+- **Markdown rendering** - Toggle between raw text and formatted output
+- **Anonymization mode** - User enables when discussing sensitive topics
+- **Expert mode** - Inject domain-specific context (legal, medical, technical)
+- **Creative writing mode** - Adjust temperature and style for creative tasks
**Example:**
```python
@@ -342,6 +351,149 @@ Here's the complete flow from admin configuration to filter execution:
---
+### 📡 Filter Behavior with API Requests
+
+When using Open WebUI's API endpoints directly (e.g., via `curl` or external applications), filters behave differently than when the request comes from the web interface. Understanding these differences is crucial for building effective filters.
+
+#### Key Behavioral Differences
+
+| Function | WebUI Request | Direct API Request |
+|----------|--------------|-------------------|
+| `inlet()` | ✅ Always called | ✅ Always called |
+| `stream()` | ✅ Called during streaming | ✅ Called during streaming |
+| `outlet()` | ✅ Called after response | ❌ **NOT called** by default |
+| `__event_emitter__` | ✅ Shows UI feedback | ⚠️ Runs but no UI to display |
+
+:::warning Outlet Not Called for API Requests
+The `outlet()` function is **only triggered for WebUI chat requests**, not for direct API calls to `/api/chat/completions`. This is because `outlet()` is invoked by the WebUI's `/api/chat/completed` endpoint after the chat is finished.
+
+If you need `outlet()` processing for API requests, your API client must call `/api/chat/completed` after receiving the full response.
+:::
+
+#### Triggering Outlet for API Requests
+
+To invoke `outlet()` filters for API requests, your client must make a second request to `/api/chat/completed` after receiving the complete response:
+
+```bash
+# After receiving the full response from /api/chat/completions, call:
+curl -X POST http://localhost:3000/api/chat/completed \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "model": "llama3.1",
+ "messages": [
+ {"role": "user", "content": "Hello"},
+ {"role": "assistant", "content": "Hi there! How can I help you?"}
+ ],
+ "chat_id": "optional-chat-id",
+ "session_id": "optional-session-id"
+ }'
+```
+
+:::tip
+Include the full conversation in `messages`, including the assistant's response. The `chat_id` and `session_id` are optional but recommended for proper logging and state tracking.
+:::
+
+#### Detecting API vs WebUI Requests
+
+You can detect whether a request originates from the WebUI or a direct API call by checking the `__metadata__` argument:
+
+```python
+def inlet(self, body: dict, __metadata__: dict = None) -> dict:
+ # Check if request is from WebUI
+ interface = __metadata__.get("interface") if __metadata__ else None
+
+ if interface == "open-webui":
+ print("Request from WebUI")
+ else:
+ print("Direct API request")
+
+ # You can also check for presence of chat context
+ chat_id = __metadata__.get("chat_id") if __metadata__ else None
+ if not chat_id:
+ print("No chat context - likely a direct API call")
+
+ return body
+```
+
+#### Example: Rate Limiting for All Requests
+
+Since `inlet()` is always called, use it for rate limiting that applies to both WebUI and API requests:
+
+```python
+from pydantic import BaseModel, Field
+from typing import Optional
+import time
+
+class Filter:
+ class Valves(BaseModel):
+ requests_per_minute: int = Field(default=60, description="Max requests per minute per user")
+
+ def __init__(self):
+ self.valves = self.Valves()
+ self.user_requests = {} # Track requests per user
+
+ def inlet(self, body: dict, __user__: dict = None) -> dict:
+ if not __user__:
+ return body
+
+ user_id = __user__.get("id")
+ current_time = time.time()
+
+ # Clean old entries and count recent requests
+ if user_id not in self.user_requests:
+ self.user_requests[user_id] = []
+
+ # Keep only requests from the last minute
+ self.user_requests[user_id] = [
+ t for t in self.user_requests[user_id]
+ if current_time - t < 60
+ ]
+
+ if len(self.user_requests[user_id]) >= self.valves.requests_per_minute:
+ raise Exception(f"Rate limit exceeded: {self.valves.requests_per_minute} requests/minute")
+
+ self.user_requests[user_id].append(current_time)
+ return body
+```
+
+#### Example: Logging All API Usage
+
+Track token usage and requests for both WebUI and direct API calls:
+
+```python
+from pydantic import BaseModel, Field
+from typing import Optional
+import logging
+
+class Filter:
+ class Valves(BaseModel):
+ log_level: str = Field(default="INFO", description="Logging level")
+
+ def __init__(self):
+ self.valves = self.Valves()
+ self.logger = logging.getLogger("api_usage")
+
+ def inlet(self, body: dict, __user__: dict = None, __metadata__: dict = None) -> dict:
+ user_email = __user__.get("email", "unknown") if __user__ else "anonymous"
+ model = body.get("model", "unknown")
+ interface = __metadata__.get("interface", "api") if __metadata__ else "api"
+ chat_id = __metadata__.get("chat_id") if __metadata__ else None
+
+ self.logger.info(
+ f"Request: user={user_email}, model={model}, "
+ f"interface={interface}, chat_id={chat_id or 'none'}"
+ )
+
+ return body
+```
+
+:::note Event Emitter Behavior
+Filters that use `__event_emitter__` will still execute for API requests, but since there's no WebUI to display the events, the status messages won't be visible. The filter logic still runs—only the visual feedback is missing.
+:::
+
+---
+
### ⚡ Filter Priority & Execution Order
When multiple filters are active, they execute in a specific order determined by their **priority** value. Understanding this is crucial when building filter chains where one filter depends on another's changes.
@@ -612,6 +764,18 @@ Modify and return the `body`. The modified version of the `body` is what the LLM
4. **Streamlining User Input**: If your model’s output improves with additional guidance, you can use the `inlet` to inject clarifying instructions automatically!
+5. **Rate Limiting**: Track requests per user and reject requests that exceed your quota (works for both WebUI and API requests).
+
+6. **Request Logging**: Log all incoming requests for analytics, debugging, or billing purposes.
+
+7. **Language Detection**: Detect the user's language and inject translation instructions or route to a language-specific model.
+
+8. **Prompt Injection Detection**: Scan user input for attempts to manipulate the system prompt and block malicious requests.
+
+9. **Cost Estimation**: Estimate input tokens before sending to the model for budget tracking.
+
+10. **A/B Testing**: Route users to different model configurations based on user ID or random selection.
+
##### 💡 Example Use Cases: Build on Food Prep
###### 🥗 Example 1: Adding System Context
@@ -669,9 +833,12 @@ The **`stream` function** is a new feature introduced in Open WebUI **0.5.17** t
Unlike `outlet`, which processes an entire completed response, `stream` operates on **individual chunks** as they are received from the model.
##### 🛠️ When to Use the Stream Hook?
-- Modify **streaming responses** before they are displayed to users.
-- Implement **real-time censorship or cleanup**.
-- **Monitor streamed data** for logging/debugging.
+- **Real-time content filtering** - Censor profanity or sensitive content as it streams
+- **Live word replacement** - Replace brand names, competitor mentions, or outdated terms
+- **Streaming analytics** - Count tokens and track response length in real-time
+- **Progress indicators** - Detect specific patterns to show loading states
+- **Debugging** - Log each chunk for troubleshooting streaming issues
+- **Format correction** - Fix common formatting issues as they appear
##### 📜 Example: Logging Streaming Chunks
@@ -719,6 +886,19 @@ The `outlet` function is like a **proofreader**: tidy up the AI's response (or m
- Prefer logging over direct edits in the outlet (e.g., for debugging or analytics).
- If heavy modifications are needed (like formatting outputs), consider using the **pipe function** instead.
+##### 🛠️ Use Cases for `outlet`:
+- **Response logging** - Track all model outputs for analytics or compliance
+- **Token usage tracking** - Count output tokens after completion for billing
+- **Langfuse/observability integration** - Send traces to monitoring platforms
+- **Citation formatting** - Reformat reference links in the final output
+- **Disclaimer injection** - Append legal notices or AI disclosure statements
+- **Response caching** - Store responses for future retrieval
+- **Quality scoring** - Run automated quality checks on model outputs
+
+:::warning Outlet and API Requests
+Remember: `outlet()` is **not called** for direct API requests to `/api/chat/completions`. If you need outlet processing for API calls, see the [Filter Behavior with API Requests](#-filter-behavior-with-api-requests) section above.
+:::
+
💡 **Example Use Case**: Strip out sensitive API responses you don't want the user to see:
```python
def outlet(self, body: dict, __user__: Optional[dict] = None) -> dict:
diff --git a/docs/features/plugin/functions/index.mdx b/docs/features/plugin/functions/index.mdx
index e3f719a762..f6548f42bb 100644
--- a/docs/features/plugin/functions/index.mdx
+++ b/docs/features/plugin/functions/index.mdx
@@ -11,6 +11,12 @@ Unlike external tools that may require complex integrations, **Functions are bui
Think of Functions as **modular building blocks** that let you enhance how the WebUI works, tailored exactly to what you need. They’re lightweight, highly customizable, and written in **pure Python**, so you have the freedom to create anything—from new AI-powered workflows to integrations with anything you use, like Google Search or Home Assistant.
+:::danger ⚠️ Security Warning
+
+**Functions execute arbitrary Python code on your server.** Only install Functions from trusted sources. Before importing any Function, review its source code to understand what it does. A malicious Function could access your file system, exfiltrate data, or compromise your system. See the [Security Policy](/security) for more details.
+
+:::
+
---
## 🏗️ Types of Functions
diff --git a/docs/features/plugin/index.mdx b/docs/features/plugin/index.mdx
index f8e6dd4341..20842e2d64 100644
--- a/docs/features/plugin/index.mdx
+++ b/docs/features/plugin/index.mdx
@@ -17,6 +17,28 @@ Getting started with Tools and Functions is easy because everything’s already
## What are "Tools" and "Functions"?
+---
+
+:::danger ⚠️ Critical Security Warning
+
+**Tools, Functions, Pipes, Filters, and Pipelines execute arbitrary Python code on your server.** This is by design—it's what makes them powerful. However, this also means:
+
+1. **Only install from trusted sources.** Never import Tools or Functions from unknown or untrusted sources. Malicious code can compromise your entire system.
+
+2. **Review code before importing.** Before installing any community Tool or Function, review its source code. If you don't understand what it does, don't install it.
+
+3. **Protect your data directory.** The `data` directory (mounted at `/app/backend/data` in Docker) contains your database, configurations, and cached Tools/Functions. If an attacker gains write access to this directory, they can inject malicious code that will execute on your server.
+
+4. **Restrict Workspace access.** Only trusted administrators should have permission to create, import, or modify Tools and Functions. Regular users should **not** have Workspace access unless explicitly required.
+
+5. **Audit installed plugins regularly.** Periodically review the Tools and Functions installed in your instance via **Workspace → Tools** and **Admin Panel → Functions**.
+
+**What could go wrong?** A malicious Tool or Function could exfiltrate data, install malware, mine cryptocurrency, pivot to other systems on your network, or corrupt your instance.
+
+:::
+
+---
+
Let's start by thinking of **Open WebUI** as a "base" software that can do many tasks related to using Large Language Models (LLMs). But sometimes, you need extra features or abilities that don't come *out of the box*—this is where **tools** and **functions** come into play.
### Tools
diff --git a/docs/features/plugin/tools/development.mdx b/docs/features/plugin/tools/development.mdx
index d636f622ca..b0244dc3ce 100644
--- a/docs/features/plugin/tools/development.mdx
+++ b/docs/features/plugin/tools/development.mdx
@@ -145,60 +145,8 @@ You can configure the function calling mode in two places:
If the model seems to be unable to call the tool, make sure it is enabled (either via the Model page or via the `+` sign next to the chat input field).
-### Built-in System Tools (Native/Agentic Mode)
-
-When **Native Mode (Agentic Mode)** is enabled, Open WebUI automatically injects built-in system tools based on the features enabled for the chat. This enables powerful agentic behaviors where capable models (like GPT-5, Claude 4.5 Sonnet, Gemini 3 Flash, or MiniMax M2.1) can perform multi-step research, explore knowledge bases autonomously, or manage user memory dynamically.
-
-:::warning Quality Models Required for Agentic Behavior
-Agentic tool calling requires **high-quality frontier models** to work reliably. Small local models often struggle with the complex reasoning, proper JSON formatting, and multi-step planning required for effective tool use. For production agentic workflows, use models like **GPT-5**, **Claude 4.5+**, **Gemini 3+**, or **MiniMax M2.1**. Small local models may work better with **Default Mode** instead.
-:::
-
-#### Available Built-in Tools
-
-| Tool | Purpose | Requirements |
-|------|---------|--------------|
-| **Search & Web** | | |
-| `search_web` | Search the public web for information. Best for current events, external references, or topics not covered in internal documents. | `ENABLE_WEB_SEARCH` enabled. |
-| `fetch_url` | Visits a URL and extracts text content via the Web Loader. | Part of Web Search feature. |
-| **Knowledge Base** | | |
-| `list_knowledge_bases` | List the user's accessible knowledge bases with file counts. | Always available. |
-| `search_knowledge_bases` | Search knowledge bases by name and description. | Always available. |
-| `search_knowledge_files` | Search files across accessible knowledge bases by filename. | Always available. |
-| `view_knowledge_file` | Get the full content of a file from a knowledge base. | Always available. |
-| `query_knowledge_bases` | Search knowledge bases using semantic/vector search (default: 5 results). **Note:** Does not use hybrid search or reranking. | Always available. |
-| **Image Gen** | | |
-| `generate_image` | Generates a new image based on a prompt (supports `steps`). | `ENABLE_IMAGE_GENERATION` enabled. |
-| `edit_image` | Edits an existing image based on a prompt and URL. | `ENABLE_IMAGE_EDIT` enabled.|
-| **Memory** | | |
-| `search_memories` | Searches the user's personal memory/personalization bank. | Memory feature enabled. |
-| `add_memory` | Stores a new fact in the user's personalization memory. | Memory feature enabled. |
-| `replace_memory_content` | Updates an existing memory record by its unique ID. | Memory feature enabled. |
-| **Notes** | | |
-| `search_notes` | Search the user's notes by title and content. | `ENABLE_NOTES` enabled. |
-| `view_note` | Get the full markdown content of a specific note. | `ENABLE_NOTES` enabled. |
-| `write_note` | Create a new private note for the user. | `ENABLE_NOTES` enabled. |
-| `replace_note_content` | Update an existing note's content or title. | `ENABLE_NOTES` enabled. |
-| **Chat History** | | |
-| `search_chats` | Simple text search across chat titles and message content. Returns matching chat IDs and snippets. | Always available. |
-| `view_chat` | Reads and returns the full message history of a specific chat by ID. | Always available. |
-| **Channels** | | |
-| `search_channels` | Find public or accessible channels by name/description. | `ENABLE_CHANNELS` enabled. |
-| `search_channel_messages` | Search for specific messages inside accessible channels. | `ENABLE_CHANNELS` enabled. |
-| `view_channel_message` | View a specific message or its details in a channel. | `ENABLE_CHANNELS` enabled. |
-| `view_channel_thread` | View a full message thread/replies in a channel. | `ENABLE_CHANNELS` enabled. |
-| **Time Tools** | | |
-| `get_current_timestamp` | Get the current UTC Unix timestamp and ISO date. | Always available. |
-| `calculate_timestamp` | Calculate relative timestamps (e.g., "3 days ago"). | Always available. |
-
-#### Why Use Built-in Tools?
-- **Agentic Research**: Models can invoke `search_web` multiple times to refine results, then use `fetch_url` to read specific deep-dive articles.
-- **Knowledge Base Search**: Models can use `query_knowledge_bases` to search internal documents semantically, or `list_knowledge_bases` and `view_knowledge_file` to browse and read specific files.
-- **Contextual Awareness**: Models can search your previous chat history or notes to find specific details without manual copy-pasting.
-- **Dynamic Personalization**: Models can proactively store important facts about the user using `add_memory` during the conversation.
-- **Improved Context Selection**: Instead of forcing a search before every prompt, the model decides *when* a search or retrieval is actually necessary.
-
-:::info Complete Tool Reference
-This table provides a quick reference for developers. For the complete user-facing guide on how to enable and use these tools, see the [**Tool Calling Modes Guide**](/features/plugin/tools#tool-calling-modes-default-vs-native).
+:::info Native Mode & Built-in Tools
+When writing custom tools, be aware that Open WebUI also provides **built-in system tools** when Native Mode is enabled. For details on built-in tools, function calling modes, and model requirements, see the [**Tool Calling Modes Guide**](/features/plugin/tools#tool-calling-modes-default-vs-native).
:::
@@ -1605,7 +1553,6 @@ When embedding external content, several security options can be configured thro
- `iframeSandboxAllowForms`: Allow form submissions within embedded content
- `iframeSandboxAllowSameOrigin`: Allow same-origin requests (use with caution)
-- `iframeSandboxAllowPopups`: Allow popup windows from embedded content
#### Use Cases
diff --git a/docs/features/plugin/tools/index.mdx b/docs/features/plugin/tools/index.mdx
index 05ccaf5b59..7ad37607f1 100644
--- a/docs/features/plugin/tools/index.mdx
+++ b/docs/features/plugin/tools/index.mdx
@@ -174,76 +174,93 @@ These models excel at multi-step reasoning, proper JSON formatting, and autonomo
🛠️ When **Native Mode (Agentic Mode)** is enabled, Open WebUI automatically injects powerful system tools. This unlocks truly agentic behaviors where capable models (like GPT-5, Claude 4.5 Sonnet, Gemini 3 Flash, or MiniMax M2.1) can perform multi-step research, explore knowledge bases, or manage user memory autonomously.
-| Tool | Purpose | Requirements |
-|------|---------|--------------|
+| Tool | Purpose |
+|------|---------|
+| **Search & Web** | *Requires `ENABLE_WEB_SEARCH` enabled.* |
+| `search_web` | Search the public web for information. Best for current events, external references, or topics not covered in internal documents. |
+| `fetch_url` | Visits a URL and extracts text content via the Web Loader. |
+| **Knowledge Base** | *Requires per-model "Knowledge Base" category enabled (default: on).* |
+| `list_knowledge_bases` | List the user's accessible knowledge bases with file counts. **Use this first** to discover what knowledge is available. |
+| `query_knowledge_bases` | Search KB *names and descriptions* by semantic similarity. Use to find which KB is relevant when you don't know which one to query. |
+| `search_knowledge_bases` | Search knowledge bases by name/description (text match). |
+| `query_knowledge_files` | Search *file contents* inside KBs using vector search. **This is your main tool for finding information.** When a KB is attached to the model, searches are automatically scoped to that KB. |
+| `search_knowledge_files` | Search files across accessible knowledge bases by filename (not content). |
+| `view_knowledge_file` | Get the full content of a file from a knowledge base. |
+| **Image Gen** | *Requires image generation enabled (per-tool).* |
+| `generate_image` | Generates a new image based on a prompt. Requires `ENABLE_IMAGE_GENERATION`. |
+| `edit_image` | Edits existing images based on a prompt and image URLs. Requires `ENABLE_IMAGE_EDIT`. |
+| **Memory** | *Requires Memory feature enabled AND per-model "Memory" category enabled (default: on).* |
+| `search_memories` | Searches the user's personal memory/personalization bank. |
+| `add_memory` | Stores a new fact in the user's personalization memory. |
+| `replace_memory_content` | Updates an existing memory record by its unique ID. |
+| **Notes** | *Requires `ENABLE_NOTES` AND per-model "Notes" category enabled (default: on).* |
+| `search_notes` | Search the user's notes by title and content. |
+| `view_note` | Get the full markdown content of a specific note. |
+| `write_note` | Create a new private note for the user. |
+| `replace_note_content` | Update an existing note's content or title. |
+| **Chat History** | *Requires per-model "Chat History" category enabled (default: on).* |
+| `search_chats` | Simple text search across chat titles and message content. Returns matching chat IDs and snippets. |
+| `view_chat` | Reads and returns the full message history of a specific chat by ID. |
+| **Channels** | *Requires `ENABLE_CHANNELS` AND per-model "Channels" category enabled (default: on).* |
+| `search_channels` | Find public or accessible channels by name/description. |
+| `search_channel_messages` | Search for specific messages inside accessible channels. |
+| `view_channel_message` | View a specific message or its details in a channel. |
+| `view_channel_thread` | View a full message thread/replies in a channel. |
+| **Time Tools** | *Requires per-model "Time & Calculation" category enabled (default: on).* |
+| `get_current_timestamp` | Get the current UTC Unix timestamp and ISO date. |
+| `calculate_timestamp` | Calculate relative timestamps (e.g., "3 days ago"). |
+
+#### Tool Reference
+
+| Tool | Parameters | Output |
+|------|------------|--------|
| **Search & Web** | | |
-| `search_web` | Search the public web for information. Best for current events, external references, or topics not covered in internal documents. | `ENABLE_WEB_SEARCH` enabled. |
-| `fetch_url` | Visits a URL and extracts text content via the Web Loader. | Part of Web Search feature. |
+| `search_web` | `query` (required), `count` (default: 5) | Array of `{title, link, snippet}` |
+| `fetch_url` | `url` (required) | Plain text content (max 50,000 chars) |
| **Knowledge Base** | | |
-| `list_knowledge_bases` | List the user's accessible knowledge bases with file counts. | Always available. |
-| `query_knowledge_bases` | Search knowledge bases by semantic similarity to query. Finds KBs whose name/description match the meaning of your query. Use this to discover relevant knowledge bases before querying their files. | Always available. |
-| `search_knowledge_bases` | Search knowledge bases by name and description. | Always available. |
-| `query_knowledge_files` | Search knowledge base files using simple vector search. **Note:** Does not use hybrid search or reranking—for full RAG pipeline with reranking, use File Context instead by attaching files via `#` or assigning knowledge bases. | Always available. |
-| `search_knowledge_files` | Search files across accessible knowledge bases by filename. | Always available. |
-| `view_knowledge_file` | Get the full content of a file from a knowledge base. | Always available. |
+| `list_knowledge_bases` | `count` (default: 10), `skip` (default: 0) | Array of `{id, name, description, file_count}` |
+| `query_knowledge_bases` | `query` (required), `count` (default: 5) | Array of `{id, name, description}` by similarity |
+| `search_knowledge_bases` | `query` (required), `count` (default: 5), `skip` (default: 0) | Array of `{id, name, description, file_count}` |
+| `query_knowledge_files` | `query` (required), `knowledge_ids` (optional), `count` (default: 5) | Array of `{id, filename, content_snippet, knowledge_id}` |
+| `search_knowledge_files` | `query` (required), `knowledge_id` (optional), `count` (default: 5), `skip` (default: 0) | Array of `{id, filename, knowledge_id, knowledge_name}` |
+| `view_knowledge_file` | `file_id` (required) | `{id, filename, content}` |
| **Image Gen** | | |
-| `generate_image` | Generates a new image based on a prompt. | `ENABLE_IMAGE_GENERATION` enabled. |
-| `edit_image` | Edits existing images based on a prompt and image URLs. | `ENABLE_IMAGE_EDIT` enabled. |
+| `generate_image` | `prompt` (required) | `{status, message, images}` — auto-displayed |
+| `edit_image` | `prompt` (required), `image_urls` (required) | `{status, message, images}` — auto-displayed |
| **Memory** | | |
-| `search_memories` | Searches the user's personal memory/personalization bank. | Memory feature enabled. |
-| `add_memory` | Stores a new fact in the user's personalization memory. | Memory feature enabled. |
-| `replace_memory_content` | Updates an existing memory record by its unique ID. | Memory feature enabled. |
+| `search_memories` | `query` (required), `count` (default: 5) | Array of `{id, date, content}` |
+| `add_memory` | `content` (required) | `{status: "success", id}` |
+| `replace_memory_content` | `memory_id` (required), `content` (required) | `{status: "success", id, content}` |
| **Notes** | | |
-| `search_notes` | Search the user's notes by title and content. | `ENABLE_NOTES` enabled. |
-| `view_note` | Get the full markdown content of a specific note. | `ENABLE_NOTES` enabled. |
-| `write_note` | Create a new private note for the user. | `ENABLE_NOTES` enabled. |
-| `replace_note_content` | Update an existing note's content or title. | `ENABLE_NOTES` enabled. |
+| `search_notes` | `query` (required), `count` (default: 5), `start_timestamp`, `end_timestamp` | Array of `{id, title, snippet, updated_at}` |
+| `view_note` | `note_id` (required) | `{id, title, content, updated_at, created_at}` |
+| `write_note` | `title` (required), `content` (required) | `{status: "success", id}` |
+| `replace_note_content` | `note_id` (required), `content` (required), `title` (optional) | `{status: "success", id, title}` |
| **Chat History** | | |
-| `search_chats` | Simple text search across chat titles and message content. Returns matching chat IDs and snippets. | Always available. |
-| `view_chat` | Reads and returns the full message history of a specific chat by ID. | Always available. |
+| `search_chats` | `query` (required), `count` (default: 5), `start_timestamp`, `end_timestamp` | Array of `{id, title, snippet, updated_at}` |
+| `view_chat` | `chat_id` (required) | `{id, title, messages: [{role, content}]}` |
| **Channels** | | |
-| `search_channels` | Find public or accessible channels by name/description. | `ENABLE_CHANNELS` enabled. |
-| `search_channel_messages` | Search for specific messages inside accessible channels. | `ENABLE_CHANNELS` enabled. |
-| `view_channel_message` | View a specific message or its details in a channel. | `ENABLE_CHANNELS` enabled. |
-| `view_channel_thread` | View a full message thread/replies in a channel. | `ENABLE_CHANNELS` enabled. |
+| `search_channels` | `query` (required), `count` (default: 5) | Array of `{id, name, description}` |
+| `search_channel_messages` | `query` (required), `count` (default: 10), `start_timestamp`, `end_timestamp` | Array of `{id, channel_id, content, user_name, created_at}` |
+| `view_channel_message` | `message_id` (required) | `{id, content, user_name, created_at, reply_count}` |
+| `view_channel_thread` | `parent_message_id` (required) | Array of `{id, content, user_name, created_at}` |
| **Time Tools** | | |
-| `get_current_timestamp` | Get the current UTC Unix timestamp and ISO date. | Always available. |
-| `calculate_timestamp` | Calculate relative timestamps (e.g., "3 days ago"). | Always available. |
-
-#### Tool Parameters Reference
-
-| Tool | Parameters |
-|------|------------|
-| `search_web` | `query` (required), `count` (default: 5) |
-| `fetch_url` | `url` (required) |
-| `list_knowledge_bases` | `count` (default: 10), `skip` (default: 0) |
-| `query_knowledge_bases` | `query` (required), `count` (default: 5) |
-| `search_knowledge_bases` | `query` (required), `count` (default: 5), `skip` (default: 0) |
-| `query_knowledge_files` | `query` (required), `knowledge_ids` (optional), `count` (default: 5) |
-| `search_knowledge_files` | `query` (required), `knowledge_id` (optional), `count` (default: 5), `skip` (default: 0) |
-| `view_knowledge_file` | `file_id` (required) |
-| `generate_image` | `prompt` (required) |
-| `edit_image` | `prompt` (required), `image_urls` (required) |
-| `search_memories` | `query` (required), `count` (default: 5) |
-| `add_memory` | `content` (required) |
-| `replace_memory_content` | `memory_id` (required), `content` (required) |
-| `search_notes` | `query` (required), `count` (default: 5), `start_timestamp` (optional), `end_timestamp` (optional) |
-| `view_note` | `note_id` (required) |
-| `write_note` | `title` (required), `content` (required) |
-| `replace_note_content` | `note_id` (required), `content` (required), `title` (optional) |
-| `search_chats` | `query` (required), `count` (default: 5), `start_timestamp` (optional), `end_timestamp` (optional) |
-| `view_chat` | `chat_id` (required) |
-| `search_channels` | `query` (required), `count` (default: 5) |
-| `search_channel_messages` | `query` (required), `count` (default: 10), `start_timestamp` (optional), `end_timestamp` (optional) |
-| `view_channel_message` | `message_id` (required) |
-| `view_channel_thread` | `parent_message_id` (required) |
-| `get_current_timestamp` | None |
-| `calculate_timestamp` | `days_ago` (default: 0), `weeks_ago` (default: 0), `months_ago` (default: 0), `years_ago` (default: 0) |
+| `get_current_timestamp` | None | `{current_timestamp, current_iso}` |
+| `calculate_timestamp` | `days_ago`, `weeks_ago`, `months_ago`, `years_ago` (all default: 0) | `{current_timestamp, current_iso, calculated_timestamp, calculated_iso}` |
:::info Automatic Timezone Detection
Open WebUI automatically detects and stores your timezone when you log in. This allows time-related tools and features to provide accurate local times without any manual configuration. Your timezone is determined from your browser settings.
:::
+:::info Recommended KB Tool Workflow
+**When an attached KB is returning empty results:**
+1. First call `list_knowledge_bases` to confirm the model can see the attached KB
+2. Then use `query_knowledge_files` (without specifying `knowledge_ids` — it auto-scopes to attached KBs)
+3. If still empty, the files may not be embedded yet, or you may have **Full Context mode enabled** which bypasses the vector store
+
+**Do NOT use Full Context mode with knowledge tools** — Full Context injects file content directly and doesn't store embeddings, so `query_knowledge_files` will return empty. Use Focused Retrieval (default) for tool-based access.
+:::
+
:::tip Knowledge Base Tools vs RAG Pipeline
The native `query_knowledge_files` tool uses **simple vector search** with a default of 5 results. It does **not** use:
- Hybrid search (BM25 + vector)
@@ -253,6 +270,17 @@ The native `query_knowledge_files` tool uses **simple vector search** with a def
For the full RAG pipeline with hybrid search and reranking, use the **File Context** capability (attach files via `#` or knowledge base assignment) instead of relying on autonomous tool calls.
:::
+:::warning Knowledge is NOT Auto-Injected in Native Mode
+**Important:** When using Native Function Calling, attached knowledge is **not automatically injected** into the conversation. The model must actively call knowledge tools to search and retrieve information.
+
+**If your model isn't using attached knowledge:**
+1. **Add instructions to your system prompt** telling the model to discover and query knowledge bases. Example: *"When users ask questions, first use list_knowledge_bases to see what knowledge is available, then use query_knowledge_files to search the relevant knowledge base before answering."*
+2. **Or disable Native Function Calling** for that model to restore automatic RAG injection.
+3. **Or use "Full Context" mode** for attached knowledge (click on the attachment and select "Use Entire Document") which always injects the full content.
+
+See [Knowledge Scoping with Native Function Calling](/features/workspace/knowledge#knowledge-scoping-with-native-function-calling) for more details.
+:::
+
**Why use these?** It allows for **Deep Research** (searching the web multiple times, or querying knowledge bases), **Contextual Awareness** (looking up previous chats or notes), **Dynamic Personalization** (saving facts), and **Precise Automation** (generating content based on existing notes or documents).
#### Disabling Builtin Tools (Per-Model)
@@ -274,6 +302,38 @@ The **Builtin Tools** capability can be toggled on or off for each model in the
2. **RAG still works** (if File Context is enabled): Attached files are still processed via RAG and injected as context.
3. **No autonomous retrieval**: The model cannot decide to search knowledge bases or fetch additional information—it works only with what's provided upfront.
+#### Granular Builtin Tool Categories (Per-Model)
+
+When the **Builtin Tools** capability is enabled, you can further control which **categories** of builtin tools are available to the model. This appears in the Model Editor as a set of checkboxes under **Builtin Tools**.
+
+| Category | Tools Included | Description |
+|----------|----------------|-------------|
+| **Time & Calculation** | `get_current_timestamp`, `calculate_timestamp` | Get current time and perform date/time calculations |
+| **Memory** | `search_memories`, `add_memory`, `replace_memory_content` | Search and manage user memories |
+| **Chat History** | `search_chats`, `view_chat` | Search and view user chat history |
+| **Notes** | `search_notes`, `view_note`, `write_note`, `replace_note_content` | Search, view, and manage user notes |
+| **Knowledge Base** | `list_knowledge_bases`, `search_knowledge_bases`, `query_knowledge_bases`, `search_knowledge_files`, `query_knowledge_files`, `view_knowledge_file` | Browse and query knowledge bases |
+| **Channels** | `search_channels`, `search_channel_messages`, `view_channel_message`, `view_channel_thread` | Search channels and channel messages |
+
+All categories are **enabled by default**. Disabling a category prevents those specific tools from being injected, while keeping other categories active.
+
+**Use cases for granular control:**
+
+| Scenario | Recommended Configuration |
+|----------|---------------------------|
+| **Privacy-focused model** | Disable Memory and Chat History to prevent access to personal data |
+| **Read-only assistant** | Disable Notes (prevents creating/modifying notes) but keep Knowledge Base enabled |
+| **Minimal token usage** | Enable only the categories the model actually needs |
+| **Knowledge-centric bot** | Disable everything except Knowledge Base and Time |
+
+:::note
+These per-category toggles only appear when the main **Builtin Tools** capability is enabled. If you disable Builtin Tools entirely, no tools are injected regardless of category settings.
+:::
+
+:::info Global Features Take Precedence
+Enabling a per-model category toggle does **not** override global feature flags. For example, if `ENABLE_NOTES` is disabled globally (Admin Panel), Notes tools will not be available even if the "Notes" category is enabled for the model. The per-model toggles only allow you to *further restrict* what's already available—they cannot enable features that are disabled at the global level.
+:::
+
:::tip Builtin Tools vs File Context
**Builtin Tools** controls whether the model gets *tools* for autonomous retrieval. It does **not** control whether file content is injected via RAG—that's controlled by the separate **File Context** capability.
diff --git a/docs/features/plugin/tools/openapi-servers/index.mdx b/docs/features/plugin/tools/openapi-servers/index.mdx
index 8b57948a6b..9ab87319de 100644
--- a/docs/features/plugin/tools/openapi-servers/index.mdx
+++ b/docs/features/plugin/tools/openapi-servers/index.mdx
@@ -29,10 +29,10 @@ By leveraging OpenAPI, we eliminate the need for a proprietary or unfamiliar com
While OpenAPI tools are powerful for extending Open WebUI with external services, they have some constraints compared to native Python tools:
-- **No real-time UI events**: OpenAPI tools cannot emit status updates, notifications, or request user input via the [event system](/features/plugin/development/events). They communicate via standard HTTP request/response only.
+- **One-way events only**: OpenAPI tools can emit status updates, notifications, and other [one-way events](/features/plugin/development/events#-external-tool-events) via the REST endpoint. Open WebUI passes `X-Open-WebUI-Chat-Id` and `X-Open-WebUI-Message-Id` headers to enable this. However, interactive events (user input prompts, confirmations) are only available for native Python tools.
- **No streaming output**: Tool responses are returned as complete results, not streamed token-by-token.
-If you need real-time UI feedback (progress updates, confirmations, streaming), consider implementing your tool as a [native Python Tool](/features/plugin/tools/development) instead.
+If you need interactive UI feedback (confirmations, user input prompts), consider implementing your tool as a [native Python Tool](/features/plugin/tools/development) instead.
## 🚀 Quickstart
diff --git a/docs/features/plugin/tools/openapi-servers/mcp.mdx b/docs/features/plugin/tools/openapi-servers/mcp.mdx
index 28bbd09b5d..c517439284 100644
--- a/docs/features/plugin/tools/openapi-servers/mcp.mdx
+++ b/docs/features/plugin/tools/openapi-servers/mcp.mdx
@@ -45,8 +45,8 @@ So even though adding mcpo might at first seem like "just one more layer"—in r
✨ With mcpo, your local-only AI tools become cloud-ready, UI-friendly, and instantly interoperable—without changing a single line of tool server code.
-:::note
-**Limitation**: Since mcpo exposes MCP tools as OpenAPI endpoints, they inherit OpenAPI's limitations—specifically, they cannot use Open WebUI's [event system](/features/plugin/development/events) for real-time UI updates (status messages, notifications, user input prompts). These features are only available for native Python tools.
+:::tip
+**Events Supported**: While mcpo exposes MCP tools as OpenAPI endpoints, they can still emit events (status updates, notifications) via Open WebUI's [event REST endpoint](/features/plugin/development/events#-external-tool-events). Open WebUI automatically passes the required `X-Open-WebUI-Chat-Id` and `X-Open-WebUI-Message-Id` headers to your tool. However, interactive events requiring user input are only available for native Python tools.
:::
### ✅ Quickstart: Running the Proxy Locally
diff --git a/docs/features/rag/index.md b/docs/features/rag/index.md
index 816c1b7d96..ab43f13866 100644
--- a/docs/features/rag/index.md
+++ b/docs/features/rag/index.md
@@ -17,6 +17,10 @@ One of the key advantages of RAG is its ability to access and integrate informat
Local documents must first be uploaded via the Documents section of the Workspace area to access them using the `#` symbol before a query. Click on the formatted URL in the that appears above the chat box. Once selected, a document icon appears above `Send a message`, indicating successful retrieval.
+:::tip Bulk File Management
+Need to clean up multiple uploaded documents or audit your storage? You can now use the centralized **[File Manager](/features/data-controls/files)** located in **Settings > Data Controls > Manage Files**. Deleting files there will automatically clean up their corresponding RAG embeddings.
+:::
+
You can also load documents into the workspace area with their access by starting a prompt with `#`, followed by a URL. This can help incorporate web content directly into your conversations.
## Web Search for RAG
@@ -164,6 +168,10 @@ The **File Context** capability controls whether Open WebUI performs RAG (Retrie
When File Context is disabled, file content is **not automatically extracted or injected**. Open WebUI does not forward files to the model's native API. If you disable this, the only way the model can access file content is through builtin tools (if enabled) that query knowledge bases or retrieve attached files on-demand (agentic file processing).
:::
+:::tip Per-File Retrieval Mode
+Individual files and knowledge bases can also be set to bypass RAG entirely using the **"Using Entire Document"** toggle. This injects the full file content into every message regardless of native function calling settings. See [Full Context vs Focused Retrieval](/features/workspace/knowledge#full-context-vs-focused-retrieval) for details.
+:::
+
:::info
The File Context toggle only appears when **File Upload** is enabled for the model.
:::
diff --git a/docs/features/rbac/groups.md b/docs/features/rbac/groups.md
index 7b9d70c4a8..01d4fd9d90 100644
--- a/docs/features/rbac/groups.md
+++ b/docs/features/rbac/groups.md
@@ -69,6 +69,10 @@ You can restrict access to specific objects (like a proprietary Model or sensiti
1. **Tag the Resource**: When creating/editing a Model or Knowledge Base, set its visibility to **Private** or **Restricted**.
2. **Grant Access**: Select the specific **Groups** (or individual users) that should have "Read" or "Write" access.
+:::tip Knowledge Scoping for Models
+Beyond visibility, knowledge access is also scoped by model configuration. When a model has **attached knowledge bases**, it can only access those specific KBs (not all user-accessible KBs). See [Knowledge Scoping with Native Function Calling](/features/workspace/knowledge#knowledge-scoping-with-native-function-calling) for details.
+:::
+
### Access Control Object
At a deeper level, resources store an access control list (ACL) looking like this:
diff --git a/docs/features/web-search/agentic-search.mdx b/docs/features/web-search/agentic-search.mdx
index a4fdbdeeb2..5f9f39cbdf 100644
--- a/docs/features/web-search/agentic-search.mdx
+++ b/docs/features/web-search/agentic-search.mdx
@@ -29,13 +29,19 @@ For comprehensive information about all built-in agentic tools (including web se
To unlock these features, your model must support native tool calling and have strong reasoning capabilities (e.g., GPT-5, Claude 4.5 Sonnet, Gemini 3 Flash, MiniMax M2.1). Administrator-level configuration for these built-in system tools is handled via the [**Central Tool Calling Guide**](/features/plugin/tools#tool-calling-modes-default-vs-native).
-1. **Enable Web Search**: Ensure a search engine is configured in **Admin Panel > Settings > Web Search**.
-2. **Enable Native Mode (Agentic Mode)**:
- * Go to **Admin Panel > Settings > Models**.
- * Navigate to **Model Specific Settings** for your target model.
- * Under **Advanced Parameters**, set **Function Calling** to `Native`.
-3. **Use a Quality Model**: Ensure you're using a frontier model with strong reasoning capabilities for best results.
-4. **Chat Features**: Ensure the **Web Search** feature is toggled **ON** for your chat session.
+1. **Enable Web Search Globally**: Ensure a search engine is configured in **Admin Panel → Settings → Web Search**.
+2. **Enable Model Capability**: In **Admin Panel → Settings → Models**, select your model and enable the **Web Search** capability.
+3. **Enable Native Mode (Agentic Mode)**:
+ * In the same model settings, under **Advanced Parameters**, set **Function Calling** to `Native`.
+4. **Use a Quality Model**: Ensure you're using a frontier model with strong reasoning capabilities for best results.
+
+:::tip Model Capability vs. Chat Toggle
+In **Native Mode**, the `search_web` and `fetch_url` tools are automatically included based on the model's `web_search` capability setting. The chat toggle is not required.
+
+In **Default Mode** (non-native), the chat toggle still controls whether web search is performed via RAG-style injection.
+
+**Important**: If you disable the `web_search` capability on a model but use Native Mode, the tools won't be available even if you manually toggle Web Search on in the chat.
+:::
## How Native Tools Handle Data (Agentic Mode)
🔗 It is important to understand that Native Mode (Agentic Mode) works fundamentally differently from the global "Web Search" toggle found in standard models.
diff --git a/docs/features/web-search/google-pse.md b/docs/features/web-search/google-pse.md
index 4c3f2e4d94..c1a2f7bb3f 100644
--- a/docs/features/web-search/google-pse.md
+++ b/docs/features/web-search/google-pse.md
@@ -5,6 +5,12 @@ title: "Google PSE"
:::warning
+**New Google PSE projects are no longer supported.** Google has restricted the legacy JSON API to existing customers only. New users attempting to use Google PSE will receive a `403 Forbidden` error.
+
+:::
+
+:::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.
:::
diff --git a/docs/features/web-search/searxng.md b/docs/features/web-search/searxng.md
index 3d90c12997..e3aeefd804 100644
--- a/docs/features/web-search/searxng.md
+++ b/docs/features/web-search/searxng.md
@@ -261,7 +261,7 @@ docker compose up -d
:::note
-On the first run, you must remove `cap_drop: - ALL` from the `docker-compose.yaml` file for the `searxng` service to successfully create `/etc/searxng/uwsgi`.ini. This is necessary because the `cap_drop: - ALL` directive removes all capabilities, including those required for the creation of the `uwsgi.ini` file. After the first run, you should re-add `cap_drop: - ALL` to the `docker-compose.yaml` file for security reasons.
+On the first run, you must remove `cap_drop: - ALL` from the `docker-compose.yaml` file for the `searxng` service to successfully create `/etc/searxng/uwsgi.ini`. This is necessary because the `cap_drop: - ALL` directive removes all capabilities, including those required for the creation of the `uwsgi.ini` file. After the first run, you should re-add `cap_drop: - ALL` to the `docker-compose.yaml` file for security reasons.
:::
diff --git a/docs/features/web-search/yandex.md b/docs/features/web-search/yandex.md
new file mode 100644
index 0000000000..4dc1c9ee95
--- /dev/null
+++ b/docs/features/web-search/yandex.md
@@ -0,0 +1,49 @@
+---
+sidebar_position: 14
+title: "Yandex"
+---
+
+:::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.
+
+:::
+
+:::tip
+
+For a comprehensive list of all environment variables related to Web Search (including concurrency settings, result counts, and more), please refer to the [Environment Configuration documentation](../../getting-started/env-configuration#web-search).
+
+:::
+
+:::tip Troubleshooting
+
+Having issues with web search? Check out the [Web Search Troubleshooting Guide](../../troubleshooting/web-search) for solutions to common problems like proxy configuration, connection timeouts, and empty content.
+
+:::
+
+## Yandex Search API
+
+Support for Yandex Web Search is integrated via the [Yandex Cloud Search API](https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search).
+
+### Docker Compose Setup
+
+Add the following environment variables to your Open WebUI `docker-compose.yaml` file:
+
+```yaml
+services:
+ open-webui:
+ environment:
+ ENABLE_RAG_WEB_SEARCH: True
+ RAG_WEB_SEARCH_ENGINE: "yandex"
+ YANDEX_WEB_SEARCH_API_KEY: "YOUR_YANDEX_CLOUD_API_KEY"
+ # Optional: Override default search URL
+ # YANDEX_WEB_SEARCH_URL: "https://searchapi.api.cloud.yandex.net/v2/web/search"
+ # Optional: Custom JSON configuration for Yandex Search API
+ # YANDEX_WEB_SEARCH_CONFIG: '{"query": {"searchType": "SEARCH_TYPE_RU"}}'
+```
+
+### Configuration Options
+
+* **YANDEX_WEB_SEARCH_URL**: The endpoint for the Yandex Search API. Defaults to `https://searchapi.api.cloud.yandex.net/v2/web/search`.
+* **YANDEX_WEB_SEARCH_API_KEY**: Your Yandex Cloud API Key.
+* **YANDEX_WEB_SEARCH_CONFIG**: An optional JSON string to customize the search request. This allows you to set any parameters supported by the Yandex Search API.
diff --git a/docs/features/workspace/files.md b/docs/features/workspace/files.md
new file mode 100644
index 0000000000..b5ecbf6b89
--- /dev/null
+++ b/docs/features/workspace/files.md
@@ -0,0 +1,65 @@
+---
+sidebar_position: 5
+title: "📁 File Management"
+---
+
+Open WebUI provides a comprehensive file management system that allows you to upload, organize, and utilize your documents across various features like Knowledge Bases and RAG.
+
+## Centralized File Manager
+
+The **Centralized File Manager** provides a unified interface to view, search, and manage every file you have uploaded to your Open WebUI instance, whether it was uploaded directly to a chat or into a Knowledge Base.
+
+### Accessing the File Manager
+
+1. Click on your **profile name** or avatar in the bottom-left corner.
+2. Select **Settings** from the menu.
+3. Navigate to the **Data Controls** tab.
+4. Locate the **Manage Files** row and click the **Manage** button.
+
+### Key Features
+
+The File Manager modal offers several powerful tools for maintaining your data:
+
+- **Universal Search**: Quickly find any file by its filename using the integrated search bar.
+- **Advanced Sorting**: Organize your file list by:
+ - **Filename**: Sort alphabetically to find specific documents.
+ - **Created At**: See your most recent uploads or find older files.
+- **File Details**: View important information at a glance, including:
+ - **File Size**: See how much space each document occupies (e.g., KB, MB).
+ - **Upload Date**: Track when each file was added to your instance.
+- **Built-in Viewer**: Click on any file to open the **File Item Viewer**, which displays the file's metadata and specific details (such as size and type).
+- **Safe Deletion**: Easily remove files you no longer need.
+ - :::info **Knowledge Base Cleanup**
+ When you delete a file through the File Manager, Open WebUI automatically performs a deep cleanup. It removes the file from all associated Knowledge Bases and deletes its corresponding vector embeddings, ensuring your database stays clean and efficient.
+ :::
+
+## Using Files in Open WebUI
+
+Files are at the heart of the platform's advanced capabilities:
+
+### 1. Retrieval Augmented Generation (RAG)
+By uploading documents (PDFs, Word docs, text files, etc.), you can ground your AI's responses in your own data.
+- **Chat Uploads**: Simply drag and drop files into a chat or use the upload icon.
+- **Knowledge Bases**: Add files to structured collections for more permanent and organized retrieval.
+
+### 2. File Metadata
+Every file carries metadata that helps both you and the AI understand its context. This includes content type, original filename, and size.
+
+## Best Practices
+
+- **Naming Conventions**: Use clear, descriptive filenames. This improves the accuracy of the File Manager's search and helps you identify specific documents.
+- **Regular Audits**: Periodically use the **Manage Files** dashboard to delete old or redundant documents. This saves disk/database space and improves the performance of your system by ensuring only relevant data is retained.
+
+## FAQ
+
+**Q: If I delete a file, is it gone from my chats?**
+**A:** Yes. Deleting a file via the File Manager removes it from the system entirely. Any chat that referenced that file using RAG will no longer be able to pull information from it.
+
+**Q: Can I download my files back from the File Manager?**
+**A:** Currently, the File Manager focuses on viewing metadata and management (deletion). To download a file, you should typically access it from the original chat or Knowledge Base where it was used.
+
+**Q: Are there limits on the number of files I can manage?**
+**A:** There is no hard-coded limit in Open WebUI. The scalability depends on your storage (disk/S3) and your Vector Database (e.g., ChromaDB, PGVector).
+
+**Q: Does managing files require Admin privileges?**
+**A:** Regular users can manage their *own* uploaded files. Administrators have additional tools to manage global files and configuration via the Admin Panel.
diff --git a/docs/features/workspace/index.mdx b/docs/features/workspace/index.mdx
index 6a08a8e303..46d6145d61 100644
--- a/docs/features/workspace/index.mdx
+++ b/docs/features/workspace/index.mdx
@@ -10,5 +10,6 @@ The Workspace in Open WebUI provides a comprehensive environment for managing yo
- [🤖 Models](./models.md) - Create and manage custom models tailored to specific purposes
- [🧠 Knowledge](./knowledge.md) - Manage your knowledge bases for retrieval augmented generation
- [📚 Prompts](./prompts.md) - Create and organize reusable prompts
+- [📁 Files](./files.md) - Centralized management for all your uploaded documents
Each section of the Workspace is designed to give you fine-grained control over your Open WebUI experience, allowing for customization and optimization of your AI interactions.
diff --git a/docs/features/workspace/knowledge.md b/docs/features/workspace/knowledge.md
index 052eee44b9..787938706d 100644
--- a/docs/features/workspace/knowledge.md
+++ b/docs/features/workspace/knowledge.md
@@ -56,6 +56,62 @@ Autonomous knowledge base exploration works best with frontier models (GPT-5, Cl
These tools enable models to autonomously explore and retrieve information from your knowledge bases, making conversations more contextually aware and grounded in your stored documents.
+#### Knowledge Scoping with Native Function Calling
+
+When native function calling is enabled, the model's access to knowledge bases depends on whether you've attached specific knowledge to the model:
+
+| Model Configuration | Knowledge Access |
+|-------------------|------------------|
+| **No KB attached** | Model can access **all** knowledge bases the user has access to (public KBs, user's own KBs) |
+| **KB attached to model** | Model is **limited** to only the attached knowledge base(s) |
+
+:::warning Knowledge is NOT Auto-Injected with Native Function Calling
+
+**Important behavioral difference:** When using Native Function Calling, attached knowledge is **not automatically injected** into the conversation. Instead, the model must actively call the knowledge tools to search and retrieve information.
+
+**If your model isn't using attached knowledge:**
+
+1. **Add instructions to your system prompt** telling the model to discover and query knowledge bases. For example:
+ > "When users ask questions, first use list_knowledge_bases to see what knowledge is available, then use query_knowledge_files to search the relevant knowledge base before answering."
+
+2. **Or disable Native Function Calling** for that model to restore the automatic RAG injection behavior from earlier versions.
+
+3. **Or use "Full Context" mode** for the attached knowledge (click on the attachment and select "Use Entire Document") which bypasses RAG and always injects the full content.
+
+:::
+
+:::tip Restricting Knowledge Access
+If you want a model to focus on specific documents, attach those knowledge bases to the model in **Workspace > Models > Edit**. This prevents the model from searching other available knowledge bases.
+:::
+
+### Full Context vs Focused Retrieval
+
+When attaching files, notes, or knowledge bases to a model, you can choose between two retrieval modes by clicking on the attached item:
+
+#### 🔍 Focused Retrieval (Default)
+
+- Uses **RAG (Retrieval Augmented Generation)** to find relevant chunks
+- Only injects the most relevant portions of documents based on the user's query
+- Best for large documents or knowledge bases where only specific sections are relevant
+- With native function calling enabled, the model decides when to search
+
+#### 📄 Using Entire Document (Full Context)
+
+- Injects the **complete content** of the file/note into every message
+- Bypasses RAG entirely—no chunking or semantic search
+- Best for short reference documents, style guides, or context that's always relevant
+- **Always injected** regardless of native function calling settings
+
+:::info Full Context with Native Function Calling
+When "Using Entire Document" is enabled for a file or knowledge base, its content is **always injected** into the conversation, even when native function calling is enabled. The model does not need to call any tools to access this content—it's automatically included in the context.
+
+Files set to Focused Retrieval (the default) will only be accessed when the model calls the appropriate knowledge tools.
+:::
+
+:::note Per-Model Control
+The Knowledge Base tools require the **Knowledge Base** category to be enabled for the model in **Workspace > Models > Edit > Builtin Tools** (enabled by default). Administrators can disable this category per-model to prevent autonomous knowledge base access.
+:::
+
:::info Central Tool Documentation
For complete details on all built-in agentic tools and how to configure them, see the [**Native/Agentic Mode Tools Guide**](/features/plugin/tools#built-in-system-tools-nativeagentic-mode).
:::
@@ -88,7 +144,7 @@ Key API endpoints:
:::warning Important: Async File Processing
When uploading files via API, processing happens asynchronously. You **must** wait for file processing to complete before adding files to a knowledge base, or you will receive an "empty content" error.
-For detailed examples and proper workflow handling, see the [API Endpoints documentation](/getting-started/api-endpoints#retrieval-augmented-generation-rag).
+For detailed examples and proper workflow handling, see the [API Endpoints documentation](/getting-started/api-endpoints#-retrieval-augmented-generation-rag).
:::
## Summary
diff --git a/docs/features/workspace/models.md b/docs/features/workspace/models.md
index 62f0361fad..7b1c7da6c8 100644
--- a/docs/features/workspace/models.md
+++ b/docs/features/workspace/models.md
@@ -72,7 +72,7 @@ Clicking **Show** on **Advanced Params** allows you to fine-tune the inference g
You can transform a generic model into a specialized agent by toggling specific capabilities and binding resources.
-- **Knowledge**: Instead of manually selecting documents for every chat, you can bind a specific knowledgebase **Collection** or **File** to this model. Whenever this model is selected, RAG (Retrieval Augmented Generation) is automatically active for those specific files.
+- **Knowledge**: Instead of manually selecting documents for every chat, you can bind a specific knowledgebase **Collection** or **File** to this model. Whenever this model is selected, RAG (Retrieval Augmented Generation) is automatically active for those specific files. Click on attached items to toggle between **Focused Retrieval** (RAG chunks) and **Using Entire Document** (full content injection). See [Full Context vs Focused Retrieval](/features/workspace/knowledge#full-context-vs-focused-retrieval) for details.
- **Tools**: Force specific tools to be enabled by default (e.g., always enable the **Calculator** tool for a "Math Bot").
- **Filters**: Attach specific Pipelines/Filters (e.g., a Profanity Filter or PII Redaction script) to run exclusively on this model.
- **Actions**: Attach actionable scripts like `Add to Memories` or `Button` triggers.
@@ -81,11 +81,11 @@ You can transform a generic model into a specialized agent by toggling specific
- **Web Search**: Enable the model to access the configured search provider (e.g., Google, SearxNG) for real-time information.
- **File Upload**: Allow users to upload files to this model.
- **File Context**: When enabled (default), attached files are processed via RAG and their content is injected into the conversation. When disabled, file content is **not** extracted or injected—the model receives no file content unless it retrieves it via builtin tools. Only visible when File Upload is enabled. See [File Context vs Builtin Tools](../rag/index.md#file-context-vs-builtin-tools) for details.
- - **Code Interpreter**: Enable Python code execution.
+ - **Code Interpreter**: Enable Python code execution. See [Python Code Execution](../chat-features/code-execution/python.md) for details.
- **Image Generation**: Enable image generation integration.
- **Usage / Citations**: Toggle usage tracking or source citations.
- **Status Updates**: Show visible progress steps in the chat UI (e.g., "Searching web...", "Reading file...") during generation. Useful for slower, complex tasks.
- - **Builtin Tools**: When enabled (default), automatically injects system tools (timestamps, memory, chat history, knowledge base queries, notes, etc.) in [Native Function Calling mode](../plugin/tools/index.mdx#disabling-builtin-tools-per-model). Disable this if the model doesn't support function calling or you need to save context window tokens. Note: This is separate from **File Context**—see [File Context vs Builtin Tools](../rag/index.md#file-context-vs-builtin-tools) for the difference.
+ - **Builtin Tools**: When enabled (default), automatically injects system tools (timestamps, memory, chat history, knowledge base queries, notes, etc.) in [Native Function Calling mode](../plugin/tools/index.mdx#disabling-builtin-tools-per-model). When enabled, you can further control which **tool categories** are available (Time, Memory, Chats, Notes, Knowledge, Channels) via checkboxes in the Model Editor. Disable the main toggle if the model doesn't support function calling or you need to save context window tokens. Note: This is separate from **File Context**—see [File Context vs Builtin Tools](../rag/index.md#file-context-vs-builtin-tools) for the difference.
- **TTS Voice**: Set a specific Text-to-Speech voice for this model. When users read responses aloud, this voice will be used instead of the global default. Useful for giving different personas distinct voices. Leave empty to use the user's settings or system default. See [Per-Model TTS Voice](../audio/text-to-speech/openai-tts-integration#per-model-tts-voice) for details.
- **Default Features**: Force specific toggles (like Web Search) to be "On" immediately when a user starts a chat with this model.
@@ -116,6 +116,32 @@ A raw Base Model can be cloned as a custom Workspace model, but it will not clon
To download new raw Base Models (like `Llama-3.2-3B-Instruct-GGUF:Q8_0` or `Mistral-7B-Instruct-v0.2-GGUF:Q4_K_M`), navigate to **Settings > Connections > Ollama**. Alternatively, type `ollama run hf.co/{username}/{repository}:{quantization}` in the model selector to pull directly from Hugging Face. This action will create a button within the model selector labeled "Pull [Model Name]" that will begin downloading the model from its source once clicked.
:::
+## Global Model Management (Admin)
+
+Administrators have access to a centralized management interface via **Admin Panel > Settings > Models**. This page provides powerful tools for decluttering and organizing the model list, especially when connected to providers with hundreds of available models.
+
+### View Filtering
+
+The **Admin View Selector** allows you to filter the entire list of models by their operational status. This is located next to the search bar and includes the following views:
+
+- **All**: Shows every model available to the system.
+- **Enabled**: Displays only models that are currently active and selectable by users.
+- **Disabled**: Shows models that have been deactivated.
+- **Visible**: Shows models that are currently visible in the user model selector.
+- **Hidden**: Displays only the models that have been hidden (these appear with reduced opacity in the list).
+
+### Bulk Actions
+
+To streamline the management of large model collections, the Admin Panel includes **Bulk Actions** that apply to the models currently visible in your filtered view.
+
+1. **Filter your view** (e.g., select "Disabled" or "Hidden").
+2. **Open the Actions menu** (Ellipsis icon next to the search bar).
+3. **Select an action**:
+ - **Enable All**: Activates all models in the current filtered list simultaneously.
+ - **Disable All**: Deactivates all models in the current filtered list.
+
+These tools are specifically designed to help administrators quickly manage external providers (like OpenAI or Anthropic) that expose a high volume of models, allowing for instant site-wide configuration changes.
+
## Model Switching in Chat
Open WebUI allows for dynamic model switching and parallel inference within a chat session.
diff --git a/docs/features/workspace/prompts.md b/docs/features/workspace/prompts.md
index eba31f61db..00ca12419a 100644
--- a/docs/features/workspace/prompts.md
+++ b/docs/features/workspace/prompts.md
@@ -9,19 +9,23 @@ The `Prompts` section of the `Workspace` within Open WebUI enables users to crea
The Prompts interface provides several key features for managing your custom prompts:
-* **Create**: Design new prompts with customizable titles, access levels, and content.
+* **Create**: Design new prompts with customizable names, tags, access levels, and content.
* **Share**: Share prompts with other users based on configured access permissions.
* **Access Control**: Set visibility and usage permissions for each prompt (refer to [Permissions](/features/rbac/permissions) for more details).
* **Slash Commands**: Quickly access prompts using custom slash commands during chat sessions.
+* **Versioning & History**: Track every change with a full version history, allowing you to compare and revert to previous versions.
+* **Tags & Filtering**: Organize your prompts using tags and easily filter through your collection in the workspace.
### Creating and Editing Prompts
When creating or editing a prompt, you can configure the following settings:
-* **Title**: Give your prompt a descriptive name for easy identification.
+* **Name**: Give your prompt a descriptive name for easy identification.
+* **Tags**: Categorize your prompts with tags to make them easier to find and filter in your workspace.
* **Access**: Set the access level to control who can view and use the prompt.
-* **Command**: Define a slash command that will trigger the prompt (e.g., `/summarize`).
+* **Command**: Define a slash command that will trigger the prompt (e.g., `/summarize`). Commands are triggered in the chat by typing `/` followed by the command name.
* **Prompt Content**: Write the actual prompt text that will be sent to the model.
+* **Commit Message**: When saving changes, you can provide an optional commit message to describe what was updated in this version.
### Prompt Variables
@@ -38,6 +42,11 @@ Open WebUI supports two kinds of variables to make your prompts more dynamic and
* `{{CURRENT_WEEKDAY}}`: Current day of the week
* **User Information**:
* `{{USER_NAME}}`: Current user's name
+ * `{{USER_EMAIL}}`: Current user's email address
+ * `{{USER_BIO}}`: Current user's bio. Configured in **Settings > Account > User Profile**. If not set, the variable remains unreplaced.
+ * `{{USER_GENDER}}`: Current user's gender. Configured in **Settings > Account > User Profile**. If not set, the variable remains unreplaced.
+ * `{{USER_BIRTH_DATE}}`: Current user's birth date. Configured in **Settings > Account > User Profile**. If not set, the variable remains unreplaced.
+ * `{{USER_AGE}}`: Current user's age, calculated from birth date. If birth date is not set, the variable remains unreplaced.
* `{{USER_LANGUAGE}}`: User's selected language
* `{{USER_LOCATION}}`: User's location (requires HTTPS and Settings > Interface toggle)
@@ -53,7 +62,19 @@ By leveraging custom input variables, you can move beyond static text and build
* The `{{USER_LOCATION}}` system variable requires:
* A secure HTTPS connection
* Enabling the feature in `Settings` > `Interface`
-* The `{{CLIPBOARD}}` system variable requires clipboard access permission from your device
+* The `{{CLIPBOARD}}` system variable requires clipboard access permission from your device.
+
+---
+
+#### Advanced Variable Modifiers
+
+Certain system variables like `{{prompt}}` and `{{MESSAGES}}` support optional modifiers to control their length and which part of the content is included. This is particularly useful for managing context window limits.
+
+* **Start Truncation**: `{{prompt:start:N}}` - Includes only the first **N** characters of the content.
+* **End Truncation**: `{{prompt:end:N}}` - Includes only the last **N** characters of the content.
+* **Middle Truncation**: `{{prompt:middletruncate:N}}` - Includes a total of **N** characters, taking half from the beginning and half from the end, with `...` in the middle.
+
+These modifiers also work with the `{{MESSAGES}}` variable (e.g., `{{MESSAGES:START:5}}` to include only the first 5 messages).
---
@@ -234,6 +255,26 @@ A flexible template for reviewing various types of content.
Please provide detailed feedback and suggestions for improvement.
```
+### Prompt Versioning and History
+
+Open WebUI includes a robust versioning system for prompts, allowing you to track changes over time and revert to previous versions if needed.
+
+#### Version Tracking
+Every time you save changes to a prompt's content, name, command, or access control, a new version is automatically created. This ensures that your prompt's evolution is preserved.
+
+#### History Sidebar
+When editing an existing prompt, you will see a **History** sidebar (on desktop) that lists all previous versions in reverse chronological order. Each entry shows:
+* **Commit Message**: A brief description of the changes (if provided).
+* **Author**: The user who made the changes, including their profile picture.
+* **Timestamp**: When the change was made.
+* **Live Badge**: Indicates which version is currently active in the chat.
+
+#### Managing Versions
+* **Previewing**: Click on any version in the history sidebar to preview its content in the main editor.
+* **Setting as Production**: To make a previous version the active "Live" version, select it and click **Set as Production**.
+* **Deleting Versions**: You can delete individual history entries by clicking the menu icon next to the version. Note that you cannot delete the currently active production version.
+* **Copying ID**: Click the prompt ID or a specific version's short ID to copy it to your clipboard for reference.
+
### Access Control and Permissions
Prompt management is controlled by the following permission settings:
@@ -256,8 +297,6 @@ Prompt management is controlled by the following permission settings:
### Migration Notes
-If you have existing prompts created before this update, they will continue to work as before. However, note that:
-
-* All existing variables are now treated as optional by default
-* If you want to maintain required behavior for critical fields, edit your prompts to add the `:required` flag to those variables
-* This change provides better user experience by allowing flexible usage of prompt templates
+* **Prompt History Migration**: Existing prompts created before the versioning update have been automatically migrated to the new system. Their current content has been preserved as the initial "Live" version in their history.
+* **ID-based URLs**: The URL structure for editing prompts has changed from using commands to using unique IDs. Existing bookmarks to prompt edit pages may need to be updated.
+* **Variable Requirement**: As of the v0.5.0 update, all variables are now treated as optional by default. To maintain required behavior for critical fields, edit your prompts to add the `:required` flag to those variables.
diff --git a/docs/getting-started/api-endpoints.md b/docs/getting-started/api-endpoints.md
index 189bd61b49..7ec3f89b5a 100644
--- a/docs/getting-started/api-endpoints.md
+++ b/docs/getting-started/api-endpoints.md
@@ -81,6 +81,81 @@ Access detailed API documentation for different services provided by Open WebUI:
return response.json()
```
+### 🔧 Filter and Function Behavior with API Requests
+
+When using the API endpoints directly, filters (Functions) behave differently than when requests come from the web interface.
+
+:::info Authentication Note
+Open WebUI accepts both **API keys** (prefixed with `sk-`) and **JWT tokens** for API authentication. This is intentional—the web interface uses JWT tokens internally for the same API endpoints. Both authentication methods provide equivalent API access.
+:::
+
+#### Filter Execution
+
+| Filter Function | WebUI Request | Direct API Request |
+|----------------|--------------|-------------------|
+| `inlet()` | ✅ Runs | ✅ Runs |
+| `stream()` | ✅ Runs | ✅ Runs |
+| `outlet()` | ✅ Runs | ❌ **Does NOT run** |
+
+The `inlet()` function always executes, making it ideal for:
+- **Rate limiting** - Track and limit requests per user
+- **Request logging** - Log all API usage for monitoring
+- **Input validation** - Reject invalid requests before they reach the model
+
+#### Triggering Outlet Processing
+
+The `outlet()` function only runs when the WebUI calls `/api/chat/completed` after a chat finishes. For direct API requests, you must call this endpoint yourself if you need outlet processing:
+
+- **Endpoint**: `POST /api/chat/completed`
+- **Description**: Triggers outlet filter processing for a completed chat
+
+- **Curl Example**:
+
+ ```bash
+ curl -X POST http://localhost:3000/api/chat/completed \
+ -H "Authorization: Bearer YOUR_API_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "model": "llama3.1",
+ "messages": [
+ {"role": "user", "content": "Hello"},
+ {"role": "assistant", "content": "Hi! How can I help you today?"}
+ ],
+ "chat_id": "optional-uuid",
+ "session_id": "optional-session-id"
+ }'
+ ```
+
+- **Python Example**:
+
+ ```python
+ import requests
+
+ def complete_chat_with_outlet(token, model, messages, chat_id=None):
+ """
+ Call after receiving the full response from /api/chat/completions
+ to trigger outlet filter processing.
+ """
+ url = 'http://localhost:3000/api/chat/completed'
+ headers = {
+ 'Authorization': f'Bearer {token}',
+ 'Content-Type': 'application/json'
+ }
+ payload = {
+ 'model': model,
+ 'messages': messages # Include the full conversation with assistant response
+ }
+ if chat_id:
+ payload['chat_id'] = chat_id
+
+ response = requests.post(url, headers=headers, json=payload)
+ return response.json()
+ ```
+
+:::tip
+For more details on writing filters that work with API requests, see the [Filter Function documentation](/features/plugin/functions/filter#-filter-behavior-with-api-requests).
+:::
+
### 🦙 Ollama API Proxy Support
If you want to interact directly with Ollama models—including for embedding generation or raw prompt streaming—Open WebUI offers a transparent passthrough to the native Ollama API via a proxy route.
diff --git a/docs/getting-started/env-configuration.mdx b/docs/getting-started/env-configuration.mdx
index 5dbe5bf359..8f0c47fb25 100644
--- a/docs/getting-started/env-configuration.mdx
+++ b/docs/getting-started/env-configuration.mdx
@@ -270,23 +270,11 @@ is also being used and set to `True`. **Never disable this if OAUTH/SSO is not b
- Default: `True`
- Description: Enables admin users to directly access the chats of other users. When disabled, admins can no longer accesss user's chats in the admin panel. If you disable this, consider disabling `ENABLE_ADMIN_EXPORT` too, if you are using SQLite, as the exports also contain user chats.
-#### `ENABLE_ADMIN_WORKSPACE_CONTENT_ACCESS`
-
-- Type: `bool`
-- Default: `True`
-- Description: Enables admin users to access all workspace content (models, knowledge bases, prompts, and tools) regardless of access control settings. When set to `False`, admins will only see workspace items they have been explicitly granted access to.
-
-:::warning **Deprecated**
-
-**This environment variable is deprecated and may be removed in a future release.** Use [`BYPASS_ADMIN_ACCESS_CONTROL`](#bypass_admin_access_control) instead, which provides the same functionality with a clearer name.
-
-:::
-
#### `BYPASS_ADMIN_ACCESS_CONTROL`
- Type: `bool`
- Default: `True`
-- Description: When disabled, admin users are treated like regular users for workspace access (models, knowledge, prompts and tools) and only see items they have **explicit permission to access** through the existing access control system. This also applies to the visibility of models in the model selector - admins will be treated as regular users: base models and custom models they do not have **explicit permission to access**, will be hidden. If set to `True` (Default), admins have access to **all created items** in the workspace area and all models in the model selector, **regardless of access permissions**.
+- Description: When disabled, admin users are treated like regular users for workspace access (models, knowledge, prompts and tools) and only see items they have **explicit permission to access** through the existing access control system. This also applies to the visibility of models in the model selector - admins will be treated as regular users: base models and custom models they do not have **explicit permission to access**, will be hidden. If set to `True` (Default), admins have access to **all created items** in the workspace area and all models in the model selector, **regardless of access permissions**. This environment variable deprecates `ENABLE_ADMIN_WORKSPACE_CONTENT_ACCESS`. If you are still using `ENABLE_ADMIN_WORKSPACE_CONTENT_ACCESS` you should switch to `BYPASS_ADMIN_ACCESS_CONTROL`.
#### `ENABLE_USER_WEBHOOKS`
@@ -341,6 +329,12 @@ If you are running larger instances, you WILL NEED to set this to a higher value
- Description: Globally enables or disables user status functionality. When disabled, the status UI (including blinking active/away indicators and status messages) is hidden across the application, and user status API endpoints are restricted.
- Persistence: This environment variable is a `PersistentConfig` variable. It can be toggled in the **Admin Panel > Settings > General > User Status**.
+#### `ENABLE_EASTER_EGGS`
+
+- Type: `bool`
+- Default: `True`
+- Description: Enables or disables easter egg features in the UI, such as special themes (e.g., the "Her" theme option in the theme selector). Set to `False` to hide these optional novelty features from users.
+
#### `ADMIN_EMAIL`
- Type: `str`
@@ -1356,7 +1350,7 @@ If you have already deployed with `JWT_EXPIRES_IN=-1`, you can rotate or change
- type: `bool`
- Default: `False`
-- Description: Forwards user information (name, ID, email, role and chat-id) as X-headers to OpenAI API and Ollama API.
+- Description: Forwards user and session information as HTTP headers to OpenAI API, Ollama API, MCP servers, and Tool servers.
If enabled, the following headers are forwarded:
- `X-OpenWebUI-User-Name`
- `X-OpenWebUI-User-Id`
@@ -1364,6 +1358,50 @@ If enabled, the following headers are forwarded:
- `X-OpenWebUI-User-Role`
- `X-OpenWebUI-Chat-Id`
+This enables per-user authorization, auditing, rate limiting, and request tracing on external services.
+
+#### `FORWARD_USER_INFO_HEADER_USER_NAME`
+
+- Type: `str`
+- Default: `X-OpenWebUI-User-Name`
+- Description: Customizes the header name used to forward the user's display name. Change this if your infrastructure requires a specific header prefix.
+
+#### `FORWARD_USER_INFO_HEADER_USER_ID`
+
+- Type: `str`
+- Default: `X-OpenWebUI-User-Id`
+- Description: Customizes the header name used to forward the user's ID.
+
+#### `FORWARD_USER_INFO_HEADER_USER_EMAIL`
+
+- Type: `str`
+- Default: `X-OpenWebUI-User-Email`
+- Description: Customizes the header name used to forward the user's email address.
+
+#### `FORWARD_USER_INFO_HEADER_USER_ROLE`
+
+- Type: `str`
+- Default: `X-OpenWebUI-User-Role`
+- Description: Customizes the header name used to forward the user's role.
+
+#### `FORWARD_SESSION_INFO_HEADER_CHAT_ID`
+
+- Type: `str`
+- Default: `X-OpenWebUI-Chat-Id`
+- Description: Customizes the header name used to forward the current chat/session ID.
+
+:::tip Custom Header Prefix
+Use these variables when integrating with services that require specific header naming conventions. For example, AWS Bedrock AgentCore requires headers prefixed with `X-Amzn-Bedrock-AgentCore-Runtime-Custom-`:
+
+```bash
+FORWARD_USER_INFO_HEADER_USER_NAME=X-Amzn-Bedrock-AgentCore-Runtime-Custom-User-Name
+FORWARD_USER_INFO_HEADER_USER_ID=X-Amzn-Bedrock-AgentCore-Runtime-Custom-User-Id
+FORWARD_USER_INFO_HEADER_USER_EMAIL=X-Amzn-Bedrock-AgentCore-Runtime-Custom-User-Email
+FORWARD_USER_INFO_HEADER_USER_ROLE=X-Amzn-Bedrock-AgentCore-Runtime-Custom-User-Role
+FORWARD_SESSION_INFO_HEADER_CHAT_ID=X-Amzn-Bedrock-AgentCore-Runtime-Custom-Chat-Id
+```
+:::
+
#### `ENABLE_WEB_LOADER_SSL_VERIFICATION`
- Type: `bool`
@@ -1481,6 +1519,19 @@ Invalid regex patterns will cause password validation to fail, potentially preve
:::
+#### `PASSWORD_VALIDATION_HINT`
+
+- Type: `str`
+- Default: `""` (empty string)
+- Description: Custom hint message displayed to users when their password fails validation. This message appears in error dialogs during signup, password changes, and admin user creation when the password doesn't meet the requirements defined by `PASSWORD_VALIDATION_REGEX_PATTERN`. Use this to explain your specific password requirements in user-friendly terms.
+- Example: `Password must be at least 12 characters with uppercase, lowercase, number, and special character.`
+
+:::tip
+
+When setting a custom `PASSWORD_VALIDATION_REGEX_PATTERN`, always set `PASSWORD_VALIDATION_HINT` to explain the requirements in plain language. Without a hint, users will only see a generic "Invalid password" error with no guidance on what's required.
+
+:::
+
#### `WEBUI_SECRET_KEY`
- Type: `str`
@@ -2262,11 +2313,25 @@ When using Pinecone as the vector store, the following environment variables are
### Weaviate
+:::info
+
+**Self-Hosted and Cloud Deployments**
+
+Open WebUI uses `connect_to_custom` for Weaviate connections, which supports both locally hosted and remote Weaviate instances. This is essential for self-hosted deployments where HTTP and gRPC endpoints may be on different ingresses or hostnames, which is common in container orchestration platforms like Kubernetes or Azure Container Apps.
+
+:::
+
#### `WEAVIATE_HTTP_HOST`
- Type: `str`
- Default: Empty string (' ')
-- Description: Specifies the hostname of the Weaviate server for HTTP connections.
+- Description: Specifies the hostname of the Weaviate server for HTTP connections. For self-hosted deployments, this is typically your Weaviate HTTP endpoint hostname.
+
+#### `WEAVIATE_GRPC_HOST`
+
+- Type: `str`
+- Default: Empty string (' ')
+- Description: Specifies the hostname of the Weaviate server for gRPC connections. This can be different from `WEAVIATE_HTTP_HOST` when HTTP and gRPC are served on separate ingresses, which is common in container orchestration environments.
#### `WEAVIATE_HTTP_PORT`
@@ -2280,12 +2345,30 @@ When using Pinecone as the vector store, the following environment variables are
- Default: `50051`
- Description: Specifies the gRPC port for connecting to the Weaviate server.
+#### `WEAVIATE_HTTP_SECURE`
+
+- Type: `bool`
+- Default: `False`
+- Description: Enables HTTPS for HTTP connections to the Weaviate server. Set to `true` when connecting to a Weaviate instance with TLS enabled on the HTTP endpoint.
+
+#### `WEAVIATE_GRPC_SECURE`
+
+- Type: `bool`
+- Default: `False`
+- Description: Enables TLS for gRPC connections to the Weaviate server. Set to `true` when connecting to a Weaviate instance with TLS enabled on the gRPC endpoint.
+
#### `WEAVIATE_API_KEY`
- Type: `str`
- Default: `None`
- Description: Sets the API key for authenticating with Weaviate server.
+#### `WEAVIATE_SKIP_INIT_CHECKS`
+
+- Type: `bool`
+- Default: `False`
+- Description: Skips Weaviate initialization checks when connecting. This can be useful in certain network configurations where the checks may fail but the connection itself works.
+
### Oracle 23ai Vector Search (oracle23ai)
#### `ORACLE_DB_USE_WALLET`
@@ -2708,6 +2791,16 @@ The `markdown_header` option has been removed from `RAG_TEXT_SPLITTER`. Markdown
- Description: Extracts images from PDFs using OCR when loading documents.
- Persistence: This environment variable is a `PersistentConfig` variable.
+#### `PDF_LOADER_MODE`
+
+- Type: `str`
+- Options:
+ - `page` - Creates one document per page (default).
+ - `single` - Combines all pages into one document for better chunking across page boundaries.
+- Default: `page`
+- Description: Controls how PDFs are loaded and split into documents when using the **default content extraction engine** (PyPDFLoader). Page mode creates one document per page, while single mode combines all pages into one document, which can improve chunking quality when content spans across page boundaries. This setting has no effect when using external content extraction engines like Tika, Docling, Document Intelligence, MinerU, or Mistral OCR, as those engines have their own document handling logic.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
#### `RAG_FILE_MAX_SIZE`
- Type: `int`
@@ -2858,6 +2951,14 @@ If you are embedding externally via API, ensure your rate limits are high enough
### Reranking
+#### `RAG_RERANKING_ENGINE`
+
+- Type: `str`
+- Options: `external`, or empty for local Sentence-Transformer CrossEncoder
+- Default: Empty string (local reranking)
+- Description: Specifies the reranking engine to use. Set to `external` to use an external reranker API (requires `RAG_EXTERNAL_RERANKER_URL`). Leave empty to use a local Sentence-Transformer CrossEncoder model.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
#### `RAG_RERANKING_MODEL`
- Type: `str`
@@ -3224,6 +3325,7 @@ Allow only specific domains: WEB_FETCH_FILTER_LIST="example.com,trusted-site.org
- `ollama_cloud` - Uses the [Ollama Cloud](https://ollama.com/blog/web-search) search engine.
- `azure_ai_search`
- `yacy`
+ - `yandex` - Uses the [Yandex Search API](https://yandex.cloud/en/docs/search-api/api-ref/WebSearch/search).
- Persistence: This environment variable is a `PersistentConfig` variable.
#### `DDGS_BACKEND`
@@ -3488,6 +3590,27 @@ Brave's free tier enforces a rate limit of 1 request per second. Open WebUI auto
- Description: Sets the API key for authenticating with the external web loader service.
- Persistence: This environment variable is a `PersistentConfig` variable.
+#### `YANDEX_WEB_SEARCH_URL`
+
+- Type: `str`
+- Default: `https://searchapi.api.cloud.yandex.net/v2/web/search`
+- Description: Specifies the URL of the Yandex Web Search service API endpoint.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `YANDEX_WEB_SEARCH_API_KEY`
+
+- Type: `str`
+- Default: Empty string (' ')
+- Description: Sets the API key for authenticating with the Yandex Web Search service.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `YANDEX_WEB_SEARCH_CONFIG`
+
+- Type: `str`
+- Default: Empty string (' ')
+- Description: Optional JSON configuration string for Yandex Web Search. Can be used to set parameters like `searchType` or `region` as per the Yandex API documentation.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
#### `PERPLEXITY_API_KEY`
- Type: `str`
@@ -3977,9 +4100,21 @@ Strictly return in JSON format:
- Type: `str`
- Default: `512x512`
-- Description: Sets the default output dimensions for generated images in WIDTHxHEIGHT format (e.g., `1024x1024`).
+- Description: Sets the default output dimensions for generated images in WIDTHxHEIGHT format (e.g., `1024x1024`). Set to `auto` to let the model determine the appropriate size (only supported by models matching `IMAGE_AUTO_SIZE_MODELS_REGEX_PATTERN`).
- Persistence: This environment variable is a `PersistentConfig` variable.
+#### `IMAGE_AUTO_SIZE_MODELS_REGEX_PATTERN`
+
+- Type: `str`
+- Default: `^gpt-image`
+- Description: A regex pattern to match model names that support `IMAGE_SIZE = "auto"`. When a model matches this pattern, the `auto` size option becomes available, allowing the model to determine the appropriate output dimensions. By default, only models starting with `gpt-image` (e.g., `gpt-image-1`) are matched.
+
+#### `IMAGE_URL_RESPONSE_MODELS_REGEX_PATTERN`
+
+- Type: `str`
+- Default: `^gpt-image`
+- Description: A regex pattern to match model names that return image URLs directly instead of base64-encoded data. Models matching this pattern will not include `response_format: b64_json` in API requests. By default, only models starting with `gpt-image` are matched. For other models, Open WebUI requests base64 responses and handles the conversion internally.
+
#### `IMAGE_STEPS`
- Type: `int`
@@ -4400,6 +4535,46 @@ If the OAuth picture claim is disabled by setting `OAUTH_PICTURE_CLAIM` to `''`
- Description: Controls whether the **legacy** `oauth_id_token` cookie (unsafe, not recommended, token can go stale/orphaned) is set in the browser upon a successful OAuth login. This is provided for **backward compatibility** with custom tools or older versions that might rely on scraping this cookie. **The new, recommended approach is to use the server-side session management.**
- Usage: For new and secure deployments, **it is recommended to set this to `False`** to minimize the information exposed to the client-side. Keep it as `True` only if you have integrations that depend on the old cookie-based method.
+#### `ENABLE_OAUTH_TOKEN_EXCHANGE`
+
+- Type: `bool`
+- Default: `False`
+- Description: Enables the OAuth token exchange endpoint, allowing external applications to exchange an OAuth provider's access token for an Open WebUI JWT session token. This enables programmatic authentication for external tools and services that already have OAuth tokens from your identity provider.
+- Usage: Set to `true` to enable the token exchange endpoint at `/api/v1/oauth/{provider}/token/exchange`. When enabled, external applications can POST to this endpoint with an OAuth access token to obtain an Open WebUI session token.
+
+:::warning
+
+**Security Note**: This feature should only be enabled when you have external applications that need to authenticate with Open WebUI using OAuth tokens from your identity provider. Ensure proper access controls are in place for any external applications using this endpoint.
+
+:::
+
+**Request Example:**
+```bash
+curl -X POST "http://localhost:8080/api/v1/oauth/google/token/exchange" \
+ -H "Content-Type: application/json" \
+ -d '{"token": "ya29.a0AfH6SMB..."}'
+```
+
+**Response:**
+```json
+{
+ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
+ "token_type": "Bearer",
+ "expires_at": 1735682400,
+ "id": 1,
+ "email": "user@example.com",
+ "name": "John Doe",
+ "role": "user",
+ "profile_image_url": "https://...",
+ "permissions": {...}
+}
+```
+
+**Requirements:**
+- The user must already exist in Open WebUI (they must have signed in via the web interface at least once)
+- The OAuth provider must be properly configured
+- The token exchange uses the same user lookup logic as regular OAuth login (by OAuth `sub` claim first, then by email if `OAUTH_MERGE_ACCOUNTS_BY_EMAIL` is enabled)
+
#### `OAUTH_CLIENT_INFO_ENCRYPTION_KEY`
- Type: `str`
@@ -5119,39 +5294,127 @@ For API Key creation (and the API keys themselves) to work, you need **both**:
- Description: Enables or disables user permission to access workspace tools.
- Persistence: This environment variable is a `PersistentConfig` variable.
+### Sharing (Private)
+
+These settings control whether users can share workspace items with other users **privately** (non-public sharing).
+
+#### `USER_PERMISSIONS_WORKSPACE_MODELS_ALLOW_SHARING`
+
+- Type: `str`
+- Default: `False`
+- Description: Enables or disables **private sharing** of workspace models.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ALLOW_SHARING`
+
+- Type: `str`
+- Default: `False`
+- Description: Enables or disables **private sharing** of workspace knowledge.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `USER_PERMISSIONS_WORKSPACE_PROMPTS_ALLOW_SHARING`
+
+- Type: `str`
+- Default: `False`
+- Description: Enables or disables **private sharing** of workspace prompts.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `USER_PERMISSIONS_WORKSPACE_TOOLS_ALLOW_SHARING`
+
+- Type: `str`
+- Default: `False`
+- Description: Enables or disables **private sharing** of workspace tools.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `USER_PERMISSIONS_NOTES_ALLOW_SHARING`
+
+- Type: `str`
+- Default: `True`
+- Description: Enables or disables **private sharing** of notes.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+### Sharing (Public)
+
+These settings control whether users can share workspace items **publicly**.
+
#### `USER_PERMISSIONS_WORKSPACE_MODELS_ALLOW_PUBLIC_SHARING`
- Type: `str`
- Default: `False`
-- Description: Enables or disables public sharing of workspace models.
+- Description: Enables or disables **public sharing** of workspace models.
- Persistence: This environment variable is a `PersistentConfig` variable.
#### `USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ALLOW_PUBLIC_SHARING`
- Type: `str`
- Default: `False`
-- Description: Enables or disables public sharing of workspace knowledge.
+- Description: Enables or disables **public sharing** of workspace knowledge.
- Persistence: This environment variable is a `PersistentConfig` variable.
#### `USER_PERMISSIONS_WORKSPACE_PROMPTS_ALLOW_PUBLIC_SHARING`
- Type: `str`
- Default: `False`
-- Description: Enables or disables public sharing of workspace prompts.
+- Description: Enables or disables **public sharing** of workspace prompts.
- Persistence: This environment variable is a `PersistentConfig` variable.
#### `USER_PERMISSIONS_WORKSPACE_TOOLS_ALLOW_PUBLIC_SHARING`
- Type: `str`
- Default: `False`
-- Description: Enables or disables public sharing of workspace tools.
+- Description: Enables or disables **public sharing** of workspace tools.
- Persistence: This environment variable is a `PersistentConfig` variable.
#### `USER_PERMISSIONS_NOTES_ALLOW_PUBLIC_SHARING`
- Type: `str`
- Default: `True`
-- Description: Enables or disables public sharing of notes.
+- Description: Enables or disables **public sharing** of notes.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+### Import / Export
+
+#### `USER_PERMISSIONS_WORKSPACE_MODELS_IMPORT`
+
+- Type: `str`
+- Default: `True`
+- Description: Enables or disables user permission to import workspace models.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `USER_PERMISSIONS_WORKSPACE_MODELS_EXPORT`
+
+- Type: `str`
+- Default: `True`
+- Description: Enables or disables user permission to export workspace models.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `USER_PERMISSIONS_WORKSPACE_PROMPTS_IMPORT`
+
+- Type: `str`
+- Default: `True`
+- Description: Enables or disables user permission to import workspace prompts.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `USER_PERMISSIONS_WORKSPACE_PROMPTS_EXPORT`
+
+- Type: `str`
+- Default: `True`
+- Description: Enables or disables user permission to export workspace prompts.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `USER_PERMISSIONS_WORKSPACE_TOOLS_IMPORT`
+
+- Type: `str`
+- Default: `False`
+- Description: Enables or disables user permission to import workspace tools.
+- Persistence: This environment variable is a `PersistentConfig` variable.
+
+#### `USER_PERMISSIONS_WORKSPACE_TOOLS_EXPORT`
+
+- Type: `str`
+- Default: `False`
+- Description: Enables or disables user permission to export workspace tools.
+- Persistence: This environment variable is a `PersistentConfig` variable.
### Settings Permissions
@@ -5586,6 +5849,22 @@ For deployments with many concurrent users, consider increasing both `DATABASE_P
:::
+:::warning Pool Size Multiplies with Concurrency
+
+**Each Open WebUI process maintains its own independent connection pool.** This applies whether you're running multiple Uvicorn workers (`UVICORN_WORKERS > 1`), multiple Kubernetes pods, Docker Swarm replicas, or any other multi-instance deployment.
+
+The actual maximum number of database connections is:
+
+```
+Total connections = (DATABASE_POOL_SIZE + DATABASE_POOL_MAX_OVERFLOW) × Number of processes/instances
+```
+
+For example, with `DATABASE_POOL_SIZE=15`, `DATABASE_POOL_MAX_OVERFLOW=20`, and 4 instances (whether workers, pods, or replicas), you could open up to **140 connections** (35 × 4).
+
+When calculating pool settings, always account for this multiplier to avoid exhausting your database's `max_connections` limit. This is a fundamental limitation—connection pools cannot be shared across separate processes or containers.
+
+:::
+
#### `DATABASE_POOL_MAX_OVERFLOW`
- Type: `int`
@@ -5662,6 +5941,46 @@ If you're running Open WebUI as a single instance with `UVICORN_WORKERS=1` (the
:::
+:::danger
+
+**Critical Redis Server Configuration — Prevent Connection Exhaustion**
+
+Open WebUI uses Redis for token validation, WebSocket management, and session storage. Each user action can create Redis connections. If your Redis server is misconfigured, connections will accumulate over time until the limit is reached, causing **500 Internal Server Errors** and preventing all users from logging in.
+
+**You must configure these settings in your `redis.conf` (not Open WebUI environment variables):**
+
+| Setting | Bad Default | Recommended | Why |
+|---------|-------------|-------------|-----|
+| `maxclients` | 1000 (some distros) | `10000` or higher | Low limits cause "max number of clients reached" errors |
+| `timeout` | 0 (never close) | `1800` (30 minutes) | Without timeout, idle connections accumulate forever |
+
+**Example `redis.conf` settings:**
+```conf
+maxclients 10000
+timeout 1800
+```
+
+**Symptoms of this misconfiguration:**
+- Works fine for days/weeks, then suddenly all logins fail with 500 errors
+- `redis.exceptions.ConnectionError: max number of clients reached` in logs
+- Problem appears to "fix itself" temporarily, then returns
+
+**Why this happens:**
+With `timeout 0`, every Redis connection stays open indefinitely. Over days or weeks, connections from token checks, WebSocket events, and session validations accumulate. Once `maxclients` is reached, no new connections can be made, and authentication fails completely.
+
+**To check your current connection count:**
+```bash
+redis-cli INFO clients | grep connected_clients
+```
+
+**To verify your settings:**
+```bash
+redis-cli CONFIG GET maxclients
+redis-cli CONFIG GET timeout
+```
+
+:::
+
#### `REDIS_SENTINEL_HOSTS`
- Type: `str`
@@ -5677,7 +5996,7 @@ If you're running Open WebUI as a single instance with `UVICORN_WORKERS=1` (the
- Type: `bool`
- Default: `False`
-- Description: Connect to a Redis Cluster instead of a single instance or using Redis Sentinels. If `True`, `REDIS_URL` must also be defined.
+- Description: Connect to a Redis Cluster instead of a single instance or using Redis Sentinels. If `True`, `REDIS_URL` must also be defined. This mode is compatible with AWS Elasticache Serverless and other Redis Cluster implementations.
:::info
@@ -5685,6 +6004,12 @@ This option has no effect if `REDIS_SENTINEL_HOSTS` is defined.
:::
+:::tip OpenTelemetry Support
+
+Redis Cluster mode is fully compatible with OpenTelemetry instrumentation. When `ENABLE_OTEL` is enabled, Redis operations are properly traced regardless of whether you're using a single Redis instance or Redis Cluster mode.
+
+:::
+
#### `REDIS_KEY_PREFIX`
- Type: `str`
@@ -5720,6 +6045,24 @@ If `WEBSOCKET_REDIS_OPTIONS` is not set, `REDIS_SOCKET_CONNECT_TIMEOUT` will be
:::
+#### `REDIS_SENTINEL_MAX_RETRY_COUNT`
+
+- Type: `int`
+- Default: `2`
+- Description: Sets the maximum number of retries for Redis operations when using Sentinel fail-over. This is a critical high-availability setting that allows the application time for master election and promotion. If your Sentinel `down-after-milliseconds` is high, you should tune this value accordingly to ensure the service survives the failover window without dropping connections.
+
+#### `REDIS_RECONNECT_DELAY`
+
+- Type: `float` (milliseconds)
+- Default: None
+- Description: Optional reconnect delay in milliseconds for Redis Sentinel retry logic, applied consistently across both synchronous and asynchronous Redis operations. This improves stability during Sentinel failover by preventing tight retry loops. When unset or invalid, retry behavior remains unchanged.
+
+#### `WEBSOCKET_REDIS_LOCK_TIMEOUT`
+
+- Type: `int`
+- Default: `60`
+- Description: Sets the timeout in seconds for Redis locks used by the websocket manager.
+
#### `ENABLE_WEBSOCKET_SUPPORT`
- Type: `bool`
@@ -5836,8 +6179,8 @@ When this variable is left empty (default), `REDIS_SOCKET_CONNECT_TIMEOUT` is au
#### `WEBSOCKET_SERVER_ENGINEIO_LOGGING`
- Type: `bool`
-- Default: `false`
-- Description: Controls logging for EngineIO server related to websocket operations.
+- Default: Falls back to `WEBSOCKET_SERVER_LOGGING` if not set, otherwise `false`
+- Description: Controls logging for Engine.IO server related to websocket operations. If not explicitly set, this inherits the value from `WEBSOCKET_SERVER_LOGGING`.
:::warning
diff --git a/docs/getting-started/quick-start/index.mdx b/docs/getting-started/quick-start/index.mdx
index c85c08b791..c0e4f4f7e5 100644
--- a/docs/getting-started/quick-start/index.mdx
+++ b/docs/getting-started/quick-start/index.mdx
@@ -169,6 +169,9 @@ You are now ready to start using Open WebUI!
## Using Open WebUI with Ollama
If you're using Open WebUI with Ollama, be sure to check out our [Starting with Ollama Guide](/getting-started/quick-start/starting-with-ollama) to learn how to manage your Ollama instances with Open WebUI.
+## Experimental: Open Responses
+Open WebUI has experimental support for the [Open Responses](https://www.openresponses.org/) specification. See the [Starting with Open Responses Guide](/getting-started/quick-start/starting-with-open-responses) to learn how to enable it.
+
## Help Us Improve Open WebUI 🧪
**Want to help make Open WebUI better?** Consider running the [development branch](/#using-the-dev-branch-)! Testing dev builds is one of the most valuable contributions you can make—no code required. Just use it and report any issues you find on [GitHub](https://github.com/open-webui/open-webui/issues).
diff --git a/docs/getting-started/quick-start/starting-with-llama-cpp.mdx b/docs/getting-started/quick-start/starting-with-llama-cpp.mdx
index 148a0fb2f2..b838e8f7ac 100644
--- a/docs/getting-started/quick-start/starting-with-llama-cpp.mdx
+++ b/docs/getting-started/quick-start/starting-with-llama-cpp.mdx
@@ -82,12 +82,16 @@ Start the model server using the llama-server binary. Navigate to your llama.cpp
- --ctx-size: Token context length (can increase if RAM allows)
- --n-gpu-layers: Layers offloaded to GPU for faster performance
-Once the server runs, it will expose a local OpenAI-compatible API on:
+Once the server runs, it will expose a local **OpenAI-compatible API** (Chat Completions) on:
```
http://127.0.0.1:10000
```
+:::tip
+Open WebUI also supports the experimental [Open Responses](/getting-started/quick-start/starting-with-open-responses) specification for providers that implement it.
+:::
+
---
## Step 4: Connect Llama.cpp to Open WebUI
diff --git a/docs/getting-started/quick-start/starting-with-open-responses.mdx b/docs/getting-started/quick-start/starting-with-open-responses.mdx
new file mode 100644
index 0000000000..5438485276
--- /dev/null
+++ b/docs/getting-started/quick-start/starting-with-open-responses.mdx
@@ -0,0 +1,90 @@
+---
+
+sidebar_position: 7
+title: "Starting With Open Responses"
+
+---
+
+## Overview
+
+Open WebUI has experimental support for **[Open Responses](https://www.openresponses.org/)**, an open specification for multi-provider, interoperable LLM interfaces. This guide walks you through enabling the Open Responses API for a connection.
+
+:::warning Experimental Feature
+This feature is currently experimental and may not work as expected with all providers.
+:::
+
+---
+
+## What is Open Responses?
+
+Open Responses is an open-source specification that standardizes how LLM requests and responses are structured across providers. It provides:
+
+- **One spec, many providers**: Describe inputs/outputs once; run on OpenAI, Anthropic, Gemini, or local models.
+- **Composable agentic loops**: Unified streaming, tool invocation, and message orchestration.
+- **Easier evaluation and routing**: Compare providers, route requests, and log results through a shared schema.
+
+Open Responses builds on the OpenAI Responses API format but is designed to work across any provider that implements the spec.
+
+---
+
+## Step 1: Add or Edit a Connection
+
+1. Go to the ⚙️ **Admin Settings**.
+2. Navigate to **Connections > OpenAI > Manage** (look for the wrench icon).
+3. Click ➕ **Add New Connection** or edit an existing connection.
+
+---
+
+## Step 2: Select the API Type
+
+In the connection modal, look for the **API Type** setting:
+
+- **Chat Completions** (default): Uses the standard OpenAI Chat Completions API format.
+- **Responses** (experimental): Uses the Open Responses API format.
+
+Click the toggle to switch to **Responses**. You'll see an "Experimental" label indicating this feature is still in development.
+
+
+
+---
+
+## Step 3: Configure Your Provider
+
+Enter the connection details for a provider that supports the Open Responses format:
+
+- **URL**: Your provider's API endpoint
+- **API Key**: Your authentication credentials
+- **Model IDs**: (Optional) Specify specific models to use
+
+---
+
+## Supported Providers
+
+Open Responses is a new specification, so provider support is still growing. Check the [Open Responses website](https://www.openresponses.org/) for the latest list of compliant providers and implementations.
+
+---
+
+## Troubleshooting
+
+### Connection works with Chat Completions but not Responses
+
+Not all providers support the Open Responses format yet. Try:
+
+1. Switching back to Chat Completions
+2. Checking if your provider explicitly supports Open Responses
+3. Using a middleware proxy that can translate to Open Responses format
+
+### Streaming or tool calls behave unexpectedly
+
+This feature is experimental. If you encounter issues:
+
+1. Check the [Open WebUI Discord](https://discord.gg/5rJgQTnV4s) for known issues
+2. Report bugs on [GitHub](https://github.com/open-webui/open-webui/issues)
+
+---
+
+## Learn More
+
+- **[Open Responses Specification](https://www.openresponses.org/specification)**: Full technical specification
+- **[Open Responses GitHub](https://github.com/openresponses/openresponses)**: Source code and discussions
+- **[FAQ: Why doesn't Open WebUI natively support proprietary APIs?](/faq#q-why-doesnt-open-webui-natively-support-provider-xs-proprietary-api)**: Learn about our protocol-first philosophy
diff --git a/docs/getting-started/quick-start/starting-with-openai-compatible.mdx b/docs/getting-started/quick-start/starting-with-openai-compatible.mdx
index a4b4de7ca9..daa03f9e46 100644
--- a/docs/getting-started/quick-start/starting-with-openai-compatible.mdx
+++ b/docs/getting-started/quick-start/starting-with-openai-compatible.mdx
@@ -17,10 +17,12 @@ Open WebUI is built around **Standard Protocols**. Instead of building specific
This means that while Open WebUI handles the **interface and tools**, it expects your backend to follow the universal Chat Completions standard.
-- **We Support Protocols**: Any provider that follows the OpenAI Chat Completions standard (like Groq, OpenRouter, or LiteLLM) is natively supported.
-- **We Avoid Proprietary APIs**: We do not implement provider-specific, non-standard APIs (such as OpenAI's stateful Responses API or Anthropic's native Messages API) to maintain a universal, maintainable codebase.
+- **We Support Protocols**: Any provider that follows widely adopted API standards (like Groq, OpenRouter, OpenAI, Mistral, Perplexity and many more) is natively supported. We also have experimental support for **[Open Responses](https://www.openresponses.org/)**.
+- **We Avoid Proprietary APIs**: We do not implement provider-specific, non-standard APIs in the core to maintain a universal, maintainable codebase. For unsupported providers, use a pipe or middleware proxy.
-If you are using a provider that requires a proprietary API, we recommend using a proxy tool like **LiteLLM** or **OpenRouter** to bridge them to the standard OpenAI protocol supported by Open WebUI.
+If you are using a provider that requires a proprietary API, we recommend using a **[pipe](/features/plugin/functions/pipe)** (browse [community pipes](https://openwebui.com/)) or a middleware proxy like LiteLLM or OpenRouter to bridge them to a supported protocol.
+
+For a detailed explanation of why we've made this architectural decision, see our **[FAQ: Why doesn't Open WebUI natively support proprietary APIs?](/faq#q-why-doesnt-open-webui-natively-support-provider-xs-proprietary-api)**
### Popular Compatible Servers and Providers
diff --git a/docs/getting-started/quick-start/starting-with-openai.mdx b/docs/getting-started/quick-start/starting-with-openai.mdx
index d8485c4451..7b86d6e504 100644
--- a/docs/getting-started/quick-start/starting-with-openai.mdx
+++ b/docs/getting-started/quick-start/starting-with-openai.mdx
@@ -13,9 +13,9 @@ Open WebUI makes it easy to connect and use OpenAI and other OpenAI-compatible A
## Important: Protocols, Not Providers
-Open WebUI is a **protocol-centric** platform. While we provide first-class support for OpenAI models, we do so exclusively through the **OpenAI Chat Completions API protocol**.
+Open WebUI is a **protocol-centric** platform. While we provide first-class support for OpenAI models, we do so mainly through the **OpenAI Chat Completions API protocol**.
-We do **not** support proprietary, non-standard APIs such as OpenAI’s new stateful **Responses API**. Instead, Open WebUI focuses on universal standards that are shared across dozens of providers. This approach keeps Open WebUI fast, stable, and truly open-sourced.
+We focus on universal standards shared across dozens of providers, with experimental support for emerging standards like **[Open Responses](https://www.openresponses.org/)**. For a detailed explanation, see our **[FAQ on protocol support](/faq#q-why-doesnt-open-webui-natively-support-provider-xs-proprietary-api)**.
---
diff --git a/docs/getting-started/quick-start/starting-with-vllm.mdx b/docs/getting-started/quick-start/starting-with-vllm.mdx
index 90a4f1b141..adf2ba41ee 100644
--- a/docs/getting-started/quick-start/starting-with-vllm.mdx
+++ b/docs/getting-started/quick-start/starting-with-vllm.mdx
@@ -5,7 +5,11 @@ title: "Starting With vLLM"
## Overview
-vLLM provides an OpenAI-compatible API, making it easy to connect to Open WebUI. This guide will show you how to connect your vLLM server.
+vLLM provides an **OpenAI-compatible API** (Chat Completions), making it easy to connect to Open WebUI. This guide will show you how to connect your vLLM server.
+
+:::tip
+Open WebUI also supports the experimental [Open Responses](/getting-started/quick-start/starting-with-open-responses) specification for providers that implement it.
+:::
---
diff --git a/docs/security.mdx b/docs/security.mdx
index b57dcd72fa..dcf5bc7ad4 100644
--- a/docs/security.mdx
+++ b/docs/security.mdx
@@ -85,6 +85,50 @@ If your concern does not meet the vulnerability requirements outlined above, is
Examples of non-vulnerability, still security-related concerns include suggestions for better default configuration values, security hardening recommendations, deployment best practices guidance, unclear configuration instructions, need for additional security documentation, feature requests for optional security enhancements (2FA, audit logging, etc.), and general security questions about production deployment. Please use the adequate channel for your specific issue.
+## Tools, Functions, and Pipelines Security
+
+Open WebUI provides powerful extensibility through **Tools**, **Functions** (including Pipes, Filters, and Actions), and **Pipelines**. These features allow you to extend Open WebUI's capabilities with custom Python code. However, this power comes with security responsibilities.
+
+:::warning
+
+**Tools, Functions, and Pipelines execute arbitrary Python code on your server.** This is intentional—it's what makes them powerful. However, this means they have the same level of access as the Open WebUI backend process itself.
+
+:::
+
+### Security Implications
+
+When you install a Tool, Function, or Pipeline, you are granting it the ability to:
+
+- **Access the file system** — read or write any files the backend process can access
+- **Make network requests** — connect to external services, potentially exfiltrating data
+- **Execute system commands** — run shell commands via subprocess
+- **Access environment variables** — read API keys, secrets, and configuration
+- **Modify the database** — access or alter stored data
+- **Consume compute resources** — run CPU-intensive operations
+
+### Best Practices
+
+| Practice | Description |
+|----------|-------------|
+| **Only install from trusted sources** | Only use Tools/Functions from the official community library or sources you trust |
+| **Review code before installing** | Read and understand what a Tool/Function does before importing it |
+| **Restrict Workspace access** | Only grant Workspace permissions to trusted administrators |
+| **Audit installed plugins** | Regularly review installed Tools (Workspace → Tools) and Functions (Admin Panel → Functions) |
+| **Protect your data directory** | The `/app/backend/data` directory contains your database and cached plugins—protect it from unauthorized access |
+| **Monitor resource usage** | Watch for unexpected CPU spikes that could indicate cryptomining or other abuse |
+| **Use official Docker images** | Only pull from `ghcr.io/open-webui/open-webui`—unofficial images may be compromised |
+
+### What Is NOT a Vulnerability
+
+The following scenarios are **not** considered vulnerabilities because they require administrator action:
+
+- An admin installing a malicious Tool or Function
+- An admin granting Workspace access to an untrusted user
+- An admin importing code from an untrusted source
+- An attacker with write access to the data volume injecting malicious plugins
+
+These scenarios represent **admin negligence** or **environment compromise**, not vulnerabilities in Open WebUI itself. See [our Security Policy](https://github.com/open-webui/open-webui/security) for details.
+
## Product Security Process
- Internal and periodic external reviews of our architecture and pipelines
diff --git a/docs/team.mdx b/docs/team.mdx
index 457195d714..7945eab824 100644
--- a/docs/team.mdx
+++ b/docs/team.mdx
@@ -38,5 +38,11 @@ Beyond our contributors, Open WebUI, Inc. has an incredible global team working
We greatly appreciate enthusiasm and thoughtful suggestions from our community. At the same time, **we're not looking for unsolicited governance recommendations or guidance on how to operate**—we know exactly how we want to run our project (just as, for example, you wouldn't tell OpenAI how to run theirs). Open WebUI maintains strong, opinionated leadership because that's precisely what we believe is necessary to build something truly great, fast-moving, and purposeful.
+## 📜 Community Standards
+
+All community members — contributors, users, and collaborators alike — are expected to uphold our **[Code of Conduct](https://github.com/open-webui/open-webui/blob/main/CODE_OF_CONDUCT.md)**. This project is built by volunteers who dedicate their time and expertise freely. We enforce a **zero-tolerance policy**: disrespectful, entitled, or hostile behavior toward any community member will result in immediate action without prior warning.
+
+We believe that protecting our contributors from burnout and abuse is essential to the long-term health of this project. A respectful, professional environment isn't optional — it's a requirement for participation.
+
Thank you for respecting our perspective and for your continued support and contributions. We're excited to keep building with the community around the vision we've established together!
diff --git a/docs/troubleshooting/index.mdx b/docs/troubleshooting/index.mdx
index bbec3251b7..046c3056ee 100644
--- a/docs/troubleshooting/index.mdx
+++ b/docs/troubleshooting/index.mdx
@@ -17,7 +17,7 @@ With this project constantly evolving, updates and fixes are regularly added. Ke
### 🤝 Community Support
-This project thrives on community spirit and passion. If you still face problems after updating, we warmly invite you to join our vibrant community on [Discord](https://discord.com/invite/5rJgQTnV4s). There, you can share your experiences, find solutions, and connect with fellow enthusiasts who might be navigating similar challenges. Engaging with our community doesn't just help solve your problems; it strengthens the entire network of support, so we all grow together. 🌱
+This project thrives on community spirit and passion. If you still face problems after updating, we warmly invite you to join our vibrant community on [Discord](https://discord.com/invite/5rJgQTnV4s) or [Reddit](https://www.reddit.com/r/OpenWebUI/). There, you can share your experiences, find solutions, and connect with fellow enthusiasts who might be navigating similar challenges. Engaging with our community doesn't just help solve your problems; it strengthens the entire network of support, so we all grow together. 🌱
🌟 If your issues are pressing and you need a quicker resolution, consider [supporting our project](/sponsorships). Your sponsorship not only fast-tracks your queries in a dedicated sponsor-only channel, but also directly supports the [dedicated maintainer](/mission) who is passionately committed to refining and enhancing this tool for everyone.
diff --git a/docs/troubleshooting/multi-replica.mdx b/docs/troubleshooting/multi-replica.mdx
index 2a0dc9a1e9..a3f18fa1de 100644
--- a/docs/troubleshooting/multi-replica.mdx
+++ b/docs/troubleshooting/multi-replica.mdx
@@ -156,6 +156,22 @@ DATABASE_POOL_MAX_OVERFLOW=20 (or higher)
**Important:** The combined total (`DATABASE_POOL_SIZE` + `DATABASE_POOL_MAX_OVERFLOW`) should remain well below your database's `max_connections` limit. PostgreSQL defaults to 100 max connections, so keep the combined total under 50-80 per Open WebUI instance to leave room for other clients and maintenance operations.
+:::warning Pool Size Multiplies with Concurrency
+
+**Each Open WebUI process maintains its own independent connection pool.** This applies to multiple replicas (Kubernetes pods, Docker Swarm replicas) *and* multiple Uvicorn workers within each replica.
+
+The actual maximum number of database connections is:
+
+```
+Total connections = (DATABASE_POOL_SIZE + DATABASE_POOL_MAX_OVERFLOW) × Total processes
+```
+
+Where `Total processes = Number of replicas × UVICORN_WORKERS per replica`.
+
+For example, with `DATABASE_POOL_SIZE=15`, `DATABASE_POOL_MAX_OVERFLOW=20`, 3 replicas, and 2 workers each, you could open up to **210 connections** (35 × 6 processes).
+
+:::
+
See [DATABASE_POOL_SIZE](/getting-started/env-configuration#database_pool_size) for details.
---
diff --git a/docs/troubleshooting/performance.md b/docs/troubleshooting/performance.md
index e20ba1349c..678eb956d2 100644
--- a/docs/troubleshooting/performance.md
+++ b/docs/troubleshooting/performance.md
@@ -176,8 +176,48 @@ Defines the number of worker threads available for handling requests.
- **Env Var**: `THREAD_POOL_SIZE=2000`
+#### AIOHTTP Client Timeouts
+Long LLM completions can exceed default HTTP client timeouts. Configure these to prevent requests being cut off mid-response:
+
+- **Env Var**: `AIOHTTP_CLIENT_TIMEOUT=1800` (30 minutes for completions)
+- **Env Var**: `AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST=15` (shorter for model listing)
+- **Env Var**: `AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST=15`
+
+#### Container Resource Limits
+For Docker deployments, ensure adequate resource allocation:
+
+```yaml
+deploy:
+ resources:
+ limits:
+ memory: 8G # Adjust based on usage
+ cpus: '4.0'
+ reservations:
+ memory: 4G
+ cpus: '2.0'
+
+# Increase file descriptor limits
+ulimits:
+ nofile:
+ soft: 65536
+ hard: 65536
+```
+
+**Diagnosis commands:**
+```bash
+# Check container resource usage
+docker stats openwebui --no-stream
+
+# Check connection states
+docker exec openwebui netstat -an | grep -E "ESTABLISHED|TIME_WAIT|CLOSE_WAIT" | sort | uniq -c
+
+# Check open file descriptors
+docker exec openwebui ls -la /proc/1/fd | wc -l
+```
+
---
+
## ☁️ Cloud Infrastructure Latency
When deploying Open WebUI in cloud Kubernetes environments (AKS, EKS, GKE), you may notice significant performance degradation compared to local Kubernetes (Rancher Desktop, kind, Minikube) or bare-metal deployments—even with identical resource allocations. This is almost always caused by **latency** in the underlying infrastructure.
diff --git a/docs/tutorials/https/nginx.md b/docs/tutorials/https/nginx.md
index dafa1c95d2..916c4499a5 100644
--- a/docs/tutorials/https/nginx.md
+++ b/docs/tutorials/https/nginx.md
@@ -89,6 +89,154 @@ import Windows from '../tab-nginx/Windows.md';
+## Complete Optimized NGINX Configuration
+
+This section provides a production-ready NGINX configuration optimized for Open WebUI streaming, WebSocket connections, and high-concurrency deployments.
+
+### Upstream Configuration
+
+Define an upstream with keepalive connections to reduce connection setup overhead:
+
+```nginx
+upstream openwebui {
+ server 127.0.0.1:3000;
+ keepalive 128; # Persistent connections
+ keepalive_timeout 1800s; # 30 minutes
+ keepalive_requests 10000;
+}
+```
+
+### Timeout Configuration
+
+Long-running LLM completions require extended timeouts:
+
+```nginx
+location /api/ {
+ proxy_connect_timeout 1800; # 30 minutes
+ proxy_send_timeout 1800;
+ proxy_read_timeout 1800;
+}
+
+# WebSocket connections need even longer timeouts
+location ~ ^/(ws/|socket\.io/) {
+ proxy_connect_timeout 86400; # 24 hours
+ proxy_send_timeout 86400;
+ proxy_read_timeout 86400;
+}
+```
+
+### Header and Body Size Limits
+
+Prevent errors with large requests or OAuth tokens:
+
+```nginx
+# In http {} or server {} block
+client_max_body_size 100M; # Large file uploads
+proxy_buffer_size 128k; # Large headers (OAuth tokens)
+proxy_buffers 4 256k;
+proxy_busy_buffers_size 256k;
+large_client_header_buffers 4 32k;
+```
+
+### Common Streaming Mistakes
+
+| Setting | Impact on Streaming |
+|---------|---------------------|
+| `gzip on` with `application/json` | 🔴 Buffers for compression |
+| `proxy_buffering on` | 🔴 Buffers entire response |
+| `proxy_request_buffering on` | Should be turned off |
+| `tcp_nodelay on` | 🔴 **Most Critical:** Disables Nagle's algorithm to send packets immediately (prevents 200ms delays) |
+| `chunked_transfer_encoding on` | 🟡 Can break SSE |
+| `proxy_cache` enabled on `/api/` | 🟡 Adds overhead |
+| `X-Accel-Buffering "yes"` | This header should be set to "no" for extra safety |
+| `HTTP/2` | If you experience streaming issues, lag, streaming ending before the last chunk arrived on the frontend, then using HTTP 1.1 instead of HTTP/2 might also help |
+
+### Full Example Configuration
+
+```nginx
+upstream openwebui {
+ server 127.0.0.1:3000;
+ keepalive 128;
+ keepalive_timeout 1800s;
+ keepalive_requests 10000;
+}
+
+server {
+ listen 443 ssl http2;
+ server_name your-domain.com;
+
+ # SSL configuration...
+
+ # Compression - EXCLUDE streaming content types
+ gzip on;
+ gzip_types text/plain text/css application/javascript image/svg+xml;
+ # DO NOT include: application/json, text/event-stream
+
+ # API endpoints - streaming optimized
+ location /api/ {
+ proxy_pass http://openwebui;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+
+ # CRITICAL: Disable all buffering for streaming
+ gzip off;
+ proxy_buffering off;
+ proxy_request_buffering off;
+ proxy_cache off;
+ tcp_nodelay on;
+ add_header X-Accel-Buffering "no" always;
+ add_header Cache-Control "no-store" always;
+
+ # Extended timeouts for LLM completions
+ proxy_connect_timeout 1800;
+ proxy_send_timeout 1800;
+ proxy_read_timeout 1800;
+ }
+
+ # WebSocket endpoints
+ location ~ ^/(ws/|socket\.io/) {
+ proxy_pass http://openwebui;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+
+ gzip off;
+ proxy_buffering off;
+ proxy_cache off;
+
+ # 24-hour timeout for persistent connections
+ proxy_connect_timeout 86400;
+ proxy_send_timeout 86400;
+ proxy_read_timeout 86400;
+ }
+
+ # Static assets - CAN buffer and cache
+ location /static/ {
+ proxy_pass http://openwebui;
+ proxy_buffering on;
+ proxy_cache_valid 200 7d;
+ add_header Cache-Control "public, max-age=604800, immutable";
+ }
+
+ # Default location
+ location / {
+ proxy_pass http://openwebui;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+}
+```
+
+---
+
## Caching Configuration
Proper caching significantly improves Open WebUI performance by reducing backend load and speeding up page loads. This section provides guidance for advanced users who want to implement server-side and client-side caching.
diff --git a/docs/tutorials/integrations/amazon-bedrock.md b/docs/tutorials/integrations/amazon-bedrock.md
index 9ff014462c..c5d3ce48dc 100644
--- a/docs/tutorials/integrations/amazon-bedrock.md
+++ b/docs/tutorials/integrations/amazon-bedrock.md
@@ -73,6 +73,23 @@ docker run -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY=$AWS
You should now be able to access the BAG's swagger page at: http://localhost:8000/docs
+:::warning Troubleshooting: Container Exits Immediately
+
+If the Bedrock Gateway container starts and immediately exits (especially on Windows), check the logs with `docker logs `. If you see Python/Uvicorn errors, this is likely a **Python 3.13 compatibility issue** with the BAG's Dockerfile.
+
+**Workaround:** Edit the `Dockerfile` before building and change the Python version from 3.13 to 3.12:
+
+```dockerfile
+# Change this line:
+FROM python:3.13-slim
+# To:
+FROM python:3.12-slim
+```
+
+Then rebuild with `docker build . -f Dockerfile -t bedrock-gateway`.
+
+:::
+

## Step 3: Add Connection in Open-WebUI
diff --git a/docs/tutorials/integrations/entra-group-name-sync.md b/docs/tutorials/integrations/entra-group-name-sync.md
new file mode 100644
index 0000000000..6aec23f6fe
--- /dev/null
+++ b/docs/tutorials/integrations/entra-group-name-sync.md
@@ -0,0 +1,209 @@
+---
+sidebar_position: 15
+title: "Microsoft Entra ID Group Name Sync"
+---
+
+:::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.
+
+:::
+
+# Microsoft Entra ID Group Name Sync
+
+By default, when you configure Microsoft Entra ID OAuth and automatic group creation with Open WebUI, security groups are synced using their **Group IDs (GUIDs)** rather than human-readable group names. This is a Microsoft limitation where the ID token doesn't include group display names by default.
+
+This tutorial explains how to configure Microsoft Entra ID to return group **names** instead of IDs, enabling a much better user experience when working with groups in Open WebUI.
+
+## Prerequisites
+
+- An Open WebUI instance configured with [Microsoft OAuth](/features/auth/sso#microsoft)
+- An Azure account with permissions to modify App Registrations
+- Access to the Microsoft Entra admin center
+- Basic understanding of Microsoft Entra ID application configuration
+
+## Overview
+
+To get human-readable group names in Open WebUI, you need to:
+
+1. Configure your App Registration to include groups in the token
+2. Modify the application manifest to use `cloud_displayname`
+3. Set `groupMembershipClaims` to `ApplicationGroup` only
+4. Assign security groups to the Enterprise Application
+5. Configure Open WebUI environment variables for [OAuth Group Management](/features/auth/sso#oauth-group-management)
+
+:::info Key Requirement
+
+The `cloud_displayname` property in the manifest **only works** when `groupMembershipClaims` is set to `ApplicationGroup`. If you include other options (like `SecurityGroup` or `All`), the token will revert to using Group IDs instead of names.
+
+:::
+
+## Step 1: Configure Token Claims in App Registration
+
+1. Navigate to the **Microsoft Entra admin center** > **App registrations**
+2. Select your Open WebUI application
+3. Go to **Token configuration** in the left menu
+4. Click **Add groups claim**
+5. Select **Security groups** (or the appropriate group type for your needs)
+6. Under **Customize token properties by type**, ensure groups are added for:
+ - ID token
+ - Access token
+7. Click **Add**
+
+## Step 2: Modify the Application Manifest
+
+This is the critical step that enables group names instead of IDs.
+
+1. In your App Registration, go to **Manifest** in the left menu
+2. Locate the `optionalClaims` section
+3. Add `cloud_displayname` to the `additionalProperties` array for each token type
+
+Your manifest should look like this:
+
+```json
+"optionalClaims": {
+ "idToken": [
+ {
+ "name": "groups",
+ "source": null,
+ "essential": false,
+ "additionalProperties": [
+ "cloud_displayname"
+ ]
+ }
+ ],
+ "accessToken": [
+ {
+ "name": "groups",
+ "source": null,
+ "essential": false,
+ "additionalProperties": [
+ "cloud_displayname"
+ ]
+ }
+ ],
+ "saml2Token": [
+ {
+ "name": "groups",
+ "source": null,
+ "essential": false,
+ "additionalProperties": [
+ "cloud_displayname"
+ ]
+ }
+ ]
+}
+```
+
+4. **Critical**: Set `groupMembershipClaims` to `ApplicationGroup` only:
+
+```json
+"groupMembershipClaims": "ApplicationGroup"
+```
+
+:::warning
+
+If `groupMembershipClaims` includes other values like `SecurityGroup` or `All`, the `cloud_displayname` property will be ignored and the token will contain Group IDs instead of names. See [Microsoft's optional claims documentation](https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims) for more details.
+
+:::
+
+5. Click **Save**
+
+## Step 3: Assign Groups to the Enterprise Application
+
+When using `ApplicationGroup`, only groups explicitly assigned to the Enterprise Application will be included in the token.
+
+1. Navigate to **Microsoft Entra admin center** > **Enterprise applications**
+2. Find and select your Open WebUI application
+3. Go to **Users and groups** in the left menu
+4. Click **Add user/group**
+5. Select the security groups you want to sync with Open WebUI
+6. Click **Assign**
+
+:::warning Multiple Group Assignment
+
+When a user belongs to multiple groups, ensure all relevant groups are assigned to the Enterprise Application. Note that only groups explicitly assigned here will appear in the user's token and subsequently sync to Open WebUI.
+
+:::
+
+## Step 4: Configure API Permissions
+
+Ensure your App Registration has the required Microsoft Graph permissions:
+
+1. In your App Registration, go to **API permissions**
+2. Click **Add a permission** > **Microsoft Graph** > **Delegated permissions**
+3. Add the following permissions from the OpenID section if not already present:
+ - `openid`
+ - `email`
+ - `profile`
+4. Click **Grant admin consent for [your organization]**
+
+## Step 5: Configure Open WebUI Environment Variables
+
+Configure the following environment variables for your Open WebUI deployment. For more details on each variable, see the [environment variable documentation](/getting-started/env-configuration).
+
+```bash
+# Required: Your public WebUI address
+WEBUI_URL=https://your-open-webui-domain
+
+# Microsoft OAuth Configuration (required)
+MICROSOFT_CLIENT_ID=your_client_id
+MICROSOFT_CLIENT_SECRET=your_client_secret
+MICROSOFT_CLIENT_TENANT_ID=your_tenant_id
+MICROSOFT_REDIRECT_URI=https://your-open-webui-domain/oauth/microsoft/callback
+
+# Required for logout to work properly
+OPENID_PROVIDER_URL=https://login.microsoftonline.com/your_tenant_id/v2.0/.well-known/openid-configuration
+
+# Enable OAuth signup
+ENABLE_OAUTH_SIGNUP=true
+
+# OAuth Group Management
+OAUTH_GROUP_CLAIM=groups
+ENABLE_OAUTH_GROUP_MANAGEMENT=true
+ENABLE_OAUTH_GROUP_CREATION=true
+
+# Recommended: Set a consistent secret key
+WEBUI_SECRET_KEY=your_secure_secret_key
+```
+
+### Environment Variable Reference
+
+| Variable | Default | Description |
+| ------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `OAUTH_GROUP_CLAIM` | `groups` | The claim in the ID/access token containing the user's group memberships. |
+| `ENABLE_OAUTH_GROUP_MANAGEMENT` | `false` | When `true`, user group memberships are synchronized with OAuth claims upon each login. |
+| `ENABLE_OAUTH_GROUP_CREATION` | `false` | When `true`, enables **Just-in-Time (JIT) group creation** - groups present in OAuth claims but not in Open WebUI will be created automatically. |
+
+:::warning Strict Group Synchronization
+
+When `ENABLE_OAUTH_GROUP_MANAGEMENT` is set to `true`, a user's group memberships in Open WebUI are **strictly synchronized** with the groups received in their OAuth claims upon each login.
+
+- Users will be **added** to Open WebUI groups that match their OAuth claims.
+- Users will be **removed** from any Open WebUI groups (including those manually assigned within Open WebUI) if those groups are **not** present in their OAuth claims for that login session.
+
+:::
+
+## Verification
+
+After completing the configuration:
+
+1. **Test the token**: Use [https://jwt.ms](https://jwt.ms) to decode your ID token and verify that the `groups` claim contains display names instead of GUIDs.
+2. **Log in as a non-admin user**: Admin users' group memberships are not automatically updated via OAuth group management. Use a standard user account for testing.
+3. **Check Open WebUI**: Navigate to the Admin Panel and verify that groups appear with readable names.
+
+:::info Admin Users
+
+Admin users' group memberships are **not** automatically updated via OAuth group management. If you need to test the configuration, use a non-admin user account.
+
+:::
+
+
+## Additional Resources
+
+- [SSO (OAuth, OIDC, Trusted Header)](/features/auth/sso) - OAuth configuration overview
+- [OAuth Group Management](/features/auth/sso#oauth-group-management) - Group synchronization details
+- [Groups](/features/rbac/groups) - Group management in Open WebUI
+- [SSO Troubleshooting Guide](/troubleshooting/sso) - Common OAuth issues and solutions
+- [Environment Configuration](/getting-started/env-configuration) - All environment variables
+- [Microsoft Optional Claims Documentation](https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims) - Microsoft's official documentation
diff --git a/docs/tutorials/integrations/redis.md b/docs/tutorials/integrations/redis.md
index 2e48e1daa4..7bdde6268a 100644
--- a/docs/tutorials/integrations/redis.md
+++ b/docs/tutorials/integrations/redis.md
@@ -63,6 +63,70 @@ Without Redis in multi-worker or multi-instance scenarios, you will experience:
- A Docker network for communication between Open WebUI and Redis
- Basic understanding of Docker, Redis, and Open WebUI
+### Critical: Redis Server Configuration
+
+:::danger
+
+**Prevent "Max Number of Clients Reached" Errors**
+
+Before configuring Open WebUI to use Redis, you **must** ensure your Redis server itself is properly configured. A common misconfiguration causes connections to accumulate over time, eventually exhausting the connection limit and causing **complete authentication failure** (500 Internal Server Error for all users).
+
+**The Problem:**
+
+Open WebUI uses Redis for:
+- Token validation/revocation checking (every authenticated request)
+- WebSocket management (real-time updates)
+- Session storage (if `ENABLE_STAR_SESSIONS_MIDDLEWARE` is enabled)
+
+With default Redis settings on some distributions (`maxclients 1000`, `timeout 0`), connections are never closed. Over days or weeks, they accumulate silently until the limit is reached. Then, suddenly, no one can log in.
+
+**The Symptoms:**
+- Application works fine for days/weeks
+- Suddenly, all users get 500 Internal Server Error on login
+- Error in logs: `redis.exceptions.ConnectionError: max number of clients reached`
+- May temporarily "fix itself" as old connections eventually die, then fail again
+
+**The Solution:**
+
+Add these settings to your Redis configuration:
+
+```conf
+# Allow sufficient concurrent connections
+maxclients 10000
+
+# Close idle connections after 30 minutes (1800 seconds)
+# This does NOT affect session validity — only the TCP connection to Redis
+timeout 1800
+```
+
+**For Docker deployments**, add to your Redis command:
+
+```yml
+services:
+ redis:
+ image: docker.io/valkey/valkey:8.0.1-alpine
+ command: "valkey-server --save 30 1 --maxclients 10000 --timeout 1800"
+ # ... rest of config
+```
+
+**Why `timeout 1800` is safe:**
+
+The timeout only affects idle Redis TCP connections, not user sessions. When a connection times out:
+- The user's JWT token remains valid
+- Their session is not affected
+- The next request simply opens a new Redis connection (adds ~1-5ms, imperceptible)
+
+**Monitoring:**
+
+Check current connection count:
+```bash
+redis-cli INFO clients | grep connected_clients
+```
+
+With proper `timeout` configuration, this number should fluctuate naturally (rising during active hours, falling during quiet periods) rather than climbing indefinitely.
+
+:::
+
## Setting up Redis
To set up Redis for websocket support, you will need to create a `docker-compose.yml` file with the following contents:
@@ -75,7 +139,7 @@ services:
container_name: redis-valkey
volumes:
- redis-data:/data
- command: "valkey-server --save 30 1"
+ command: "valkey-server --save 30 1 --maxclients 10000 --timeout 1800"
healthcheck:
test: "[ $$(valkey-cli ping) = 'PONG' ]"
start_period: 5s
@@ -113,6 +177,8 @@ The `ports` directive is not included in this configuration, as it is not necess
The above configuration sets up a Redis container named `redis-valkey` and mounts a volume for data persistence. The `healthcheck` directive ensures that the container is restarted if it fails to respond to the `ping` command. The `--save 30 1` command option saves the Redis database to disk every 30 minutes if at least 1 key has changed.
+**Important:** The `--maxclients 10000 --timeout 1800` flags prevent connection exhaustion. See the "Critical: Redis Server Configuration" section above for details.
+
:::
To create a Docker network for communication between Open WebUI and Redis, run the following command:
@@ -215,6 +281,48 @@ WEBSOCKET_REDIS_OPTIONS='{"socket_connect_timeout": 5}'
:::
+#### Retry and Reconnect Logic
+
+To enhance resilience during Sentinel failover—the window when a new master is being elected and promoted—you can configure retry behavior to prevent the application from exhausting its reconnection attempts too quickly.
+
+- **`REDIS_SENTINEL_MAX_RETRY_COUNT`**: Sets the maximum number of retries for Redis operations when using Sentinel (Default: `2`).
+- **`REDIS_RECONNECT_DELAY`**: Adds an optional delay in **milliseconds** between retry attempts (e.g., `REDIS_RECONNECT_DELAY=500`). This prevents tight retry loops that may otherwise overwhelm the event loop or block the application before a new master is ready.
+
+### Redis Cluster Mode
+
+For deployments using Redis Cluster (including managed services like **AWS Elasticache Serverless**), enable cluster mode with the following configuration:
+
+```bash
+REDIS_URL="redis://your-cluster-endpoint:6379/0"
+REDIS_CLUSTER="true"
+```
+
+:::info
+
+**Key Configuration Notes**
+
+- `REDIS_CLUSTER` enables cluster-aware connection handling
+- The `REDIS_URL` should point to your cluster's configuration endpoint
+- This option has no effect if `REDIS_SENTINEL_HOSTS` is defined (Sentinel takes precedence)
+- When using cluster mode, the `REDIS_KEY_PREFIX` is automatically formatted as `{prefix}:` to ensure multi-key operations target the same hash slot
+
+:::
+
+#### AWS Elasticache Serverless
+
+For AWS Elasticache Serverless deployments, use the following configuration:
+
+```bash
+REDIS_URL="rediss://your-elasticache-endpoint.serverless.use1.cache.amazonaws.com:6379/0"
+REDIS_CLUSTER="true"
+```
+
+Note the `rediss://` scheme (with double 's') which enables TLS, required for Elasticache Serverless.
+
+#### OpenTelemetry Support
+
+Redis Cluster mode is fully compatible with OpenTelemetry instrumentation. When `ENABLE_OTEL` is enabled, Redis operations are properly traced regardless of whether you're using a single Redis instance, Redis Sentinel, or Redis Cluster mode.
+
### Complete Example Configuration
Here's a complete example showing all Redis-related environment variables:
@@ -229,6 +337,8 @@ WEBSOCKET_REDIS_URL="redis://redis-valkey:6379/1"
# Recommended for Sentinel deployments (prevents failover hangs)
REDIS_SOCKET_CONNECT_TIMEOUT=5
+REDIS_SENTINEL_MAX_RETRY_COUNT=5
+REDIS_RECONNECT_DELAY=1000
# Optional
REDIS_KEY_PREFIX="open-webui"
@@ -236,6 +346,25 @@ REDIS_KEY_PREFIX="open-webui"
For Redis Sentinel deployments specifically, ensure `REDIS_SOCKET_CONNECT_TIMEOUT` is set to prevent application hangs during master failover.
+#### Redis Cluster Mode Example
+
+For Redis Cluster deployments (including AWS Elasticache Serverless):
+
+```bash
+# Required for Redis Cluster
+REDIS_URL="rediss://your-cluster-endpoint:6379/0"
+REDIS_CLUSTER="true"
+
+# Required for websocket support
+ENABLE_WEBSOCKET_SUPPORT="true"
+WEBSOCKET_MANAGER="redis"
+WEBSOCKET_REDIS_URL="rediss://your-cluster-endpoint:6379/0"
+WEBSOCKET_REDIS_CLUSTER="true"
+
+# Optional
+REDIS_KEY_PREFIX="open-webui"
+```
+
### Docker Run Example
When running Open WebUI using Docker, connect it to the same Docker network and include all necessary Redis variables:
@@ -443,6 +572,54 @@ REDIS_KEY_PREFIX="openwebui-dev"
2. Monitor Redis memory: `docker exec -it redis-valkey valkey-cli info memory`
3. Clear old keys if needed: `docker exec -it redis-valkey valkey-cli FLUSHDB`
+#### Issue: "max number of clients reached" after days/weeks of operation
+
+**Symptoms:**
+
+- Application worked fine for an extended period, then suddenly fails
+- All login attempts return 500 Internal Server Error
+- Error in logs: `redis.exceptions.ConnectionError: max number of clients reached`
+- May temporarily recover, then fail again
+
+**Cause:** Redis `maxclients` limit reached due to connection accumulation. This happens when:
+- `timeout` is set to `0` (connections never close)
+- `maxclients` is too low for your usage pattern
+
+**Solution:**
+
+1. Check current connection count:
+ ```bash
+ redis-cli INFO clients | grep connected_clients
+ ```
+
+2. Check current settings:
+ ```bash
+ redis-cli CONFIG GET maxclients
+ redis-cli CONFIG GET timeout
+ ```
+
+3. Fix the configuration:
+ ```bash
+ redis-cli CONFIG SET maxclients 10000
+ redis-cli CONFIG SET timeout 1800
+ ```
+
+4. Make permanent by adding to `redis.conf` or Docker command:
+ ```conf
+ maxclients 10000
+ timeout 1800
+ ```
+
+5. Restart Redis to clear accumulated connections:
+ ```bash
+ # For systemd
+ sudo systemctl restart redis
+
+ # For Docker
+ docker restart redis-valkey
+
+**Prevention:** Always configure `timeout` to a reasonable value (e.g., 1800 seconds). The timeout only affects idle TCP connections, not user sessions — it's safe and recommended.
+
### Additional Resources
- [Redis Documentation](https://redis.io/docs)
diff --git a/docs/tutorials/tab-nginx/LetsEncrypt.md b/docs/tutorials/tab-nginx/LetsEncrypt.md
index 2e17a4eb30..21e3b7ce07 100644
--- a/docs/tutorials/tab-nginx/LetsEncrypt.md
+++ b/docs/tutorials/tab-nginx/LetsEncrypt.md
@@ -270,7 +270,12 @@ With the certificate saved in your `ssl` directory, you can now update the Nginx
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
- proxy_read_timeout 10m;
+
+ # Extended timeout for long LLM completions (30 minutes)
+ proxy_read_timeout 1800;
+ proxy_send_timeout 1800;
+ proxy_connect_timeout 1800;
+
proxy_buffering off;
proxy_cache off;
client_max_body_size 20M;
diff --git a/docs/tutorials/tab-nginx/NginxProxyManager.md b/docs/tutorials/tab-nginx/NginxProxyManager.md
index 1f8c0cf1ad..93859dd5d2 100644
--- a/docs/tutorials/tab-nginx/NginxProxyManager.md
+++ b/docs/tutorials/tab-nginx/NginxProxyManager.md
@@ -94,6 +94,20 @@ Without this, Nginx re-chunks SSE streams, breaking markdown formatting (visible
:::
+:::tip Extended Timeouts for Long Completions
+
+Long LLM completions (30+ minutes for complex tasks) may exceed the default 60-second timeout. Add these directives in the **Advanced** tab → **Custom Nginx Configuration**:
+
+```nginx
+proxy_read_timeout 1800;
+proxy_send_timeout 1800;
+proxy_connect_timeout 1800;
+```
+
+This sets a 30-minute timeout. Adjust as needed for your use case.
+
+:::
+
:::tip Caching Best Practice
While Nginx Proxy Manager handles most configuration automatically, be aware that:
diff --git a/docs/tutorials/tab-nginx/SelfSigned.md b/docs/tutorials/tab-nginx/SelfSigned.md
index aa024d579d..369bd24a4a 100644
--- a/docs/tutorials/tab-nginx/SelfSigned.md
+++ b/docs/tutorials/tab-nginx/SelfSigned.md
@@ -83,7 +83,11 @@ Using self-signed certificates is suitable for development or internal use where
proxy_cache off;
client_max_body_size 20M;
- proxy_read_timeout 10m;
+
+ # Extended timeout for long LLM completions (30 minutes)
+ proxy_read_timeout 1800;
+ proxy_send_timeout 1800;
+ proxy_connect_timeout 1800;
add_header Cache-Control "public, max-age=300, must-revalidate";
}
diff --git a/docs/tutorials/tab-nginx/Windows.md b/docs/tutorials/tab-nginx/Windows.md
index 3675c788a9..42a8763f54 100644
--- a/docs/tutorials/tab-nginx/Windows.md
+++ b/docs/tutorials/tab-nginx/Windows.md
@@ -156,7 +156,11 @@ http {
proxy_buffering off;
proxy_cache off;
client_max_body_size 20M;
- proxy_read_timeout 10m;
+
+ # Extended timeout for long LLM completions (30 minutes)
+ proxy_read_timeout 1800;
+ proxy_send_timeout 1800;
+ proxy_connect_timeout 1800;
add_header Cache-Control "public, max-age=300, must-revalidate";
}
diff --git a/docs/tutorials/tips/sqlite-database.md b/docs/tutorials/tips/sqlite-database.md
index 1310959582..50860c9cf9 100644
--- a/docs/tutorials/tips/sqlite-database.md
+++ b/docs/tutorials/tips/sqlite-database.md
@@ -79,9 +79,10 @@ Here is a complete list of tables in Open-WebUI's SQLite database. The tables ar
| 23 | note | Stores user-created notes and annotations |
| 24 | oauth_session | Manages active OAuth sessions for users |
| 25 | prompt | Stores templates and configurations for AI prompts |
-| 26 | tag | Manages tags/labels for content categorization |
-| 27 | tool | Stores configurations for system tools and integrations |
-| 28 | user | Maintains user profiles and account information |
+| 26 | prompt_history | Tracks version history and snapshots for prompts |
+| 27 | tag | Manages tags/labels for content categorization |
+| 28 | tool | Stores configurations for system tools and integrations |
+| 29 | user | Maintains user profiles and account information |
Note: there are two additional tables in Open-WebUI's SQLite database that are not related to Open-WebUI's core functionality, that have been excluded:
@@ -446,14 +447,33 @@ The `access_control` fields expected structure:
## Prompt Table
-| **Column Name** | **Data Type** | **Constraints** | **Description** |
-| --------------- | ------------- | --------------- | ------------------------- |
-| command | String | PRIMARY KEY | Unique command identifier |
-| user_id | String | - | Prompt owner |
-| title | Text | - | Prompt title |
-| content | Text | - | Prompt content/template |
-| timestamp | BigInteger | - | Last update timestamp |
-| access_control | JSON | nullable | Access permissions |
+| **Column Name** | **Data Type** | **Constraints** | **Description** |
+| --------------- | ------------- | --------------- | ----------------------------------- |
+| id | Text | PRIMARY KEY | Unique identifier (UUID) |
+| command | String | UNIQUE, INDEX | Unique command identifier |
+| user_id | String | NOT NULL | Owner of the prompt |
+| name | Text | NOT NULL | Display name of the prompt |
+| content | Text | NOT NULL | Prompt content/template |
+| data | JSON | nullable | Additional prompt data |
+| meta | JSON | nullable | Prompt metadata |
+| access_control | JSON | nullable | Permission settings |
+| is_active | Boolean | default=True | Active status |
+| version_id | Text | nullable | Current version identifier |
+| tags | JSON | nullable | Associated tags |
+| created_at | BigInteger | NOT NULL | Creation timestamp |
+| updated_at | BigInteger | NOT NULL | Last update timestamp |
+
+## Prompt History Table
+
+| **Column Name** | **Data Type** | **Constraints** | **Description** |
+| --------------- | ------------- | ------------------------------ | --------------------------------- |
+| id | Text | PRIMARY KEY | Unique identifier (UUID) |
+| prompt_id | Text | FOREIGN KEY(prompt.id), INDEX | Reference to the prompt |
+| parent_id | Text | nullable | Reference to the parent version |
+| snapshot | JSON | NOT NULL | Snapshot of the prompt at version |
+| user_id | Text | NOT NULL | User who created the version |
+| commit_message | Text | nullable | Version commit message |
+| created_at | BigInteger | NOT NULL | Creation timestamp |
## Tag Table
@@ -524,6 +544,8 @@ erDiagram
user ||--o{ memory : "owns"
user ||--o{ model : "manages"
user ||--o{ prompt : "creates"
+ user ||--o{ prompt_history : "creates"
+ prompt ||--o{ prompt_history : "has"
user ||--o{ tag : "creates"
user ||--o{ tool : "manages"
user ||--o{ note : "owns"
@@ -698,11 +720,26 @@ erDiagram
}
prompt {
- string command PK
+ text id PK
+ string command
string user_id FK
- text title
+ text name
text content
+ json data
+ json meta
json access_control
+ boolean is_active
+ text version_id
+ json tags
+ }
+
+ prompt_history {
+ text id PK
+ text prompt_id FK
+ text parent_id FK
+ json snapshot
+ text user_id FK
+ text commit_message
}
tag {
diff --git a/static/images/getting-started/quick-start/api-type-responses.gif b/static/images/getting-started/quick-start/api-type-responses.gif
new file mode 100644
index 0000000000..d3daae0e05
Binary files /dev/null and b/static/images/getting-started/quick-start/api-type-responses.gif differ