Realistvik0 commited on
Commit
09e6612
·
verified ·
1 Parent(s): 07efde4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +202 -9
app.py CHANGED
@@ -1,9 +1,12 @@
 
 
1
  import yaml
 
 
 
2
 
3
  from smolagents import CodeAgent, OpenAIServerModel, LiteLLMModel, Tool
4
 
5
- from Gradio_UI import GradioUI
6
-
7
  from tools.calculator import Calculator
8
  from tools.final_answer import FinalAnswerTool
9
  from tools.visit_webpage import VisitWebpageTool
@@ -11,12 +14,13 @@ from tools.web_search import DuckDuckGoSearchTool
11
 
12
  from research_state import ResearchState
13
  from verifier import verify_research
14
- import os
15
 
16
  # =========================================================
17
- # Configuration
18
  # =========================================================
19
 
 
 
20
  MODEL_ID = "gemini/gemini-2.5-flash"
21
 
22
  MAX_STEPS = 10
@@ -31,7 +35,6 @@ TEMPERATURE = 0.2
31
  class ResearchContext:
32
  """
33
  Holds the state for a single research run.
34
-
35
  The context is shared by the research tools so that
36
  searches, webpages, claims, and verification results
37
  belong to the same research session.
@@ -254,7 +257,7 @@ visit_webpage = StatefulVisitWebpageTool()
254
 
255
  calculator = Calculator()
256
 
257
- verify_research = VerifyResearchTool()
258
 
259
  final_answer = FinalAnswerTool()
260
 
@@ -262,7 +265,7 @@ tools = [
262
  web_search,
263
  visit_webpage,
264
  calculator,
265
- verify_research,
266
  final_answer,
267
  ]
268
 
@@ -301,9 +304,199 @@ agent = CodeAgent(
301
  )
302
 
303
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  # =========================================================
305
- # Launch
306
  # =========================================================
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  if __name__ == "__main__":
309
- GradioUI(agent).launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import inspect
3
  import yaml
4
+ import requests
5
+ import gradio as gr
6
+ import pandas as pd
7
 
8
  from smolagents import CodeAgent, OpenAIServerModel, LiteLLMModel, Tool
9
 
 
 
10
  from tools.calculator import Calculator
11
  from tools.final_answer import FinalAnswerTool
12
  from tools.visit_webpage import VisitWebpageTool
 
14
 
15
  from research_state import ResearchState
16
  from verifier import verify_research
 
17
 
18
  # =========================================================
19
+ # Constants
20
  # =========================================================
21
 
22
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
23
+
24
  MODEL_ID = "gemini/gemini-2.5-flash"
25
 
26
  MAX_STEPS = 10
 
35
  class ResearchContext:
36
  """
37
  Holds the state for a single research run.
 
38
  The context is shared by the research tools so that
39
  searches, webpages, claims, and verification results
40
  belong to the same research session.
 
257
 
258
  calculator = Calculator()
259
 
260
+ verify_research_tool = VerifyResearchTool()
261
 
262
  final_answer = FinalAnswerTool()
263
 
 
265
  web_search,
266
  visit_webpage,
267
  calculator,
268
+ verify_research_tool,
269
  final_answer,
270
  ]
271
 
 
304
  )
305
 
306
 
