Toumaima commited on
Commit
bbf17d2
·
verified ·
1 Parent(s): 370aee1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +106 -11
app.py CHANGED
@@ -1,4 +1,12 @@
1
- from langgraph.graph import START, StateGraph, MessagesState
 
 
 
 
 
 
 
 
2
  from langgraph.prebuilt import tools_condition, ToolNode
3
  from langchain_core.messages import SystemMessage, HumanMessage
4
  from langchain_core.tools import tool
@@ -6,35 +14,32 @@ from langchain_google_genai import ChatGoogleGenerativeAI
6
  from langchain_community.document_loaders import WikipediaLoader, ArxivLoader
7
  from langchain_community.tools.tavily_search import TavilySearchResults
8
  from groq import Groq
9
- import os
10
- import re
11
 
12
- # Define the tools
 
 
 
13
  @tool
14
  def wiki_search(query: str) -> str:
15
- """Search Wikipedia for a query and return up to 2 results."""
16
  docs = WikipediaLoader(query=query, load_max_docs=2).load()
17
  return "\n\n".join([doc.page_content for doc in docs])
18
 
19
  @tool
20
  def web_search(query: str) -> str:
21
- """Search the web using Tavily."""
22
  docs = TavilySearchResults(max_results=3).invoke(query)
23
  return "\n\n".join([doc.page_content for doc in docs])
24
 
25
  @tool
26
  def arvix_search(query: str) -> str:
27
- """Search Arxiv and return up to 3 results."""
28
  docs = ArxivLoader(query=query, load_max_docs=3).load()
29
  return "\n\n".join([doc.page_content[:1000] for doc in docs])
30
 
31
- # Tool-based LangGraph builder
32
  def build_tool_graph(system_prompt):
33
  llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash", temperature=0)
34
  llm_with_tools = llm.bind_tools([wiki_search, web_search, arvix_search])
35
 
36
  def assistant(state: MessagesState):
37
- return {"messages": [llm_with_tools.invoke(state["messages"]) ]}
38
 
39
  builder = StateGraph(MessagesState)
40
  builder.add_node("assistant", assistant)
@@ -45,6 +50,7 @@ def build_tool_graph(system_prompt):
45
  builder.add_edge("tools", "assistant")
46
  return builder.compile()
47
 
 
48
  class BasicAgent:
49
  def __init__(self):
50
  print("BasicAgent initialized.")
@@ -65,7 +71,8 @@ class BasicAgent:
65
 
66
  def format_final_answer(self, answer: str) -> str:
67
  cleaned = " ".join(answer.split())
68
- return f"FINAL ANSWER: {cleaned}"
 
69
 
70
  def query_groq(self, question: str) -> str:
71
  full_prompt = f"{self.agent_prompt}\n\nQuestion: {question}"
@@ -150,4 +157,92 @@ class BasicAgent:
150
  }
151
  opposite = opposites.get(word, f"UNKNOWN_OPPOSITE_OF_{word}")
152
  return f"FINAL ANSWER: {opposite.upper()}"
153
- return self.format_final_answer("COULD_NOT_SOLVE")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import requests
4
+ import pandas as pd
5
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
6
+
7
+ # ---------- Imports for Advanced Agent ----------
8
+ import re
9
+ from langgraph.graph import StateGraph, MessagesState
10
  from langgraph.prebuilt import tools_condition, ToolNode
11
  from langchain_core.messages import SystemMessage, HumanMessage
12
  from langchain_core.tools import tool
 
14
  from langchain_community.document_loaders import WikipediaLoader, ArxivLoader
15
  from langchain_community.tools.tavily_search import TavilySearchResults
16
  from groq import Groq
 
 
17
 
18
+ # --- Constants ---
19
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
20
+
21
+ # ---------- Tools ----------
22
  @tool
23
  def wiki_search(query: str) -> str:
 
24
  docs = WikipediaLoader(query=query, load_max_docs=2).load()
25
  return "\n\n".join([doc.page_content for doc in docs])
26
 
27
  @tool
28
  def web_search(query: str) -> str:
 
29
  docs = TavilySearchResults(max_results=3).invoke(query)
30
  return "\n\n".join([doc.page_content for doc in docs])
31
 
32
  @tool
33
  def arvix_search(query: str) -> str:
 
34
  docs = ArxivLoader(query=query, load_max_docs=3).load()
35
  return "\n\n".join([doc.page_content[:1000] for doc in docs])
