likki1715 commited on
Commit
f2f921c
·
verified ·
1 Parent(s): d717837

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -21
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import os
 
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
@@ -23,7 +24,6 @@ def web_search(query: str) -> str:
23
  except Exception as e:
24
  return f"Search error: {e}"
25
 
26
-
27
  def wikipedia_search(query: str) -> str:
28
  try:
29
  search_url = "https://en.wikipedia.org/w/api.php"
@@ -48,7 +48,6 @@ def wikipedia_search(query: str) -> str:
48
  except Exception as e:
49
  return f"Wikipedia error: {e}"
50
 
51
-
52
  def run_python(code: str) -> str:
53
  import sys
54
  from io import StringIO
@@ -64,14 +63,13 @@ def run_python(code: str) -> str:
64
  finally:
65
  sys.stdout = old_stdout
66
 
67
-
68
  class SmartAgent:
69
  def __init__(self):
70
  self.api_key = os.getenv("GEMINI_API_KEY")
71
  if not self.api_key:
72
  raise ValueError("GEMINI_API_KEY environment variable not set!")
73
- # Gemini 1.5 Flash - FREE tier: 1500 requests/day, 1M tokens/min
74
- self.api_url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite-preview-06-17:generateContent?key={self.api_key}"
75
  print("SmartAgent initialized with Gemini 1.5 Flash (FREE - 1500 req/day)")
76
 
77
  def call_llm(self, prompt: str) -> str:
@@ -82,10 +80,20 @@ class SmartAgent:
82
  "maxOutputTokens": 1024,
83
  }
84
  }
85
- response = requests.post(self.api_url, json=payload, timeout=60)
86
- response.raise_for_status()
87
- data = response.json()
88
- return data["candidates"][0]["content"]["parts"][0]["text"].strip()
 
 
 
 
 
 
 
 
 
 
89
 
90
  def __call__(self, question: str) -> str:
91
  print(f"\nQuestion: {question[:100]}...")
@@ -98,9 +106,10 @@ WIKIPEDIA: <query>
98
  PYTHON: <code>
99
 
100
  After gathering enough info, give your final answer as:
101
- ANSWER: <your answer>
102
 
103
  Rules for the answer:
 
104
  - Numbers only (no units unless asked, no commas in numbers)
105
  - Short phrases (no articles like a/the, no abbreviations for proper nouns)
106
  - Comma-separated list if multiple items needed
@@ -109,6 +118,9 @@ Rules for the answer:
109
  conversation = f"{system}\n\nQuestion: {question}"
110
 
111
  for iteration in range(6):
 
 
 
112
  response = self.call_llm(conversation)
113
  print(f" LLM [{iteration}]: {response[:200]}")
114
 
@@ -116,27 +128,27 @@ Rules for the answer:
116
  answer_match = re.search(r'ANSWER:\s*(.+?)(?:\n|$)', response, re.IGNORECASE)
117
  if answer_match:
118
  answer = answer_match.group(1).strip()
119
- print(f" Final answer: {answer}")
120
  return answer
121
 
122
  tool_result = None
123
 
124
  search_match = re.search(r'SEARCH:\s*(.+?)(?:\n|$)', response)
 
 
 
 
 
 
125
  if search_match:
126
  query = search_match.group(1).strip()
127
  print(f" Tool: web_search({query})")
128
  tool_result = f"Search results for '{query}':\n{web_search(query)}"
129
-
130
- wiki_match = re.search(r'WIKIPEDIA:\s*(.+?)(?:\n|$)', response)
131
- if wiki_match:
132
  query = wiki_match.group(1).strip()
133
  print(f" Tool: wikipedia({query})")
134
  tool_result = f"Wikipedia results for '{query}':\n{wikipedia_search(query)}"
135
-
136
- python_match = re.search(r'PYTHON:\s*```(?:python)?\n?(.*?)```', response, re.DOTALL)
137
- if not python_match:
138
- python_match = re.search(r'PYTHON:\s*(.+?)(?:\nSEARCH|\nWIKIPEDIA|\nANSWER|$)', response, re.DOTALL)
139
- if python_match:
140
  code = python_match.group(1).strip()
141
  print(f" Tool: python({code[:50]})")
142
  tool_result = f"Python output:\n{run_python(code)}"
@@ -146,7 +158,7 @@ Rules for the answer:
146
  else:
147
  conversation += f"\n\nAssistant: {response}\n\nProvide your final answer as: ANSWER: <answer>"
148
 
149
- # Final attempt
150
  conversation += "\n\nGive only the final answer as: ANSWER: <answer>"
151
  last = self.call_llm(conversation)
152
  answer_match = re.search(r'ANSWER:\s*(.+?)(?:\n|$)', last, re.IGNORECASE)
@@ -199,7 +211,9 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
199
  except Exception as e:
200
  print(f"Error on task {task_id}: {e}")
201
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"ERROR: {e}"})
202
- import time; time.sleep(7) # avoid rate limiting (free tier: 15 req/min)
 
 
203
 
204
  if not answers_payload:
205
  return "Agent did not produce any answers.", pd.DataFrame(results_log)
 
1
  import os
2
+ import time
3
  import gradio as gr
4
  import requests
