Toumaima commited on
Commit
6b9c0e4
·
verified ·
1 Parent(s): c323dcc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -133
app.py CHANGED
@@ -1,17 +1,50 @@
 
 
 
 
 
 
 
 
1
  import os
2
- import gradio as gr
3
- import requests
4
- import string
5
- import warnings
6
- import pandas as pd
7
  import re
8
- from huggingface_hub import login
9
- from groq import Groq
10
 
11
- # --- Constants ---
12
- DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
- # --- Basic Agent Definition ---
15
  class BasicAgent:
16
  def __init__(self):
17
  print("BasicAgent initialized.")
@@ -28,11 +61,53 @@ class BasicAgent:
28
  If you are asked for a comma separated list, apply the above rules depending of whether the element
29
  to be put in the list is a number or a string."""
30
  )
 
31
 
32
  def format_final_answer(self, answer: str) -> str:
33
  cleaned = " ".join(answer.split())
34
  return f"FINAL ANSWER: {cleaned}"
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  def check_commutativity(self):
37
  S = ['a', 'b', 'c', 'd', 'e']
38
  counter_example_elements = set()
@@ -75,126 +150,4 @@ class BasicAgent:
75
  }
76
  opposite = opposites.get(word, f"UNKNOWN_OPPOSITE_OF_{word}")
77
  return f"FINAL ANSWER: {opposite.upper()}"
78
- return self.format_final_answer("COULD_NOT_SOLVE")
79
-
80
- def query_groq(self, question: str) -> str:
81
- full_prompt = f"{self.agent_prompt}\n\nQuestion: {question}"
82
- try:
83
- response = self.client.chat.completions.create(
84
- model="llama3-8b-8192",
85
- messages=[{"role": "user", "content": full_prompt}]
86
- )
87
- answer = response.choices[0].message.content
88
- print(f"[Groq Raw Response]: {answer}")
89
- if "FINAL ANSWER: " in answer:
90
- return answer.split("FINAL ANSWER: ")[-1].strip().upper()
91
- else:
92
- return self.format_final_answer(answer).upper()
93
- except Exception as e:
94
- print(f"[Groq ERROR]: {e}")
95
- return self.format_final_answer("GROQ_ERROR")
96
-
97
- def __call__(self, question: str) -> str:
98
- print(f"Received question: {question[:50]}...")
99
- if "commutative" in question.lower():
100
- return self.check_commutativity()
101
- if self.maybe_reversed(question):
102
- print("Detected likely reversed riddle.")
103
- return self.solve_riddle(question)
104
- return self.query_groq(question)
105
-
106
- def run_and_submit_all(profile: gr.OAuthProfile | None):
107
- space_id = os.getenv("SPACE_ID")
108
- if profile:
109
- username = f"{profile.username}"
110
- print("User logged in.")
111
- else:
112
- print("User not logged in.")
113
- return "Please Login to Hugging Face with the button.", None
114
-
115
- api_url = DEFAULT_API_URL
116
- questions_url = f"{api_url}/questions"
117
- submit_url = f"{api_url}/submit"
118
-
119
- try:
120
- agent = BasicAgent()
121
- except Exception as e:
122
- return f"Error initializing agent: {e}", None
123
-
124
- agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
125
- try:
126
- response = requests.get(questions_url, timeout=15)
127
- response.raise_for_status()
128
- questions_data = response.json()
129
- if not questions_data:
130
- return "Fetched questions list is empty or invalid format.", None
131
- except requests.exceptions.RequestException as e:
132
- return f"Error fetching questions: {e}", None
133
-
134
- results_log = []
135
- answers_payload = []
136
- for item in questions_data:
137
- task_id = item.get("task_id")
138
- question_text = item.get("question")
139
-
140
- if not task_id or question_text is None:
141
- continue
142
- try:
143
- submitted_answer = agent(question_text)
144
- print(f"Q: {question_text}")
145
- print(f"Predicted: {submitted_answer}")
146
-
147
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
148
- results_log.append({
149
- "Task ID": task_id,
150
- "Question": question_text,
151
- "Submitted Answer": submitted_answer
152
- })
153
- except Exception as e:
154
- results_log.append({
155
- "Task ID": task_id,
156
- "Question": question_text,
157
- "Submitted Answer": f"AGENT ERROR: {e}"
158
- })
159
-
160
- if not answers_payload:
161
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
162
-
163
- submission_data = {
164
- "username": username.strip(),
165
- "agent_code": agent_code,
166
- "answers": answers_payload
167
- }
168
-
169
- try:
170
- response = requests.post(submit_url, json=submission_data, timeout=60)
171
- response.raise_for_status()
172
- result_data = response.json()
173
- print(result_data)
174
- final_status = (
175
- f"Submission Successful!\n"
176
- f"User: {result_data.get('username')}\n"
177
- f"Overall Score: {result_data.get('score', '?')}% "
178
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
179
- f"Message: {result_data.get('message', 'No message received.')}"
180
- )
181
- return final_status, pd.DataFrame(results_log)
182
- except Exception as e:
183
- return f"Submission Failed: {e}", pd.DataFrame(results_log)
184
-
185
- # --- Build Gradio Interface ---
186
- with gr.Blocks() as demo:
187
- gr.Markdown("# Basic Agent Evaluation Runner")
188
- gr.LoginButton()
189
- run_button = gr.Button("Run Evaluation & Submit All Answers")
190
- status_output = gr.Textbox(label="Run Status / Submission Result", max_lines=5, interactive=False, max_length=200)
191
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
192
-
193
- run_button.click(
194
- fn=run_and_submit_all,
195
- outputs=[status_output, results_table]
196
- )
197
-
198
- if __name__ == "__main__":
199
- print("Launching Gradio Interface for Basic Agent Evaluation...")
200
- demo.launch(debug=True, share=False)
 
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
5
+ 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)
41
+ builder.add_node("tools", ToolNode([wiki_search, web_search, arvix_search]))
42
+ builder.set_entry_point("assistant")
43
+ builder.set_finish_point("assistant")
44
+ builder.add_conditional_edges("assistant", tools_condition)
45
+ builder.add_edge("tools", "assistant")
46
+ return builder.compile()
47
 
 
48
  class BasicAgent:
49
  def __init__(self):
50
  print("BasicAgent initialized.")
 
61
  If you are asked for a comma separated list, apply the above rules depending of whether the element
62
  to be put in the list is a number or a string."""