36
 
 
37
  def build_tool_graph(system_prompt):
38
  llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash", temperature=0)
39
  llm_with_tools = llm.bind_tools([wiki_search, web_search, arvix_search])
40
 
41
  def assistant(state: MessagesState):
42
+ return {"messages": [llm_with_tools.invoke(state["messages"])]}
43
 
44
  builder = StateGraph(MessagesState)
45
  builder.add_node("assistant", assistant)
 
50
  builder.add_edge("tools", "assistant")
51
  return builder.compile()
52
 
53
+ # --- Advanced BasicAgent Class ---
54
  class BasicAgent:
55
  def __init__(self):
56
  print("BasicAgent initialized.")
 
71
 
72
  def format_final_answer(self, answer: str) -> str:
73
  cleaned = " ".join(answer.split())
74
+ match = re.search(r"FINAL ANSWER:\s*(.*)", cleaned, re.IGNORECASE)
75
+ return f"FINAL ANSWER: {match.group(1).strip()}" if match else f"FINAL ANSWER: {cleaned}"
76
 
77
  def query_groq(self, question: str) -> str:
78
  full_prompt = f"{self.agent_prompt}\n\nQuestion: {question}"
 
157
  }
158
  opposite = opposites.get(word, f"UNKNOWN_OPPOSITE_OF_{word}")
159
  return f"FINAL ANSWER: {opposite.upper()}"
160
+ return self.format_final_answer("COULD_NOT_SOLVE")
161
+
162
+ # --- Evaluation Logic ---
163
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
164
+ space_id = os.getenv("SPACE_ID")
165
+ if profile:
166
+ username = profile.username
167
+ print(f"User logged in: {username}")
168
+ else:
169
+ return "Please Login to Hugging Face with the button.", None
170
+
171
+ api_url = DEFAULT_API_URL
172
+ questions_url = f"{api_url}/questions"
173
+ submit_url = f"{api_url}/submit"
174
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
175
+
176
+ try:
177
+ agent = BasicAgent()
178
+ except Exception as e:
179
+ return f"Error initializing agent: {e}", None
180
+
181
+ try:
182
+ response = requests.get(questions_url, timeout=15)
183
+ response.raise_for_status()
184
+ questions_data = response.json()
185
+ if not questions_data:
186
+ return "Fetched questions list is empty or invalid format.", None
187
+ except Exception as e:
188
+ return f"Error fetching questions: {e}", None
189
+
190
+ results_log = []
191
+ answers_payload = []
192
+
193
+ for item in questions_data:
194
+ task_id = item.get("task_id")
195
+ question_text = item.get("question")
196
+ if not task_id or question_text is None:
197
+ continue
198
+ try:
199
+ submitted_answer = agent(question_text)
200
+ answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
201
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
202
+ except Exception as e:
203
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
204
+
205
+ if not answers_payload:
206
+ return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
207
+
208
+ submission_data = {
209
+ "username": username.strip(),
210
+ "agent_code": agent_code,
211
+ "answers": answers_payload
212
+ }
213
+
214
+ try:
215
+ response = requests.post(submit_url, json=submission_data, timeout=60)
216
+ response.raise_for_status()
217
+ result_data = response.json()
218
+ final_status = (
219
+ f"Submission Successful!\n"
220
+ f"User: {result_data.get('username')}\n"
221
+ f"Overall Score: {result_data.get('score', 'N/A')}% "
222
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
223
+ f"Message: {result_data.get('message', 'No message received.')}"
224
+ )
225
+ return final_status, pd.DataFrame(results_log)
226
+ except Exception as e:
227
+ return f"Submission Failed: {e}", pd.DataFrame(results_log)
228
+
229
+ # --- Gradio UI ---
230
+ with gr.Blocks() as demo:
231
+ gr.Markdown("# Basic Agent Evaluation Runner")
232
+ gr.Markdown(
233
+ """
234
+ **Instructions:**
235
+ 1. Clone and customize your agent logic.
236
+ 2. Log in with Hugging Face.
237
+ 3. Click the button to run evaluation and submit your answers.
238
+ """
239
+ )
240
+ gr.LoginButton()
241
+ run_button = gr.Button("Run Evaluation & Submit All Answers")
242
+ status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
243
+ results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
244
+ run_button.click(fn=run_and_submit_all, outputs=[status_output, results_table])
245
+
246
+ if __name__ == "__main__":
247
+ print("Launching Gradio Interface...")
248
+ demo.launch(debug=True, share=False)