cyberosa commited on
Commit
7ace26a
Β·
1 Parent(s): c0f5ad3

adding download file of the question

Browse files
Files changed (4) hide show
  1. agents.py +9 -3
  2. app.py +26 -19
  3. tools.py +63 -0
  4. utils.py +64 -0
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
- fixed_answer = self.agent.run(question, max_steps=10)
 
 
 
 
 
 
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=30
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": submitted_answer}
90
  )
91
  results_log.append(
92
  {
93
  "Task ID": task_id,
94
  "Question": question_text,
95
- "Submitted Answer": 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
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
173
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
174
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
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