63
  )
64
+ self.tool_chain = build_tool_graph(self.agent_prompt)
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}"
72
+ try:
73
+ response = self.client.chat.completions.create(
74
+ model="llama3-8b-8192",
75
+ messages=[{"role": "user", "content": full_prompt}]
76
+ )
77
+ answer = response.choices[0].message.content
78
+ print(f"[Groq Raw Response]: {answer}")
79
+ return self.format_final_answer(answer).upper()
80
+ except Exception as e:
81
+ print(f"[Groq ERROR]: {e}")
82
+ return self.format_final_answer("GROQ_ERROR")
83
+
84
+ def query_tools(self, question: str) -> str:
85
+ try:
86
+ input_state = {
87
+ "messages": [
88
+ SystemMessage(content=self.agent_prompt),
89
+ HumanMessage(content=question)
90
+ ]
91
+ }
92
+ result = self.tool_chain.invoke(input_state)
93
+ final_msg = result["messages"][-1].content
94
+ print(f"[LangGraph Final Response]: {final_msg}")
95
+ return self.format_final_answer(final_msg)
96
+ except Exception as e:
97
+ print(f"[LangGraph ERROR]: {e}")
98
+ return self.format_final_answer("TOOL_ERROR")
99
+
100
+ def __call__(self, question: str) -> str:
101
+ print(f"Received question: {question[:50]}...")
102
+ if "commutative" in question.lower():
103
+ return self.check_commutativity()
104
+ if self.maybe_reversed(question):
105
+ print("Detected likely reversed riddle.")
106
+ return self.solve_riddle(question)
107
+ if "use tools" in question.lower():
108
+ return self.query_tools(question)
109
+ return self.query_groq(question)
110
+
111
  def check_commutativity(self):
112
  S = ['a', 'b', 'c', 'd', 'e']
113
  counter_example_elements = set()
 
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")