[PR #16423] enh: Functions/Tools & Valves additional gimmicks #47174

Open
opened 2026-04-29 22:16:40 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/open-webui/open-webui/pull/16423
Author: @Rain6435
Created: 8/9/2025
Status: 🔄 Open

Base: devHead: feature/issue-5486-valves-enhancements


📝 Commits (3)

  • 4fb7402 feat: implement all valve enhancements from issue #5486
  • ca101b5 fix: format code with Black and Prettier for CI compliance
  • 34e7ef1 Merge branch 'dev' into feature/issue-5486-valves-enhancements

📊 Changes

8 files changed (+591 additions, -52 deletions)

View changed files

📝 backend/open_webui/routers/functions.py (+57 -0)
📝 backend/open_webui/routers/tools.py (+39 -0)
backend/open_webui/utils/function_logging.py (+83 -0)
📝 backend/open_webui/utils/models.py (+10 -0)
📝 backend/open_webui/utils/plugin.py (+28 -0)
backend/open_webui/utils/valve_helpers.py (+91 -0)
📝 src/lib/components/common/Valves.svelte (+184 -20)
📝 src/lib/components/workspace/common/ValvesModal.svelte (+99 -32)

📄 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:

  • Target branch: Please verify that the pull request targets the dev branch.

  • 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: Have you updated relevant documentation Open WebUI Docs, or other documentation sources?

  • Dependencies: Are there any new dependencies? Have you updated the dependency versions in the documentation?

  • Testing: Have you written and run sufficient tests to validate the changes?

  • 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?

  • 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 implements all 10 valve enhancements requested in issue #5486, significantly expanding the valve system for Functions and Tools with new input types, callbacks, logging, and user experience improvements.

Added

  • Added on_valves_updated callback support for Functions/Tools (similar to pipelines)
  • Implemented valve self-updating capability from within function code via injected helper functions
  • Added icon_url_dark support for Actions to enable proper light/dark theme compatibility
  • Implemented comprehensive logging system specifically for functions and tools
  • Added new valve input types:
    • Comboboxes (single-select dropdown with predefined options)
    • Listview (multi-select dropdown for array values)
    • Sliders for numeric values with min/max/step configuration
    • Multiline textbox for longer text inputs
    • Static text components for read-only information display
  • Implemented valve pinning functionality allowing users to pin frequently used valves to appear first
  • Added animated save button loader with smooth CSS transitions
  • Enhanced valve specification system to support custom get_valve_spec() methods
  • Added proper array handling for multi-select valve inputs

Fixed

  • Fixed array conversion logic that was interfering with non-array valve types
  • Fixed save button spinner getting stuck on API errors
  • Fixed conditional rendering for textbox inputs in valve components

Additional Information

Fixes #5486

Test Plan

  • Create a test function using the test function provided in this PR.

"""
Test function to demonstrate all new valve features from issue #5486
Place this file in your functions directory to test the enhancements.
"""

from pydantic import BaseModel, Field
from typing import Optional, List


def on_valves_updated(valve_data):
    """Test the new on_valves_updated callback"""
    log.info(f"Valves were updated with data: {valve_data}")
    
    # Temporarily disabled to test basic valve functionality
    # Test self-updating valves - only auto-update temperature when model_provider is being changed to openai
    # if "model_provider" in valve_data and valve_data.get("model_provider") == "openai":
    #     # Only auto-update if temperature wasn't manually set in this same update
    #     if "temperature" not in valve_data:
    #         update_valves({"temperature": 0.5})
    #         log.info("Auto-updated temperature to 0.5 when switching to OpenAI")


class Pipe:
    class Valves(BaseModel):
        # Combobox (dropdown with predefined options)
        model_provider: str = Field(default="openai", description="Choose your model provider")
        
        # Listview (multi-select dropdown)
        enabled_features: List[str] = Field(default=["feature1", "feature2"], description="Select multiple features")
        
        # Slider for numeric values
        temperature: float = Field(default=0.7, description="Model temperature")
        max_tokens: int = Field(default=1000, description="Maximum tokens")
        
        # Multiline textbox
        system_prompt: str = Field(default="You are a helpful assistant.\nProvide detailed responses.", description="System prompt")
        
        # Static text component (read-only)
        info_text: str = Field(default="This is informational text that cannot be edited.", description="Information")

    def __init__(self):
        self.valves = self.Valves()

    def get_valve_spec(self):
        return {
            "type": "object",
            "properties": {
                "model_provider": {
                    "type": "string",
                    "title": "Model Provider",
                    "description": "Choose your model provider",
                    "enum": ["openai", "anthropic", "google", "microsoft"],
                    "input": {
                        "type": "combobox"
                    }
                },
                "enabled_features": {
                    "type": "array",
                    "title": "Enabled Features", 
                    "description": "Select multiple features to enable",
                    "enum": ["feature1", "feature2", "feature3", "feature4", "feature5"],
                    "input": {
                        "type": "listview"
                    }
                },
                "temperature": {
                    "type": "number",
                    "title": "Temperature",
                    "description": "Model temperature (0.0 to 2.0)",
                    "minimum": 0.0,
                    "maximum": 2.0,
                    "step": 0.1,
                    "input": {
                        "type": "slider"
                    }
                },
                "max_tokens": {
                    "type": "integer", 
                    "title": "Max Tokens",
                    "description": "Maximum tokens to generate",
                    "minimum": 100,
                    "maximum": 4000,
                    "step": 100,
                    "input": {
                        "type": "slider"
                    }
                },
                "system_prompt": {
                    "type": "string",
                    "title": "System Prompt",
                    "description": "Multi-line system prompt",
                    "input": {
                        "type": "textbox",
                        "rows": 4
                    }
                },
                "info_text": {
                    "type": "string",
                    "title": "Information",
                    "description": "Read-only information text",
                    "default": "This is informational text that cannot be edited.",
                    "input": {
                        "type": "static"
                    }
                }
            }
        }

    def pipe(self, body: dict) -> str:
        """Test function that uses the new logging and valve features"""
        
        log.info(f"Function called with provider: {self.valves.model_provider}")
        log.info(f"Enabled features: {self.valves.enabled_features}")
        log.info(f"Temperature: {self.valves.temperature}, Max tokens: {self.valves.max_tokens}")
        
        # Test getting current valves
        current_valves = get_valves()
        log.debug(f"Current valves: {current_valves}")
        
        return f"Test function executed successfully with valves: {self.valves.model_provider}"

  • Verify all new valve input types render correctly (combobox, listview, sliders, textbox, static text)
  • Test valve pinning functionality persists across browser sessions
  • Verify on_valves_updated callback is triggered on valve changes
  • Test valve self-updating functionality with injected helper functions
  • Verify animated save button loader works correctly
  • Test proper logging output for functions and tools
  • Verify array handling works correctly for multi-select inputs

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/16423 **Author:** [@Rain6435](https://github.com/Rain6435) **Created:** 8/9/2025 **Status:** 🔄 Open **Base:** `dev` ← **Head:** `feature/issue-5486-valves-enhancements` --- ### 📝 Commits (3) - [`4fb7402`](https://github.com/open-webui/open-webui/commit/4fb7402cb544bb049e46e78e089db852048829f3) feat: implement all valve enhancements from issue #5486 - [`ca101b5`](https://github.com/open-webui/open-webui/commit/ca101b5ea725cf08cb59ce29c25ad24ef448e65a) fix: format code with Black and Prettier for CI compliance - [`34e7ef1`](https://github.com/open-webui/open-webui/commit/34e7ef17cc67c4a691b6844e87fcfffc49c84ffd) Merge branch 'dev' into feature/issue-5486-valves-enhancements ### 📊 Changes **8 files changed** (+591 additions, -52 deletions) <details> <summary>View changed files</summary> 📝 `backend/open_webui/routers/functions.py` (+57 -0) 📝 `backend/open_webui/routers/tools.py` (+39 -0) ➕ `backend/open_webui/utils/function_logging.py` (+83 -0) 📝 `backend/open_webui/utils/models.py` (+10 -0) 📝 `backend/open_webui/utils/plugin.py` (+28 -0) ➕ `backend/open_webui/utils/valve_helpers.py` (+91 -0) 📝 `src/lib/components/common/Valves.svelte` (+184 -20) 📝 `src/lib/components/workspace/common/ValvesModal.svelte` (+99 -32) </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:** Please verify that the pull request targets the `dev` branch. * [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. * [x] **Documentation:** Have you updated relevant documentation [Open WebUI Docs](https://github.com/open-webui/docs), or other documentation sources? * [x] **Dependencies:** Are there any new dependencies? Have you updated the dependency versions in the documentation? * [x] **Testing:** Have you written and run sufficient tests to validate the changes? * [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] **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 implements all 10 valve enhancements requested in issue #5486, significantly expanding the valve system for Functions and Tools with new input types, callbacks, logging, and user experience improvements. ### Added * Added `on_valves_updated` callback support for Functions/Tools (similar to pipelines) * Implemented valve self-updating capability from within function code via injected helper functions * Added `icon_url_dark` support for Actions to enable proper light/dark theme compatibility * Implemented comprehensive logging system specifically for functions and tools * Added new valve input types: - Comboboxes (single-select dropdown with predefined options) - Listview (multi-select dropdown for array values) - Sliders for numeric values with min/max/step configuration - Multiline textbox for longer text inputs - Static text components for read-only information display * Implemented valve pinning functionality allowing users to pin frequently used valves to appear first * Added animated save button loader with smooth CSS transitions * Enhanced valve specification system to support custom `get_valve_spec()` methods * Added proper array handling for multi-select valve inputs ### Fixed * Fixed array conversion logic that was interfering with non-array valve types * Fixed save button spinner getting stuck on API errors * Fixed conditional rendering for textbox inputs in valve components ### Additional Information Fixes #5486 ### Test Plan * Create a test function using the test function provided in this PR. ```python """ Test function to demonstrate all new valve features from issue #5486 Place this file in your functions directory to test the enhancements. """ from pydantic import BaseModel, Field from typing import Optional, List def on_valves_updated(valve_data): """Test the new on_valves_updated callback""" log.info(f"Valves were updated with data: {valve_data}") # Temporarily disabled to test basic valve functionality # Test self-updating valves - only auto-update temperature when model_provider is being changed to openai # if "model_provider" in valve_data and valve_data.get("model_provider") == "openai": # # Only auto-update if temperature wasn't manually set in this same update # if "temperature" not in valve_data: # update_valves({"temperature": 0.5}) # log.info("Auto-updated temperature to 0.5 when switching to OpenAI") class Pipe: class Valves(BaseModel): # Combobox (dropdown with predefined options) model_provider: str = Field(default="openai", description="Choose your model provider") # Listview (multi-select dropdown) enabled_features: List[str] = Field(default=["feature1", "feature2"], description="Select multiple features") # Slider for numeric values temperature: float = Field(default=0.7, description="Model temperature") max_tokens: int = Field(default=1000, description="Maximum tokens") # Multiline textbox system_prompt: str = Field(default="You are a helpful assistant.\nProvide detailed responses.", description="System prompt") # Static text component (read-only) info_text: str = Field(default="This is informational text that cannot be edited.", description="Information") def __init__(self): self.valves = self.Valves() def get_valve_spec(self): return { "type": "object", "properties": { "model_provider": { "type": "string", "title": "Model Provider", "description": "Choose your model provider", "enum": ["openai", "anthropic", "google", "microsoft"], "input": { "type": "combobox" } }, "enabled_features": { "type": "array", "title": "Enabled Features", "description": "Select multiple features to enable", "enum": ["feature1", "feature2", "feature3", "feature4", "feature5"], "input": { "type": "listview" } }, "temperature": { "type": "number", "title": "Temperature", "description": "Model temperature (0.0 to 2.0)", "minimum": 0.0, "maximum": 2.0, "step": 0.1, "input": { "type": "slider" } }, "max_tokens": { "type": "integer", "title": "Max Tokens", "description": "Maximum tokens to generate", "minimum": 100, "maximum": 4000, "step": 100, "input": { "type": "slider" } }, "system_prompt": { "type": "string", "title": "System Prompt", "description": "Multi-line system prompt", "input": { "type": "textbox", "rows": 4 } }, "info_text": { "type": "string", "title": "Information", "description": "Read-only information text", "default": "This is informational text that cannot be edited.", "input": { "type": "static" } } } } def pipe(self, body: dict) -> str: """Test function that uses the new logging and valve features""" log.info(f"Function called with provider: {self.valves.model_provider}") log.info(f"Enabled features: {self.valves.enabled_features}") log.info(f"Temperature: {self.valves.temperature}, Max tokens: {self.valves.max_tokens}") # Test getting current valves current_valves = get_valves() log.debug(f"Current valves: {current_valves}") return f"Test function executed successfully with valves: {self.valves.model_provider}" ``` * Verify all new valve input types render correctly (combobox, listview, sliders, textbox, static text) * Test valve pinning functionality persists across browser sessions * Verify `on_valves_updated` callback is triggered on valve changes * Test valve self-updating functionality with injected helper functions * Verify animated save button loader works correctly * Test proper logging output for functions and tools * Verify array handling works correctly for multi-select inputs ### Contributor License Agreement By submitting this pull request, I confirm that I have read and fully agree to the [Contributor License Agreement (CLA)](/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>
GiteaMirror added the pull-request label 2026-04-29 22:16:40 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#47174