Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -22,63 +22,53 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
|
22 |
|
23 |
llm = ChatOpenAI(model_name="gpt-4.1-mini", temperature=0.0)
|
24 |
tool_node = ToolNode([ocr_image, parse_excel, web_search])
|
|
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
tools=tool_node
|
29 |
-
# (Use default prompt/state_schema; do NOT pass your own TypedDict.)
|
30 |
-
)
|
31 |
-
|
32 |
-
# ─── 4) Build a graph that simply wires START → "agent" → END ───
|
33 |
-
graph = StateGraph(dict) # We’ll use plain dicts instead of a custom TypedDict
|
34 |
graph.add_node("agent", agent)
|
35 |
-
|
36 |
-
# 4.a) Whenever user input arrives, send it straight into the agent
|
37 |
graph.add_edge(START, "agent")
|
38 |
-
|
39 |
-
# 4.b) Once the agent returns a final answer, go to END
|
40 |
graph.add_edge("agent", END)
|
41 |
-
|
42 |
-
# 4.c) Compile so we can call `.invoke()` at runtime
|
43 |
compiled_graph = graph.compile()
|
44 |
|
45 |
-
#
|
46 |
def respond_to_input(user_input: str) -> str:
|
47 |
-
|
|
|
|
|
|
|
|
|
48 |
system_msg = SystemMessage(
|
49 |
content=(
|
50 |
"You are an assistant with access to the following tools:\n"
|
51 |
-
" 1) web_search(query: str) → Returns the top search results for the query
|
52 |
" 2) parse_excel(path: str, sheet_name: str) → Reads an Excel file and returns its contents.\n"
|
53 |
" 3) ocr_image(path: str) → Runs OCR on an image and returns any detected text.\n\n"
|
54 |
-
"When you need to
|
55 |
-
' {"tool":"web_search","query":"<search terms>"}\n'
|
56 |
-
"If you need to
|
57 |
-
' {"tool":"parse_excel","path":"<file.xlsx>","sheet_name":"<SheetName>"}\n'
|
58 |
-
"If you need
|
59 |
-
' {"tool":"ocr_image","path":"<image.png>"}\n'
|
60 |
-
"
|
61 |
)
|
62 |
)
|
63 |
|
64 |
-
#
|
65 |
-
initial_state = {
|
66 |
-
"messages": [
|
67 |
-
system_msg,
|
68 |
-
HumanMessage(content=user_input)
|
69 |
-
]
|
70 |
-
}
|
71 |
|
72 |
-
#
|
73 |
-
final_state = compiled_graph.invoke(initial_state)
|
74 |
|
75 |
-
#
|
76 |
-
|
77 |
msg.content
|
78 |
for msg in final_state["messages"]
|
79 |
if isinstance(msg, AIMessage)
|
80 |
]
|
81 |
-
return
|
|
|
|
|
82 |
class BasicAgent:
|
83 |
def __init__(self):
|
84 |
print("BasicAgent initialized.")
|
|
|
22 |
|
23 |
llm = ChatOpenAI(model_name="gpt-4.1-mini", temperature=0.0)
|
24 |
tool_node = ToolNode([ocr_image, parse_excel, web_search])
|
25 |
+
agent = create_react_agent(model=llm, tools=tool_node)
|
26 |
|
27 |
+
# 2) Build a two‐edge graph:
|
28 |
+
graph = StateGraph(dict)
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
graph.add_node("agent", agent)
|
|
|
|
|
30 |
graph.add_edge(START, "agent")
|
|
|
|
|
31 |
graph.add_edge("agent", END)
|
|
|
|
|
32 |
compiled_graph = graph.compile()
|
33 |
|
34 |
+
# 3) The corrected respond_to_input:
|
35 |
def respond_to_input(user_input: str) -> str:
|
36 |
+
"""
|
37 |
+
We place only a SystemMessage in state["messages"], and pass the actual
|
38 |
+
user_input string as the second argument to invoke().
|
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
|
58 |
+
initial_state = { "messages": [system_msg] }
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
+
# (C) Now invoke, passing user_input separately:
|
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:
|
73 |
def __init__(self):
|
74 |
print("BasicAgent initialized.")
|