NOTICE
Open WebUI Community is currently undergoing a major revamp to improve user experience and performance ✨

Function
filter
v0.1.8
Busca_ML
Buscador de titulos
Function ID
busca_ml
Creator
@masterdan
Downloads
13+

Function Content
python
"""
title: AutoTool Filter
author: open-webui
author_url: https://github.com/open-webui
funding_url: https://github.com/open-webui
version: 0.1.8
required_open_webui_version: 0.3.8
"""

from pydantic import BaseModel, Field
from typing import Callable, Awaitable, Any, Optional, Literal
import json
import re
import requests  # Adicionado

from apps.webui.models.users import Users
from apps.webui.models.tools import Tools
from apps.webui.models.models import Models

from main import generate_chat_completions
from utils.misc import get_last_user_message


class Filter:
    class Valves(BaseModel):
        template: str = Field(
            default="""Tools: 
If a tool doesn't match the query, return an empty list []. Otherwise, return a list of matching tool IDs in the format ["tool_id"]. Select multiple tools if applicable. Only return the list. Do not return any other text only the list. Review the entire chat history to ensure the selected tool matches the context. If unsure, default to an empty list []. Use tools conservatively."""
        )
        status: bool = Field(default=False)
        pass

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

    def buscar_titulos_mercado_livre(self, query: str) -> dict:
        url = "https://api.mercadolibre.com/sites/MLB/search"
        params = {"q": query, "limit": 50}

        try:
            response = requests.get(url, params=params)
            response.raise_for_status()
            data = response.json()
            titulos = [item["title"] for item in data.get("results", [])]
            return {"titulos": titulos}
        except requests.exceptions.RequestException as e:
            return {"error": str(e)}

    async def inlet(
        self,
        body: dict,
        __event_emitter__: Callable[[Any], Awaitable[None]],
        __user__: Optional[dict] = None,
        __model__: Optional[dict] = None,
    ) -> dict:
        messages = body["messages"]
        user_message = get_last_user_message(messages)

        # Chamada à função de busca no Mercado Livre
        busca_resultado = self.buscar_titulos_mercado_livre(user_message)
        
        if "error" in busca_resultado:
            if self.valves.status:
                await __event_emitter__(
                    {
                        "type": "status",
                        "data": {
                            "description": f"Erro na busca: {busca_resultado['error']}",
                            "done": True,
                        },
                    }
                )
        else:
            titulos = busca_resultado["titulos"]
            print(f"Títulos encontrados: {titulos}")
            # Exemplo: adicionar os títulos ao body ou realizar outra lógica

        if self.valves.status:
            await __event_emitter__(
                {
                    "type": "status",
                    "data": {
                        "description": "Finding the right tools...",
                        "done": False,
                    },
                }
            )

        all_tools = [
            {"id": tool.id, "description": tool.meta.description}
            for tool in Tools.get_tools()
        ]
        available_tool_ids = (
            __model__.get("info", {}).get("meta", {}).get("toolIds", [])
        )
        available_tools = [
            tool for tool in all_tools if tool["id"] in available_tool_ids
        ]

        system_prompt = self.valves.template.replace("", str(available_tools))
        prompt = (
            "History:\n"
            + "\n".join(
                [
                    f"{message['role'].upper()}: \"\"\"{message['content']}\"\"\""
                    for message in messages[::-1][:4]
                ]
            )
            + f"\nQuery: {user_message}"
        )

        payload = {
            "model": body["model"],
            "messages": [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": prompt},
            ],
            "stream": False,
        }

        try:
            user = Users.get_user_by_id(__user__["id"])
            response = await generate_chat_completions(form_data=payload, user=user)
            content = response["choices"][0]["message"]["content"]

            # Parse the function response
            if content is not None:
                print(f"content: {content}")
                content = content.replace("'", '"')

                pattern = r"$$.*?$$"
                match = re.search(pattern, content)

                if match:
                    content = str(match.group(0))

                result = json.loads(content)

                if isinstance(result, list) and len(result) > 0:
                    body["tool_ids"] = result
                    if self.valves.status:
                        await __event_emitter__(
                            {
                                "type": "status",
                                "data": {
                                    "description": f"Found matching tools: {', '.join(result)}",
                                    "done": True,
                                },
                            }
                        )
                else:
                    if self.valves.status:
                        await __event_emitter__(
                            {
                                "type": "status",
                                "data": {
                                    "description": "No matching tools found.",
                                    "done": True,
                                },
                            }
                        )

        except Exception as e:
            print(e)
            if self.valves.status:
                await __event_emitter__(
                    {
                        "type": "status",
                        "data": {
                            "description": f"Error processing request: {e}",
                            "done": True,
                        },
                    }
                )
            pass

        return body