Milkfish033 commited on
Commit
d6a77ec
·
1 Parent(s): 81917a3
Files changed (2) hide show
  1. app.py +36 -1
  2. tool.py +123 -0
app.py CHANGED
@@ -10,15 +10,50 @@ 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
  """
24
  Fetches all questions, runs the BasicAgent on them, submits all answers,
 
10
 
11
  # --- Basic Agent Definition ---
12
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
13
+ from smolagents import CodeAgent, OpenAIModel
14
+ from tool import web_search_tool, web_fetch_tool
15
+
16
+ #model used for CodeAgent, need to be multi-modal
17
+ llm= OpenAIModel(
18
+ model="gpt-4o", # or gpt-4.1, gpt-4-turbo
19
+ api_key="YOUR_API_KEY",
20
+ )
21
+
22
  class BasicAgent:
23
  def __init__(self):
24
+
25
  print("BasicAgent initialized.")
26
+ self.smart_agent = CodeAgent(
27
+ tools=[web_search_tool, web_fetch_tool],
28
+ model=llm,
29
+ max_steps = 5,
30
+ )
31
+
32
  def __call__(self, question: str) -> str:
33
  print(f"Agent received question (first 50 chars): {question[:50]}...")
34
+
35
+ help_prompt = (
36
+ "You are a general AI assistant. "
37
+ "Answer the following question and respond ONLY using this template:\n"
38
+ "FINAL ANSWER: [ANSWER]\n\n"
39
+ "Rules:\n"
40
+ "- The answer should be a number, a few words, or a comma-separated list.\n"
41
+ "- Do NOT include explanations or reasoning.\n"
42
+ "- Do NOT use units unless explicitly requested.\n"
43
+ "- Do NOT use articles (a, an, the).\n"
44
+ "- Write digits in plain text unless specified otherwise.\n\n"
45
+ "Question:\n"
46
+ )
47
+ fixed_answer = self.smart_agent.run(help_prompt + question)
48
+
49
+
50
  print(f"Agent returning fixed answer: {fixed_answer}")
51
+
52
  return fixed_answer
53
 
54
+
55
+
56
+
57
  def run_and_submit_all( profile: gr.OAuthProfile | None):
58
  """
59
  Fetches all questions, runs the BasicAgent on them, submits all answers,
tool.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from smolagents import DuckDuckGoSearchTool
2
+
3
+ # Initialize the DuckDuckGo search tool
4
+ web_search_tool = DuckDuckGoSearchTool()
5
+
6
+ from smolagents import Tool
7
+ import json
8
+ import os
9
+
10
+ # PDF support
11
+ import pdfplumber
12
+
13
+ # CSV support
14
+ import csv
15
+
16
+
17
+ class FileReader(Tool):
18
+ name = "file_reader"
19
+ description = (
20
+ "Read local files and return extracted text. "
21
+ "Supports PDF, JSON, TXT, and CSV."
22
+ )
23
+
24
+ inputs = {
25
+ "path": {
26
+ "type": "string",
27
+ "description": "Path to the file on disk"
28
+ }
29
+ }
30
+
31
+ output_type = "string"
32
+
33
+ def forward(self, path: str) -> str:
34
+ if not os.path.exists(path):
35
+ return f"Error: file not found at {path}"
36
+
37
+ ext = os.path.splitext(path)[1].lower()
38
+
39
+ try:
40
+ if ext == ".pdf":
41
+ return self._read_pdf(path)
42
+
43
+ elif ext == ".json":
44
+ return self._read_json(path)
45
+
46
+ elif ext == ".txt":
47
+ return self._read_txt(path)
48
+
49
+ elif ext == ".csv":
50
+ return self._read_csv(path)
51
+
52
+ else:
53
+ return f"Unsupported file type: {ext}"
54
+
55
+ except Exception as e:
56
+ return f"Error reading file: {str(e)}"
57
+
58
+ def _read_pdf(self, path: str) -> str:
59
+ text = []
60
+ with pdfplumber.open(path) as pdf:
61
+ for page in pdf.pages:
62
+ page_text = page.extract_text()
63
+ if page_text:
64
+ text.append(page_text)
65
+ return "\n".join(text)
66
+
67
+ def _read_json(self, path: str) -> str:
68
+ with open(path, "r", encoding="utf-8") as f:
69
+ data = json.load(f)
70
+ return json.dumps(data, indent=2)
71
+
72
+ def _read_txt(self, path: str) -> str:
73
+ with open(path, "r", encoding="utf-8") as f:
74
+ return f.read()
75
+
76
+ def _read_csv(self, path: str) -> str:
77
+ rows = []
78
+ with open(path, newline="", encoding="utf-8") as f:
79
+ reader = csv.reader(f)
80
+ for row in reader:
81
+ rows.append(", ".join(row))
82
+ return "\n".join(rows)
83
+
84
+
85
+ file_reader_tool = FileReader()
86
+
87
+
88
+ from smolagents import Tool
89
+ import httpx
90
+ from bs4 import BeautifulSoup
91
+
92
+ class WebFetch(Tool):
93
+ name = "web_fetch"
94
+ description = "Fetch and read webpage content from a URL."
95
+ inputs = {
96
+ "url": {
97
+ "type": "string",
98
+ "description": "URL of the webpage to read"
99
+ }
100
+ }
101
+ output_type = "string"
102
+
103
+ def forward(self, url: str) -> str:
104
+ try:
105
+ with httpx.Client(follow_redirects=True, timeout=20) as client:
106
+ r = client.get(url)
107
+ r.raise_for_status()
108
+
109
+ soup = BeautifulSoup(r.text, "html.parser")
110
+
111
+ # Remove scripts, styles, nav, footer
112
+ for tag in soup(["script", "style", "noscript", "nav", "footer", "header", "aside"]):
113
+ tag.decompose()
114
+
115
+ text = soup.get_text(separator="\n")
116
+ lines = [line.strip() for line in text.splitlines() if line.strip()]
117
+
118
+ return "\n".join(lines[:5000]) # cap length for LLM
119
+
120
+ except Exception as e:
121
+ return f"Error fetching page: {str(e)}"
122
+
123
+ web_fetch_tool = WebFetch()