import os from dataclasses import asdict from datetime import datetime from pathlib import Path import gradio as gr import pandas as pd from agent import LangGraphBenchmarkAgent from gaia import CourseAPIClient, TaskRecord DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space" RUNS_DIR = Path("runs") def _save_results(prefix: str, df: pd.DataFrame) -> Path: RUNS_DIR.mkdir(parents=True, exist_ok=True) timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") output_path = RUNS_DIR / f"{prefix}_{timestamp}.csv" df.to_csv(output_path, index=False, encoding="utf-8-sig") return output_path def build_agent() -> LangGraphBenchmarkAgent: api_url = os.getenv("COURSE_API_URL", DEFAULT_API_URL) return LangGraphBenchmarkAgent(api_url=api_url) def run_and_submit_all(profile: gr.OAuthProfile | None): space_id = os.getenv("SPACE_ID") if not profile: return "Please login to Hugging Face with the button.", None username = profile.username.strip() api_url = os.getenv("COURSE_API_URL", DEFAULT_API_URL) client = CourseAPIClient(api_url=api_url) try: agent = build_agent() except Exception as exc: return f"Error initializing agent: {exc}", None agent_code = ( f"https://huggingface.co/spaces/{space_id}/tree/main" if space_id else "SPACE_ID not available" ) try: questions = client.fetch_questions() except Exception as exc: return f"Error fetching questions: {exc}", None results_log = [] answers_payload = [] for task in questions: try: submitted_answer = agent.solve(task) answers_payload.append( {"task_id": task.task_id, "submitted_answer": submitted_answer} ) results_log.append( { "Task ID": task.task_id, "Question": task.question, "File": task.file_name or "", "Answer": submitted_answer, } ) except Exception as exc: results_log.append( { "Task ID": task.task_id, "Question": task.question, "File": task.file_name or "", "Answer": f"AGENT ERROR: {exc}", } ) if not answers_payload: return "Agent did not produce any answers to submit.", pd.DataFrame(results_log) try: result = client.submit_answers( username=username, agent_code=agent_code, answers=answers_payload, ) results_df = pd.DataFrame(results_log) saved_path = _save_results("submission_results", results_df) final_status = ( "Submission Successful!\n" f"User: {result.get('username')}\n" f"Overall Score: {result.get('score', 'N/A')}% " f"({result.get('correct_count', '?')}/{result.get('total_attempted', '?')} correct)\n" f"Message: {result.get('message', 'No message received.')}\n" f"Saved results: {saved_path}" ) return final_status, results_df except Exception as exc: results_df = pd.DataFrame(results_log) if not results_df.empty: saved_path = _save_results("submission_failed_results", results_df) return f"Submission Failed: {exc}\nSaved partial results: {saved_path}", results_df return f"Submission Failed: {exc}", results_df def run_single_random_question(): client = CourseAPIClient(api_url=os.getenv("COURSE_API_URL", DEFAULT_API_URL)) agent = build_agent() task = client.fetch_random_question() answer = agent.solve(task) row = asdict(task) row["answer"] = answer df = pd.DataFrame([row]) _save_results("random_question", df) return df with gr.Blocks() as demo: gr.Markdown("# LangGraph GAIA Agent Runner") gr.Markdown( """ This Space is organized for the Hugging Face Agents course Unit 4 hands-on. Workflow: 1. Log in with Hugging Face. 2. Use "Run One Random Question" while iterating on the agent. 3. Use "Run Evaluation & Submit All Answers" when you are ready to submit. Environment variables expected for the current implementation: - `LLM_PROVIDER=openai_compatible` - `OPENAI_COMPATIBLE_API_KEY` - `OPENAI_COMPATIBLE_BASE_URL` - `OPENAI_COMPATIBLE_MODEL` - `ENABLE_LLM_QUERY_REWRITE=false` to reduce model calls """ ) gr.LoginButton() random_button = gr.Button("Run One Random Question") random_output = gr.DataFrame(label="Random Question Result", wrap=True) submit_button = gr.Button("Run Evaluation & Submit All Answers") status_output = gr.Textbox(label="Submission Result", lines=5, interactive=False) results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True) random_button.click(fn=run_single_random_question, outputs=random_output) submit_button.click( fn=run_and_submit_all, outputs=[status_output, results_table], ) if __name__ == "__main__": print("Launching Gradio interface...") demo.launch( server_name="0.0.0.0", server_port=7860, ssr_mode=False, debug=False, share=False, )