Kackle commited on
Commit
335d05f
·
verified ·
1 Parent(s): 30b74d9

login button async

Browse files
Files changed (1) hide show
  1. app.py +128 -86
app.py CHANGED
@@ -3,6 +3,8 @@ import gradio as gr
3
  import requests
4
  import inspect
5
  import pandas as pd
 
 
6
  from smolagents import FinalAnswerTool, Tool, tool, OpenAIServerModel, DuckDuckGoSearchTool, CodeAgent, VisitWebpageTool
7
 
8
 
@@ -21,21 +23,23 @@ OPENAI_TOKEN = os.getenv("OPENAI_API_KEY")
21
  class SlpMultiAgent:
22
  def __init__(self):
23
  print("BasicAgent initialized.")
24
- def __call__(self, question: str) -> str:
 
25
  print(f"Agent received question (first 50 chars): {question[:50]}...")
26
  fixed_answer = "This is a default answer."
27
  print(f"Agent returning fixed answer: {fixed_answer}")
28
 
29
- # Truncate question to avoid exceeding model context length
30
  MAX_QUESTION_LENGTH = 1000
31
- short_question = question[:MAX_QUESTION_LENGTH]
32
 
33
- # Use GPT-4o model with larger context window
34
  model = OpenAIServerModel(
35
  model_id="gpt-4o",
36
  temperature=0.0,
37
  max_tokens=1500
38
  )
 
39
  # Here you can implement your agent logic, tools, and model calls
40
  web_agent = CodeAgent(
41
  tools=[DuckDuckGoSearchTool(), VisitWebpageTool()],
@@ -48,41 +52,49 @@ class SlpMultiAgent:
48
  )
49
 
50
  manager_agent = CodeAgent(
51
- model=OpenAIServerModel("gpt-4o"),
52
- tools=[],
53
- managed_agents=[web_agent],
54
- name="ManagerAgent",
55
- description="A manager agent that can delegate tasks to other agents and manage their execution.",
56
- additional_authorized_imports=[
57
- "pandas",
58
- ],
59
- planning_interval=5,
60
- verbosity_level=2,
61
- max_steps=15,
62
- final_answer_checks=[check_reasoning]
63
- )
64
- manager_agent.run(f"""
65
- You are a question answering agent. That specializes in complex questions that require multiple steps to answer.
66
- Take a few steps and think about the question before answering.
67
- You can use the tools available to you, but you should not use them unless necessary.
68
- You should always try to answer the question using your own knowledge and reasoning.
69
- If you need to use a tool, you should explain why you are using it and what you expect to find.
70
- If you are not sure about something, you should say so and explain why you are not sure.
71
- You should always try to provide a complete and accurate answer to the question.
72
- If you are not able to answer the question, you should say so and explain why
73
-
74
- Never try to process strings using code: when you have a string to read, just print it and you'll see it.
75
-
76
- Here is the question: {short_question}
77
- Thoughts: [your reasoning about how to solve the problem]
78
- Code:
79
- ```py
80
- # Your Python code here
81
- ```<end_code>
82
-
83
- The code block MUST start with ```py on its own line and end with ```<end_code> on its own line.
84
- """)
85
- return fixed_answer
 
 
 
 
 
 
 
 
86
 
87
  def check_reasoning(final_answer, agent_memory):
