Spaces:
Sleeping
Sleeping
cyberosa
commited on
Commit
Β·
7ace26a
1
Parent(s):
c0f5ad3
adding download file of the question
Browse files
agents.py
CHANGED
@@ -4,10 +4,10 @@ from smolagents import (
|
|
4 |
ToolCallingAgent,
|
5 |
CodeAgent,
|
6 |
VisitWebpageTool,
|
7 |
-
DuckDuckGoSearchTool,
|
8 |
WebSearchTool,
|
9 |
)
|
10 |
import os
|
|
|
11 |
|
12 |
|
13 |
gemini_api_key = os.environ.get("GEMINI_API_KEY", None)
|
@@ -43,8 +43,14 @@ class SkynetMultiAgent:
|
|
43 |
additional_authorized_imports=["time", "numpy", "pandas"],
|
44 |
)
|
45 |
|
46 |
-
def __call__(self, question: str) -> str:
|
47 |
print(f"Agent received question (first 50 chars): {question[:50]}...")
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
print(f"Agent returning fixed answer: {fixed_answer}")
|
50 |
return fixed_answer
|
|
|
4 |
ToolCallingAgent,
|
5 |
CodeAgent,
|
6 |
VisitWebpageTool,
|
|
|
7 |
WebSearchTool,
|
8 |
)
|
9 |
import os
|
10 |
+
from typing import Optional
|
11 |
|
12 |
|
13 |
gemini_api_key = os.environ.get("GEMINI_API_KEY", None)
|
|
|
43 |
additional_authorized_imports=["time", "numpy", "pandas"],
|
44 |
)
|
45 |
|
46 |
+
def __call__(self, question: str, file_path: Optional[str] = None) -> str:
|
47 |
print(f"Agent received question (first 50 chars): {question[:50]}...")
|
48 |
+
# Adding extra content if provided
|
49 |
+
if file_path and os.path.exists(file_path):
|
50 |
+
eval_question = f"{question}\n\nFile provided: {file_path}"
|
51 |
+
print(f"Processing question with file: {file_path}")
|
52 |
+
else:
|
53 |
+
eval_question = question
|
54 |
+
fixed_answer = self.agent.run(eval_question, max_steps=10)
|
55 |
print(f"Agent returning fixed answer: {fixed_answer}")
|
56 |
return fixed_answer
|
app.py
CHANGED
@@ -3,6 +3,7 @@ import gradio as gr
|
|
3 |
import requests
|
4 |
import pandas as pd
|
5 |
from agents import SkynetMultiAgent
|
|
|
6 |
|
7 |
# (Keep Constants as is)
|
8 |
# --- Constants ---
|
@@ -27,7 +28,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
27 |
api_url = DEFAULT_API_URL
|
28 |
questions_url = f"{api_url}/questions"
|
29 |
submit_url = f"{api_url}/submit"
|
30 |
-
|
31 |
# 1. Instantiate Agent ( modify this part to create your agent)
|
32 |
try:
|
33 |
agent = SkynetMultiAgent()
|
@@ -43,7 +44,7 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
43 |
print(f"Fetching questions from: {questions_url}")
|
44 |
try:
|
45 |
response = requests.get(
|
46 |
-
questions_url, timeout=
|
47 |
) # increasing timeout because gemini model.
|
48 |
response.raise_for_status()
|
49 |
questions_data = response.json()
|
@@ -65,34 +66,32 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
65 |
# 3. Run your Agent
|
66 |
results_log = []
|
67 |
answers_payload = []
|
|
|
68 |
print(f"Running agent on {len(questions_data)} questions...")
|
69 |
for item in questions_data:
|
70 |
task_id = item.get("task_id")
|
71 |
-
# try to download the file if available
|
72 |
-
files_url = f"{api_url}/files/{task_id}"
|
73 |
-
try:
|
74 |
-
file_response = requests.get(files_url, timeout=10)
|
75 |
-
if file_response.status_code == 200:
|
76 |
-
item["file_content"] = file_response.text
|
77 |
-
print(f"File for task {task_id} fetched successfully.")
|
78 |
-
else:
|
79 |
-
print(f"No file found for task {task_id}. Status code: {file_response.status_code}")
|
80 |
-
except requests.exceptions.RequestException as e:
|
81 |
-
print(f"Error fetching file for task {task_id}: {e}")
|
82 |
question_text = item.get("question")
|
|
|
83 |
if not task_id or question_text is None:
|
84 |
print(f"Skipping item with missing task_id or question: {item}")
|
85 |
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
try:
|
87 |
-
submitted_answer = agent(question_text)
|
|
|
88 |
answers_payload.append(
|
89 |
-
{"task_id": task_id, "submitted_answer":
|
90 |
)
|
91 |
results_log.append(
|
92 |
{
|
93 |
"Task ID": task_id,
|
94 |
"Question": question_text,
|
95 |
-
"Submitted Answer":
|
96 |
}
|
97 |
)
|
98 |
except Exception as e:
|
@@ -104,6 +103,14 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
|
|
104 |
"Submitted Answer": f"AGENT ERROR: {e}",
|
105 |
}
|
106 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
|
108 |
if not answers_payload:
|
109 |
print("Agent did not produce any answers to submit.")
|
@@ -169,9 +176,9 @@ with gr.Blocks() as demo:
|
|
169 |
"""
|
170 |
**Instructions:**
|
171 |
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
|
176 |
---
|
177 |
**Disclaimers:**
|
|
|
3 |
import requests
|
4 |
import pandas as pd
|
5 |
from agents import SkynetMultiAgent
|
6 |
+
from utils import download_file, clean_answer_for_eval
|
7 |
|
8 |
# (Keep Constants as is)
|
9 |
# --- Constants ---
|
|
|
28 |
api_url = DEFAULT_API_URL
|
29 |
questions_url = f"{api_url}/questions"
|
30 |
submit_url = f"{api_url}/submit"
|
31 |
+
|
32 |
# 1. Instantiate Agent ( modify this part to create your agent)
|
33 |
try:
|
34 |
agent = SkynetMultiAgent()
|
|
|
44 |
print(f"Fetching questions from: {questions_url}")
|
45 |
try:
|
46 |
response = requests.get(
|
47 |
+
questions_url, timeout=60
|
48 |
) # increasing timeout because gemini model.
|
49 |
response.raise_for_status()
|
50 |
questions_data = response.json()
|
|
|
66 |
# 3. Run your Agent
|
67 |
results_log = []
|
68 |
answers_payload = []
|
69 |
+
downloaded_files = []
|
70 |
print(f"Running agent on {len(questions_data)} questions...")
|
71 |
for item in questions_data:
|
72 |
task_id = item.get("task_id")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
question_text = item.get("question")
|
74 |
+
file_name = item.get("file_name")
|
75 |
if not task_id or question_text is None:
|
76 |
print(f"Skipping item with missing task_id or question: {item}")
|
77 |
continue
|
78 |
+
downloaded_file_path = None
|
79 |
+
if file_name:
|
80 |
+
print(f"Task {task_id} has file: {file_name}")
|
81 |
+
downloaded_file_path = download_file(task_id, api_url)
|
82 |
+
if downloaded_file_path:
|
83 |
+
downloaded_files.append(downloaded_file_path)
|
84 |
try:
|
85 |
+
submitted_answer = agent(question_text, downloaded_file_path)
|
86 |
+
cleaned_answer = clean_answer_for_eval(submitted_answer)
|
87 |
answers_payload.append(
|
88 |
+
{"task_id": task_id, "submitted_answer": cleaned_answer}
|
89 |
)
|
90 |
results_log.append(
|
91 |
{
|
92 |
"Task ID": task_id,
|
93 |
"Question": question_text,
|
94 |
+
"Submitted Answer": cleaned_answer,
|
95 |
}
|
96 |
)
|
97 |
except Exception as e:
|
|
|
103 |
"Submitted Answer": f"AGENT ERROR: {e}",
|
104 |
}
|
105 |
)
|
106 |
+
# cleanup downloaded files
|
107 |
+
for file_path in downloaded_files:
|
108 |
+
try:
|
109 |
+
if os.path.exists(file_path):
|
110 |
+
os.remove(file_path)
|
111 |
+
print(f"Removed file: {file_path}")
|
112 |
+
except Exception as e:
|
113 |
+
print(f"Could not remove {file_path}: {e}")
|
114 |
|
115 |
if not answers_payload:
|
116 |
print("Agent did not produce any answers to submit.")
|
|
|
176 |
"""
|
177 |
**Instructions:**
|
178 |
|
179 |
+
|
180 |
+
1. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
|
181 |
+
2. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
|
182 |
|
183 |
---
|
184 |
**Disclaimers:**
|
tools.py
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
from smolagents import Tool
|
4 |
+
from langchain_community.retrievers import BM25Retriever
|
5 |
+
from langchain.docstore.document import Document
|
6 |
+
|
7 |
+
# Create a tool to download a file
|
8 |
+
# The point is: in the basic HF template, you just pass the question to the model,
|
9 |
+
# instead you should provide also the file name when available and then allow the model to
|
10 |
+
# automatically download the file from the /files/{task_id} api
|
11 |
+
# doc https://agents-course-unit4-scoring.hf.space/docs
|
12 |
+
|
13 |
+
class DownloadFilesTool(Tool):
|
14 |
+
name = "topic_info_retriever"
|
15 |
+
description = "Retrieves detailed information about a specific topic from a set of documents."
|
16 |
+
inputs = {
|
17 |
+
"query": {
|
18 |
+
"type": "string",
|
19 |
+
"description": "The topic you want information about.",
|
20 |
+
}
|
21 |
+
}
|
22 |
+
output_type = "string"
|
23 |
+
|
24 |
+
def __init__(self, docs):
|
25 |
+
self.is_initialized = False
|
26 |
+
self.retriever = BM25Retriever.from_documents(docs)
|
27 |
+
|
28 |
+
def forward(self, query: str):
|
29 |
+
results = self.retriever.get_relevant_documents(query)
|
30 |
+
if results:
|
31 |
+
return "\n\n".join([doc.page_content for doc in results[:3]])
|
32 |
+
else:
|
33 |
+
return "No matching guest information found."
|
34 |
+
|
35 |
+
class PythonCodeAnalyzerTool(Tool):
|
36 |
+
name = "python_code_analyzer"
|
37 |
+
description = "Analyzes Python code to identify potential issues. If requested it may execute the code."
|
38 |
+
inputs = {
|
39 |
+
"file_path": {
|
40 |
+
"type": "string",
|
41 |
+
"description": "The Python code file to analyze.",
|
42 |
+
},
|
43 |
+
"question": {
|
44 |
+
"type": "string",
|
45 |
+
"description": "A question or request for analysis of the code.",
|
46 |
+
}
|
47 |
+
}
|
48 |
+
output_type = "string"
|
49 |
+
def __init__(self, file_path: str, question: str):
|
50 |
+
try:
|
51 |
+
# Read the Python file
|
52 |
+
with open(file_path, 'r', encoding='utf-8') as f:
|
53 |
+
self.code_content = f.read()
|
54 |
+
except Exception as e:
|
55 |
+
error_msg = f"Error analyzing Python file: {str(e)}"
|
56 |
+
raise ValueError(error_msg)
|
57 |
+
self.question = question
|
58 |
+
self.is_initialized = True
|
59 |
+
|
60 |
+
def forward(self, code: str):
|
61 |
+
# Placeholder for actual code analysis logic
|
62 |
+
# In a real implementation, you would use a library or service to analyze the code
|
63 |
+
return f"Analyzed code:\n{code}\n\nNo issues found."
|
utils.py
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import requests
|
3 |
+
from typing import Optional
|
4 |
+
import tempfile
|
5 |
+
|
6 |
+
# --- File Download Helper Function ---
|
7 |
+
def download_file(task_id: str, api_url: str) -> Optional[str]:
|
8 |
+
"""Download file associated with a task_id from the evaluation API"""
|
9 |
+
try:
|
10 |
+
file_url = f"{api_url}/files/{task_id}"
|
11 |
+
print(f"π Downloading file for task {task_id}")
|
12 |
+
|
13 |
+
response = requests.get(file_url, timeout=30)
|
14 |
+
response.raise_for_status()
|
15 |
+
|
16 |
+
# Get filename from headers or create one
|
17 |
+
content_disposition = response.headers.get('Content-Disposition', '')
|
18 |
+
if 'filename=' in content_disposition:
|
19 |
+
filename = content_disposition.split('filename=')[1].strip('"')
|
20 |
+
else:
|
21 |
+
content_type = response.headers.get('Content-Type', '')
|
22 |
+
if 'image' in content_type:
|
23 |
+
extension = '.jpg'
|
24 |
+
elif 'audio' in content_type:
|
25 |
+
extension = '.mp3'
|
26 |
+
elif 'video' in content_type:
|
27 |
+
extension = '.mp4'
|
28 |
+
else:
|
29 |
+
extension = '.txt'
|
30 |
+
filename = f"task_{task_id}_file{extension}"
|
31 |
+
|
32 |
+
# Save to temporary file
|
33 |
+
temp_dir = tempfile.gettempdir()
|
34 |
+
file_path = os.path.join(temp_dir, filename)
|
35 |
+
|
36 |
+
with open(file_path, 'wb') as f:
|
37 |
+
f.write(response.content)
|
38 |
+
|
39 |
+
print(f"β
File downloaded: {file_path}")
|
40 |
+
return file_path
|
41 |
+
|
42 |
+
except Exception as e:
|
43 |
+
print(f"β Error downloading file for task {task_id}: {e}")
|
44 |
+
return None
|
45 |
+
|
46 |
+
def clean_answer_for_eval(answer: str) -> str:
|
47 |
+
"""Clean the answer string for evaluation purposes."""
|
48 |
+
#
|
49 |
+
if isinstance(answer, str):
|
50 |
+
answer = answer.strip()
|
51 |
+
|
52 |
+
prefixes_to_remove = [
|
53 |
+
"The answer is: ",
|
54 |
+
"Answer: ",
|
55 |
+
"The result is: ",
|
56 |
+
"Result: ",
|
57 |
+
"The final answer is: ",
|
58 |
+
]
|
59 |
+
|
60 |
+
for prefix in prefixes_to_remove:
|
61 |
+
if answer.startswith(prefix):
|
62 |
+
answer = answer[len(prefix):].strip()
|
63 |
+
break
|
64 |
+
return answer
|