Skip to content

Commit f39e444

Browse files
Copilotowndev
andcommitted
Add model system prompt support and update prompt hierarchy to: default → model → user
Co-authored-by: owndev <69784886+owndev@users.noreply.github.com>
1 parent 3aff155 commit f39e444

2 files changed

Lines changed: 92 additions & 30 deletions

File tree

docs/google-gemini-integration.md

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -253,15 +253,19 @@ Native tool calling is enabled/disabled via the standard 'Function calling' Open
253253

254254
## System Prompt Hierarchy
255255

256-
The Google Gemini pipeline supports a hierarchical system prompt configuration that combines multiple sources. This allows for flexible customization at different levels: global defaults, per-user personalization, and per-chat customization.
256+
The Google Gemini pipeline supports a hierarchical system prompt configuration that combines multiple sources. This allows for flexible customization at different levels: global defaults, model-specific settings, and user preferences.
257257

258258
### Prompt Sources (in order of combination)
259259

260260
1. **Default System Prompt** (`GOOGLE_DEFAULT_SYSTEM_PROMPT`): Global default applied to all chats, configurable via environment variable or Admin UI valves.
261261

262-
2. **Per-User System Prompt** (User Personalization): Each user can set their own system prompt in Open WebUI's Settings > Personalization. This is stored in `settings.ui.system` and is automatically included.
262+
2. **Model System Prompt**: The system prompt configured in the model settings (Admin > Models > Select Model > System Prompt). This is passed via `__metadata__["chat"]["params"]["system"]`.
263263

264-
3. **Chat-Level System Prompt**: The system message defined in the model settings or passed with individual chat messages.
264+
3. **User System Prompt**: The user's personalized system prompt from either:
265+
- **User Settings** (Settings > Personalization): Stored in `settings.ui.system`
266+
- **Chat Controls**: The system message passed with individual chat messages
267+
268+
Note: User settings take precedence over chat controls if both are set.
265269

266270
### How It Works
267271

@@ -270,9 +274,9 @@ All available prompts are combined in order, separated by blank lines:
270274
```
271275
{Default System Prompt}
272276
273-
{Per-User Personalization Prompt}
277+
{Model System Prompt}
274278
275-
{Chat-Level System Prompt}
279+
{User System Prompt}
276280
```
277281

278282
If only one prompt source is set, it is used as-is without any additional formatting.
@@ -283,20 +287,30 @@ If only one prompt source is set, it is used as-is without any additional format
283287

284288
```bash
285289
# Default system prompt applied to all chats
286-
# Combined with per-user and chat-level prompts if they exist
290+
# Combined with model and user prompts if they exist
287291
GOOGLE_DEFAULT_SYSTEM_PROMPT="You are a helpful AI assistant. Always be concise and accurate."
288292
```
289293

290294
Or configure through the pipeline valves in Open WebUI's Admin panel.
291295

292-
**Per-User Personalization:**
296+
**Model System Prompt:**
297+
298+
Configure the model's system prompt in Open WebUI:
299+
1. Go to Admin > Models
300+
2. Select the model you want to configure
301+
3. Enter the system prompt in the "System Prompt" field
302+
4. Save settings
303+
304+
This prompt will be applied to all chats using this model.
305+
306+
**User System Prompt:**
293307

294308
Users can set their personalized system prompt in Open WebUI:
295309
1. Go to Settings > Personalization
296310
2. Enter your preferred system prompt in the "System Prompt" field
297311
3. Save settings
298312

299-
This prompt will be automatically applied to all your Gemini chats, combined with any default and chat-level prompts.
313+
This prompt will be automatically applied to all your Gemini chats, combined with any default and model prompts.
300314

301315
### Example
302316