307
+ class ResearchAgentWrapper:
308
+ """
309
+ Thin wrapper so the research agent can be called like
310
+ BasicAgent: agent(question) -> answer string.
311
+ Resets the shared research context for every new question
312
+ so state doesn't leak between questions.
313
+ """
314
+
315
+ def __init__(self, agent: CodeAgent):
316
+ self.agent = agent
317
+ print("ResearchAgentWrapper initialized.")
318
+
319
+ def __call__(self, question: str) -> str:
320
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
321
+ research_context.reset()
322
+ research_context.start(question)
323
+ answer = self.agent.run(question)
324
+ print(f"Agent returning answer (first 50 chars): {str(answer)[:50]}...")
325
+ return str(answer)
326
+
327
+
328
+ # =========================================================
329
+ # Evaluation Runner
330
+ # =========================================================
331
+
332
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
333
+ """
334
+ Fetches all questions, runs the research agent on them,
335
+ submits all answers, and displays the results.
336
+ """
337
+ space_id = os.getenv("SPACE_ID")
338
+
339
+ if profile:
340
+ username = f"{profile.username}"
341
+ print(f"User logged in: {username}")
342
+ else:
343
+ print("User not logged in.")
344
+ return "Please Login to Hugging Face with the button.", None
345
+
346
+ api_url = DEFAULT_API_URL
347
+ questions_url = f"{api_url}/questions"
348
+ submit_url = f"{api_url}/submit"
349
+
350
+ # 1. Instantiate Agent
351
+ try:
352
+ agent_runner = ResearchAgentWrapper(agent)
353
+ except Exception as e:
354
+ print(f"Error instantiating agent: {e}")
355
+ return f"Error initializing agent: {e}", None
356
+
357
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
358
+ print(agent_code)
359
+
360
+ # 2. Fetch Questions
361
+ print(f"Fetching questions from: {questions_url}")
362
+ try:
363
+ response = requests.get(questions_url, timeout=15)
364
+ response.raise_for_status()
365
+ questions_data = response.json()
366
+ if not questions_data:
367
+ print("Fetched questions list is empty.")
368
+ return "Fetched questions list is empty or invalid format.", None
369
+ print(f"Fetched {len(questions_data)} questions.")
370
+ except requests.exceptions.RequestException as e:
371
+ print(f"Error fetching questions: {e}")
372
+ return f"Error fetching questions: {e}", None
373
+ except requests.exceptions.JSONDecodeError as e:
374
+ print(f"Error decoding JSON response from questions endpoint: {e}")
375
+ print(f"Response text: {response.text[:500]}")
376
+ return f"Error decoding server response for questions: {e}", None
377
+ except Exception as e:
378
+ print(f"An unexpected error occurred fetching questions: {e}")
379
+ return f"An unexpected error occurred fetching questions: {e}", None
380
+
381
+ # 3. Run your Agent
382
+ results_log = []
383
+ answers_payload = []
384
+ print(f"Running agent on {len(questions_data)} questions...")
385
+ for item in questions_data:
386
+ task_id = item.get("task_id")
387
+ question_text = item.get("question")
388
+ if not task_id or question_text is None:
389
+ print(f"Skipping item with missing task_id or question: {item}")
390
+ continue
391
+ try:
392
+ submitted_answer = agent_runner(question_text)
393
+ answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
394
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
395
+ except Exception as e:
396
+ print(f"Error running agent on task {task_id}: {e}")
397
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
398
+
399
+ if not answers_payload:
400
+ print("Agent did not produce any answers to submit.")
401
+ return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
402
+
403
+ # 4. Prepare Submission
404
+ submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
405
+ status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
406
+ print(status_update)
407
+
408
+ # 5. Submit
409
+ print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
410
+ try:
411
+ response = requests.post(submit_url, json=submission_data, timeout=60)
412
+ response.raise_for_status()
413
+ result_data = response.json()
414
+ final_status = (
415
+ f"Submission Successful!\n"
416
+ f"User: {result_data.get('username')}\n"
417
+ f"Overall Score: {result_data.get('score', 'N/A')}% "
418
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
419
+ f"Message: {result_data.get('message', 'No message received.')}"
420
+ )
421
+ print("Submission successful.")
422
+ results_df = pd.DataFrame(results_log)
423
+ return final_status, results_df
424
+ except requests.exceptions.HTTPError as e:
425
+ error_detail = f"Server responded with status {e.response.status_code}."
426
+ try:
427
+ error_json = e.response.json()
428
+ error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
429
+ except requests.exceptions.JSONDecodeError:
430
+ error_detail += f" Response: {e.response.text[:500]}"
431
+ status_message = f"Submission Failed: {error_detail}"
432
+ print(status_message)
433
+ results_df = pd.DataFrame(results_log)
434
+ return status_message, results_df
435
+ except requests.exceptions.Timeout:
436
+ status_message = "Submission Failed: The request timed out."
437
+ print(status_message)
438
+ results_df = pd.DataFrame(results_log)
439
+ return status_message, results_df
440
+ except requests.exceptions.RequestException as e:
441
+ status_message = f"Submission Failed: Network error - {e}"
442
+ print(status_message)
443
+ results_df = pd.DataFrame(results_log)
444
+ return status_message, results_df
445
+ except Exception as e:
446
+ status_message = f"An unexpected error occurred during submission: {e}"
447
+ print(status_message)
448
+ results_df = pd.DataFrame(results_log)
449
+ return status_message, results_df
450
+
451
+
452
  # =========================================================
453
+ # Gradio Interface
454
  # =========================================================
455
 
456
+ with gr.Blocks() as demo:
457
+ gr.Markdown("# Web Research Agent Evaluation Runner")
458
+ gr.Markdown(
459
+ """
460
+ **Instructions:**
461
+ 1. Log in to your Hugging Face account using the button below.
462
+ 2. Click 'Run Evaluation & Submit All Answers' to fetch questions, run the research agent, submit answers, and see the score.
463
+ ---
464
+ **Disclaimers:**
465
+ Once clicking the submit button, it can take some time (the agent must search, read sources, and verify claims for every question).
466
+ """
467
+ )
468
+
469
+ gr.LoginButton()
470
+
471
+ run_button = gr.Button("Run Evaluation & Submit All Answers")
472
+
473
+ status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
474
+ results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
475
+
476
+ run_button.click(
477
+ fn=run_and_submit_all,
478
+ outputs=[status_output, results_table]
479
+ )
480
+
481
  if __name__ == "__main__":
482
+ print("\n" + "-" * 30 + " App Starting " + "-" * 30)
483
+ space_host_startup = os.getenv("SPACE_HOST")
484
+ space_id_startup = os.getenv("SPACE_ID")
485
+
486
+ if space_host_startup:
487
+ print(f"✅ SPACE_HOST found: {space_host_startup}")
488
+ print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
489
+ else:
490
+ print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
491
+
492
+ if space_id_startup:
493
+ print(f"✅ SPACE_ID found: {space_id_startup}")
494
+ print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
495
+ print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
496
+ else:
497
+ print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
498
+
499
+ print("-" * (60 + len(" App Starting ")) + "\n")
500
+
501
+ print("Launching Gradio Interface for Web Research Agent Evaluation...")
502
+ demo.launch(debug=True, share=False)