NOTICE
Open WebUI Community is currently undergoing a major revamp to improve user experience and performance. Expected completion by year-end! ✨

Function
filter
v1.0
Myzer
Minimise token count by stripping unnecessary white space and padding words, and optionally automatically request a concise answer. Minimising token count will (should) increase answer speed on low-powered GPU/CPU installs, and reduce costs on paid-for LLMs.
Function ID
myzer
Creator
@mgscox
Downloads
547+

Function Content
python
"""
title: Myzer - token minimiser
author: mgscox
author_url: 
funding_url: 
version: 1.0
"""

from pydantic import BaseModel, Field
from typing import Optional
import time
import re


class Filter:
    class Valves(BaseModel):
        CONCISE_MYZER: bool = Field(
            default=False, description="Automatically request a concise answer."
        )
        pass

    def __init__(self):
        # Indicates custom file handling logic. This flag helps disengage default routines in favor of custom
        # implementations, informing the WebUI to defer file-related operations to designated methods within this class.
        # Alternatively, you can remove the files directly from the body in from the inlet hook
        # self.file_handler = True

        # Initialize 'valves' with specific configurations. Using 'Valves' instance helps encapsulate settings,
        # which ensures settings are managed cohesively and not confused with operational flags like 'file_handler'.
        self.valves = self.Valves()
        pass

    def inlet(self, body: dict, __user__: Optional[dict] = None) -> dict:
        # Modify the request body or validate it before processing by the chat completion API.
        # This function is the pre-processor for the API where various checks on the input can be performed.
        # It can also modify the request before sending it to the API.
        print(f"inlet:{__name__}")
        print(f"inlet:body:{body}")
        print(f"inlet:user:{__user__}")

        if __user__.get("role", "admin") in ["user", "admin"]:
            start_time = time.time()
            # List of common words to strip from input
            # Do not include words which might change the meaning of the request if not proesent
            COMMON_WORDS = set(
                """a,an,the,is,are,was,were,can,am,has,been,be,of,and,it,in,to,for,on,at,by,as,or,if,but,so,yet""".split(
                    ","
                )
            )

            messages = body.get("messages", [])

            for message in messages:
                if message.get("role") == "user":

                    if self.valves.CONCISE_MYZER:
                        message[
                            "content"
                        ] += ". Be concise. Do NOT provide any explanation."

                    message["content"] = " ".join(
                        [
                            word
                            for word in message["content"].split()
                            if word.lower() not in COMMON_WORDS
                        ]
                    )
                    message["content"] = re.sub(
                        r"\s+", " ", re.sub(r"[^\w\s.!?]", "", message["content"])
                    ).strip()

            print(f"Myzer processed in: {time.time() - start_time:.6f}s")

        return body

    def outlet(self, body: dict, __user__: Optional[dict] = None) -> dict:
        # Modify or analyze the response body after processing by the API.
        # This function is the post-processor for the API, which can be used to modify the response
        # or perform additional checks and analytics.
        print(f"outlet:{__name__}")
        print(f"outlet:body:{body}")
        print(f"outlet:user:{__user__}")

        return body