Skip to content

Commit 2812022

Browse files
Copilotowndev
andcommitted
Add multiple fallback paths for model system prompt and enhanced logging
Co-authored-by: owndev <69784886+owndev@users.noreply.github.com>
1 parent 1abe860 commit 2812022

2 files changed

Lines changed: 104 additions & 28 deletions

File tree

docs/google-gemini-integration.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,10 @@ The Google Gemini pipeline supports a hierarchical system prompt configuration t
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. **Model System Prompt**: The system prompt configured in the model settings (Admin > Models > Select Model > System Prompt). This is accessed via `__model__["info"]["params"]["system"]`.
262+
2. **Model System Prompt**: The system prompt configured in the model settings (Admin > Models > Select Model > System Prompt). The pipeline attempts to retrieve this from multiple sources in order:
263+
- `__model__["info"]["params"]["system"]` (primary)
264+
- `__model__["params"]["system"]` (alternative)
265+
- `__metadata__["chat"]["params"]["system"]` (fallback)
263266

264267
3. **User System Prompt**: The user's personalized system prompt from either:
265268
- **Chat Controls**: The system message passed with individual chat messages

pipelines/google/google_gemini.py

Lines changed: 100 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -321,71 +321,138 @@ def _get_user_personalization_prompt(
321321
return None
322322

323323
def _get_model_system_prompt(
324-
self, __model__: Optional[dict] = None
324+
self,
325+
__model__: Optional[dict] = None,
326+
__metadata__: Optional[dict] = None,
327+
body: Optional[dict] = None,
325328
) -> Optional[str]:
326329
"""Get the model's system prompt from model settings.
327330
328331
In Open WebUI, each model can have its own system prompt configured
329332
in Admin > Models > Select Model > System Prompt. This is accessed
330-
via __model__["info"]["params"]["system"].
333+
via __model__["info"]["params"]["system"] or alternative paths.
331334
332335
Args:
333336
__model__: The model dict passed to the pipe method
337+
__metadata__: The metadata dict passed to the pipe method (fallback)
338+
body: The request body (fallback)
334339
335340
Returns:
336341
The model's system prompt or None if not set
337342
"""
338-
if __model__ is None:
339-
self.log.debug("__model__ is None - model system prompt not available")
340-
return None
343+
# Try __model__ first (the official reserved argument)
344+
if __model__ is not None:
345+
self.log.debug(
346+
f"__model__ received: {type(__model__)}, "
347+
f"keys: {list(__model__.keys()) if isinstance(__model__, dict) else 'not a dict'}"
348+
)
341349

342-
self.log.debug(f"__model__ received: {type(__model__)}, keys: {list(__model__.keys()) if isinstance(__model__, dict) else 'not a dict'}")
350+
try:
351+
# Try path: __model__["info"]["params"]["system"]
352+
info = __model__.get("info")
353+
if info and isinstance(info, dict):
354+
self.log.debug(f"__model__['info'] keys: {list(info.keys())}")
355+
params = info.get("params")
356+
if params and isinstance(params, dict):
357+
self.log.debug(
358+
f"__model__['info']['params'] keys: {list(params.keys())}"
359+
)
360+
system_prompt = params.get("system")
361+
if system_prompt and isinstance(system_prompt, str):
362+
self.log.debug(
363+
f"Found model system prompt via __model__['info']['params']['system'] ({len(system_prompt)} chars)"
364+
)
365+
return system_prompt.strip() or None
343366

344-
try:
345-
info = __model__.get("info")
346-
if info and isinstance(info, dict):
347-
self.log.debug(f"__model__['info'] keys: {list(info.keys())}")
348-
params = info.get("params")
367+
# Try alternative path: __model__["params"]["system"] (directly)
368+
params = __model__.get("params")
349369
if params and isinstance(params, dict):
350-
self.log.debug(f"__model__['info']['params'] keys: {list(params.keys())}")
370+
self.log.debug(f"__model__['params'] keys: {list(params.keys())}")
351371
system_prompt = params.get("system")
352372
if system_prompt and isinstance(system_prompt, str):
353-
self.log.debug(f"Found model system prompt ({len(system_prompt)} chars)")
373+
self.log.debug(
374+
f"Found model system prompt via __model__['params']['system'] ({len(system_prompt)} chars)"
375+
)
354376
return system_prompt.strip() or None
355-
else:
356-
self.log.debug("No system prompt in __model__['info']['params']['system']")
357-
else:
358-
self.log.debug("No params in __model__['info']")
359-
else:
360-
self.log.debug("No info in __model__")
361-
except Exception as e:
362-
self.log.debug(f"Could not retrieve model system prompt: {e}")
377+
except Exception as e:
378+
self.log.debug(f"Could not retrieve model system prompt from __model__: {e}")
379+
else:
380+
self.log.debug("__model__ is None - trying fallback paths")
381+
382+
# Fallback: Try __metadata__["chat"]["params"]["system"]
383+
if __metadata__ is not None:
384+
self.log.debug(
385+
f"__metadata__ keys: {list(__metadata__.keys()) if isinstance(__metadata__, dict) else 'not a dict'}"
386+
)
387+
try:
388+
chat = __metadata__.get("chat")
389+
if chat and isinstance(chat, dict):
390+
self.log.debug(f"__metadata__['chat'] keys: {list(chat.keys())}")
391+
params = chat.get("params")
392+
if params and isinstance(params, dict):
393+
self.log.debug(
394+
f"__metadata__['chat']['params'] keys: {list(params.keys())}"
395+
)
396+
system_prompt = params.get("system")
397+
if system_prompt and isinstance(system_prompt, str):
398+
self.log.debug(
399+
f"Found model system prompt via __metadata__['chat']['params']['system'] ({len(system_prompt)} chars)"
400+
)
401+
return system_prompt.strip() or None
402+
except Exception as e:
403+
self.log.debug(f"Could not retrieve model system prompt from __metadata__: {e}")
404+
405+
# Fallback: Try body["model_info"]["params"]["system"] or similar
406+
if body is not None:
407+
self.log.debug(f"body keys: {list(body.keys()) if isinstance(body, dict) else 'not a dict'}")
408+
try:
409+
# Check if model info is embedded in body
410+
model_info = body.get("model_info") or body.get("model")
411+
if model_info and isinstance(model_info, dict):
412+
self.log.debug(f"body model_info keys: {list(model_info.keys())}")
413+
info = model_info.get("info")
414+
if info and isinstance(info, dict):
415+
params = info.get("params")
416+
if params and isinstance(params, dict):
417+
system_prompt = params.get("system")
418+
if system_prompt and isinstance(system_prompt, str):
419+
self.log.debug(
420+
f"Found model system prompt via body['model_info']['info']['params']['system'] ({len(system_prompt)} chars)"
421+
)
422+
return system_prompt.strip() or None
423+
except Exception as e:
424+
self.log.debug(f"Could not retrieve model system prompt from body: {e}")
363425

426+
self.log.debug("No model system prompt found in any source")
364427
return None
365428

366429
def _combine_system_prompts(
367430
self,
368431
chat_system_prompt: Optional[str],
369432
__user__: Optional[dict] = None,
370433
__model__: Optional[dict] = None,
434+
__metadata__: Optional[dict] = None,
435+
body: Optional[dict] = None,
371436
) -> Optional[str]:
372437
"""Combine default, model, and user system prompts.
373438
374439
Prompt hierarchy (all prompts are combined if set):
375440
1. DEFAULT_SYSTEM_PROMPT (environment/valve setting)
376-
2. Model system prompt (from model settings - __model__["info"]["system"])
441+
2. Model system prompt (from model settings)
377442
3. User system prompt (from chat controls OR user settings - chat controls take precedence)
378443
379444
Args:
380445
chat_system_prompt: The chat-level system prompt from messages (may be None)
381446
__user__: The user dict passed to the pipe method
382447
__model__: The model dict passed to the pipe method
448+
__metadata__: The metadata dict passed to the pipe method
449+
body: The request body
383450
384451
Returns:
385452
Combined system prompt or None if none are set
386453
"""
387454
default_prompt = self.valves.DEFAULT_SYSTEM_PROMPT.strip() or None
388-
model_prompt = self._get_model_system_prompt(__model__)
455+
model_prompt = self._get_model_system_prompt(__model__, __metadata__, body)
389456
user_personalization = self._get_user_personalization_prompt(__user__)
390457
chat_prompt = chat_system_prompt.strip() if chat_system_prompt else None
391458

@@ -498,6 +565,8 @@ async def _build_image_generation_contents(
498565
__event_emitter__: Callable,
499566
__user__: Optional[dict] = None,
500567
__model__: Optional[dict] = None,
568+
__metadata__: Optional[dict] = None,
569+
body: Optional[dict] = None,
501570
) -> Tuple[List[Dict[str, Any]], Optional[str]]:
502571
"""Construct the contents payload for image-capable models.
503572
@@ -511,7 +580,7 @@ async def _build_image_generation_contents(
511580

512581
# Combine with default system prompt if configured
513582
system_instruction = self._combine_system_prompts(
514-
user_system_instruction, __user__, __model__
583+
user_system_instruction, __user__, __model__, __metadata__, body
515584
)
516585

517586
last_user_msg = next(
@@ -975,6 +1044,8 @@ def _prepare_content(
9751044
messages: List[Dict[str, Any]],
9761045
__user__: Optional[dict] = None,
9771046
__model__: Optional[dict] = None,
1047+
__metadata__: Optional[dict] = None,
1048+
body: Optional[dict] = None,
9781049
) -> Tuple[List[Dict[str, Any]], Optional[str]]:
9791050
"""
9801051
Prepare messages content for the API and extract system message if present.
@@ -983,6 +1054,8 @@ def _prepare_content(
9831054
messages: List of message objects from the request
9841055
__user__: The user dict passed to the pipe method
9851056
__model__: The model dict passed to the pipe method
1057+
__metadata__: The metadata dict passed to the pipe method
1058+
body: The request body
9861059
9871060
Returns:
9881061
Tuple of (prepared content list, system message string or None)
@@ -995,7 +1068,7 @@ def _prepare_content(
9951068

9961069
# Combine with default system prompt if configured
9971070
system_message = self._combine_system_prompts(
998-
user_system_message, __user__, __model__
1071+
user_system_message, __user__, __model__, __metadata__, body
9991072
)
10001073

10011074
# Prepare contents for the API
@@ -2260,7 +2333,7 @@ async def pipe(
22602333
contents,
22612334
system_instruction,
22622335
) = await self._build_image_generation_contents(
2263-
messages, __event_emitter__, __user__, __model__
2336+
messages, __event_emitter__, __user__, __model__, __metadata__, body
22642337
)
22652338
# For image generation, system_instruction is integrated into the prompt
22662339
# so it will be None here (this is expected and correct)
@@ -2273,7 +2346,7 @@ async def pipe(
22732346
# For non-image generation models, use the full conversation history
22742347
# Prepare content and extract system message normally
22752348
contents, system_instruction = self._prepare_content(
2276-
messages, __user__, __model__
2349+
messages, __user__, __model__, __metadata__, body
22772350
)
22782351
if not contents:
22792352
return "Error: No valid message content found"

0 commit comments

Comments
 (0)