Spaces:
Sleeping
Sleeping
better tool handling
Browse files
app.py
CHANGED
|
@@ -22,14 +22,10 @@ from tools import (
|
|
| 22 |
math_calculation_tool,
|
| 23 |
wiki_search_tool,
|
| 24 |
python_repl_tool,
|
| 25 |
-
save_and_read_file_tool,
|
| 26 |
-
download_file_from_url_tool,
|
| 27 |
extract_text_from_image_tool,
|
| 28 |
analyze_csv_file_tool,
|
| 29 |
analyze_excel_file_tool,
|
| 30 |
-
|
| 31 |
-
download_gaia_file_tool,
|
| 32 |
-
download_file,
|
| 33 |
)
|
| 34 |
import re
|
| 35 |
|
|
@@ -52,13 +48,10 @@ tools = [
|
|
| 52 |
code_execution_tool,
|
| 53 |
math_calculation_tool,
|
| 54 |
python_repl_tool,
|
| 55 |
-
|
| 56 |
-
download_file_from_url_tool,
|
| 57 |
extract_text_from_image_tool,
|
| 58 |
analyze_csv_file_tool,
|
| 59 |
analyze_excel_file_tool,
|
| 60 |
-
handle_file_tool,
|
| 61 |
-
download_gaia_file_tool,
|
| 62 |
]
|
| 63 |
chat_with_tools = llm.bind_tools(tools)
|
| 64 |
|
|
@@ -149,8 +142,10 @@ def assistant(state: MyAgent):
|
|
| 149 |
You are a helpful assistant tasked with answering questions using a set of tools.
|
| 150 |
|
| 151 |
IMPORTANT: When a question mentions an attached file, follow this process:
|
| 152 |
-
1.
|
| 153 |
-
|
|
|
|
|
|
|
| 154 |
2. Use the appropriate analysis tool based on file type:
|
| 155 |
- For images: use image_recognition_tool or extract_text_from_image_tool
|
| 156 |
- For audio: use audio_processing_tool
|
|
@@ -158,8 +153,6 @@ IMPORTANT: When a question mentions an attached file, follow this process:
|
|
| 158 |
- For text files: use read_file_tool
|
| 159 |
- For code files: use python_execution_tool or code_execution_tool
|
| 160 |
|
| 161 |
-
For intermediate steps, you can use save_and_read_file_tool to save content and then process it.
|
| 162 |
-
|
| 163 |
Think step by step and report your answer with the following template:
|
| 164 |
FINAL ANSWER: [YOUR FINAL ANSWER].
|
| 165 |
|
|
|
|
| 22 |
math_calculation_tool,
|
| 23 |
wiki_search_tool,
|
| 24 |
python_repl_tool,
|
|
|
|
|
|
|
| 25 |
extract_text_from_image_tool,
|
| 26 |
analyze_csv_file_tool,
|
| 27 |
analyze_excel_file_tool,
|
| 28 |
+
download_file_tool,
|
|
|
|
|
|
|
| 29 |
)
|
| 30 |
import re
|
| 31 |
|
|
|
|
| 48 |
code_execution_tool,
|
| 49 |
math_calculation_tool,
|
| 50 |
python_repl_tool,
|
| 51 |
+
download_file_tool,
|
|
|
|
| 52 |
extract_text_from_image_tool,
|
| 53 |
analyze_csv_file_tool,
|
| 54 |
analyze_excel_file_tool,
|
|
|
|
|
|
|
| 55 |
]
|
| 56 |
chat_with_tools = llm.bind_tools(tools)
|
| 57 |
|
|
|
|
| 142 |
You are a helpful assistant tasked with answering questions using a set of tools.
|
| 143 |
|
| 144 |
IMPORTANT: When a question mentions an attached file, follow this process:
|
| 145 |
+
1. Use download_file_tool with the task_id or URL to download the file
|
| 146 |
+
- For GAIA files: pass the task_id directly
|
| 147 |
+
- For other URLs: pass the full URL
|
| 148 |
+
- For content: pass the content to save as a file
|
| 149 |
2. Use the appropriate analysis tool based on file type:
|
| 150 |
- For images: use image_recognition_tool or extract_text_from_image_tool
|
| 151 |
- For audio: use audio_processing_tool
|
|
|
|
| 153 |
- For text files: use read_file_tool
|
| 154 |
- For code files: use python_execution_tool or code_execution_tool
|
| 155 |
|
|
|
|
|
|
|
| 156 |
Think step by step and report your answer with the following template:
|
| 157 |
FINAL ANSWER: [YOUR FINAL ANSWER].
|
| 158 |
|
tools.py
CHANGED
|
@@ -561,51 +561,6 @@ python_repl_tool = Tool(
|
|
| 561 |
# --- New Tools ---
|
| 562 |
|
| 563 |
|
| 564 |
-
def save_and_read_file(content: str, filename: str = "") -> str:
|
| 565 |
-
temp_dir = tempfile.gettempdir()
|
| 566 |
-
if filename == "":
|
| 567 |
-
temp_file = tempfile.NamedTemporaryFile(delete=False, dir=temp_dir)
|
| 568 |
-
filepath = temp_file.name
|
| 569 |
-
else:
|
| 570 |
-
filepath = os.path.join(temp_dir, filename)
|
| 571 |
-
with open(filepath, "w") as f:
|
| 572 |
-
f.write(content)
|
| 573 |
-
return f"File saved to {filepath}. You can read this file to process its contents."
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
save_and_read_file_tool = Tool(
|
| 577 |
-
name="save_and_read_file_tool",
|
| 578 |
-
func=save_and_read_file,
|
| 579 |
-
description="Save content to a file and return the path. Optionally specify a filename."
|
| 580 |
-
)
|
| 581 |
-
|
| 582 |
-
|
| 583 |
-
def download_file_from_url(url: str, filename: str = "") -> str:
|
| 584 |
-
try:
|
| 585 |
-
if filename == "":
|
| 586 |
-
path = urlparse(url).path
|
| 587 |
-
filename = os.path.basename(path)
|
| 588 |
-
if not filename:
|
| 589 |
-
filename = f"downloaded_{uuid.uuid4().hex[:8]}"
|
| 590 |
-
temp_dir = tempfile.gettempdir()
|
| 591 |
-
filepath = os.path.join(temp_dir, filename)
|
| 592 |
-
response = requests.get(url, stream=True)
|
| 593 |
-
response.raise_for_status()
|
| 594 |
-
with open(filepath, "wb") as f:
|
| 595 |
-
for chunk in response.iter_content(chunk_size=8192):
|
| 596 |
-
f.write(chunk)
|
| 597 |
-
return f"File downloaded to {filepath}. You can read this file to process its contents."
|
| 598 |
-
except Exception as e:
|
| 599 |
-
return f"Error downloading file: {str(e)}"
|
| 600 |
-
|
| 601 |
-
|
| 602 |
-
download_file_from_url_tool = Tool(
|
| 603 |
-
name="download_file_from_url_tool",
|
| 604 |
-
func=download_file_from_url,
|
| 605 |
-
description="Download a file from a URL and save it to a temporary location. Optionally specify a filename."
|
| 606 |
-
)
|
| 607 |
-
|
| 608 |
-
|
| 609 |
def extract_text_from_image(image_path: str) -> str:
|
| 610 |
try:
|
| 611 |
image = Image.open(image_path)
|
|
@@ -660,83 +615,83 @@ analyze_excel_file_tool = Tool(
|
|
| 660 |
)
|
| 661 |
|
| 662 |
# =========================
|
| 663 |
-
#
|
| 664 |
# =========================
|
| 665 |
|
| 666 |
|
| 667 |
-
def
|
| 668 |
"""
|
| 669 |
-
|
|
|
|
|
|
|
|
|
|
| 670 |
|
| 671 |
Args:
|
| 672 |
-
|
| 673 |
-
filename: Optional filename
|
| 674 |
"""
|
| 675 |
try:
|
| 676 |
-
|
| 677 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 678 |
|
| 679 |
-
|
| 680 |
-
|
| 681 |
-
file_url = f"{api_url}/files/{task_id}"
|
| 682 |
|
| 683 |
-
|
| 684 |
-
|
| 685 |
|
| 686 |
-
|
| 687 |
-
|
|
|
|
| 688 |
|
| 689 |
-
|
| 690 |
-
for chunk in response.iter_content(chunk_size=8192):
|
| 691 |
-
f.write(chunk)
|
| 692 |
|
| 693 |
-
|
| 694 |
-
|
| 695 |
-
|
|
|
|
| 696 |
|
|
|
|
|
|
|
| 697 |
|
| 698 |
-
|
| 699 |
-
|
| 700 |
-
func=download_gaia_file,
|
| 701 |
-
description="Download a file from the GAIA API using task_id. Use this specifically for GAIA benchmark files."
|
| 702 |
-
)
|
| 703 |
|
| 704 |
-
|
| 705 |
-
|
| 706 |
-
# =========================
|
| 707 |
|
|
|
|
|
|
|
|
|
|
| 708 |
|
| 709 |
-
|
| 710 |
-
"""
|
| 711 |
-
Comprehensive file handling tool that can download from URL or save content.
|
| 712 |
|
| 713 |
-
Args:
|
| 714 |
-
file_source: Either a URL to download from or content to save
|
| 715 |
-
file_type: "url" for downloading, "content" for saving, "auto" to detect
|
| 716 |
-
"""
|
| 717 |
-
try:
|
| 718 |
-
if file_type == "auto":
|
| 719 |
-
# Auto-detect if it's a URL or content
|
| 720 |
-
if file_source.startswith(('http://', 'https://')):
|
| 721 |
-
file_type = "url"
|
| 722 |
-
else:
|
| 723 |
-
file_type = "content"
|
| 724 |
-
|
| 725 |
-
if file_type == "url":
|
| 726 |
-
# Download from URL
|
| 727 |
-
return download_file_from_url(file_source)
|
| 728 |
-
elif file_type == "content":
|
| 729 |
-
# Save content to file
|
| 730 |
-
return save_and_read_file(file_source)
|
| 731 |
else:
|
| 732 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 733 |
|
| 734 |
except Exception as e:
|
| 735 |
return f"Error handling file: {str(e)}"
|
| 736 |
|
| 737 |
|
| 738 |
-
|
| 739 |
-
name="
|
| 740 |
-
func=
|
| 741 |
-
description="
|
| 742 |
)
|
|
|
|
| 561 |
# --- New Tools ---
|
| 562 |
|
| 563 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 564 |
def extract_text_from_image(image_path: str) -> str:
|
| 565 |
try:
|
| 566 |
image = Image.open(image_path)
|
|
|
|
| 615 |
)
|
| 616 |
|
| 617 |
# =========================
|
| 618 |
+
# Smart File Download Tool (Consolidated)
|
| 619 |
# =========================
|
| 620 |
|
| 621 |
|
| 622 |
+
def download_file_smart(file_source: str, filename: str = "") -> str:
|
| 623 |
"""
|
| 624 |
+
Smart file download tool that handles:
|
| 625 |
+
- GAIA files (using task_id)
|
| 626 |
+
- Regular URLs
|
| 627 |
+
- Content saving
|
| 628 |
|
| 629 |
Args:
|
| 630 |
+
file_source: task_id, URL, or content to save
|
| 631 |
+
filename: Optional filename (auto-generated if not provided)
|
| 632 |
"""
|
| 633 |
try:
|
| 634 |
+
# Auto-detect the type of file_source
|
| 635 |
+
if file_source.startswith(('http://', 'https://')):
|
| 636 |
+
# Regular URL download
|
| 637 |
+
if filename == "":
|
| 638 |
+
path = urlparse(file_source).path
|
| 639 |
+
filename = os.path.basename(path)
|
| 640 |
+
if not filename:
|
| 641 |
+
filename = f"downloaded_{uuid.uuid4().hex[:8]}"
|
| 642 |
|
| 643 |
+
temp_dir = tempfile.gettempdir()
|
| 644 |
+
filepath = os.path.join(temp_dir, filename)
|
|
|
|
| 645 |
|
| 646 |
+
response = requests.get(file_source, stream=True, timeout=15)
|
| 647 |
+
response.raise_for_status()
|
| 648 |
|
| 649 |
+
with open(filepath, "wb") as f:
|
| 650 |
+
for chunk in response.iter_content(chunk_size=8192):
|
| 651 |
+
f.write(chunk)
|
| 652 |
|
| 653 |
+
return f"File downloaded to {filepath}. You can read this file to process its contents."
|
|
|
|
|
|
|
| 654 |
|
| 655 |
+
elif len(file_source) == 36 and '-' in file_source:
|
| 656 |
+
# Likely a GAIA task_id (UUID format)
|
| 657 |
+
if filename == "":
|
| 658 |
+
filename = f"gaia_file_{file_source}"
|
| 659 |
|
| 660 |
+
api_url = "https://agents-course-unit4-scoring.hf.space"
|
| 661 |
+
file_url = f"{api_url}/files/{file_source}"
|
| 662 |
|
| 663 |
+
temp_dir = tempfile.gettempdir()
|
| 664 |
+
filepath = os.path.join(temp_dir, filename)
|
|
|
|
|
|
|
|
|
|
| 665 |
|
| 666 |
+
response = requests.get(file_url, stream=True, timeout=15)
|
| 667 |
+
response.raise_for_status()
|
|
|
|
| 668 |
|
| 669 |
+
with open(filepath, "wb") as f:
|
| 670 |
+
for chunk in response.iter_content(chunk_size=8192):
|
| 671 |
+
f.write(chunk)
|
| 672 |
|
| 673 |
+
return f"GAIA file downloaded to {filepath}. You can read this file to process its contents."
|
|
|
|
|
|
|
| 674 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 675 |
else:
|
| 676 |
+
# Treat as content to save
|
| 677 |
+
if filename == "":
|
| 678 |
+
temp_file = tempfile.NamedTemporaryFile(
|
| 679 |
+
delete=False, dir=tempfile.gettempdir())
|
| 680 |
+
filepath = temp_file.name
|
| 681 |
+
else:
|
| 682 |
+
filepath = os.path.join(tempfile.gettempdir(), filename)
|
| 683 |
+
|
| 684 |
+
with open(filepath, "w") as f:
|
| 685 |
+
f.write(file_source)
|
| 686 |
+
|
| 687 |
+
return f"Content saved to {filepath}. You can read this file to process its contents."
|
| 688 |
|
| 689 |
except Exception as e:
|
| 690 |
return f"Error handling file: {str(e)}"
|
| 691 |
|
| 692 |
|
| 693 |
+
download_file_tool = Tool(
|
| 694 |
+
name="download_file_tool",
|
| 695 |
+
func=download_file_smart,
|
| 696 |
+
description="Smart file download tool: automatically detects if input is a GAIA task_id, URL, or content and handles accordingly. Use this for all file operations."
|
| 697 |
)
|