import os import gradio as gr import requests # import inspect import pandas as pd from typing import Optional from smolagents import CodeAgent, LiteLLMModel, VisitWebpageTool, DuckDuckGoSearchTool # (Keep Constants as is) # --- Constants --- DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space" # Define the Agent Class class BasicAgent: def __init__(self): print("Initializing Mistral-Powered Agent...") # --- 1. API KEY CHECK --- mistral_key = os.getenv("MISTRAL_API_KEY") if not mistral_key: # Fallback to Qwen if Mistral is unavailable. print("Mistral Key not found. Please set MISTRAL_API_KEY for best results.") # Fallback logic if needed, but for now we raise error to alert user raise ValueError("MISTRAL_API_KEY missing!") # --- 2. MODEL SETUP --- model = LiteLLMModel( model_id="mistral/mistral-large-latest", api_key=mistral_key ) # --- 3. TOOLS --- search_tool = DuckDuckGoSearchTool() visit_tool = VisitWebpageTool() # --- 4. CREATE AGENT --- self.agent = CodeAgent( tools=[search_tool, visit_tool], model=model, additional_authorized_imports=[ "numpy", "pandas", "math", "datetime", "re", "csv", "json", "random", "itertools" ], max_steps=25, verbosity_level=2, name="Mistral_Gaia_Solver" ) def __call__(self, question: str, file_path: str = None) -> str: # Prompt Logic prompt = f""" Task: {question} INSTRUCTIONS: 1. Use Python code to solve this step-by-step. 2. If a file is attached, YOU MUST READ IT using Python immediately. 3. Output ONLY the final answer value. """ if file_path: prompt += f"\n\n ATTACHED FILE: '{file_path}'" try: print(f" Agent working on: {question[:30]}...") response = self.agent.run(prompt) # Output Cleaning final_answer = str(response).replace("Final Answer:", "").strip() if final_answer.endswith(".") and len(final_answer) < 20: final_answer = final_answer[:-1] return final_answer except Exception as e: print(f" Error in Agent: {e}") return f"Error: {e}" # Evaluation def run_and_submit_all(profile: gr.OAuthProfile | None): """ 1. Fetch questions. 2. Download the file (previously missing). 3. Run the agent. 4. Submit the results. """ # --- A. LOGIN CHECK --- if profile is None: return " Please Login to Hugging Face with the button above.", None username = profile.username space_id = os.getenv("SPACE_ID") # URLs api_url = DEFAULT_API_URL questions_url = f"{api_url}/questions" submit_url = f"{api_url}/submit" # --- B. INIT AGENT --- try: agent = BasicAgent() except Exception as e: return f" Agent Init Error: {e}", None agent_code_link = f"https://huggingface.co/spaces/{space_id}/tree/main" print(f"Code Link: {agent_code_link}") # --- C. FETCH QUESTIONS --- try: print(" Fetching questions...") questions_data = requests.get(questions_url).json() except Exception as e: return f"Error fetching questions: {e}", None results_log = [] answers_payload = [] print(f" Starting processing of {len(questions_data)} questions...") # --- D. PROCESSING LOOP --- for item in questions_data: task_id = item["task_id"] question_text = item["question"] file_name = item.get("file_name") # GAIA tasks often have files print(f"\n--- Processing Task {task_id} ---") local_file_path = None # 1. DOWNLOAD FILE (CRITICAL STEP) if file_name: print(f" Downloading file: {file_name}") try: file_url = f"{api_url}/files/{task_id}" file_resp = requests.get(file_url, timeout=10) if file_resp.status_code == 200: with open(file_name, "wb") as f: f.write(file_resp.content) local_file_path = file_name print(" File downloaded successfully.") else: print(f" File download failed (Status {file_resp.status_code})") except Exception as e: print(f" File download error: {e}") # 2. RUN AGENT try: # The agent receives the file path as input. submitted_answer = agent(question_text, file_path=local_file_path) print(f" Final Answer: {submitted_answer}") answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer}) results_log.append({ "Task ID": task_id, "Question": question_text, "File": file_name if file_name else "None", "Answer": submitted_answer }) except Exception as e: results_log.append({"Task ID": task_id, "Error": str(e)}) # 3. CLEANUP (File delete karo) if local_file_path and os.path.exists(local_file_path): os.remove(local_file_path) # --- E. SUBMIT --- print("Submitting answers to leaderboard...") submission_data = { "username": username, "agent_code": agent_code_link, "answers": answers_payload } try: response = requests.post(submit_url, json=submission_data, timeout=60) res_json = response.json() score = res_json.get('score', 0) correct = res_json.get('correct_count', 0) status_msg = ( f"Submission Done!\n" f"User: {username}\n" f"Score: {score}%\n" f"Correct: {correct}" ) return status_msg, pd.DataFrame(results_log) except Exception as e: return f"Submission Failed: {e}", pd.DataFrame(results_log) # --- GRADIO UI --- with gr.Blocks() as demo: gr.Markdown("# GAIA Agent Solver (Mistral + Files Fix)") gr.Markdown(""" **Instruction:** 1. Login via Hugging Face button. 2. Click 'Run Evaluation'. 3. Wait (it takes time to process all questions). """) gr.LoginButton() run_btn = gr.Button("Run Evaluation & Submit", variant="primary") status_out = gr.Textbox(label="Status") results_df = gr.DataFrame(label="Detailed Logs") run_btn.click( fn=run_and_submit_all, outputs=[status_out, results_df] ) if __name__ == "__main__": # Enabling the queue eliminates timeout issues. demo.queue(default_concurrency_limit=1).launch()