File size: 5,008 Bytes
632bae9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c5bb770
 
632bae9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c5bb770
632bae9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c5bb770
632bae9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c5bb770
632bae9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import os
from typing import List, Optional, Tuple

from langchain.agents import Tool
from langchain_community.agent_toolkits import (
    FileManagementToolkit,
    PlayWrightBrowserToolkit,
)
from langchain_community.tools.arxiv.tool import ArxivQueryRun
from langchain_community.tools.wikipedia.tool import WikipediaQueryRun
from langchain_community.utilities import ArxivAPIWrapper, GoogleSerperAPIWrapper
from langchain_community.utilities.wikipedia import WikipediaAPIWrapper
from langchain_experimental.tools import PythonREPLTool
from playwright.async_api import async_playwright
from sympy import SympifyError, sympify

from config import SANDBOX_DIR


# Custom math tool
def safe_math_calculator(expression: str) -> str:
    """Safely evaluate mathematical expressions using sympy."""
    try:
        result = sympify(expression).evalf()
        return str(result)
    except (SympifyError, Exception) as e:
        return f"Error: Unable to evaluate expression '{expression}'. {str(e)}"


def create_search_tool() -> Optional[Tool]:
    """Create a web search tool"""
    try:
        serper = GoogleSerperAPIWrapper()
        return Tool(
            name="search",
            func=serper.run,
            description="Use this tool when you want to get the results of an online web search",
        )
    except Exception as e:
        print(f"Warning: Could not initialize search tool: {e}")
        return None


def create_math_tool() -> List[Tool]:
    """Create mathematical calculation tools."""
    return [
        Tool(
            name="calculator",
            func=safe_math_calculator,
            description="Use this tool when you want to do math, provide the expression as a string",
        )
    ]


def create_file_tools(root_dir: str = SANDBOX_DIR) -> List[Tool]:
    """Create file management tools"""
    try:
        # Ensure the directory exists
        os.makedirs(root_dir, exist_ok=True)
        toolkit = FileManagementToolkit(root_dir=root_dir)
        return toolkit.get_tools()
    except Exception as e:
        print(f"Warning: Could not initialize file tools: {e}")
        return []


def create_wikipedia_tool() -> Optional[Tool]:
    """Create Wikipedia search tool"""
    try:
        wikipedia = WikipediaAPIWrapper()
        return WikipediaQueryRun(api_wrapper=wikipedia)
    except Exception as e:
        print(f"Warning: Could not initialize Wikipedia tool: {e}")
        return None


def create_arxiv_tool() -> Optional[Tool]:
    """Create ArXiv search tool"""
    try:
        return ArxivQueryRun(api_wrapper=ArxivAPIWrapper())
    except Exception as e:
        print(f"Warning: Could not initialize ArXiv tool: {e}")
        return None


def create_python_repl_tool() -> Optional[Tool]:
    """Create Python REPL tool"""
    try:
        return PythonREPLTool()
    except Exception as e:
        print(f"Warning: Could not initialize Python REPL tool: {e}")
        return None


async def create_playwright_tools() -> (
    Tuple[List[Tool], Optional[object], Optional[object]]
):
    """Create Playwright browser tools"""
    try:
        playwright = await async_playwright().start()
        browser = await playwright.chromium.launch(headless=False)
        toolkit = PlayWrightBrowserToolkit.from_browser(async_browser=browser)
        return toolkit.get_tools(), browser, playwright
    except Exception as e:
        print(f"Warning: Could not initialize Playwright tools: {e}")
        return [], None, None


def get_tools(sandbox_dir: str = SANDBOX_DIR) -> List[Tool]:
    """
    Get all available tools.

    Args:
        sandbox_dir: Directory for file operations (default: "sandbox")

    Returns:
        List of initialized tools
    """
    tools = []

    # Add file management tools
    file_tools = create_file_tools(sandbox_dir)
    tools.extend(file_tools)

    # Add search tool
    search_tool = create_search_tool()
    if search_tool:
        tools.append(search_tool)

    # Add math tools
    math_tool = create_math_tool()
    tools.extend(math_tool)

    # Add Wikipedia tool
    wiki_tool = create_wikipedia_tool()
    if wiki_tool:
        tools.append(wiki_tool)

    # Add Python REPL tool
    python_tool = create_python_repl_tool()
    if python_tool:
        tools.append(python_tool)

    # Add ArXiv tool
    arxiv_tool = create_arxiv_tool()
    if arxiv_tool:
        tools.append(arxiv_tool)

    return tools


async def get_all_tools_with_browser(
    sandbox_dir: str = SANDBOX_DIR,
) -> Tuple[List[Tool], Optional[object], Optional[object]]:
    """
    Get all tools including browser tools.

    Args:
        sandbox_dir: Directory for file operations (default: "sandbox")

    Returns:
        Tuple of (tools_list, browser_instance, playwright_instance)
    """
    # Get basic tools
    tools = get_tools(sandbox_dir)

    # Add browser tools
    browser_tools, browser, playwright = await create_playwright_tools()
    tools.extend(browser_tools)

    return tools, browser, playwright