Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -91,39 +91,30 @@ def plan_node(state: AgentState) -> AgentState:
|
|
| 91 |
|
| 92 |
# ─── 3) Revised finalize_node ───
|
| 93 |
def finalize_node(state: AgentState) -> AgentState:
|
| 94 |
-
|
| 95 |
-
Collect any tool results from state and then ask the LLM for a final answer.
|
| 96 |
-
We build a fresh list of SystemMessages for tool results (no reuse of prior AIMessage).
|
| 97 |
-
"""
|
| 98 |
-
# 1) Create a list of SystemMessages for each available tool result
|
| 99 |
-
messages_for_llm = []
|
| 100 |
-
if state.get("web_search_result") is not None:
|
| 101 |
-
messages_for_llm.append(
|
| 102 |
-
SystemMessage(content=f"WEB_SEARCH_RESULT: {state['web_search_result']}")
|
| 103 |
-
)
|
| 104 |
-
if state.get("ocr_result") is not None:
|
| 105 |
-
messages_for_llm.append(
|
| 106 |
-
SystemMessage(content=f"OCR_RESULT: {state['ocr_result']}")
|
| 107 |
-
)
|
| 108 |
-
if state.get("excel_result") is not None:
|
| 109 |
-
messages_for_llm.append(
|
| 110 |
-
SystemMessage(content=f"EXCEL_RESULT: {state['excel_result']}")
|
| 111 |
-
)
|
| 112 |
-
|
| 113 |
-
# 2) If plan_node already set final_answer, return it without calling LLM again
|
| 114 |
if state.get("final_answer") is not None:
|
| 115 |
return {"final_answer": state["final_answer"]}
|
| 116 |
|
| 117 |
-
#
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
|
|
|
|
|
|
| 121 |
|
| 122 |
-
#
|
| 123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
return {"final_answer": llm_response.content.strip()}
|
| 125 |
|
| 126 |
-
|
| 127 |
# ─── 4) Wrap tools in a ToolNode ───
|
| 128 |
tool_node = ToolNode([web_search_tool, ocr_image_tool, parse_excel_tool])
|
| 129 |
|
|
@@ -185,19 +176,15 @@ def respond_to_input(user_input: str) -> str:
|
|
| 185 |
Then invoke the graph; return the final_answer from the resulting state.
|
| 186 |
"""
|
| 187 |
system_msg = SystemMessage(
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
" • excel_sheet_name: <sheet name>\n"
|
| 198 |
-
"Otherwise, set final_answer: <your answer>.\n"
|
| 199 |
-
"Respond with only that Python dict literal—no extra text."
|
| 200 |
-
)
|
| 201 |
)
|
| 202 |
human_msg = HumanMessage(content=user_input)
|
| 203 |
|
|
|
|
| 91 |
|
| 92 |
# ─── 3) Revised finalize_node ───
|
| 93 |
def finalize_node(state: AgentState) -> AgentState:
|
| 94 |
+
# If plan_node already provided a final answer, skip LLM
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
if state.get("final_answer") is not None:
|
| 96 |
return {"final_answer": state["final_answer"]}
|
| 97 |
|
| 98 |
+
# Re-extract the last user question from messages
|
| 99 |
+
question = ""
|
| 100 |
+
for msg in reversed(state.get("messages", [])):
|
| 101 |
+
if isinstance(msg, HumanMessage):
|
| 102 |
+
question = msg.content
|
| 103 |
+
break
|
| 104 |
|
| 105 |
+
# Build a combined context
|
| 106 |
+
combined = f"USER_QUESTION: {question}\n"
|
| 107 |
+
if sr := state.get("web_search_result"):
|
| 108 |
+
combined += f"WEB_SEARCH_RESULT: {sr}\n"
|
| 109 |
+
if orc := state.get("ocr_result"):
|
| 110 |
+
combined += f"OCR_RESULT: {orc}\n"
|
| 111 |
+
if exr := state.get("excel_result"):
|
| 112 |
+
combined += f"EXCEL_RESULT: {exr}\n"
|
| 113 |
+
combined += "Based on the above, provide the final answer."
|
| 114 |
+
|
| 115 |
+
llm_response = llm([SystemMessage(content=combined)])
|
| 116 |
return {"final_answer": llm_response.content.strip()}
|
| 117 |
|
|
|
|
| 118 |
# ─── 4) Wrap tools in a ToolNode ───
|
| 119 |
tool_node = ToolNode([web_search_tool, ocr_image_tool, parse_excel_tool])
|
| 120 |
|
|
|
|
| 176 |
Then invoke the graph; return the final_answer from the resulting state.
|
| 177 |
"""
|
| 178 |
system_msg = SystemMessage(
|
| 179 |
+
content=(
|
| 180 |
+
"You are an agent that decides whether to call a tool or answer the user directly. "
|
| 181 |
+
"The user’s question is below. If the answer can be given directly, return {'final_answer': <your answer>}."
|
| 182 |
+
"If you need to call a tool, set exactly one key from the following in a Python dict: "
|
| 183 |
+
" • web_search_query: <search terms>\n"
|
| 184 |
+
" • ocr_path: <path to an image file>\n"
|
| 185 |
+
" • excel_path: <path to a .xlsx file>, excel_sheet_name: <sheet name>.\n"
|
| 186 |
+
"Do not include any extra text or markdown—only return a valid Python dict literal."
|
| 187 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
)
|
| 189 |
human_msg = HumanMessage(content=user_input)
|
| 190 |
|