88
  multimodal_model = OpenAIServerModel("gpt-4o",
@@ -112,10 +124,10 @@ def check_reasoning(final_answer, agent_memory):
112
  print("Reasoning check failed. Please review the agent's reasoning.")
113
 
114
 
115
- def run_and_submit_all( profile: gr.OAuthProfile | None):
116
  """
117
  Fetches all questions, runs the BasicAgent on them, submits all answers,
118
- and displays the results.
119
  """
120
  # --- Determine HF Space Runtime URL and Repo URL ---
121
  space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
@@ -144,20 +156,20 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
144
  # 2. Fetch Questions
145
  print(f"Fetching questions from: {questions_url}")
146
  try:
147
- response = requests.get(questions_url, timeout=15)
148
- response.raise_for_status()
149
- questions_data = response.json()
150
- if not questions_data:
151
- print("Fetched questions list is empty.")
152
- return "Fetched questions list is empty or invalid format.", None
153
- print(f"Fetched {len(questions_data)} questions.")
154
- except requests.exceptions.RequestException as e:
 
155
  print(f"Error fetching questions: {e}")
156
  return f"Error fetching questions: {e}", None
157
- except requests.exceptions.JSONDecodeError as e:
158
- print(f"Error decoding JSON response from questions endpoint: {e}")
159
- print(f"Response text: {response.text[:500]}")
160
- return f"Error decoding server response for questions: {e}", None
161
  except Exception as e:
162
  print(f"An unexpected error occurred fetching questions: {e}")
163
  return f"An unexpected error occurred fetching questions: {e}", None
@@ -166,19 +178,36 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
166
  results_log = []
167
  answers_payload = []
168
  print(f"Running agent on {len(questions_data)} questions...")
169
- for item in questions_data:
 
 
 
 
170
  task_id = item.get("task_id")
171
  question_text = item.get("question")
172
  if not task_id or question_text is None:
173
  print(f"Skipping item with missing task_id or question: {item}")
174
- continue
175
- try:
176
- submitted_answer = agent(question_text)
177
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
178
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
179
- except Exception as e:
180
- print(f"Error running agent on task {task_id}: {e}")
181
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
 
 
 
 
 
 
 
 
 
 
 
 
 
182
 
183
  if not answers_payload:
184
  print("Agent did not produce any answers to submit.")
@@ -192,36 +221,41 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
192
  # 5. Submit
193
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
194
  try:
195
- response = requests.post(submit_url, json=submission_data, timeout=60)
196
- response.raise_for_status()
197
- result_data = response.json()
198
- final_status = (
199
- f"Submission Successful!\n"
200
- f"User: {result_data.get('username')}\n"
201
- f"Overall Score: {result_data.get('score', 'N/A')}% "
202
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
203
- f"Message: {result_data.get('message', 'No message received.')}"
204
- )
205
- print("Submission successful.")
206
- results_df = pd.DataFrame(results_log)
207
- return final_status, results_df
208
- except requests.exceptions.HTTPError as e:
209
- error_detail = f"Server responded with status {e.response.status_code}."
 
210
  try:
211
- error_json = e.response.json()
212
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
213
- except requests.exceptions.JSONDecodeError:
214
- error_detail += f" Response: {e.response.text[:500]}"
 
 
 
 
215
  status_message = f"Submission Failed: {error_detail}"
216
  print(status_message)
217
  results_df = pd.DataFrame(results_log)
218
  return status_message, results_df
219
- except requests.exceptions.Timeout:
220
  status_message = "Submission Failed: The request timed out."
221
  print(status_message)
222
  results_df = pd.DataFrame(results_log)
223
  return status_message, results_df
224
- except requests.exceptions.RequestException as e:
225
  status_message = f"Submission Failed: Network error - {e}"
226
  print(status_message)
227
  results_df = pd.DataFrame(results_log)
@@ -251,16 +285,24 @@ with gr.Blocks() as demo:
251
  """
252
  )
253
 
254
- gr.LoginButton()
255
 
256
  run_button = gr.Button("Run Evaluation & Submit All Answers")
257
 
258
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
259
  # Removed max_rows=10 from DataFrame constructor
260
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
261
-
 
 
 
 
 
 
 
262
  run_button.click(
263
- fn=run_and_submit_all,
 
264
  outputs=[status_output, results_table]
265
  )
266
 
 
3
  import requests
4
  import inspect
5
  import pandas as pd
6
+ import asyncio
7
+ import aiohttp
8
  from smolagents import FinalAnswerTool, Tool, tool, OpenAIServerModel, DuckDuckGoSearchTool, CodeAgent, VisitWebpageTool
9
 
10
 
 
23
  class SlpMultiAgent:
24
  def __init__(self):
25
  print("BasicAgent initialized.")
26
+
27
+ async def __call__(self, question: str) -> str:
28
  print(f"Agent received question (first 50 chars): {question[:50]}...")
29
  fixed_answer = "This is a default answer."
30
  print(f"Agent returning fixed answer: {fixed_answer}")
31
 
32
+ # Truncate question to avoid exceeding model context length
33
  MAX_QUESTION_LENGTH = 1000
34
+ short_question = question # [:MAX_QUESTION_LENGTH]
35
 
36
+ # Use GPT-4o model with larger context window
37
  model = OpenAIServerModel(
38
  model_id="gpt-4o",
39
  temperature=0.0,
40
  max_tokens=1500
41
  )
42
+
43
  # Here you can implement your agent logic, tools, and model calls
44
  web_agent = CodeAgent(
45
  tools=[DuckDuckGoSearchTool(), VisitWebpageTool()],
 
52
  )
53
 
54
  manager_agent = CodeAgent(
55
+ model=OpenAIServerModel("gpt-4o"),
56
+ tools=[],
57
+ managed_agents=[web_agent],
58
+ name="ManagerAgent",
59
+ description="A manager agent that can delegate tasks to other agents and manage their execution.",
60
+ additional_authorized_imports=[
61
+ "pandas",
62
+ ],
63
+ planning_interval=5,
64
+ verbosity_level=2,
65
+ max_steps=15,
66
+ final_answer_checks=[check_reasoning]
67
+ )
68
+
69
+ # Create a task for the agent run to avoid blocking
70
+ loop = asyncio.get_event_loop()
71
+ result = await loop.run_in_executor(
72
+ None,
73
+ lambda: manager_agent.run(f"""
74
+ You are a question answering agent. That specializes in complex questions that require multiple steps to answer.
75
+ Take a few steps and think about the question before answering.
76
+ You can use the tools available to you, but you should not use them unless necessary.
77
+ You should always try to answer the question using your own knowledge and reasoning.
78
+ If you need to use a tool, you should explain why you are using it and what you expect to find.
79
+ If you are not sure about something, you should say so and explain why you are not sure.
80
+ You should always try to provide a complete and accurate answer to the question.
81
+ If you are not able to answer the question, you should say so and explain why
82
+
83
+ Never try to process strings using code: when you have a string to read, just print it and you'll see it.
84
+
85
+ Here is the question: {short_question}
86
+ Thoughts: [your reasoning about how to solve the problem]
87
+ Code:
88
+ ```py
89
+ # Your Python code here
90
+ ```<end_code>
91
+
92
+ The code block MUST start with ```py on its own line and end with ```<end_code> on its own line.
93
+ """)
94
+ )
95
+
96
+ # Return the result from the agent
97
+ return result
98
 
99
  def check_reasoning(final_answer, agent_memory):
100
  multimodal_model = OpenAIServerModel("gpt-4o",
 
124
  print("Reasoning check failed. Please review the agent's reasoning.")
125
 
126
 
127
+ async def run_and_submit_all(profile: gr.OAuthProfile | None):
128
  """
129
  Fetches all questions, runs the BasicAgent on them, submits all answers,
130
+ and displays the results asynchronously.
131
  """
132
  # --- Determine HF Space Runtime URL and Repo URL ---
133
  space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
 
156
  # 2. Fetch Questions
157
  print(f"Fetching questions from: {questions_url}")
158
  try:
159
+ async with aiohttp.ClientSession() as session:
160
+ async with session.get(questions_url, timeout=15) as response:
161
+ response.raise_for_status()
162
+ questions_data = await response.json()
163
+ if not questions_data:
164
+ print("Fetched questions list is empty.")
165
+ return "Fetched questions list is empty or invalid format.", None
166
+ print(f"Fetched {len(questions_data)} questions.")
167
+ except aiohttp.ClientError as e:
168
  print(f"Error fetching questions: {e}")
169
  return f"Error fetching questions: {e}", None
170
+ except ValueError as e: # JSON decode error
171
+ print(f"Error decoding JSON response from questions endpoint: {e}")
172
+ return f"Error decoding server response for questions: {e}", None
 
173
  except Exception as e:
174
  print(f"An unexpected error occurred fetching questions: {e}")
175
  return f"An unexpected error occurred fetching questions: {e}", None
 
178
  results_log = []
179
  answers_payload = []
180
  print(f"Running agent on {len(questions_data)} questions...")
181
+
182
+ # Process questions concurrently with a semaphore to limit concurrency
183
+ semaphore = asyncio.Semaphore(3) # Limit to 3 concurrent requests
184
+
185
+ async def process_question(item):
186
  task_id = item.get("task_id")
187
  question_text = item.get("question")
188
  if not task_id or question_text is None:
189
  print(f"Skipping item with missing task_id or question: {item}")
190
+ return None
191
+
192
+ async with semaphore:
193
+ try:
194
+ submitted_answer = await agent(question_text)
195
+ return {"task_id": task_id, "submitted_answer": submitted_answer,
196
+ "log": {"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer}}
197
+ except Exception as e:
198
+ print(f"Error running agent on task {task_id}: {e}")
199
+ return {"task_id": task_id, "submitted_answer": f"AGENT ERROR: {e}",
200
+ "log": {"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"}}
201
+
202
+ # Create tasks for all questions
203
+ tasks = [process_question(item) for item in questions_data]
204
+ results = await asyncio.gather(*tasks)
205
+
206
+ # Process results
207
+ for result in results:
208
+ if result is not None:
209
+ answers_payload.append({"task_id": result["task_id"], "submitted_answer": result["submitted_answer"]})
210
+ results_log.append(result["log"])
211
 
212
  if not answers_payload:
213
  print("Agent did not produce any answers to submit.")
 
221
  # 5. Submit
222
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
223
  try:
224
+ async with aiohttp.ClientSession() as session:
225
+ async with session.post(submit_url, json=submission_data, timeout=60) as response:
226
+ response.raise_for_status()
227
+ result_data = await response.json()
228
+ final_status = (
229
+ f"Submission Successful!\n"
230
+ f"User: {result_data.get('username')}\n"
231
+ f"Overall Score: {result_data.get('score', 'N/A')}% "
232
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
233
+ f"Message: {result_data.get('message', 'No message received.')}"
234
+ )
235
+ print("Submission successful.")
236
+ results_df = pd.DataFrame(results_log)
237
+ return final_status, results_df
238
+ except aiohttp.ClientResponseError as e:
239
+ error_detail = f"Server responded with status {e.status}."
240
  try:
241
+ error_text = await e.response.text()
242
+ try:
243
+ error_json = await e.response.json()
244
+ error_detail += f" Detail: {error_json.get('detail', error_text)}"
245
+ except ValueError:
246
+ error_detail += f" Response: {error_text[:500]}"
247
+ except:
248
+ pass
249
  status_message = f"Submission Failed: {error_detail}"
250
  print(status_message)
251
  results_df = pd.DataFrame(results_log)
252
  return status_message, results_df
253
+ except asyncio.TimeoutError:
254
  status_message = "Submission Failed: The request timed out."
255
  print(status_message)
256
  results_df = pd.DataFrame(results_log)
257
  return status_message, results_df
258
+ except aiohttp.ClientError as e:
259
  status_message = f"Submission Failed: Network error - {e}"
260
  print(status_message)
261
  results_df = pd.DataFrame(results_log)
 
285
  """
286
  )
287
 
288
+ login_button = gr.LoginButton()
289
 
290
  run_button = gr.Button("Run Evaluation & Submit All Answers")
291
 
292
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
293
  # Removed max_rows=10 from DataFrame constructor
294
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
295
+
296
+ def sync_wrapper(profile):
297
+ # This wrapper ensures we have access to the profile
298
+ if not profile:
299
+ print("No profile available in sync_wrapper")
300
+ return "Please Login to Hugging Face with the button.", None
301
+ return asyncio.run(run_and_submit_all(profile))
302
+
303
  run_button.click(
304
+ fn=sync_wrapper,
305
+ inputs=login_button,
306
  outputs=[status_output, results_table]
307
  )
308