aiagent_playground/openwebui/pipelines/deepresearch/smolagent_deepresearch.py
2025-02-24 11:59:54 +00:00

177 lines
5.8 KiB
Python

"""
title: SmolAgents Deep Research Pipeline
author: elabbarw, aymeric-roucher & albertvillanova
author_url: https://github.com/elabbarw
original_author_url: https://github.com/huggingface/smolagents
git_url: https://github.com/elabbarw/aiagent_playground/blob/main/openwebui/pipelines/deepresearch/smolagent_deepresearch.py
date: 2024-02-11
version: 0.1.0
license: MIT
description: A pipeline to kick off deep research - install requirements directly in pipelines shell or through docker-compose
"""
import os
import threading
from pydantic import BaseModel, Field
from typing import Optional, Union, Generator, Iterator
from dotenv import load_dotenv
from scripts.text_inspector_tool import TextInspectorTool
from scripts.text_web_browser import (
ArchiveSearchTool,
FinderTool,
FindNextTool,
PageDownTool,
PageUpTool,
SearchInformationTool,
SimpleTextBrowser,
VisitTool,
)
from scripts.visual_qa import visualizer
from smolagents import (
CodeAgent,
ToolCallingAgent,
OpenAIServerModel,
)
AUTHORIZED_IMPORTS = [
"requests",
"zipfile",
"os",
"pandas",
"numpy",
"sympy",
"json",
"bs4",
"pubchempy",
"xml",
"yahoo_finance",
"Bio",
"sklearn",
"scipy",
"pydub",
"io",
"PIL",
"chess",
"PyPDF2",
"pptx",
"torch",
"datetime",
"fractions",
"csv",
]
load_dotenv(override=True)
append_answer_lock = threading.Lock()
custom_role_conversions = {"tool-call": "assistant", "tool-response": "user"}
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0"
class Pipeline:
class Valves(BaseModel):
# Add any valves parameters if needed.
OPENAI_BASE_URL: str = Field(
default="", description="OpenAI Base URL")
OPENAI_API_KEY: str = Field(
default="", description="OpenAI Key")
OPENAI_MODEL: str = Field(
default="", description="Model to use")
SERPAPI_API_KEY: Optional[str] = Field(
default="", description="The SERP API Key if required"
)
BING_API_KEY: Optional[str] = Field(
default="", description="The BING API Key if required"
)
GOOGLE_API_KEY: Optional[str] = Field(
default="", description="The Google Search API Key if required"
)
GOOGLE_API_CX: Optional[str] = Field(
default="", description="The Google Search CX Key if required"
)
pass
def __init__(self):
self.valves = self.Valves()
self.BROWSER_CONFIG = {
"viewport_size": 1024 * 5,
"downloads_folder": "downloads_folder",
"request_kwargs": {
"headers": {"User-Agent": user_agent},
"timeout": 300,
},
"serpapi_key": self.valves.SERPAPI_API_KEY,
"bingapi_key": self.valves.BING_API_KEY,
"googleapi_key": self.valves.GOOGLE_API_KEY,
"googleapi_cx": self.valves.GOOGLE_API_CX
}
os.makedirs(f"./{self.BROWSER_CONFIG['downloads_folder']}", exist_ok=True)
def pipe(self,
body: dict,
messages: list[dict],
user_message: str,
model_id: str,
) -> Union[str, Generator, Iterator]:
incomingmessages = "\n".join([f"{message['role']}: {message['content']}" for message in messages])
text_limit = 100000
model = OpenAIServerModel(
api_base=self.valves.OPENAI_BASE_URL,
api_key=self.valves.OPENAI_API_KEY,
model_id=self.valves.OPENAI_MODEL
)
document_inspection_tool = TextInspectorTool(model, text_limit)
browser = SimpleTextBrowser(**self.BROWSER_CONFIG)
WEB_TOOLS = [
SearchInformationTool(browser),
VisitTool(browser),
PageUpTool(browser),
PageDownTool(browser),
FinderTool(browser),
FindNextTool(browser),
ArchiveSearchTool(browser),
TextInspectorTool(model, text_limit),
]
text_webbrowser_agent = ToolCallingAgent(
model=model,
tools=WEB_TOOLS,
max_steps=20,
verbosity_level=2,
planning_interval=4,
name="search_agent",
description="""A team member that will search the internet to answer your question.
Ask him for all your questions that require browsing the web.
Provide him as much context as possible, in particular if you need to search on a specific timeframe!
And don't hesitate to provide him with a complex search task, like finding a difference between two webpages.
Your request must be a real sentence, not a google search! Like "Find me this information (...)" rather than a few keywords.
""",
provide_run_summary=True,
)
text_webbrowser_agent.prompt_templates["managed_agent"]["task"] += """You can navigate to .txt online files.
If a non-html page is in another format, especially .pdf or a Youtube video, use tool 'inspect_file_as_text' to inspect it.
Additionally, if after some searching you find out that you need more information to answer the question, you can use `final_answer` with your request for clarification as argument to request for more information."""
manager_agent = CodeAgent(
model=model,
tools=[visualizer, document_inspection_tool],
max_steps=12,
verbosity_level=2,
additional_authorized_imports=AUTHORIZED_IMPORTS,
planning_interval=4,
managed_agents=[text_webbrowser_agent],
)
answer = manager_agent.run(incomingmessages)
yield f"Got this answer: {answer}"