Note to first-time contributors: Please open a discussion post in Discussions and describe your changes before submitting a pull request.
Before submitting, make sure you've checked the following:
Target branch: Verify that the pull request targets the dev branch. Not targeting the dev branch may lead to immediate closure of the PR.
Description: Provide a concise description of the changes made in this pull request.
Changelog: Ensure a changelog entry following the format of Keep a Changelog is added at the bottom of the PR description.
Documentation: If necessary, update relevant documentation Open WebUI Docs like environment variables, the tutorials, or other documentation sources.
Testing: Perform manual tests to verify the implemented fix/feature works as intended AND does not break any other functionality. Take this as an opportunity to make screenshots of the feature/fix and include it in the PR description.
Agentic AI Code:: Confirm this Pull Request is not written by any AI Agent or has at least gone through additional human review and manual testing. If any AI Agent is the co-author of this PR, it may lead to immediate closure of the PR.
Code review: Have you performed a self-review of your code, addressing any coding standard issues and ensuring adherence to the project's coding standards?
Title Prefix: To clearly categorize this pull request, prefix the pull request title using one of the following:
feat: Introduces a new feature or enhancement to the codebase
Changelog Entry
Description
This PR introduces a powerful new feature that combines workspace prompts with prompt variables, allowing users to reference workspace prompts using {{PROMPTS.prompt_name}} syntax within model system prompts and other contexts. The feature includes intelligent access control that respects user permissions while providing elevated access for admin-owned models, ensuring security without sacrificing functionality.
Added
Prompt Variable Substitution: New {{PROMPTS.prompt_name}} variable syntax that allows referencing workspace prompts by their command name
Recursive Variable Resolution: Variables within referenced prompts (like {{CURRENT_DATETIME}}, {{USER_NAME}}, etc.) are automatically resolved
Self-injection Prevention: Built-in protection against infinite recursion when prompts reference themselves
Admin-Owned Model Privilege Escalation: Models created by admin users can access ALL workspace prompts, regardless of the end user's permissions
Helper functions in task.py:
_get_user_variables(): Extracts user information into a dictionary for template processing
_resolve_basic_variables(): Handles resolution of date/time and user-related variables
replace_prompts_variable(): Core function for {{PROMPTS.*}} substitution with recursion prevention
Changed
Modified apply_system_prompt_to_body() in payload.py to accept optional model parameter for ownership checks
Updated apply_system_prompt_to_body() to fetch appropriate prompts based on model ownership (all prompts for admin-owned models, accessible prompts for others)
Refactored template processing functions to use DRY principles with shared helper functions
Updated all call sites of apply_system_prompt_to_body() in:
middleware.py (2 locations)
openai.py (1 location)
ollama.py (2 locations)
functions.py (1 location)
Deprecated
None
Removed
None
Fixed
Eliminated code duplication in variable extraction and date formatting logic
Removed unused import of Prompts from task.py
Security
Access Control: Respects prompt access control settings - users can only reference prompts they have read access to
Recursion Prevention: Prevents infinite loops when prompts reference themselves or create circular dependencies
Privilege Escalation: Admin-owned models can access all prompts, allowing admins to create powerful system prompts that work for all users without requiring individual permission grants
Breaking Changes
None - This is a purely additive feature with backward compatibility
Additional Information
Use Cases
Reusable System Prompt Components: Create modular prompt components that can be referenced and reused across multiple models
Dynamic Prompt Composition: Compose complex system prompts by referencing multiple workspace prompts
Admin-Managed Templates: Admins can create models with prompts that reference private or restricted workspace prompts, and those models will work for all users
Example Usage
Create a workspace prompt with command expert-persona:
You are an expert in software development with deep knowledge of Python, JavaScript, and system design.
Current time: {{CURRENT_DATETIME}}
Reference it in a model's system prompt:
{{PROMPTS.expert-persona}}
Additional instructions: Help the user debug their code and provide best practices.
User: {{USER_NAME}}
The final resolved prompt will include the expert persona content with all variables expanded.
Technical Implementation Details
Prompts are fetched once per request and cached for the duration of the template processing
Variable resolution happens in order: metadata variables → basic variables (dates, user info) → prompt references
Nested {{PROMPTS.*}} references within referenced prompts are intentionally not resolved to prevent complexity and potential circular dependencies
Model ownership is determined by checking if the model's user_id belongs to a user with role == "admin"
Screenshots or Videos
N/A - Backend feature, behavior visible in chat interactions
Contributor License Agreement
By submitting this pull request, I confirm that I have read and fully agree to the Contributor License Agreement (CLA), and I am providing my contributions under its terms.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/open-webui/open-webui/pull/18639
**Author:** [@Davixk](https://github.com/Davixk)
**Created:** 10/26/2025
**Status:** ❌ Closed
**Base:** `dev` ← **Head:** `feat/prompts-as-variables`
---
### 📝 Commits (3)
- [`8cb2f85`](https://github.com/open-webui/open-webui/commit/8cb2f85625831bc054eff324f44ad921f2d07428) feat(prompts): add support for prompt variable substitution
- [`1cf5250`](https://github.com/open-webui/open-webui/commit/1cf5250018337a844f7f83cdb88fd0e939c75b2f) refactor(prompts): add recursive prompt variable resolution
- [`dee3db4`](https://github.com/open-webui/open-webui/commit/dee3db41ee8f9d1bdc88109a699003eb6280529d) feat(prompts): add prompt reference validation on save
### 📊 Changes
**9 files changed** (+520 additions, -35 deletions)
<details>
<summary>View changed files</summary>
📝 `backend/open_webui/functions.py` (+3 -1)
📝 `backend/open_webui/routers/ollama.py` (+6 -2)
📝 `backend/open_webui/routers/openai.py` (+3 -1)
📝 `backend/open_webui/routers/prompts.py` (+98 -1)
📝 `backend/open_webui/utils/middleware.py` (+13 -4)
📝 `backend/open_webui/utils/payload.py` (+47 -3)
📝 `backend/open_webui/utils/task.py` (+280 -15)
📝 `src/lib/apis/prompts/index.ts` (+32 -0)
📝 `src/lib/components/workspace/Prompts/PromptEditor.svelte` (+38 -8)
</details>
### 📄 Description
# Pull Request Checklist
### Note to first-time contributors: Please open a discussion post in [Discussions](https://github.com/open-webui/open-webui/discussions) and describe your changes before submitting a pull request.
**Before submitting, make sure you've checked the following:**
- [x] **Target branch:** Verify that the pull request targets the `dev` branch. Not targeting the `dev` branch may lead to immediate closure of the PR.
- [x] **Description:** Provide a concise description of the changes made in this pull request.
- [x] **Changelog:** Ensure a changelog entry following the format of [Keep a Changelog](https://keepachangelog.com/) is added at the bottom of the PR description.
- [ ] **Documentation:** If necessary, update relevant documentation [Open WebUI Docs](https://github.com/open-webui/docs) like environment variables, the tutorials, or other documentation sources.
- [x] **Testing:** Perform manual tests to verify the implemented fix/feature works as intended AND does not break any other functionality. Take this as an opportunity to make screenshots of the feature/fix and include it in the PR description.
- [x] **Agentic AI Code:**: Confirm this Pull Request is **not written by any AI Agent** or has at least gone through additional human review **and** manual testing. If any AI Agent is the co-author of this PR, it may lead to immediate closure of the PR.
- [x] **Code review:** Have you performed a self-review of your code, addressing any coding standard issues and ensuring adherence to the project's coding standards?
- [x] **Title Prefix:** To clearly categorize this pull request, prefix the pull request title using one of the following:
- **feat**: Introduces a new feature or enhancement to the codebase
# Changelog Entry
### Description
This PR introduces a powerful new feature that combines workspace prompts with prompt variables, allowing users to reference workspace prompts using `{{PROMPTS.prompt_name}}` syntax within model system prompts and other contexts. The feature includes intelligent access control that respects user permissions while providing elevated access for admin-owned models, ensuring security without sacrificing functionality.
### Added
- **Prompt Variable Substitution**: New `{{PROMPTS.prompt_name}}` variable syntax that allows referencing workspace prompts by their command name
- **Recursive Variable Resolution**: Variables within referenced prompts (like `{{CURRENT_DATETIME}}`, `{{USER_NAME}}`, etc.) are automatically resolved
- **Self-injection Prevention**: Built-in protection against infinite recursion when prompts reference themselves
- **Admin-Owned Model Privilege Escalation**: Models created by admin users can access ALL workspace prompts, regardless of the end user's permissions
- Helper functions in `task.py`:
- `_get_user_variables()`: Extracts user information into a dictionary for template processing
- `_resolve_basic_variables()`: Handles resolution of date/time and user-related variables
- `replace_prompts_variable()`: Core function for `{{PROMPTS.*}}` substitution with recursion prevention
### Changed
- Modified `apply_system_prompt_to_body()` in `payload.py` to accept optional `model` parameter for ownership checks
- Updated `apply_system_prompt_to_body()` to fetch appropriate prompts based on model ownership (all prompts for admin-owned models, accessible prompts for others)
- Refactored template processing functions to use DRY principles with shared helper functions
- Updated all call sites of `apply_system_prompt_to_body()` in:
- `middleware.py` (2 locations)
- `openai.py` (1 location)
- `ollama.py` (2 locations)
- `functions.py` (1 location)
### Deprecated
- None
### Removed
- None
### Fixed
- Eliminated code duplication in variable extraction and date formatting logic
- Removed unused import of `Prompts` from `task.py`
### Security
- **Access Control**: Respects prompt access control settings - users can only reference prompts they have read access to
- **Recursion Prevention**: Prevents infinite loops when prompts reference themselves or create circular dependencies
- **Privilege Escalation**: Admin-owned models can access all prompts, allowing admins to create powerful system prompts that work for all users without requiring individual permission grants
### Breaking Changes
- None - This is a purely additive feature with backward compatibility
---
### Additional Information
#### Use Cases
1. **Reusable System Prompt Components**: Create modular prompt components that can be referenced and reused across multiple models
2. **Dynamic Prompt Composition**: Compose complex system prompts by referencing multiple workspace prompts
3. **Admin-Managed Templates**: Admins can create models with prompts that reference private or restricted workspace prompts, and those models will work for all users
#### Example Usage
Create a workspace prompt with command `expert-persona`:
```markdown
You are an expert in software development with deep knowledge of Python, JavaScript, and system design.
Current time: {{CURRENT_DATETIME}}
```
Reference it in a model's system prompt:
```markdown
{{PROMPTS.expert-persona}}
Additional instructions: Help the user debug their code and provide best practices.
User: {{USER_NAME}}
```
The final resolved prompt will include the expert persona content with all variables expanded.
#### Technical Implementation Details
- Prompts are fetched once per request and cached for the duration of the template processing
- Variable resolution happens in order: metadata variables → basic variables (dates, user info) → prompt references
- Nested `{{PROMPTS.*}}` references within referenced prompts are intentionally not resolved to prevent complexity and potential circular dependencies
- Model ownership is determined by checking if the model's `user_id` belongs to a user with `role == "admin"`
### Screenshots or Videos
- N/A - Backend feature, behavior visible in chat interactions
### Contributor License Agreement
By submitting this pull request, I confirm that I have read and fully agree to the [Contributor License Agreement (CLA)](https://github.com/open-webui/open-webui/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT), and I am providing my contributions under its terms.
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/open-webui/open-webui/pull/18639
Author: @Davixk
Created: 10/26/2025
Status: ❌ Closed
Base:
dev← Head:feat/prompts-as-variables📝 Commits (3)
8cb2f85feat(prompts): add support for prompt variable substitution1cf5250refactor(prompts): add recursive prompt variable resolutiondee3db4feat(prompts): add prompt reference validation on save📊 Changes
9 files changed (+520 additions, -35 deletions)
View changed files
📝
backend/open_webui/functions.py(+3 -1)📝
backend/open_webui/routers/ollama.py(+6 -2)📝
backend/open_webui/routers/openai.py(+3 -1)📝
backend/open_webui/routers/prompts.py(+98 -1)📝
backend/open_webui/utils/middleware.py(+13 -4)📝
backend/open_webui/utils/payload.py(+47 -3)📝
backend/open_webui/utils/task.py(+280 -15)📝
src/lib/apis/prompts/index.ts(+32 -0)📝
src/lib/components/workspace/Prompts/PromptEditor.svelte(+38 -8)📄 Description
Pull Request Checklist
Note to first-time contributors: Please open a discussion post in Discussions and describe your changes before submitting a pull request.
Before submitting, make sure you've checked the following:
devbranch. Not targeting thedevbranch may lead to immediate closure of the PR.Changelog Entry
Description
This PR introduces a powerful new feature that combines workspace prompts with prompt variables, allowing users to reference workspace prompts using
{{PROMPTS.prompt_name}}syntax within model system prompts and other contexts. The feature includes intelligent access control that respects user permissions while providing elevated access for admin-owned models, ensuring security without sacrificing functionality.Added
{{PROMPTS.prompt_name}}variable syntax that allows referencing workspace prompts by their command name{{CURRENT_DATETIME}},{{USER_NAME}}, etc.) are automatically resolvedtask.py:_get_user_variables(): Extracts user information into a dictionary for template processing_resolve_basic_variables(): Handles resolution of date/time and user-related variablesreplace_prompts_variable(): Core function for{{PROMPTS.*}}substitution with recursion preventionChanged
apply_system_prompt_to_body()inpayload.pyto accept optionalmodelparameter for ownership checksapply_system_prompt_to_body()to fetch appropriate prompts based on model ownership (all prompts for admin-owned models, accessible prompts for others)apply_system_prompt_to_body()in:middleware.py(2 locations)openai.py(1 location)ollama.py(2 locations)functions.py(1 location)Deprecated
Removed
Fixed
Promptsfromtask.pySecurity
Breaking Changes
Additional Information
Use Cases
Example Usage
Create a workspace prompt with command
expert-persona:Reference it in a model's system prompt:
The final resolved prompt will include the expert persona content with all variables expanded.
Technical Implementation Details
{{PROMPTS.*}}references within referenced prompts are intentionally not resolved to prevent complexity and potential circular dependenciesuser_idbelongs to a user withrole == "admin"Screenshots or Videos
Contributor License Agreement
By submitting this pull request, I confirm that I have read and fully agree to the Contributor License Agreement (CLA), and I am providing my contributions under its terms.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.