garvitmathur99/GeneralPurposeAgent
0
1import os2from agents.agent import run_agent3import gradio as gr4import requests5import inspect6import pandas as pd7import traceback 8from dotenv import load_dotenv9 10load_dotenv()11# (Keep Constants as is)12# --- Constants ---13DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"14 15# --- Basic Agent Definition ---16# ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------17class BasicAgent:18 def __init__(self):19 print("BasicAgent initialized.")20 21 def __call__(self, question: str, file_path: str = None, file_type: str = None) -> str:22 # print(f"Agent received question (first 50 chars): {question[:50]}...")23 answer = run_agent(question, file_path=file_path, file_type=file_type)24 # print(f"Agent returning fixed answer: {answer}")25 return answer26 27def run_and_submit_all( profile: gr.OAuthProfile | None):28 """29 Fetches all questions, runs the BasicAgent on them, submits all answers,30 and displays the results.31 """32 # --- Determine HF Space Runtime URL and Repo URL ---33 space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code34 35 if profile:36 username= f"{profile.username}"37 print(f"User logged in: {username}")38 else:39 print("User not logged in.")40 return "Please Login to Hugging Face with the button.", None41 42 api_url = DEFAULT_API_URL43 questions_url = f"{api_url}/questions"44 submit_url = f"{api_url}/submit"45 get_file_url = f"{api_url}/files/"46 47 48 def get_file(task_id: str) -> tuple[str, str]:49 """50 Fetches a file from the /files/{task_id} endpoint and downloads it.51 52 Args:53 task_id: The task ID to fetch the file.54 55 Returns:56 The local path of the downloaded file and its type.57 """58 try:59 # Step 1: Get the download URL (response.url is the file link)60 response = requests.get(f"{get_file_url}{task_id}", allow_redirects=True, timeout=15)61 response.raise_for_status()62 file_url = response.url # This is the actual file link63 print(f"File URL: {file_url}")64 # Step 2: Download the file from that URL65 file_response = requests.get(file_url, stream=True, timeout=30)66 file_response.raise_for_status()67 68 # Step 3: Create 'download' directory69 download_dir = os.path.join(os.getcwd(), "download")70 os.makedirs(download_dir, exist_ok=True)71 72 # Step 4: Get filename from content disposition or fallback to URL73 content_disposition = file_response.headers.get('Content-Disposition')74 if content_disposition and 'filename=' in content_disposition:75 file_name = content_disposition.split("filename=")[-1].strip('"')76 else:77 file_name = os.path.basename(file_url)78 79 file_path = os.path.join(download_dir, file_name)80 file_type = file_path.split(".")[-1]81 print(f"File type: {file_type}")82 # Step 5: Save the file83 with open(file_path, 'wb') as f:84 for chunk in file_response.iter_content(chunk_size=8192):85 if chunk:86 f.write(chunk)87 88 print(f"File downloaded and saved to: {file_path}")89 return file_path, file_type90 91 except requests.exceptions.RequestException as e:92 print(f"Error fetching file for task {task_id}: {e}")93 return None, None94 except Exception as e:95 print(f"Unexpected error: {e}")96 return None, None97 98 99 100 # 1. Instantiate Agent ( modify this part to create your agent)101 try:102 agent = BasicAgent()103 except Exception as e:104 print(f"Error instantiating agent: {e}")105 return f"Error initializing agent: {e}", None106 # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)107 agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"108 print(agent_code)109 110 # 2. Fetch Questions111 print(f"Fetching questions from: {questions_url}")112 try:113 response = requests.get(questions_url, timeout=15)114 response.raise_for_status()115 questions_data = response.json()116 if not questions_data:117 print("Fetched questions list is empty.")118 return "Fetched questions list is empty or invalid format.", None119 print(f"Fetched {len(questions_data)} questions.")120 except requests.exceptions.RequestException as e:121 print(f"Error fetching questions: {e}")122 return f"Error fetching questions: {e}", None123 except requests.exceptions.JSONDecodeError as e:124 print(f"Error decoding JSON response from questions endpoint: {e}")125 print(f"Response text: {response.text[:500]}")126 return f"Error decoding server response for questions: {e}", None127 except Exception as e:128 print(f"An unexpected error occurred fetching questions: {e}")129 return f"An unexpected error occurred fetching questions: {e}", None130 131 132 # 3. Run your Agent133 results_log = []134 answers_payload = []135 print(f"Running agent on {len(questions_data)} questions...")136 for item in questions_data:137 task_id = item.get("task_id")138 question_text = item.get("question")139 file_name = item.get("file_name")140 141 if not task_id or question_text is None:142 print(f"Skipping item with missing task_id or question: {item}")143 continue144 try: 145 file_path = None146 file_type = None147 file_url = None148 if file_name:149 file_path, file_type = get_file(task_id)150 submitted_answer = agent(question_text, file_path=file_path, file_type=file_type)151 answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})152 results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})153 except Exception as e:154 error_trace = traceback.format_exc()155 print(f"Error running agent on task {task_id}: {e}")156 print(f"Traceback:\n{error_trace}")157 print(f"Error running agent on task {task_id}: {e}")158 results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})159 160 if not answers_payload:161 print("Agent did not produce any answers to submit.")162 return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)163 164 # 4. Prepare Submission 165 submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}166 status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."167 print(status_update)168 169 # 5. Submit170 print(f"Submitting {len(answers_payload)} answers to: {submit_url}")171 try:172 response = requests.post(submit_url, json=submission_data, timeout=60)173 response.raise_for_status()174 result_data = response.json()175 final_status = (176 f"Submission Successful!\n"177 f"User: {result_data.get('username')}\n"178 f"Overall Score: {result_data.get('score', 'N/A')}% "179 f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"180 f"Message: {result_data.get('message', 'No message received.')}"181 )182 print("Submission successful.")183 results_df = pd.DataFrame(results_log)184 return final_status, results_df185 except requests.exceptions.HTTPError as e:186 error_detail = f"Server responded with status {e.response.status_code}."187 try:188 error_json = e.response.json()189 error_detail += f" Detail: {error_json.get('detail', e.response.text)}"190 except requests.exceptions.JSONDecodeError:191 error_detail += f" Response: {e.response.text[:500]}"192 status_message = f"Submission Failed: {error_detail}"193 print(status_message)194 results_df = pd.DataFrame(results_log)195 return status_message, results_df196 except requests.exceptions.Timeout:197 status_message = "Submission Failed: The request timed out."198 print(status_message)199 results_df = pd.DataFrame(results_log)200 return status_message, results_df201 except requests.exceptions.RequestException as e:202 status_message = f"Submission Failed: Network error - {e}"203 print(status_message)204 results_df = pd.DataFrame(results_log)205 return status_message, results_df206 except Exception as e:207 status_message = f"An unexpected error occurred during submission: {e}"208 print(status_message)209 results_df = pd.DataFrame(results_log)210 return status_message, results_df211 212 213# --- Build Gradio Interface using Blocks ---214with gr.Blocks() as demo:215 gr.Markdown("# Basic Agent Evaluation Runner")216 gr.Markdown(217 """218 **Instructions:**219 220 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...221 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.222 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.223 224 ---225 **Disclaimers:**226 Once clicking on the "submit button, it can take quite some time ( this is the time for the agent to go through all the questions).227 This space provides a basic setup and is intentionally sub-optimal to encourage you to develop your own, more robust solution. For instance for the delay process of the submit button, a solution could be to cache the answers and submit in a seperate action or even to answer the questions in async.228 229 ---230 **Note:**231 This space uses the Gemini 2.0 model from Google Vertex AI. You can change the model in the code to use a different one if you prefer. 232 To use the model you need to have a Google Cloud account and set up and add the .json file with your credentials in the root of the space and update the environment variable.233 """234 )235 236 gr.LoginButton()237 238 run_button = gr.Button("Run Evaluation & Submit All Answers")239 240 status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)241 # Removed max_rows=10 from DataFrame constructor242 results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)243 244 run_button.click(245 fn=run_and_submit_all,246 outputs=[status_output, results_table]247 )248 249if __name__ == "__main__":250 print("\n" + "-"*30 + " App Starting " + "-"*30)251 # Check for SPACE_HOST and SPACE_ID at startup for information252 space_host_startup = os.getenv("SPACE_HOST")253 space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup254 255 if space_host_startup:256 print(f"✅ SPACE_HOST found: {space_host_startup}")257 print(f" Runtime URL should be: https://{space_host_startup}.hf.space")258 else:259 print("ℹ️ SPACE_HOST environment variable not found (running locally?).")260 261 if space_id_startup: # Print repo URLs if SPACE_ID is found262 print(f"✅ SPACE_ID found: {space_id_startup}")263 print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")264 print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")265 else:266 print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")267 268 print("-"*(60 + len(" App Starting ")) + "\n")269 270 print("Launching Gradio Interface for Basic Agent Evaluation...")271 demo.launch(debug=True, share=False)