yannis2025 commited on
Commit
ab886aa
·
verified ·
1 Parent(s): b00e015

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -25
app.py CHANGED
@@ -6,6 +6,7 @@ import re
6
  import sympy as sp
7
  import wikipedia
8
  from bs4 import BeautifulSoup
 
9
 
10
  # --- Constants ---
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
@@ -27,14 +28,13 @@ class BasicAgent:
27
  reasoning = []
28
 
29
  # Step 1: Try math-based questions
30
- is_math = any(keyword in question.lower() for keyword in [
31
- "calculate", "solve", "what is", "+", "-", "*", "/", "=",
32
- "equation", "how many", "number of", "count", "total"
33
- ])
34
  if is_math:
35
  try:
36
  expr = question.lower()
37
- for keyword in ["what is", "how many", "calculate", "solve", "number of", "count", "of"]:
38
  expr = expr.replace(keyword, "").strip()
39
  if "=" in expr:
40
  left, right = expr.split("=")
@@ -47,7 +47,7 @@ class BasicAgent:
47
  concise_answer = str(result)
48
  reasoning.append(f"Math Solver: Evaluated '{expr}'. Result: {concise_answer}")
49
  if concise_answer != "No solution":
50
- print(f"Returning math answer: {result}")
51
  return concise_answer, "\n".join(reasoning)
52
  except Exception as e:
53
  print(f"Math failed: {e}")
@@ -56,13 +56,15 @@ class BasicAgent:
56
  # Step 2: Try Wikipedia for factual questions
57
  try:
58
  wikipedia.set_lang("en")
59
- key_terms = " ".join(question.split()[:5]).strip("?")
 
 
60
  print(f"Searching Wikipedia for: {key_terms}")
61
- wiki_summary = wikipedia.summary(key_terms, sentences=3, auto_suggest=True, parser_features="html.parser")
62
  prompt = (
63
  f"Question: {question}\n"
64
  f"Context: {wiki_summary}\n"
65
- "Provide a concise answer (e.g., a number or short phrase) based on the context."
66
  )
67
  wiki_answer = self._query_llm(prompt)
68
  if wiki_answer.startswith("Error"):
@@ -71,15 +73,18 @@ class BasicAgent:
71
  answer_match = re.search(r"Answer: (.*?)(?:\n|$)", wiki_answer, re.DOTALL)
72
  if answer_match:
73
  concise_answer = answer_match.group(1).strip()
74
- reasoning.append(f"Wiki: Searched '{key_terms}'. Answer: {concise_answer}")
75
  else:
76
  concise_answer = self._extract_concise_answer(wiki_answer)
77
- reasoning.append(f"Wiki: Searched '{key_terms}'. Parsed answer: {concise_answer}")
78
- print(f"Returning Wiki answer: {concise_answer}")
79
  return concise_answer, "\n".join(reasoning)
80
  except wikipedia.exceptions.DisambiguationError as e:
81
  print(f"Wikipedia disambiguation: {e}")
82
  reasoning.append(f"Wikipedia: Disambiguation error - {e}")
 
 
 
83
  except Exception as e:
84
  print(f"Wikipedia failed: {e}")
85
  reasoning.append(f"Wikipedia failed: {e}")
@@ -89,8 +94,8 @@ class BasicAgent:
89
  search_url = f"https://duckduckgo.com/html/?q={question.replace(' ', '+')}"
90
  response = requests.get(search_url, timeout=10, headers={"User-Agent": "Mozilla/5.0"})
91
  response.raise_for_status()
92
- soup = BeautifulSoup(response.text, "html.parser")
93
- snippets = [s.text.strip() for s in soup.find_all("div", class_="result__snippet")[:2]]
94
  if snippets:
95
  prompt = (
96
  f"Question: {question}\n"
@@ -99,7 +104,7 @@ class BasicAgent:
99
  )
100
  search_answer = self._query_llm(prompt)
101
  if search_answer.startswith("Error"):
102
- reasoning.append(search_answer[:100])
103
  else:
104
  answer_match = re.search(r"Answer: (.*?)(?:\n|$)", search_answer, re.DOTALL)
105
  if answer_match:
@@ -120,8 +125,7 @@ class BasicAgent:
120
  try:
121
  prompt = (
122
  f"Question: {question}\n"
123
- "Provide a concise answer (e.g., a number or short phrase). "
124
- "Answer: "
125
  )
126
  full_response = self._query_llm(prompt)
127
  if full_response.startswith("Error"):
@@ -140,6 +144,7 @@ class BasicAgent:
140
  print(f"LLM error: {e}")
141
  return "Unknown", f"LLM failed: {e}"
142
 
 
143
  def _query_llm(self, prompt: str) -> str:
144
  try:
145
  payload = {
@@ -147,8 +152,8 @@ class BasicAgent:
147
  "parameters": {"max_length": 200, "return_full_text": False}
148
  }
149
  response = requests.post(self.api_url, headers=self.headers, json=payload, timeout=15)
150
- if response.status_code == 402:
151
- return "Error: API rate limit or payment required"
152
  response.raise_for_status()
153
  result = response.json()
154
  if isinstance(result, list) and result:
@@ -336,17 +341,17 @@ if __name__ == "__main__":
336
  space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
337
 
338
  if space_host_startup:
339
- print(f"✅ SPACE_HOST found: {space_host_startup}")
340
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
341
  else:
342
- print("ℹSPACE_HOST environment variable not found (running locally?).")
343
 
344
- if space_id_startup: # Print repo URLs if SPACE_ID is found
345
- print(f"✅ SPACE_ID found: {space_id_startup}")
346
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
347
  print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
348
  else:
349
- print("ℹSPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
350
 
351
  print("-"*(60 + len(" App Starting ")) + "\n")
352
 
 
6
  import sympy as sp
7
  import wikipedia
8
  from bs4 import BeautifulSoup
9
+ from tenacity import retry, stop_after_attempt, wait_fixed
10
 
11
  # --- Constants ---
12
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
 
28
  reasoning = []
29
 
30
  # Step 1: Try math-based questions
31
+ is_math = bool(re.search(r'\d+|[+\-*/=]', question.lower())) and any(
32
+ keyword in question.lower() for keyword in ["calculate", "solve", "what is", "equation"]
33
+ )
 
34
  if is_math:
35
  try:
36
  expr = question.lower()
37
+ for keyword in ["what is", "calculate", "solve"]:
38
  expr = expr.replace(keyword, "").strip()
39
  if "=" in expr:
40
  left, right = expr.split("=")
 
47
  concise_answer = str(result)
48
  reasoning.append(f"Math Solver: Evaluated '{expr}'. Result: {concise_answer}")
49
  if concise_answer != "No solution":
50
+ print(f"Returning math answer: {concise_answer}")
51
  return concise_answer, "\n".join(reasoning)
52
  except Exception as e:
53
  print(f"Math failed: {e}")
 
56
  # Step 2: Try Wikipedia for factual questions
57
  try:
58
  wikipedia.set_lang("en")
59
+ # Extract key nouns for search
60
+ words = question.lower().split()
61
+ key_terms = " ".join([w for w in words if w not in ["what", "is", "the", "of", "in", "on", "at", "by", "for", "?"]][:5])
62
  print(f"Searching Wikipedia for: {key_terms}")
63
+ wiki_summary = wikipedia.summary(key_terms, sentences=3, auto_suggest=True)
64
  prompt = (
65
  f"Question: {question}\n"
66
  f"Context: {wiki_summary}\n"
67
+ "Provide a concise answer (e.g., a number or short phrase): "
68
  )
69
  wiki_answer = self._query_llm(prompt)
70
  if wiki_answer.startswith("Error"):
 
73
  answer_match = re.search(r"Answer: (.*?)(?:\n|$)", wiki_answer, re.DOTALL)
74
  if answer_match:
75
  concise_answer = answer_match.group(1).strip()
76
+ reasoning.append(f"Wikipedia: Searched '{key_terms}'. Answer: {concise_answer}")
77
  else:
78
  concise_answer = self._extract_concise_answer(wiki_answer)
79
+ reasoning.append(f"Wikipedia: Searched '{key_terms}'. Parsed answer: {concise_answer}")
80
+ print(f"Returning Wikipedia answer: {concise_answer}")
81
  return concise_answer, "\n".join(reasoning)
82
  except wikipedia.exceptions.DisambiguationError as e:
83
  print(f"Wikipedia disambiguation: {e}")
84
  reasoning.append(f"Wikipedia: Disambiguation error - {e}")
85
+ except wikipedia.exceptions.PageError:
86
+ print(f"Wikipedia page not found for: {key_terms}")
87
+ reasoning.append(f"Wikipedia: Page not found - {key_terms}")
88
  except Exception as e:
89
  print(f"Wikipedia failed: {e}")
90
  reasoning.append(f"Wikipedia failed: {e}")
 
94
  search_url = f"https://duckduckgo.com/html/?q={question.replace(' ', '+')}"
95
  response = requests.get(search_url, timeout=10, headers={"User-Agent": "Mozilla/5.0"})
96
  response.raise_for_status()
97
+ soup = BeautifulSoup(response.text, "html.parser", parser_features="html.parser")
98
+ snippets = [s.text.strip() for s in soup.find_all("a", class_="result__snippet")[:2]]
99
  if snippets:
100
  prompt = (
101
  f"Question: {question}\n"
 
104
  )
105
  search_answer = self._query_llm(prompt)
106
  if search_answer.startswith("Error"):
107
+ reasoning.append(f"Search response: {search_answer}")
108
  else:
109
  answer_match = re.search(r"Answer: (.*?)(?:\n|$)", search_answer, re.DOTALL)
110
  if answer_match:
 
125
  try:
126
  prompt = (
127
  f"Question: {question}\n"
128
+ "Provide a concise answer (e.g., a number or short phrase): "
 
129
  )
130
  full_response = self._query_llm(prompt)
131
  if full_response.startswith("Error"):
 
144
  print(f"LLM error: {e}")
145
  return "Unknown", f"LLM failed: {e}"
146
 
147
+ @retry(stop=stop_after_attempt(3), wait=wait_fixed(2))
148
  def _query_llm(self, prompt: str) -> str:
149
  try:
150
  payload = {
 
152
  "parameters": {"max_length": 200, "return_full_text": False}
153
  }
154
  response = requests.post(self.api_url, headers=self.headers, json=payload, timeout=15)
155
+ if response.status_code in [402, 429]:
156
+ return f"Error: API status {response.status_code}"
157
  response.raise_for_status()
158
  result = response.json()
159
  if isinstance(result, list) and result:
 
341
  space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
342
 
343
  if space_host_startup:
344
+ print(f"✅ YES: {space_host_startup}")
345
+ print(f" Runtime URL should be: https://{space_host_startup}")
346
  else:
347
+ print("ℹ NO. SPACE_HOST environment variable not found.")
348
 
349
+ if space_id_startup:
350
+ print(f"✅ YES: {space_id_startup}")
351
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
352
  print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
353
  else:
354
+ print("ℹ NO. SPACE_ID environment variable not found. Repo URL cannot be determined.")
355
 
356
  print("-"*(60 + len(" App Starting ")) + "\n")
357