ekkasilina/Final_Assignment_Template_AgentCourse
0
1import os2import gradio as gr3import requests4import inspect5import pandas as pd6from smolagents import CodeAgent, InferenceClientModel, DuckDuckGoSearchTool, tool, ToolCallingAgent7from smolagents import OpenAIServerModel8from tools import analyze_image, get_youtube_transcript, reverse_text9 10 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 def __call__(self, question: str) -> str:21 print(f"Agent received question (first 50 chars): {question[:50]}...")22 fixed_answer = "This is a default answer."23 print(f"Agent returning fixed answer: {fixed_answer}")24 return fixed_answer25 26openai_41mini_model = OpenAIServerModel(27 model_id="gpt-4.1-mini",28 api_base="https://api.openai.com/v1",29 api_key=os.environ["OPENAI_API_KEY"],30 )31search_tool = DuckDuckGoSearchTool()32 33 34 35def run_and_submit_all( profile: gr.OAuthProfile | None):36 """37 Fetches all questions, runs the BasicAgent on them, submits all answers,38 and displays the results.39 """40 # --- Determine HF Space Runtime URL and Repo URL ---41 space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code42 43 if profile:44 username= f"{profile.username}"45 print(f"User logged in: {username}")46 else:47 print("User not logged in.")48 return "Please Login to Hugging Face with the button.", None49 50 api_url = DEFAULT_API_URL51 questions_url = f"{api_url}/questions"52 submit_url = f"{api_url}/submit"53 54 # 1. Instantiate Agent ( modify this part to create your agent)55 try:56 # agent = BasicAgent()57 # openai_41mini_model = OpenAIServerModel(58 # model_id="gpt-4.1-mini",59 # api_base="https://api.openai.com/v1",60 # api_key=os.environ["OPENAI_API_KEY"],61 # )62 # search_tool = DuckDuckGoSearchTool()63 # my_small_agent = CodeAgent(64 # model=openai_41mini_model,65 # tools=[search_tool, analyze_image, get_youtube_transcript, reverse_text],66 # name="web_agent",67 # description="Use search engine to find webpages related to a subject and get the page content",68 # #additional_authorized_imports=["pandas", "numpy","bs4"],69 # verbosity_level=1,70 # max_steps=7,71 # )72 agent = CodeAgent(73 model=openai_41mini_model,74 tools=[search_tool, analyze_image, get_youtube_transcript],75 name="web_agent",76 description="Use search engine to find webpages related to a subject and get the page content",77 additional_authorized_imports=["pandas", "numpy", "bs4"],78 verbosity_level=1,79 max_steps=7,80 )81 82 83 except Exception as e:84 print(f"Error instantiating agent: {e}")85 return f"Error initializing agent: {e}", None86 # 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)87 agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"88 print(agent_code)89 90 # 2. Fetch Questions91 print(f"Fetching questions from: {questions_url}")92 try:93 response = requests.get(questions_url, timeout=15)94 response.raise_for_status()95 questions_data = response.json()96 if not questions_data:97 print("Fetched questions list is empty.")98 return "Fetched questions list is empty or invalid format.", None99 print(f"Fetched {len(questions_data)} questions.")100 except requests.exceptions.RequestException as e:101 print(f"Error fetching questions: {e}")102 return f"Error fetching questions: {e}", None103 except requests.exceptions.JSONDecodeError as e:104 print(f"Error decoding JSON response from questions endpoint: {e}")105 print(f"Response text: {response.text[:500]}")106 return f"Error decoding server response for questions: {e}", None107 except Exception as e:108 print(f"An unexpected error occurred fetching questions: {e}")109 return f"An unexpected error occurred fetching questions: {e}", None110 111 # 3. Run your Agent112 results_log = []113 answers_payload = []114 print(f"Running agent on {len(questions_data)} questions...")115 for item in questions_data:116 task_id = item.get("task_id")117 question_text = item.get("question")118 if not task_id or question_text is None:119 print(f"Skipping item with missing task_id or question: {item}")120 continue121 try:122 #submitted_answer = agent(question_text)123 submitted_answer = agent.run(question_text)124 answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})125 results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})126 except Exception as e:127 print(f"Error running agent on task {task_id}: {e}")128 results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})129 130 if not answers_payload:131 print("Agent did not produce any answers to submit.")132 return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)133 134 # 4. Prepare Submission 135 submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}136 status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."137 print(status_update)138 139 # 5. Submit140 print(f"Submitting {len(answers_payload)} answers to: {submit_url}")141 try:142 response = requests.post(submit_url, json=submission_data, timeout=60)143 response.raise_for_status()144 result_data = response.json()145 final_status = (146 f"Submission Successful!\n"147 f"User: {result_data.get('username')}\n"148 f"Overall Score: {result_data.get('score', 'N/A')}% "149 f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"150 f"Message: {result_data.get('message', 'No message received.')}"151 )152 print("Submission successful.")153 results_df = pd.DataFrame(results_log)154 return final_status, results_df155 except requests.exceptions.HTTPError as e:156 error_detail = f"Server responded with status {e.response.status_code}."157 try:158 error_json = e.response.json()159 error_detail += f" Detail: {error_json.get('detail', e.response.text)}"160 except requests.exceptions.JSONDecodeError:161 error_detail += f" Response: {e.response.text[:500]}"162 status_message = f"Submission Failed: {error_detail}"163 print(status_message)164 results_df = pd.DataFrame(results_log)165 return status_message, results_df166 except requests.exceptions.Timeout:167 status_message = "Submission Failed: The request timed out."168 print(status_message)169 results_df = pd.DataFrame(results_log)170 return status_message, results_df171 except requests.exceptions.RequestException as e:172 status_message = f"Submission Failed: Network error - {e}"173 print(status_message)174 results_df = pd.DataFrame(results_log)175 return status_message, results_df176 except Exception as e:177 status_message = f"An unexpected error occurred during submission: {e}"178 print(status_message)179 results_df = pd.DataFrame(results_log)180 return status_message, results_df181 182 183# --- Build Gradio Interface using Blocks ---184with gr.Blocks() as demo:185 gr.Markdown("# Basic Agent Evaluation Runner")186 gr.Markdown(187 """188 **Instructions:**189 190 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...191 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.192 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.193 194 ---195 **Disclaimers:**196 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).197 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.198 """199 )200 201 gr.LoginButton()202 203 run_button = gr.Button("Run Evaluation & Submit All Answers")204 205 status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)206 # Removed max_rows=10 from DataFrame constructor207 results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)208 209 run_button.click(210 fn=run_and_submit_all,211 outputs=[status_output, results_table]212 )213 214if __name__ == "__main__":215 print("\n" + "-"*30 + " App Starting " + "-"*30)216 # Check for SPACE_HOST and SPACE_ID at startup for information217 space_host_startup = os.getenv("SPACE_HOST")218 space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup219 220 if space_host_startup:221 print(f"✅ SPACE_HOST found: {space_host_startup}")222 print(f" Runtime URL should be: https://{space_host_startup}.hf.space")223 else:224 print("ℹ️ SPACE_HOST environment variable not found (running locally?).")225 226 if space_id_startup: # Print repo URLs if SPACE_ID is found227 print(f"✅ SPACE_ID found: {space_id_startup}")228 print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")229 print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")230 else:231 print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")232 233 print("-"*(60 + len(" App Starting ")) + "\n")234 235 print("Launching Gradio Interface for Basic Agent Evaluation...")236 demo.launch(debug=True, share=False)