@@ -307,23 +321,23 @@ If your configuration is:
307321
You are a helpful AI assistant.
308322
```
309323

310-
**Per-user personalization prompt (Settings > Personalization):**
324+
**Model system prompt (Admin > Models > System Prompt):**
311325
```
312-
My name is John. I prefer detailed explanations.
326+
You specialize in Python programming.
313327
```
314328

315-
**Chat-level system prompt (model settings):**
329+
**User system prompt (Settings > Personalization OR chat controls):**
316330
```
317-
Always respond in formal English.
331+
My name is John. I prefer detailed explanations.
318332
```
319333

320334
The combined system prompt sent to Gemini will be:
321335
```
322336
You are a helpful AI assistant.
323337
324-
My name is John. I prefer detailed explanations.
338+
You specialize in Python programming.
325339
326-
Always respond in formal English.
340+
My name is John. I prefer detailed explanations.
327341
```
328342

329343
## Thinking Configuration

pipelines/google/google_gemini.py

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
author_url: https://github.com/owndev/
55
project_url: https://github.com/owndev/Open-WebUI-Functions
66
funding_url: https://github.com/sponsors/owndev
7-
version: 1.8.2
7+
version: 1.8.3
88
required_open_webui_version: 0.6.26
99
license: Apache License 2.0
1010
description: Highly optimized Google Gemini pipeline with advanced image generation capabilities, intelligent compression, and streamlined processing workflows.
@@ -34,7 +34,7 @@
3434
- Flexible upload fallback options and optimization controls
3535
- Configurable thinking levels (low/high) for Gemini 3 models
3636
- Configurable thinking budgets (0-32768 tokens) for Gemini 2.5 models
37-
- Hierarchical system prompts (default, per-user personalization, per-chat)
37+
- Hierarchical system prompts (default, model, user)
3838
"""
3939

4040
import os
@@ -209,8 +209,8 @@ class Valves(BaseModel):
209209
)
210210
DEFAULT_SYSTEM_PROMPT: str = Field(
211211
default=os.getenv("GOOGLE_DEFAULT_SYSTEM_PROMPT", ""),
212-
description="Default system prompt applied to all chats. Combined with per-user personalization "
213-
"and chat-level prompts in a hierarchy: default → per-userper-chat. Leave empty to disable.",
212+
description="Default system prompt applied to all chats. Combined with model and user prompts "
213+
"in a hierarchy: default → modeluser. Leave empty to disable.",
214214
)
215215

216216
# Image Processing Configuration
@@ -320,28 +320,67 @@ def _get_user_personalization_prompt(
320320

321321
return None
322322

323+
def _get_model_system_prompt(
324+
self, __metadata__: Optional[dict] = None
325+
) -> Optional[str]:
326+
"""Get the model's system prompt from model settings.
327+
328+
In Open WebUI, each model can have its own system prompt configured
329+
in Admin > Models > Select Model > System Prompt. This is typically
330+
passed via __metadata__["chat"]["params"]["system"].
331+
332+
Args:
333+
__metadata__: The metadata dict passed to the pipe method
334+
335+
Returns:
336+
The model's system prompt or None if not set
337+
"""
338+
if __metadata__ is None:
339+
return None
340+
341+
try:
342+
chat = __metadata__.get("chat")
343+
if chat and isinstance(chat, dict):
344+
params = chat.get("params")
345+
if params and isinstance(params, dict):
346+
system_prompt = params.get("system")
347+
if system_prompt and isinstance(system_prompt, str):
348+
return system_prompt.strip() or None
349+
except Exception as e:
350+
self.log.debug(f"Could not retrieve model system prompt: {e}")
351+
352+
return None
353+
323354
def _combine_system_prompts(
324-
self, chat_system_prompt: Optional[str], __user__: Optional[dict] = None
355+
self,
356+
chat_system_prompt: Optional[str],
357+
__user__: Optional[dict] = None,
358+
__metadata__: Optional[dict] = None,
325359
) -> Optional[str]:
326-
"""Combine default, per-user, and chat-level system prompts.
360+
"""Combine default, model, and user system prompts.
327361
328362
Prompt hierarchy (all prompts are combined if set):
329363
1. DEFAULT_SYSTEM_PROMPT (environment/valve setting)
330-
2. Per-user system prompt (from __user__["settings"]["ui"]["system"] - Personalization settings)
331-
3. Chat-level system prompt (from messages in this request)
364+
2. Model system prompt (from model settings - __metadata__["chat"]["params"]["system"])
365+
3. User system prompt (from user settings OR chat controls/messages)
332366
333367
Args:
334368
chat_system_prompt: The chat-level system prompt from messages (may be None)
335369
__user__: The user dict passed to the pipe method
370+
__metadata__: The metadata dict passed to the pipe method
336371
337372
Returns:
338373
Combined system prompt or None if none are set
339374
"""
340375
default_prompt = self.valves.DEFAULT_SYSTEM_PROMPT.strip() or None
376+
model_prompt = self._get_model_system_prompt(__metadata__)
341377
user_personalization = self._get_user_personalization_prompt(__user__)
342378
chat_prompt = chat_system_prompt.strip() if chat_system_prompt else None
343379

344-
prompts = [p for p in [default_prompt, user_personalization, chat_prompt] if p]
380+
# User prompt = user personalization OR chat prompt (user settings take precedence)
381+
user_prompt = user_personalization or chat_prompt
382+
383+
prompts = [p for p in [default_prompt, model_prompt, user_prompt] if p]
345384

346385
if not prompts:
347386
return None
@@ -354,8 +393,8 @@ def _combine_system_prompts(
354393
self.log.debug(
355394
f"Combined system prompts: "
356395
f"default={len(default_prompt) if default_prompt else 0}, "
357-
f"user_personalization={len(user_personalization) if user_personalization else 0}, "
358-
f"chat={len(chat_prompt) if chat_prompt else 0} -> "
396+
f"model={len(model_prompt) if model_prompt else 0}, "
397+
f"user={len(user_prompt) if user_prompt else 0} -> "
359398
f"total={len(combined)} chars"
360399
)
361400
return combined
@@ -446,6 +485,7 @@ async def _build_image_generation_contents(
446485
messages: List[Dict[str, Any]],
447486
__event_emitter__: Callable,
448487
__user__: Optional[dict] = None,
488+
__metadata__: Optional[dict] = None,
449489
) -> Tuple[List[Dict[str, Any]], Optional[str]]:
450490
"""Construct the contents payload for image-capable models.
451491
@@ -459,7 +499,7 @@ async def _build_image_generation_contents(
459499

460500
# Combine with default system prompt if configured
461501
system_instruction = self._combine_system_prompts(
462-
user_system_instruction, __user__
502+
user_system_instruction, __user__, __metadata__
463503
)
464504

465505
last_user_msg = next(
@@ -919,14 +959,18 @@ def _prepare_model_id(self, model_id: str) -> str:
919959
return model_id
920960

921961
def _prepare_content(
922-
self, messages: List[Dict[str, Any]], __user__: Optional[dict] = None
962+
self,
963+
messages: List[Dict[str, Any]],
964+
__user__: Optional[dict] = None,
965+
__metadata__: Optional[dict] = None,
923966
) -> Tuple[List[Dict[str, Any]], Optional[str]]:
924967
"""
925968
Prepare messages content for the API and extract system message if present.
926969
927970
Args:
928971
messages: List of message objects from the request
929972
__user__: The user dict passed to the pipe method
973+
__metadata__: The metadata dict passed to the pipe method
930974
931975
Returns:
932976
Tuple of (prepared content list, system message string or None)
@@ -938,7 +982,9 @@ def _prepare_content(
938982
)
939983

940984
# Combine with default system prompt if configured
941-
system_message = self._combine_system_prompts(user_system_message, __user__)
985+
system_message = self._combine_system_prompts(
986+
user_system_message, __user__, __metadata__
987+
)
942988

943989
# Prepare contents for the API
944990
contents = []
@@ -2197,7 +2243,7 @@ async def pipe(
21972243
contents,
21982244
system_instruction,
21992245
) = await self._build_image_generation_contents(
2200-
messages, __event_emitter__, __user__
2246+
messages, __event_emitter__, __user__, __metadata__
22012247
)
22022248
# For image generation, system_instruction is integrated into the prompt
22032249
# so it will be None here (this is expected and correct)
@@ -2209,7 +2255,9 @@ async def pipe(
22092255
else:
22102256
# For non-image generation models, use the full conversation history
22112257
# Prepare content and extract system message normally
2212-
contents, system_instruction = self._prepare_content(messages, __user__)
2258+
contents, system_instruction = self._prepare_content(
2259+
messages, __user__, __metadata__
2260+
)
22132261
if not contents:
22142262
return "Error: No valid message content found"
22152263
self.log.debug(

0 commit comments

Comments
 (0)