naman1102 commited on
Commit
e2bc6df
·
1 Parent(s): b1271ea

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -20
app.py CHANGED
@@ -14,8 +14,31 @@ from langgraph.graph import StateGraph, START, END
14
  from langgraph.graph.message import add_messages
15
  from langchain.schema import HumanMessage, AIMessage, SystemMessage
16
  # Create a ToolNode that knows about your web_search function
 
17
 
18
- # (Keep Constants as is)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  # --- Constants ---
20
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
21
 
@@ -39,19 +62,20 @@ def respond_to_input(user_input: str) -> str:
39
  """
40
  # (A) First message: describe your tools
41
  system_msg = SystemMessage(
42
- content=(
43
- "You are an assistant with access to the following tools:\n"
44
- " 1) web_search(query: str) → Returns the top search results for the query.\n"
45
- " 2) parse_excel(path: str, sheet_name: str) → Reads an Excel file and returns its contents.\n"
46
- " 3) ocr_image(path: str) → Runs OCR on an image and returns any detected text.\n\n"
47
- "When you need up‐to‐date info, respond exactly with JSON:\n"
48
- ' { "tool": "web_search", "query": "<search terms>" }\n'
49
- "If you need to read an Excel file, respond:\n"
50
- ' { "tool": "parse_excel", "path": "<file.xlsx>", "sheet_name": "<SheetName>" }\n'
51
- "If you need OCR, respond:\n"
52
- ' { "tool": "ocr_image", "path": "<image.png>" }\n'
53
- "Otherwise, reply only with your final answer as plain text."
54
- )
 
55
  )
56
 
57
  # (B) initial state has only the system prompt
@@ -61,12 +85,33 @@ def respond_to_input(user_input: str) -> str:
61
  final_state = compiled_graph.invoke(initial_state, user_input)
62
 
63
  # (D) Pull out the last AIMessage from final_state["messages"]:
64
- assistant_messages = [
65
- msg.content
66
- for msg in final_state["messages"]
67
- if isinstance(msg, AIMessage)
68
- ]
69
- return assistant_messages[-1] if assistant_messages else ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
 
72
  class BasicAgent:
 
14
  from langgraph.graph.message import add_messages
15
  from langchain.schema import HumanMessage, AIMessage, SystemMessage
16
  # Create a ToolNode that knows about your web_search function
17
+ import json
18
 
19
+ def parse_tool_json(text: str) -> dict | None:
20
+ """
21
+ Given a string like '{"tool":"web_search","query":"..."}'
22
+ or '"{\"tool\":\"web_search\",\"query\":\"...\"}"', return
23
+ the parsed dict. Otherwise, return None.
24
+ """
25
+ t = text.strip()
26
+ # If it’s wrapped in single or double quotes, remove them:
27
+ if (t.startswith('"') and t.endswith('"')) or (t.startswith("'") and t.endswith("'")):
28
+ t = t[1:-1]
29
+ try:
30
+ obj = json.loads(t)
31
+ if isinstance(obj, dict) and "tool" in obj:
32
+ return obj
33
+ except Exception:
34
+ return None
35
+ return None
36
+
37
+
38
+ # (Keep Constan
39
+ #
40
+ #
41
+ # ts as is)
42
  # --- Constants ---
43
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
44
 
 
62
  """
63
  # (A) First message: describe your tools
64
  system_msg = SystemMessage(
65
+ content=(
66
+ "You are an assistant with access to exactly these tools:\n"
67
+ " 1) web_search(query:str)\n"
68
+ " 2) parse_excel(path:str,sheet_name:str)\n"
69
+ " 3) ocr_image(path:str)\n\n"
70
+ "⚠️ **IMPORTANT** ⚠️: If (and only if) you need to call one of these tools, "
71
+ "output exactly one JSON object and nothing else. For example:\n"
72
+ "```json\n"
73
+ '{"tool":"web_search","query":"Mercedes Sosa albums 2000-2009"}\n'
74
+ "```\n"
75
+ "That JSON must start at the very first character of your response and end at the very last character—"
76
+ "no quotes, no code fences, no extra explanation. \n\n"
77
+ "If you do NOT need any tool, simply reply with your final answer as plain text (no JSON)."
78
+ )
79
  )
80
 
81
  # (B) initial state has only the system prompt
 
85
  final_state = compiled_graph.invoke(initial_state, user_input)
86
 
87
  # (D) Pull out the last AIMessage from final_state["messages"]:
88
+ last_msg = None
89
+ for msg in final_state["messages"][::-1]:
90
+ if isinstance(msg, AIMessage):
91
+ last_msg = msg.content
92
+ break
93
+
94
+ # Try to parse it as a tool‐call dict:
95
+ tool_dict = parse_tool_json(last_msg or "")
96
+ if tool_dict is not None:
97
+ # run the tool and then feed it back into the LLM:
98
+ result = tool_node.run(tool_dict)
99
+ # Append the tool’s result as an AIMessage, then invoke again:
100
+ new_state = {
101
+ "messages": [
102
+ *final_state["messages"],
103
+ AIMessage(content=result)
104
+ ]
105
+ }
106
+ second_pass = compiled_graph.invoke(new_state, "")
107
+ # Get that second pass’s last AIMessage:
108
+ for msg in second_pass["messages"][::-1]:
109
+ if isinstance(msg, AIMessage):
110
+ return msg.content
111
+ return ""
112
+ else:
113
+ # No valid tool JSON → treat last_msg as final answer
114
+ return last_msg or ""
115
 
116
 
117
  class BasicAgent: