|
4 | 4 | author_url: https://github.com/owndev/ |
5 | 5 | project_url: https://github.com/owndev/Open-WebUI-Functions |
6 | 6 | funding_url: https://github.com/sponsors/owndev |
7 | | -version: 1.8.1 |
| 7 | +version: 1.8.2 |
8 | 8 | required_open_webui_version: 0.6.26 |
9 | 9 | license: Apache License 2.0 |
10 | 10 | description: Highly optimized Google Gemini pipeline with advanced image generation capabilities, intelligent compression, and streamlined processing workflows. |
|
34 | 34 | - Flexible upload fallback options and optimization controls |
35 | 35 | - Configurable thinking levels (low/high) for Gemini 3 models |
36 | 36 | - Configurable thinking budgets (0-32768 tokens) for Gemini 2.5 models |
| 37 | + - Hierarchical system prompts (default, per-user personalization, per-chat) |
37 | 38 | """ |
38 | 39 |
|
39 | 40 | import os |
@@ -289,38 +290,67 @@ def _deduplicate_images(self, images: List[Dict[str, Any]]) -> List[Dict[str, An |
289 | 290 | result.append(part) |
290 | 291 | return result |
291 | 292 |
|
| 293 | + def _get_user_personalization_prompt(self) -> Optional[str]: |
| 294 | + """Get the per-user system prompt from user settings (Personalization). |
| 295 | +
|
| 296 | + In Open WebUI, users can configure a personalized system prompt |
| 297 | + in Settings > Personalization. This is stored in user.info.system. |
| 298 | +
|
| 299 | + Returns: |
| 300 | + The user's personalized system prompt or None if not set |
| 301 | + """ |
| 302 | + if not hasattr(self, "user") or self.user is None: |
| 303 | + return None |
| 304 | + |
| 305 | + try: |
| 306 | + user_info = self.user.info |
| 307 | + if user_info and isinstance(user_info, dict): |
| 308 | + system_prompt = user_info.get("system") |
| 309 | + if system_prompt and isinstance(system_prompt, str): |
| 310 | + return system_prompt.strip() or None |
| 311 | + except Exception as e: |
| 312 | + self.log.debug(f"Could not retrieve user personalization prompt: {e}") |
| 313 | + |
| 314 | + return None |
| 315 | + |
292 | 316 | def _combine_system_prompts( |
293 | | - self, user_system_prompt: Optional[str] |
| 317 | + self, chat_system_prompt: Optional[str] |
294 | 318 | ) -> Optional[str]: |
295 | | - """Combine default system prompt with user-defined system prompt. |
| 319 | + """Combine default, per-user, and chat-level system prompts. |
296 | 320 |
|
297 | | - If DEFAULT_SYSTEM_PROMPT is set and user_system_prompt exists, |
298 | | - the default is prepended to the user's prompt. |
299 | | - If only DEFAULT_SYSTEM_PROMPT is set, it is used as the system prompt. |
300 | | - If only user_system_prompt is set, it is used as-is. |
| 321 | + Prompt hierarchy (all prompts are combined if set): |
| 322 | + 1. DEFAULT_SYSTEM_PROMPT (environment/valve setting) |
| 323 | + 2. Per-user system prompt (from user.info.system - Personalization settings) |
| 324 | + 3. Chat-level system prompt (from messages in this request) |
301 | 325 |
|
302 | 326 | Args: |
303 | | - user_system_prompt: The user-defined system prompt from messages (may be None) |
| 327 | + chat_system_prompt: The chat-level system prompt from messages (may be None) |
304 | 328 |
|
305 | 329 | Returns: |
306 | | - Combined system prompt or None if neither is set |
| 330 | + Combined system prompt or None if none are set |
307 | 331 | """ |
308 | 332 | default_prompt = self.valves.DEFAULT_SYSTEM_PROMPT.strip() |
309 | | - user_prompt = user_system_prompt.strip() if user_system_prompt else "" |
| 333 | + user_personalization = self._get_user_personalization_prompt() or "" |
| 334 | + chat_prompt = chat_system_prompt.strip() if chat_system_prompt else "" |
310 | 335 |
|
311 | | - if default_prompt and user_prompt: |
312 | | - combined = f"{default_prompt}\n\n{user_prompt}" |
313 | | - self.log.debug( |
314 | | - f"Combined system prompts: default ({len(default_prompt)} chars) + " |
315 | | - f"user ({len(user_prompt)} chars) = {len(combined)} chars" |
316 | | - ) |
317 | | - return combined |
318 | | - elif default_prompt: |
319 | | - self.log.debug(f"Using default system prompt ({len(default_prompt)} chars)") |
320 | | - return default_prompt |
321 | | - elif user_prompt: |
322 | | - return user_prompt |
323 | | - return None |
| 336 | + prompts = [p for p in [default_prompt, user_personalization, chat_prompt] if p] |
| 337 | + |
| 338 | + if not prompts: |
| 339 | + return None |
| 340 | + |
| 341 | + if len(prompts) == 1: |
| 342 | + self.log.debug(f"Using single system prompt ({len(prompts[0])} chars)") |
| 343 | + return prompts[0] |
| 344 | + |
| 345 | + combined = "\n\n".join(prompts) |
| 346 | + self.log.debug( |
| 347 | + f"Combined system prompts: " |
| 348 | + f"default={len(default_prompt) if default_prompt else 0}, " |
| 349 | + f"user_personalization={len(user_personalization) if user_personalization else 0}, " |
| 350 | + f"chat={len(chat_prompt) if chat_prompt else 0} -> " |
| 351 | + f"total={len(combined)} chars" |
| 352 | + ) |
| 353 | + return combined |
324 | 354 |
|
325 | 355 | def _apply_order_and_limit( |
326 | 356 | self, |
|
0 commit comments