shsad commited on
Commit
648e4ea
·
verified ·
1 Parent(s): 366f412

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -7
app.py CHANGED
@@ -4,21 +4,104 @@ import requests
4
  import inspect
5
  import pandas as pd
6
 
 
 
 
 
7
  # (Keep Constants as is)
8
  # --- Constants ---
9
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
 
 
 
 
11
  # --- Basic Agent Definition ---
12
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
13
- class BasicAgent:
 
 
 
 
 
 
 
 
 
14
  def __init__(self):
15
- print("BasicAgent initialized.")
16
- def __call__(self, question: str) -> str:
17
- print(f"Agent received question (first 50 chars): {question[:50]}...")
18
- fixed_answer = "This is a default answer."
19
- print(f"Agent returning fixed answer: {fixed_answer}")
20
- return fixed_answer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
 
22
  def run_and_submit_all( profile: gr.OAuthProfile | None):
23
  """
24
  Fetches all questions, runs the BasicAgent on them, submits all answers,
 
4
  import inspect
5
  import pandas as pd
6
 
7
+ # Additional packages
8
+ from langchain import hub
9
+ from langchain_google_genai import ChatGoogleGenerativeAI
10
+
11
  # (Keep Constants as is)
12
  # --- Constants ---
13
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
14
 
15
+ # Added constants
16
+ GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
17
+ SERPER_API_KEY = os.getenv("SERPER_API_KEY")
18
+
19
  # --- Basic Agent Definition ---
20
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
21
+ #class BasicAgent:
22
+ # def __init__(self):
23
+ # print("BasicAgent initialized.")
24
+ # def __call__(self, question: str) -> str:
25
+ # print(f"Agent received question (first 50 chars): {question[:50]}...")
26
+ # fixed_answer = "This is a default answer."
27
+ # print(f"Agent returning fixed answer: {fixed_answer}")
28
+ # return fixed_answer
29
+
30
+ class FinalAgent:
31
  def __init__(self):
32
+ """Initializes the agent with the Gemini 2.5 Flash API and necessary tools."""
33
+ print("Initializing FinalAgent with official LangChain prompt...")
34
+ self.api_url = DEFAULT_API_URL
35
+
36
+ if not GOOGLE_API_KEY or not SERPER_API_KEY:
37
+ raise ValueError("Fatal Error: Both GOOGLE_API_KEY and SERPER_API_KEY secrets must be set.")
38
+
39
+ self.llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash", temperature=0, convert_system_message_to_human=True, google_api_key=GOOGLE_API_KEY)
40
+ print("Gemini 2.5 Flash client initialized successfully.")
41
+
42
+ self.tools = self._setup_tools()
43
+
44
+ # Pull the official, tested prompt from the LangChain hub, instead of creating a custom prompt.
45
+ # This prompt is guaranteed to have the correct variables and structure.
46
+ prompt = hub.pull("hwchase17/react")
47
+
48
+ agent = create_react_agent(llm=self.llm, tools=self.tools, prompt=prompt)
49
+ self.executor = AgentExecutor(agent=agent, tools=self.tools, verbose=True, handle_parsing_errors=True, max_iterations=12)
50
+ print("FinalAgent initialized successfully.")
51
+
52
+ def _setup_tools(self):
53
+ """Defines the tools available to the agent."""
54
+ search = GoogleSerperAPIWrapper(serper_api_key=SERPER_API_KEY)
55
+
56
+ def file_downloader_tool(task_id: str) -> str:
57
+ try:
58
+ all_questions_response = requests.get(f"{self.api_url}/questions", timeout=10)
59
+ all_questions_response.raise_for_status()
60
+ all_questions = all_questions_response.json()
61
+ file_name = next((q.get('file') for q in all_questions if q.get('task_id') == task_id), None)
62
+ if not file_name: return f"Error: No file associated with task_id '{task_id}'."
63
+ local_path = f"/tmp/{file_name}"
64
+ if not os.path.exists(local_path):
65
+ response = requests.get(f"{self.api_url}/files/{task_id}", timeout=10)
66
+ response.raise_for_status()
67
+ with open(local_path, "wb") as f: f.write(response.content)
68
+ return f"File '{file_name}' is available at local path: {local_path}"
69
+ except Exception as e: return f"Error downloading file for task {task_id}: {str(e)}"
70
+
71
+ def python_interpreter_tool(code: str) -> str:
72
+ try:
73
+ exec_globals = {"pd": pd, "io": io}
74
+ local_vars = {}
75
+ exec(code, exec_globals, local_vars)
76
+ return str(local_vars.get('output', 'Code executed successfully with no output.'))
77
+ except Exception as e: return f"Error executing Python code: {str(e)}"
78
+
79
+ return [
80
+ Tool(name"Search", func=search.run, description="A useful tool for searching the internet to answer questions about current events, facts, and general knowledge."),
81
+ Tool(name="FileDownloader", func=file_downloader_tool, description="Use to download a file associated with a task. The input MUST be the task_id. Returns the local path where the file is stored."),
82
+ Tool(name="PythonInterpreter", func=python_interpreter_tool, description="Use to execute Python code for calculations or data analysis. Use this to analyze files AFTER donwloading them. You have the pandas library available as 'pd'. Example: df = pd.read_excel('/tmp/filename.xlsx')"),
83
+ ]
84
+
85
+ def __call__(self, item: dict) -> str:
86
+ """Runs the agent on a single question item."""
87
+ task_id = item.get("task_id")
88
+ question = item.get("question")
89
+
90
+ prompt_input = f"Question: {question}"
91
+ if item.get("file"):
92
+ prompt_input += f"\n(This question has an associated file names '{item.get('file')}'. To use it, you must first call the FileDownloader tool with the task_id: ‘{task_id}‘)"
93
+
94
+ input_data = {"input": prompt_input}
95
+
96
+ print(f"Question: {question}")
97
+ try:
98
+ response = self.executor.invoke(input_data)
99
+ return str(response.get("output", "Agent failed to produce an answer.")).strip()
100
+ except Exception as e:
101
+ return f"AGENT_ERROR: {str(e)}"
102
+
103
 
104
+ # Submission logic Unchanged
105
  def run_and_submit_all( profile: gr.OAuthProfile | None):
106
  """
107
  Fetches all questions, runs the BasicAgent on them, submits all answers,