naman1102 commited on
Commit
a59a680
·
1 Parent(s): 55f1296
Files changed (3) hide show
  1. app.py +20 -9
  2. state.py +3 -1
  3. tools.py +66 -1
app.py CHANGED
@@ -20,7 +20,7 @@ from state import AgentState
20
  # --- Constants ---
21
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
22
 
23
- from tools import ocr_image_tool, parse_excel_tool, web_search_tool, run_tools, audio_transcriber_tool
24
 
25
  llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0.0)
26
 
@@ -46,6 +46,7 @@ def plan_node(state: AgentState) -> AgentState:
46
  " {\"ocr_path\":\"<path to image>\"}\n"
47
  " {\"excel_path\":\"<path to xlsx>\", \"excel_sheet_name\":\"<sheet>\"}\n"
48
  " {\"audio_path\":\"<path to audio file>\"}\n"
 
49
  "Do not include any extra characters or markdown—only the JSON literal."
50
  )
51
  )
@@ -76,6 +77,7 @@ def plan_node(state: AgentState) -> AgentState:
76
  "excel_path",
77
  "excel_sheet_name",
78
  "audio_path",
 
79
  "final_answer"
80
  }
81
  for k, v in parsed.items():
@@ -115,6 +117,8 @@ def finalize_node(state: AgentState) -> AgentState:
115
  # Note: your code already stores the audio transcription under "transcript"
116
  if tr := state.get("transcript"):
117
  combined += f"AUDIO_TRANSCRIPT: {tr}\n"
 
 
118
 
119
  # Here we demand a JSON response with a single key "final_answer"
120
  combined += (
@@ -174,6 +178,10 @@ def tool_node(state: AgentState) -> AgentState:
174
  out = audio_transcriber_tool(state)
175
  return out
176
 
 
 
 
 
177
  # If we somehow reach here, no recognized tool key was set:
178
  # print(">>> tools_node: no valid tool key found in state!")
179
  return {}
@@ -213,6 +221,7 @@ def route_plan(plan_out: AgentState) -> str:
213
  or plan_out.get("ocr_path")
214
  or plan_out.get("excel_path")
215
  or plan_out.get("audio_path")
 
216
  ):
217
  # print(">> route_plan ➡️ tools")
218
  return "tools"
@@ -249,14 +258,16 @@ def respond_to_input(user_input: str) -> str:
249
  """
250
  system_msg = SystemMessage(
251
  content=(
252
- "You are an agent that decides whether to call a tool or answer the user directly. "
253
- "The user's question is below. If the answer can be given directly, return {'final_answer': <your answer>}."
254
- "If you need to call a tool, set exactly one key from the following in a Python dict: "
255
- " web_search_query: <search terms>\n"
256
- " • ocr_path: <path to an image file>\n"
257
- " • excel_path: <path to a .xlsx file>, excel_sheet_name: <sheet name>.\n"
258
- " • audio_path: <path to an audio file>\n"
259
- "Do not include any extra text or markdown—only return a valid Python dict literal."
 
 
260
  )
261
  )
262
  human_msg = HumanMessage(content=user_input)
 
20
  # --- Constants ---
21
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
22
 
23
+ from tools import ocr_image_tool, parse_excel_tool, web_search_tool, run_tools, audio_transcriber_tool, wikipedia_search_tool
24
 
25
  llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0.0)
26
 
 
46
  " {\"ocr_path\":\"<path to image>\"}\n"
47
  " {\"excel_path\":\"<path to xlsx>\", \"excel_sheet_name\":\"<sheet>\"}\n"
48
  " {\"audio_path\":\"<path to audio file>\"}\n"
49
+ " {\"wiki_query\":\"<wikipedia search terms>\"}\n"
50
  "Do not include any extra characters or markdown—only the JSON literal."
51
  )
52
  )
 
77
  "excel_path",
78
  "excel_sheet_name",
79
  "audio_path",
80
+ "wiki_query",
81
  "final_answer"
82
  }
83
  for k, v in parsed.items():
 
117
  # Note: your code already stores the audio transcription under "transcript"
118
  if tr := state.get("transcript"):
119
  combined += f"AUDIO_TRANSCRIPT: {tr}\n"
120
+ if wr := state.get("wiki_result"):
121
+ combined += f"WIKIPEDIA_RESULT: {wr}\n"
122
 
123
  # Here we demand a JSON response with a single key "final_answer"
124
  combined += (
 
178
  out = audio_transcriber_tool(state)
179
  return out
180
 
181
+ if state.get("wiki_query"):
182
+ out = wikipedia_search_tool(state)
183
+ return out
184
+
185
  # If we somehow reach here, no recognized tool key was set:
186
  # print(">>> tools_node: no valid tool key found in state!")
187
  return {}
 
221
  or plan_out.get("ocr_path")
222
  or plan_out.get("excel_path")
223
  or plan_out.get("audio_path")
224
+ or plan_out.get("wiki_query")
225
  ):
226
  # print(">> route_plan ➡️ tools")
227
  return "tools"
 
258
  """