5
  import pandas as pd
 
24
  except Exception as e:
25
  return f"Search error: {e}"
26
 
 
27
  def wikipedia_search(query: str) -> str:
28
  try:
29
  search_url = "https://en.wikipedia.org/w/api.php"
 
48
  except Exception as e:
49
  return f"Wikipedia error: {e}"
50
 
 
51
  def run_python(code: str) -> str:
52
  import sys
53
  from io import StringIO
 
63
  finally:
64
  sys.stdout = old_stdout
65
 
 
66
  class SmartAgent:
67
  def __init__(self):
68
  self.api_key = os.getenv("GEMINI_API_KEY")
69
  if not self.api_key:
70
  raise ValueError("GEMINI_API_KEY environment variable not set!")
71
+ # Valid Gemini 1.5 Flash endpoint string
72
+ self.api_url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={self.api_key}"
73
  print("SmartAgent initialized with Gemini 1.5 Flash (FREE - 1500 req/day)")
74
 
75
  def call_llm(self, prompt: str) -> str:
 
80
  "maxOutputTokens": 1024,
81
  }
82
  }
83
+ # Built-in retry mechanism for Rate Limiting
84
+ for attempt in range(3):
85
+ try:
86
+ response = requests.post(self.api_url, json=payload, timeout=60)
87
+ response.raise_for_status()
88
+ data = response.json()
89
+ return data["candidates"][0]["content"]["parts"][0]["text"].strip()
90
+ except requests.exceptions.HTTPError as e:
91
+ if response.status_code == 429:
92
+ print(f"Rate limited (429)! Waiting 10 seconds... (Attempt {attempt+1}/3)")
93
+ time.sleep(10)
94
+ else:
95
+ raise e
96
+ raise Exception("Failed to call LLM after 3 attempts due to rate limiting.")
97
 
98
  def __call__(self, question: str) -> str:
99
  print(f"\nQuestion: {question[:100]}...")
 
106
  PYTHON: <code>
107
 
108
  After gathering enough info, give your final answer as:
109
+ ANSWER: <your exact short answer>
110
 
111
  Rules for the answer:
112
+ - DO NOT wrap the answer in "FINAL ANSWER: " or any other text. Output strictly "ANSWER: " followed by the exact answer string.
113
  - Numbers only (no units unless asked, no commas in numbers)
114
  - Short phrases (no articles like a/the, no abbreviations for proper nouns)
115
  - Comma-separated list if multiple items needed
 
118
  conversation = f"{system}\n\nQuestion: {question}"
119
 
120
  for iteration in range(6):
121
+ # Slowing down the ReAct loop to respect Gemini's 15 RPM Free Tier limit
122
+ time.sleep(4.5)
123
+
124
  response = self.call_llm(conversation)
125
  print(f" LLM [{iteration}]: {response[:200]}")
126
 
 
128
  answer_match = re.search(r'ANSWER:\s*(.+?)(?:\n|$)', response, re.IGNORECASE)
129
  if answer_match:
130
  answer = answer_match.group(1).strip()
131
+ print(f" {answer}")
132
  return answer
133
 
134
  tool_result = None
135
 
136
  search_match = re.search(r'SEARCH:\s*(.+?)(?:\n|$)', response)
137
+ wiki_match = re.search(r'WIKIPEDIA:\s*(.+?)(?:\n|$)', response)
138
+ python_match = re.search(r'PYTHON:\s*```(?:python)?\n?(.*?)```', response, re.DOTALL)
139
+ if not python_match:
140
+ python_match = re.search(r'PYTHON:\s*(.+?)(?:\nSEARCH|\nWIKIPEDIA|\nANSWER|$)', response, re.DOTALL)
141
+
142
+ # Execution logic changed to 'elif' to avoid overlapping tool executions
143
  if search_match:
144
  query = search_match.group(1).strip()
145
  print(f" Tool: web_search({query})")
146
  tool_result = f"Search results for '{query}':\n{web_search(query)}"
147
+ elif wiki_match:
 
 
148
  query = wiki_match.group(1).strip()
149
  print(f" Tool: wikipedia({query})")
150
  tool_result = f"Wikipedia results for '{query}':\n{wikipedia_search(query)}"
151
+ elif python_match:
 
 
 
 
152
  code = python_match.group(1).strip()
153
  print(f" Tool: python({code[:50]})")
154
  tool_result = f"Python output:\n{run_python(code)}"
 
158
  else:
159
  conversation += f"\n\nAssistant: {response}\n\nProvide your final answer as: ANSWER: <answer>"
160
 
161
+ # Final attempt fallback
162
  conversation += "\n\nGive only the final answer as: ANSWER: <answer>"
163
  last = self.call_llm(conversation)
164
  answer_match = re.search(r'ANSWER:\s*(.+?)(?:\n|$)', last, re.IGNORECASE)
 
211
  except Exception as e:
212
  print(f"Error on task {task_id}: {e}")
213
  results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"ERROR: {e}"})
214
+
215
+ # Pausing between questions to ensure global RPM limit safety
216
+ time.sleep(5)
217
 
218
  if not answers_payload:
219
  return "Agent did not produce any answers.", pd.DataFrame(results_log)