stackConsult commited on
Commit
2456578
·
verified ·
1 Parent(s): 413e679

Create smolagents/tools.py

Browse files
Files changed (1) hide show
  1. smolagents/tools.py +212 -0
smolagents/tools.py ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """CSV Tool Support for Vendor-Neutral Smolagents Fork
2
+
3
+ This module provides CSV-based tool handlers for the agent system.
4
+ Designed to be vendor-neutral and work with various LLM backends.
5
+ """
6
+
7
+ import csv
8
+ import os
9
+ from typing import List, Dict, Any, Optional
10
+ import json
11
+
12
+
13
+ class CSVToolHandler:
14
+ """Handler for CSV-based tool definitions and operations."""
15
+
16
+ def __init__(self, csv_path: Optional[str] = None):
17
+ """Initialize the CSV tool handler.
18
+
19
+ Args:
20
+ csv_path: Path to CSV file containing tool definitions.
21
+ Defaults to './tools.csv' if not specified.
22
+ """
23
+ self.csv_path = csv_path or os.getenv('CSV_TOOLS_PATH', './tools.csv')
24
+ self.tools = []
25
+ if os.path.exists(self.csv_path):
26
+ self.load_tools()
27
+
28
+ def load_tools(self) -> None:
29
+ """Load tool definitions from CSV file."""
30
+ try:
31
+ with open(self.csv_path, 'r', encoding='utf-8') as f:
32
+ reader = csv.DictReader(f)
33
+ self.tools = list(reader)
34
+ print(f"Loaded {len(self.tools)} tools from {self.csv_path}")
35
+ except Exception as e:
36
+ print(f"Error loading tools from CSV: {e}")
37
+ self.tools = []
38
+
39
+ def get_tools(self) -> List[Dict[str, Any]]:
40
+ """Return list of tool definitions."""
41
+ return self.tools
42
+
43
+ def get_tool_by_name(self, name: str) -> Optional[Dict[str, Any]]:
44
+ """Get a specific tool by name."""
45
+ for tool in self.tools:
46
+ if tool.get('name') == name:
47
+ return tool
48
+ return None
49
+
50
+ def add_tool(self, tool: Dict[str, Any]) -> None:
51
+ """Add a new tool definition."""
52
+ self.tools.append(tool)
53
+
54
+ def save_tools(self) -> None:
55
+ """Save tool definitions back to CSV file."""
56
+ if not self.tools:
57
+ print("No tools to save")
58
+ return
59
+
60
+ try:
61
+ fieldnames = list(self.tools[0].keys())
62
+ with open(self.csv_path, 'w', encoding='utf-8', newline='') as f:
63
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
64
+ writer.writeheader()
65
+ writer.writerows(self.tools)
66
+ print(f"Saved {len(self.tools)} tools to {self.csv_path}")
67
+ except Exception as e:
68
+ print(f"Error saving tools to CSV: {e}")
69
+
70
+
71
+ class CSVDataHandler:
72
+ """Handler for CSV data operations within agents."""
73
+
74
+ @staticmethod
75
+ def read_csv(file_path: str) -> List[Dict[str, Any]]:
76
+ """Read data from CSV file.
77
+
78
+ Args:
79
+ file_path: Path to the CSV file to read.
80
+
81
+ Returns:
82
+ List of dictionaries representing CSV rows.
83
+ """
84
+ try:
85
+ with open(file_path, 'r', encoding='utf-8') as f:
86
+ reader = csv.DictReader(f)
87
+ return list(reader)
88
+ except Exception as e:
89
+ print(f"Error reading CSV file {file_path}: {e}")
90
+ return []
91
+
92
+ @staticmethod
93
+ def write_csv(file_path: str, data: List[Dict[str, Any]],
94
+ fieldnames: Optional[List[str]] = None) -> bool:
95
+ """Write data to CSV file.
96
+
97
+ Args:
98
+ file_path: Path to the CSV file to write.
99
+ data: List of dictionaries to write as CSV rows.
100
+ fieldnames: Optional list of field names. If not provided,
101
+ uses keys from first data item.
102
+
103
+ Returns:
104
+ True if successful, False otherwise.
105
+ """
106
+ if not data:
107
+ print("No data to write")
108
+ return False
109
+
110
+ try:
111
+ if fieldnames is None:
112
+ fieldnames = list(data[0].keys())
113
+
114
+ with open(file_path, 'w', encoding='utf-8', newline='') as f:
115
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
116
+ writer.writeheader()
117
+ writer.writerows(data)
118
+ return True
119
+ except Exception as e:
120
+ print(f"Error writing CSV file {file_path}: {e}")
121
+ return False
122
+
123
+ @staticmethod
124
+ def query_csv(file_path: str, filter_func) -> List[Dict[str, Any]]:
125
+ """Query CSV data with a filter function.
126
+
127
+ Args:
128
+ file_path: Path to the CSV file.
129
+ filter_func: Function that takes a row dict and returns bool.
130
+
131
+ Returns:
132
+ Filtered list of row dictionaries.
133
+ """
134
+ data = CSVDataHandler.read_csv(file_path)
135
+ return [row for row in data if filter_func(row)]
136
+
137
+
138
+ def register_csv_tools(tool_handler: CSVToolHandler) -> Dict[str, callable]:
139
+ """Register CSV tools as callable functions.
140
+
141
+ Args:
142
+ tool_handler: CSVToolHandler instance with loaded tools.
143
+
144
+ Returns:
145
+ Dictionary mapping tool names to callable functions.
146
+ """
147
+ tool_functions = {}
148
+
149
+ for tool in tool_handler.get_tools():
150
+ tool_name = tool.get('name', '')
151
+ tool_description = tool.get('description', '')
152
+ tool_function = tool.get('function', '')
153
+
154
+ # Create a lambda that captures the tool configuration
155
+ def create_tool_func(name, desc, func_str):
156
+ def tool_func(*args, **kwargs):
157
+ """Dynamically created tool function."""
158
+ print(f"Executing tool: {name}")
159
+ print(f"Description: {desc}")
160
+ print(f"Args: {args}, Kwargs: {kwargs}")
161
+ # In a real implementation, this would execute the function
162
+ return {"status": "executed", "tool": name}
163
+
164
+ tool_func.__name__ = name
165
+ tool_func.__doc__ = desc
166
+ return tool_func
167
+
168
+ if tool_name:
169
+ tool_functions[tool_name] = create_tool_func(
170
+ tool_name, tool_description, tool_function
171
+ )
172
+
173
+ return tool_functions
174
+
175
+
176
+ # Example usage and testing
177
+ if __name__ == "__main__":
178
+ # Create sample tools CSV for testing
179
+ sample_tools = [
180
+ {
181
+ "name": "read_file",
182
+ "description": "Read contents of a file",
183
+ "function": "file_reader",
184
+ "parameters": "file_path:str"
185
+ },
186
+ {
187
+ "name": "write_file",
188
+ "description": "Write contents to a file",
189
+ "function": "file_writer",
190
+ "parameters": "file_path:str,content:str"
191
+ },
192
+ {
193
+ "name": "search_web",
194
+ "description": "Search the web for information",
195
+ "function": "web_search",
196
+ "parameters": "query:str"
197
+ }
198
+ ]
199
+
200
+ # Test CSV operations
201
+ print("Testing CSV Tool Handler...")
202
+ handler = CSVToolHandler('./test_tools.csv')
203
+
204
+ for tool in sample_tools:
205
+ handler.add_tool(tool)
206
+
207
+ handler.save_tools()
208
+ print(f"Tools available: {[t['name'] for t in handler.get_tools()]}")
209
+
210
+ # Register tools
211
+ tool_funcs = register_csv_tools(handler)
212
+ print(f"Registered functions: {list(tool_funcs.keys())}")