Svetlana commited on
Commit
7cb927e
Β·
1 Parent(s): 81917a3

feat: implement an agent

Browse files
Files changed (6) hide show
  1. .env.example +3 -0
  2. README.md +1 -1
  3. agent.py +53 -0
  4. app.py +16 -12
  5. requirements.txt +5 -1
  6. tools.py +79 -0
.env.example ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ SPACE_ID=
2
+ SPACE_HOST=
3
+ OPENROUTER_KEY=
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: Template Final Assignment
3
  emoji: πŸ•΅πŸ»β€β™‚οΈ
4
  colorFrom: indigo
5
  colorTo: indigo
 
1
  ---
2
+ title: Final Assignment
3
  emoji: πŸ•΅πŸ»β€β™‚οΈ
4
  colorFrom: indigo
5
  colorTo: indigo
agent.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import random
3
+ import os
4
+ from smolagents import DuckDuckGoSearchTool, CodeAgent, WikipediaSearchTool, LiteLLMModel
5
+ from tools import DownloadTaskAttachmentTool, VisitWebpageTool
6
+
7
+
8
+ class MyAgent:
9
+ def __init__(self):
10
+ self.agent = CodeAgent(
11
+ model=LiteLLMModel(model_id="openrouter/meta-llama/llama-4-maverick:free", api_key=os.getenv("OPENROUTER_KEY")),
12
+ tools=[DuckDuckGoSearchTool(), WikipediaSearchTool(), VisitWebpageTool(), DownloadTaskAttachmentTool()],
13
+ add_base_tools=True,
14
+ additional_authorized_imports=['pandas', 'numpy', 'csv', 'subprocess', 'exec']
15
+ )
16
+ print("MyAgent initialized.")
17
+
18
+ def __call__(self, question: str) -> str:
19
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
20
+ agent_answer = self.agent.run(question)
21
+ print(f"Agent answer: {agent_answer}")
22
+ return agent_answer
23
+
24
+ def download_file(self, task_id: str) -> str:
25
+ """
26
+ Downloads a file associated with the given task ID.
27
+ Returns the file path where the file is saved locally.
28
+ """
29
+ file_url = f"{DEFAULT_API_URL}/files/{task_id}"
30
+ local_file_path = f"downloads/{task_id}.file"
31
+
32
+ print(f"Downloading file for task ID {task_id} from {file_url}...")
33
+ try:
34
+ response = requests.get(file_url, stream=True, timeout=15)
35
+ response.raise_for_status()
36
+
37
+ os.makedirs("downloads", exist_ok=True)
38
+ with open(local_file_path, "wb") as file:
39
+ for chunk in response.iter_content(chunk_size=8192):
40
+ file.write(chunk)
41
+
42
+ print(f"File downloaded successfully: {local_file_path}")
43
+ return local_file_path
44
+ except requests.exceptions.RequestException as e:
45
+ print(f"Error downloading file for task {task_id}: {e}")
46
+ raise
47
+
48
+ def launch_ui(self):
49
+ GradioUI(self.agent).launch()
50
+
51
+ # if __name__ == "__main__":
52
+ # my_agent = MyAgent()
53
+ # my_agent.launch_ui()
app.py CHANGED
@@ -4,20 +4,12 @@ import requests
4
  import inspect
5
  import pandas as pd
6
 
 
 
7
  # (Keep Constants as is)
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
- # --- Basic Agent Definition ---
12
- # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
13
- class BasicAgent:
14
- def __init__(self):
15
- print("BasicAgent initialized.")
16
- def __call__(self, question: str) -> str:
17
- print(f"Agent received question (first 50 chars): {question[:50]}...")
18
- fixed_answer = "This is a default answer."
19
- print(f"Agent returning fixed answer: {fixed_answer}")
20
- return fixed_answer
21
 
22
  def run_and_submit_all( profile: gr.OAuthProfile | None):
23
  """
@@ -40,7 +32,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
40
 
41
  # 1. Instantiate Agent ( modify this part to create your agent)
42
  try:
43
- agent = BasicAgent()
44
  except Exception as e:
45
  print(f"Error instantiating agent: {e}")
46
  return f"Error initializing agent: {e}", None
@@ -76,13 +68,25 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
76
  for item in questions_data:
77
  task_id = item.get("task_id")
78
  question_text = item.get("question")
 
 
79
  if not task_id or question_text is None:
80
  print(f"Skipping item with missing task_id or question: {item}")
81
  continue
 
82
  try:
83
- submitted_answer = agent(question_text)
 
 
 
 
 
 
 
 
84
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
85
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
 
86
  except Exception as e:
87
  print(f"Error running agent on task {task_id}: {e}")
88
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
 
4
  import inspect
5
  import pandas as pd
6
 
7
+ from agent import MyAgent
8
+
9
  # (Keep Constants as is)
10
  # --- Constants ---
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  def run_and_submit_all( profile: gr.OAuthProfile | None):
15
  """
 
