Spaces:
Runtime error
Runtime error
Commit
·
c752db9
1
Parent(s):
58db9fa
Final fix
Browse files- tools/__init__.py +1 -4
- tools/code_interpreter_tool.py +0 -174
- tools/excel_analysis_tool.py +14 -2
- tools/file_tools.py +0 -110
- tools/task_file_downloader_tool.py +0 -60
tools/__init__.py
CHANGED
@@ -4,13 +4,11 @@ Contains implementations of various tools used by the agent to process different
|
|
4 |
"""
|
5 |
|
6 |
from .base_tool import EnhancedTool
|
7 |
-
from .
|
8 |
-
from .task_file_downloader_tool import TaskFileDownloaderTool
|
9 |
from .image_analysis_tool import ImageAnalysisTool
|
10 |
from .youtube_tool import YouTubeTranscriptTool
|
11 |
from .excel_analysis_tool import ExcelAnalysisTool
|
12 |
from .text_processing_tool import TextProcessingTool
|
13 |
-
from .code_interpreter_tool import CodeInterpreterTool
|
14 |
from .math_tool import MathematicalReasoningTool
|
15 |
|
16 |
__all__ = [
|
@@ -21,6 +19,5 @@ __all__ = [
|
|
21 |
"YouTubeTranscriptTool",
|
22 |
"ExcelAnalysisTool",
|
23 |
"TextProcessingTool",
|
24 |
-
"CodeInterpreterTool",
|
25 |
"MathematicalReasoningTool"
|
26 |
]
|
|
|
4 |
"""
|
5 |
|
6 |
from .base_tool import EnhancedTool
|
7 |
+
from .file_download_tool import TaskFileDownloaderTool, FileOpenerTool
|
|
|
8 |
from .image_analysis_tool import ImageAnalysisTool
|
9 |
from .youtube_tool import YouTubeTranscriptTool
|
10 |
from .excel_analysis_tool import ExcelAnalysisTool
|
11 |
from .text_processing_tool import TextProcessingTool
|
|
|
12 |
from .math_tool import MathematicalReasoningTool
|
13 |
|
14 |
__all__ = [
|
|
|
19 |
"YouTubeTranscriptTool",
|
20 |
"ExcelAnalysisTool",
|
21 |
"TextProcessingTool",
|
|
|
22 |
"MathematicalReasoningTool"
|
23 |
]
|
tools/code_interpreter_tool.py
DELETED
@@ -1,174 +0,0 @@
|
|
1 |
-
"""
|
2 |
-
Enhanced code interpreter tool for the AI agent project.
|
3 |
-
Handles Python code execution safely with proper error handling.
|
4 |
-
"""
|
5 |
-
|
6 |
-
import os
|
7 |
-
import sys
|
8 |
-
import io
|
9 |
-
import traceback
|
10 |
-
from typing import Optional
|
11 |
-
from .base_tool import EnhancedTool
|
12 |
-
|
13 |
-
class CodeInterpreterTool(EnhancedTool):
|
14 |
-
"""Tool for executing and analyzing code files."""
|
15 |
-
|
16 |
-
name = "CodeInterpreterTool"
|
17 |
-
description = "Execute Python code from a file and return the output. Useful for determining what a code snippet outputs."
|
18 |
-
inputs = {
|
19 |
-
"task_id": {
|
20 |
-
"type": "string",
|
21 |
-
"description": "Task ID for which the code file has been downloaded"
|
22 |
-
},
|
23 |
-
"query": {
|
24 |
-
"type": "string",
|
25 |
-
"description": "Specific question about the code output",
|
26 |
-
"nullable": True
|
27 |
-
}
|
28 |
-
}
|
29 |
-
output_type = "string"
|
30 |
-
|
31 |
-
def forward(self, task_id: str, query: Optional[str] = None) -> str:
|
32 |
-
"""
|
33 |
-
Execute Python code and return its output.
|
34 |
-
|
35 |
-
Args:
|
36 |
-
task_id: Task ID for which the code file has been downloaded
|
37 |
-
query: Question about the code (optional)
|
38 |
-
|
39 |
-
Returns:
|
40 |
-
Execution result or error message
|
41 |
-
"""
|
42 |
-
filename = f"{task_id}_downloaded_file"
|
43 |
-
|
44 |
-
if not os.path.exists(filename):
|
45 |
-
return f"Error: Code file {filename} does not exist. Please download it first."
|
46 |
-
|
47 |
-
try:
|
48 |
-
# Read the file content
|
49 |
-
with open(filename, 'r', encoding='utf-8') as file:
|
50 |
-
code = file.read()
|
51 |
-
|
52 |
-
# Capture stdout/stderr to get the output
|
53 |
-
old_stdout = sys.stdout
|
54 |
-
old_stderr = sys.stderr
|
55 |
-
redirected_output = io.StringIO()
|
56 |
-
redirected_error = io.StringIO()
|
57 |
-
sys.stdout = redirected_output
|
58 |
-
sys.stderr = redirected_error
|
59 |
-
|
60 |
-
# Create a namespace to capture variables
|
61 |
-
exec_namespace = {}
|
62 |
-
|
63 |
-
try:
|
64 |
-
# Execute the code
|
65 |
-
exec(code, exec_namespace)
|
66 |
-
|
67 |
-
# Get output
|
68 |
-
output = redirected_output.getvalue()
|
69 |
-
error = redirected_error.getvalue()
|
70 |
-
|
71 |
-
# Get the final variable value if needed
|
72 |
-
final_value = None
|
73 |
-
if query and "final" in query.lower() and "output" in query.lower():
|
74 |
-
# Look for 'result' or a final print statement
|
75 |
-
if "result" in exec_namespace:
|
76 |
-
final_value = str(exec_namespace["result"])
|
77 |
-
elif "answer" in exec_namespace:
|
78 |
-
final_value = str(exec_namespace["answer"])
|
79 |
-
elif "output" in exec_namespace:
|
80 |
-
final_value = str(exec_namespace["output"])
|
81 |
-
elif output.strip():
|
82 |
-
# Get the last line of output as final value
|
83 |
-
final_value = output.strip().split('\n')[-1]
|
84 |
-
else:
|
85 |
-
# Analyze globals for potential final values
|
86 |
-
final_vars = [v for k, v in exec_namespace.items()
|
87 |
-
if not k.startswith('__') and k not in ['__builtins__']]
|
88 |
-
if final_vars:
|
89 |
-
final_value = str(final_vars[-1])
|
90 |
-
|
91 |
-
# Compile the result based on what was requested
|
92 |
-
if final_value:
|
93 |
-
return final_value
|
94 |
-
elif output:
|
95 |
-
return output
|
96 |
-
elif error:
|
97 |
-
return f"Code execution produced errors: {error}"
|
98 |
-
else:
|
99 |
-
return "Code executed without output."
|
100 |
-
|
101 |
-
except Exception as exec_error:
|
102 |
-
error_msg = f"Error executing code: {str(exec_error)}\n{traceback.format_exc()}"
|
103 |
-
return error_msg
|
104 |
-
|
105 |
-
finally:
|
106 |
-
# Reset stdout/stderr
|
107 |
-
sys.stdout = old_stdout
|
108 |
-
sys.stderr = old_stderr
|
109 |
-
|
110 |
-
except Exception as e:
|
111 |
-
return f"Error processing code file: {str(e)}"
|
112 |
-
|
113 |
-
def _simulate_code_analysis(self, query: Optional[str] = None) -> str:
|
114 |
-
"""
|
115 |
-
Simulate code analysis.
|
116 |
-
|
117 |
-
Args:
|
118 |
-
query: Analysis query
|
119 |
-
|
120 |
-
Returns:
|
121 |
-
Simulated analysis results
|
122 |
-
"""
|
123 |
-
if not query:
|
124 |
-
# Default analysis
|
125 |
-
return """
|
126 |
-
Code Analysis:
|
127 |
-
- Language: Python
|
128 |
-
- 5 functions defined
|
129 |
-
- 2 classes defined
|
130 |
-
- Dependencies: os, sys, numpy, pandas
|
131 |
-
- Complexity: Moderate
|
132 |
-
"""
|
133 |
-
|
134 |
-
query_lower = query.lower()
|
135 |
-
|
136 |
-
if "explain" in query_lower or "what does" in query_lower:
|
137 |
-
return """
|
138 |
-
Explanation:
|
139 |
-
This code defines a data processing pipeline that:
|
140 |
-
1. Reads data from input files
|
141 |
-
2. Performs various cleaning operations (handling missing values, normalization)
|
142 |
-
3. Applies a machine learning algorithm (appears to be a simple regression model)
|
143 |
-
4. Outputs predictions to a file
|
144 |
-
|
145 |
-
The main function orchestrates the pipeline, while helper functions handle individual tasks.
|
146 |
-
"""
|
147 |
-
elif "complexity" in query_lower or "efficiency" in query_lower:
|
148 |
-
return """
|
149 |
-
Complexity Analysis:
|
150 |
-
- Time Complexity: O(n²) due to nested loops in the data processing function
|
151 |
-
- Space Complexity: O(n) as it stores the entire dataset in memory
|
152 |
-
- Potential Optimization: The nested loop could be vectorized using NumPy operations to improve performance
|
153 |
-
"""
|
154 |
-
elif "bug" in query_lower or "error" in query_lower or "fix" in query_lower:
|
155 |
-
return """
|
156 |
-
Issues Identified:
|
157 |
-
1. Potential division by zero in line 42 when denominator is zero
|
158 |
-
2. Unclosed file in read_data function (missing 'with' statement)
|
159 |
-
3. Variable 'result' might be referenced before assignment in some code paths
|
160 |
-
"""
|
161 |
-
elif "test" in query_lower or "execute" in query_lower or "run" in query_lower:
|
162 |
-
return """
|
163 |
-
Execution Result:
|
164 |
-
The code ran successfully with the following output:
|
165 |
-
- Processed 1000 records
|
166 |
-
- Applied transformation to 950 valid entries
|
167 |
-
- Output saved to 'results.txt'
|
168 |
-
- Execution time: 1.24 seconds
|
169 |
-
"""
|
170 |
-
else:
|
171 |
-
return """
|
172 |
-
General Code Assessment:
|
173 |
-
The code appears to be a Python script that performs data processing and analysis. It follows standard coding practices but could benefit from better error handling and documentation. The main functionality seems sound, but there are opportunities for optimization and improved structure.
|
174 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tools/excel_analysis_tool.py
CHANGED
@@ -44,8 +44,20 @@ class ExcelAnalysisTool(EnhancedTool):
|
|
44 |
if not os.path.exists(filename):
|
45 |
return f"Error: File for task {task_id} does not exist. Please download it first."
|
46 |
|
47 |
-
#
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
# Basic analysis if no specific query
|
51 |
if not query:
|
|
|
44 |
if not os.path.exists(filename):
|
45 |
return f"Error: File for task {task_id} does not exist. Please download it first."
|
46 |
|
47 |
+
# Try to determine file type and read accordingly
|
48 |
+
try:
|
49 |
+
# First try Excel format
|
50 |
+
df = pd.read_excel(filename, engine="openpyxl")
|
51 |
+
except Exception as excel_error:
|
52 |
+
# If Excel reading fails, try CSV
|
53 |
+
try:
|
54 |
+
df = pd.read_csv(filename)
|
55 |
+
except Exception as csv_error:
|
56 |
+
# If CSV reading fails, try TSV
|
57 |
+
try:
|
58 |
+
df = pd.read_csv(filename, sep='\t')
|
59 |
+
except Exception as tsv_error:
|
60 |
+
return f"Error: Unable to read file as Excel, CSV, or TSV. Original error: {str(excel_error)}"
|
61 |
|
62 |
# Basic analysis if no specific query
|
63 |
if not query:
|
tools/file_tools.py
DELETED
@@ -1,110 +0,0 @@
|
|
1 |
-
"""
|
2 |
-
File-related tools for the AI agent project.
|
3 |
-
"""
|
4 |
-
|
5 |
-
import os
|
6 |
-
import requests
|
7 |
-
from typing import Optional
|
8 |
-
from .base_tool import EnhancedTool
|
9 |
-
|
10 |
-
# Constants
|
11 |
-
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
12 |
-
|
13 |
-
class FileDownloaderTool(EnhancedTool):
|
14 |
-
"""Tool for downloading files associated with a task ID."""
|
15 |
-
|
16 |
-
name = "FileDownloaderTool"
|
17 |
-
description = "Download a specific file associated with a given task ID and save it locally"
|
18 |
-
inputs = {
|
19 |
-
"task_id": {
|
20 |
-
"type": "string",
|
21 |
-
"description": "Task ID for which to download the associated file"
|
22 |
-
}
|
23 |
-
}
|
24 |
-
output_type = "string"
|
25 |
-
|
26 |
-
def forward(self, task_id: str) -> str:
|
27 |
-
"""
|
28 |
-
Download a file associated with a task ID.
|
29 |
-
|
30 |
-
Args:
|
31 |
-
task_id: Task ID for which to download the file
|
32 |
-
|
33 |
-
Returns:
|
34 |
-
Status message
|
35 |
-
"""
|
36 |
-
try:
|
37 |
-
# Construct the download URL
|
38 |
-
download_url = f"{DEFAULT_API_URL}/files/{task_id}"
|
39 |
-
|
40 |
-
# Send the request to download the file
|
41 |
-
response = requests.get(download_url, timeout=30)
|
42 |
-
response.raise_for_status()
|
43 |
-
|
44 |
-
# Save the file
|
45 |
-
filename = f"{task_id}_downloaded_file"
|
46 |
-
with open(filename, "wb") as f:
|
47 |
-
f.write(response.content)
|
48 |
-
|
49 |
-
return f"File downloaded successfully and saved as: {filename}"
|
50 |
-
|
51 |
-
except requests.exceptions.RequestException as e:
|
52 |
-
return f"Error downloading file: {str(e)}"
|
53 |
-
except Exception as e:
|
54 |
-
return f"Unexpected error: {str(e)}"
|
55 |
-
|
56 |
-
|
57 |
-
class FileOpenerTool(EnhancedTool):
|
58 |
-
"""Tool for opening and reading downloaded files."""
|
59 |
-
|
60 |
-
name = "FileOpenerTool"
|
61 |
-
description = "Open a downloaded file associated with a task ID and read its contents as plain text."
|
62 |
-
inputs = {
|
63 |
-
"task_id": {
|
64 |
-
"type": "string",
|
65 |
-
"description": "Task ID for which the file has been downloaded"
|
66 |
-
},
|
67 |
-
"num_lines": {
|
68 |
-
"type": "integer",
|
69 |
-
"description": "Number of lines to read from the file",
|
70 |
-
"nullable": True
|
71 |
-
}
|
72 |
-
}
|
73 |
-
output_type = "string"
|
74 |
-
|
75 |
-
def forward(self, task_id: str, num_lines: int = None) -> str:
|
76 |
-
"""
|
77 |
-
Open and read a downloaded file.
|
78 |
-
|
79 |
-
Args:
|
80 |
-
task_id: Task ID for which the file has been downloaded
|
81 |
-
num_lines: Number of lines to read
|
82 |
-
|
83 |
-
Returns:
|
84 |
-
File contents
|
85 |
-
"""
|
86 |
-
# Construct the filename
|
87 |
-
filename = f"{task_id}_downloaded_file"
|
88 |
-
|
89 |
-
# Check if file exists
|
90 |
-
if not os.path.exists(filename):
|
91 |
-
return f"Error: File {filename} does not exist."
|
92 |
-
|
93 |
-
try:
|
94 |
-
# Try to read the file as text
|
95 |
-
with open(filename, "r", encoding="utf-8", errors="ignore") as file:
|
96 |
-
if num_lines:
|
97 |
-
# Read specified number of lines
|
98 |
-
lines = []
|
99 |
-
for i in range(num_lines):
|
100 |
-
line = file.readline()
|
101 |
-
if not line:
|
102 |
-
break
|
103 |
-
lines.append(line.strip())
|
104 |
-
return "\n".join(lines)
|
105 |
-
else:
|
106 |
-
# Read the entire file
|
107 |
-
return file.read()
|
108 |
-
|
109 |
-
except Exception as e:
|
110 |
-
return f"Error reading file: {str(e)}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tools/task_file_downloader_tool.py
DELETED
@@ -1,60 +0,0 @@
|
|
1 |
-
"""
|
2 |
-
Simple file downloader tool for the AI agent project.
|
3 |
-
Uses the approach from the course example.
|
4 |
-
"""
|
5 |
-
|
6 |
-
import os
|
7 |
-
import requests
|
8 |
-
from .base_tool import EnhancedTool
|
9 |
-
|
10 |
-
# Constants
|
11 |
-
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
12 |
-
|
13 |
-
class TaskFileDownloaderTool(EnhancedTool):
|
14 |
-
"""Tool for downloading files associated with a task ID."""
|
15 |
-
|
16 |
-
name = "TaskFileDownloaderTool"
|
17 |
-
description = "Download a specific file associated with a given task ID and save it locally."
|
18 |
-
inputs = {
|
19 |
-
"task_id": {
|
20 |
-
"type": "string",
|
21 |
-
"description": "Task ID for which to download the associated file"
|
22 |
-
},
|
23 |
-
"file_name": {
|
24 |
-
"type": "string",
|
25 |
-
"description": "Optional file name to download",
|
26 |
-
"nullable": True
|
27 |
-
}
|
28 |
-
}
|
29 |
-
output_type = "string"
|
30 |
-
|
31 |
-
def forward(self, task_id: str, file_name: str = None) -> str:
|
32 |
-
"""
|
33 |
-
Download a file associated with a task ID.
|
34 |
-
|
35 |
-
Args:
|
36 |
-
task_id: Task ID of the task
|
37 |
-
file_name: Optional file name to download
|
38 |
-
|
39 |
-
Returns:
|
40 |
-
Status message
|
41 |
-
"""
|
42 |
-
try:
|
43 |
-
# Determine which identifier to use for download
|
44 |
-
download_id = file_name if file_name else task_id
|
45 |
-
|
46 |
-
download_url = f"{DEFAULT_API_URL}/files/{download_id}"
|
47 |
-
response = requests.get(download_url, timeout=30)
|
48 |
-
|
49 |
-
if response.status_code == 200:
|
50 |
-
# Save the file with a consistent naming scheme
|
51 |
-
filename = f"{task_id}_downloaded_file"
|
52 |
-
with open(filename, "wb") as f:
|
53 |
-
f.write(response.content)
|
54 |
-
|
55 |
-
return f"File downloaded successfully and saved as: {filename}"
|
56 |
-
else:
|
57 |
-
return f"Failed to download file. Status code: {response.status_code}"
|
58 |
-
|
59 |
-
except Exception as e:
|
60 |
-
return f"Error downloading file: {str(e)}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|