File size: 6,865 Bytes
d26c7f3
 
 
cc6bd3b
 
 
d26c7f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
from llama_index.core.tools import FunctionTool
from llama_index.tools.duckduckgo import DuckDuckGoSearchToolSpec

import pint
import sympy as sp


class _Math:

    @staticmethod
    def symbolic_calc(expression: str) -> str:
        """
        Evaluates complex mathematical expressions using SymPy.
        
        Args:
            expression: Mathematical expression as string
        
        Returns:
            Result of the calculation
        """
        print(f"-> symbolic_math_calculator tool used (input: {expression}) !")
        try:
            result = sp.sympify(expression)
            print(f"-> (output: {result}) !")
            return str(result)
        except Exception as e:
            return f"Error in calculation: {str(e)}"

    @staticmethod
    def unit_converter(value: float, from_unit: str, to_unit: str) -> str:
        """
        Converts values between different units of measurement.
        
        Args:
            value: The numerical value to convert
            from_unit: The source unit (e.g., 'meter', 'kg', 'celsius')
            to_unit: The target unit (e.g., 'feet', 'pound', 'fahrenheit')
        
        Returns:
            The converted value with appropriate units
        """
        print(f"-> unit_converter tool used (inputs: [value: {value}, from_unit: {from_unit}, to_unit: {to_unit}]) !")
        try:
            # Create unit registry
            ureg = pint.UnitRegistry()
            
            # Create quantity with source unit
            quantity = value * ureg(from_unit)
            
            # Convert to target unit
            result = quantity.to(to_unit)
            
            answer = f"{value} {from_unit} = {result.magnitude} {to_unit}"
            print(f"-> (output: {result}) !")
            return answer
        except Exception as e:
            return f"Error in unit conversion: {str(e)}"


class _MathToolbox:
    symbolic_calc = FunctionTool.from_defaults(
        name="symbolic_calc",
        description="Evaluates complex mathematical expressions using SymPy",
        fn=_Math.symbolic_calc
    )
    unit_converter = FunctionTool.from_defaults(
        name="unit_converter",
        description="Converts values between different units of measurement",
        fn=_Math.unit_converter
    )


class _WebSearchToolbox:
    duck_duck_go_tools = DuckDuckGoSearchToolSpec().to_tool_list()


class _Encryption:

    @staticmethod
    def base64_encode(text: str) -> str:
        """
        Encodes a string to base64.
        
        Args:
            text: The text to encode
            
        Returns:
            Base64 encoded string
        """
        print(f"-> base64_encode tool used (input: {text[:30]}...) !")
        import base64
        try:
            encoded_bytes = base64.b64encode(text.encode('utf-8'))
            encoded_text = encoded_bytes.decode('utf-8')
            print(f"-> (output: {encoded_text[:30]}...) !")
            return encoded_text
        except Exception as e:
            return f"Error in base64 encoding: {str(e)}"
    
    @staticmethod
    def base64_decode(encoded_text: str) -> str:
        """
        Decodes a base64 string to plain text.
        
        Args:
            encoded_text: The base64 encoded text
            
        Returns:
            Decoded string
        """
        print(f"-> base64_decode tool used (input: {encoded_text[:30]}...) !")
        import base64
        try:
            decoded_bytes = base64.b64decode(encoded_text)
            decoded_text = decoded_bytes.decode('utf-8')
            print(f"-> (output: {decoded_text[:30]}...) !")
            return decoded_text
        except Exception as e:
            return f"Error in base64 decoding: {str(e)}"
    
    @staticmethod
    def caesar_cipher_encode(text: str, shift: int) -> str:
        """
        Encodes text using Caesar cipher with specified shift.
        
        Args:
            text: The text to encode
            shift: Number of positions to shift each character
            
        Returns:
            Caesar cipher encoded string
        """
        print(f"-> caesar_cipher_encode tool used (input: {text[:30]}..., shift: {shift}) !")
        result = ""
        try:
            for char in text:
                if char.isalpha():
                    ascii_offset = ord('a') if char.islower() else ord('A')
                    encoded_char = chr((ord(char) - ascii_offset + shift) % 26 + ascii_offset)
                    result += encoded_char
                else:
                    result += char
            print(f"-> (output: {result[:30]}...) !")
            return result
        except Exception as e:
            return f"Error in Caesar cipher encoding: {str(e)}"
    
    @classmethod
    def caesar_cipher_decode(cls, encoded_text: str, shift: int) -> str:
        """
        Decodes Caesar cipher text with specified shift.
        
        Args:
            encoded_text: The encoded text
            shift: Number of positions the text was shifted
            
        Returns:
            Decoded string
        """
        print(f"-> caesar_cipher_decode tool used (input: {encoded_text[:30]}..., shift: {shift}) !")
        # To decode, we shift in the opposite direction
        return cls.caesar_cipher_encode(encoded_text, -shift)
    
    @staticmethod
    def reverse_string(text: str) -> str:
        """
        Reverses a string.
        
        Args:
            text: The text to reverse
            
        Returns:
            Reversed string
        """
        print(f"-> reverse_string tool used (input: {text[:30]}...) !")
        reversed_text = text[::-1]
        print(f"-> (output: {reversed_text[:30]}...) !")
        return reversed_text


class _EncryptionToolbox:
    base64_encode = FunctionTool.from_defaults(
        name="base64_encode",
        description="Encode a string to base64",
        fn=_Encryption.base64_encode
    )
    base64_decode = FunctionTool.from_defaults(
        name="base64_decode",
        description="Decode a base64 string to plain text",
        fn=_Encryption.base64_decode
    )
    caesar_cipher_encode = FunctionTool.from_defaults(
        name="caesar_cipher_encode",
        description="Encode a string using Caesar cipher with specified shift",
        fn=_Encryption.caesar_cipher_encode
    )
    caesar_cipher_decode = FunctionTool.from_defaults(
        name="caesar_cipher_decode",
        description="Decode a Caesar cipher string with specified shift",
        fn=_Encryption.caesar_cipher_decode
    )
    reverse_string = FunctionTool.from_defaults(
        name="reverse_string",
        description="Reverse a string",
        fn=_Encryption.reverse_string
    )


class Toolbox:
    math = _MathToolbox()
    web_search = _WebSearchToolbox()
    encryption = _EncryptionToolbox()