32
 
33
  # 1. Instantiate Agent ( modify this part to create your agent)
34
  try:
35
+ agent = MyAgent()
36
  except Exception as e:
37
  print(f"Error instantiating agent: {e}")
38
  return f"Error initializing agent: {e}", None
 
68
  for item in questions_data:
69
  task_id = item.get("task_id")
70
  question_text = item.get("question")
71
+ requires_file = item.get("requires_file", False)
72
+
73
  if not task_id or question_text is None:
74
  print(f"Skipping item with missing task_id or question: {item}")
75
  continue
76
+
77
  try:
78
+ # Download file if required
79
+ if requires_file:
80
+ file_path = agent.download_file(task_id)
81
+ print(f"File for task {task_id} saved at: {file_path}")
82
+ # Optionally, pass the file path to the agent if needed
83
+ submitted_answer = agent(f"{question_text} (File: {file_path})")
84
+ else:
85
+ submitted_answer = agent(question_text)
86
+
87
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
88
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
89
+ time.sleep(2)
90
  except Exception as e:
91
  print(f"Error running agent on task {task_id}: {e}")
92
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
requirements.txt CHANGED
@@ -1,2 +1,6 @@
1
  gradio
2
- requests
 
 
 
 
 
1
  gradio
2
+ requests
3
+ smolagents
4
+ litellm
5
+ wikipedia-api
6
+ google.auth
tools.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import re
3
+ from markdownify import markdownify
4
+ from smolagents import Tool
5
+
6
+ class DownloadTaskAttachmentTool(Tool):
7
+ name = "download_file"
8
+ description = "Downloads the file attached to the task ID"
9
+ inputs = {'task_id': {'type': 'string', 'description': 'The task id to download attachment from.'}}
10
+ output_type = "string"
11
+
12
+ def forward(self, task_id: str) -> str:
13
+ """
14
+ Downloads a file associated with the given task ID.
15
+ Returns the file path where the file is saved locally.
16
+ """
17
+ file_url = f"{DEFAULT_API_URL}/files/{task_id}"
18
+ local_file_path = f"downloads/{task_id}.file"
19
+
20
+ print(f"Downloading file for task ID {task_id} from {file_url}...")
21
+ try:
22
+ response = requests.get(file_url, stream=True, timeout=15)
23
+ response.raise_for_status()
24
+
25
+ os.makedirs("downloads", exist_ok=True)
26
+ with open(local_file_path, "wb") as file:
27
+ for chunk in response.iter_content(chunk_size=8192):
28
+ file.write(chunk)
29
+
30
+ print(f"File downloaded successfully: {local_file_path}")
31
+ return local_file_path
32
+ except requests.exceptions.RequestException as e:
33
+ print(f"Error downloading file for task {task_id}: {e}")
34
+ raise
35
+
36
+ def __init__(self, *args, **kwargs):
37
+ self.is_initialized = False
38
+
39
+
40
+ class VisitWebpageTool(Tool):
41
+ name = "visit_webpage"
42
+ description = "Visits a webpage at the given url and reads its content as a markdown string. Use this to browse webpages."
43
+ inputs = {'url': {'type': 'string', 'description': 'The url of the webpage to visit.'}}
44
+ output_type = "string"
45
+
46
+ def forward(self, url: str) -> str:
47
+ try:
48
+ import requests
49
+ from markdownify import markdownify
50
+ from requests.exceptions import RequestException
51
+
52
+ from smolagents.utils import truncate_content
53
+ except ImportError as e:
54
+ raise ImportError(
55
+ "You must install packages `markdownify` and `requests` to run this tool: for instance run `pip install markdownify requests`."
56
+ ) from e
57
+ try:
58
+ # Send a GET request to the URL with a 20-second timeout
59
+ response = requests.get(url, timeout=20)
60
+ response.raise_for_status() # Raise an exception for bad status codes
61
+
62
+ # Convert the HTML content to Markdown
63
+ markdown_content = markdownify(response.text).strip()
64
+
65
+ # Remove multiple line breaks
66
+ markdown_content = re.sub(r"\n{3,}", "\n\n", markdown_content)
67
+
68
+ return truncate_content(markdown_content, 10000)
69
+
70
+ except requests.exceptions.Timeout:
71
+ return "The request timed out. Please try again later or check the URL."
72
+ except RequestException as e:
73
+ return f"Error fetching the webpage: {str(e)}"
74
+ except Exception as e:
75
+ return f"An unexpected error occurred: {str(e)}"
76
+
77
+ def __init__(self, *args, **kwargs):
78
+ self.is_initialized = False
79
+