259
  system_msg = SystemMessage(
260
  content=(
261
+ "You are an agent that decides whether to call a tool or answer directly.\n"
262
+ "User's question: \"" + user_input + "\"\n\n"
263
+ "If you can answer directly, return exactly {\"final_answer\":\"<your answer>\"}.\n"
264
+ "• Otherwise, respond with exactly one of:\n"
265
+ " {\"web_search_query\":\"<search terms>\"}\n"
266
+ " {\"ocr_path\":\"<path to image>\"}\n"
267
+ " {\"excel_path\":\"<path to xlsx>\", \"excel_sheet_name\":\"<sheet>\"}\n"
268
+ " {\"audio_path\":\"<path to audio file>\"}\n"
269
+ " {\"wiki_query\":\"<wikipedia search terms>\"}\n"
270
+ "Do not include any extra characters or markdown—only the JSON literal."
271
  )
272
  )
273
  human_msg = HumanMessage(content=user_input)
state.py CHANGED
@@ -15,4 +15,6 @@ class AgentState(TypedDict, total=False):
15
  user_input: str
16
  audio_path: str
17
  transcript: str
18
- audio_transcript: str
 
 
 
15
  user_input: str
16
  audio_path: str
17
  transcript: str
18
+ audio_transcript: str
19
+ wiki_query: str
20
+ wiki_result: str
tools.py CHANGED
@@ -177,4 +177,69 @@ def audio_transcriber_tool(state: AgentState) -> AgentState:
177
  return {
178
  "audio_path": None,
179
  "transcript": text
180
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  return {
178
  "audio_path": None,
179
  "transcript": text
180
+ }
181
+
182
+ # tools.py
183
+
184
+ import re
185
+ import requests
186
+ from state import AgentState
187
+
188
+ def wikipedia_search_tool(state: AgentState) -> AgentState:
189
+ """
190
+ LangGraph wrapper for searching Wikipedia.
191
+ Expects: state["wiki_query"] to be a non‐empty string.
192
+ Returns:
193
+ {
194
+ "wiki_query": None,
195
+ "wiki_result": "<text summary of first matching page or an error message>"
196
+ }
197
+ If no valid wiki_query is provided, returns {}.
198
+ """
199
+ query = state.get("wiki_query", "").strip()
200
+ if not query:
201
+ return {}
202
+
203
+ try:
204
+ # 1) Use the MediaWiki API to search for page titles matching the query
205
+ search_params = {
206
+ "action": "query",
207
+ "list": "search",
208
+ "srsearch": query,
209
+ "format": "json",
210
+ "utf8": 1
211
+ }
212
+ search_resp = requests.get("https://en.wikipedia.org/w/api.php", params=search_params, timeout=10)
213
+ search_resp.raise_for_status()
214
+ search_data = search_resp.json()
215
+
216
+ search_results = search_data.get("query", {}).get("search", [])
217
+ if not search_results:
218
+ return {"wiki_query": None, "wiki_result": f"No Wikipedia page found for '{query}'."}
219
+
220
+ # 2) Take the first search result's title
221
+ first_title = search_results[0].get("title", "")
222
+ if not first_title:
223
+ return {"wiki_query": None, "wiki_result": "Unexpected format from Wikipedia search."}
224
+
225
+ # 3) Fetch the page summary for that title via the REST summary endpoint
226
+ title_for_url = requests.utils.requote_uri(first_title)
227
+ summary_url = f"https://en.wikipedia.org/api/rest_v1/page/summary/{title_for_url}"
228
+ summary_resp = requests.get(summary_url, timeout=10)
229
+ summary_resp.raise_for_status()
230
+ summary_data = summary_resp.json()
231
+
232
+ # 4) Extract either the "extract" field or a fallback message
233
+ summary_text = summary_data.get("extract")
234
+ if not summary_text:
235
+ summary_text = summary_data.get("description", "No summary available.")
236
+
237
+ return {
238
+ "wiki_query": None,
239
+ "wiki_result": f"Title: {first_title}\n\n{summary_text}"
240
+ }
241
+
242
+ except requests.exceptions.RequestException as e:
243
+ return {"wiki_query": None, "wiki_result": f"Wikipedia search error: {e}"}
244
+ except Exception as e:
245
+ return {"wiki_query": None, "wiki_result": f"Unexpected error in wikipedia_search_tool: {e}"}