fix(researcher): Handle non-string search results in summarizer node
This commit is contained in:
@@ -17,7 +17,15 @@ def summarizer_node(state: WorkerState) -> dict:
|
|||||||
callbacks=[LangChainLoggingHandler(logger=logger)]
|
callbacks=[LangChainLoggingHandler(logger=logger)]
|
||||||
)
|
)
|
||||||
|
|
||||||
results_str = "\n---\n".join(raw_results)
|
# Ensure all results are strings (Gemini/OpenAI might return complex content)
|
||||||
|
processed_results = []
|
||||||
|
for res in raw_results:
|
||||||
|
if isinstance(res, list):
|
||||||
|
processed_results.append(str(res))
|
||||||
|
else:
|
||||||
|
processed_results.append(str(res))
|
||||||
|
|
||||||
|
results_str = "\n---\n".join(processed_results)
|
||||||
|
|
||||||
prompt = f"""You are a Research Specialist sub-agent. You have completed a research sub-task.
|
prompt = f"""You are a Research Specialist sub-agent. You have completed a research sub-task.
|
||||||
Task: {task}
|
Task: {task}
|
||||||
|
|||||||
@@ -84,3 +84,53 @@ def test_orchestrator_full_flow():
|
|||||||
assert mock_reflector.called
|
assert mock_reflector.called
|
||||||
assert mock_synthesizer.called
|
assert mock_synthesizer.called
|
||||||
assert "Final synthesized answer" in [m.content for m in final_state["messages"]]
|
assert "Final synthesized answer" in [m.content for m in final_state["messages"]]
|
||||||
|
|
||||||
|
def test_orchestrator_researcher_flow():
|
||||||
|
"""Verify that the Orchestrator can route to the researcher worker."""
|
||||||
|
|
||||||
|
mock_analyzer = MagicMock()
|
||||||
|
mock_planner = MagicMock()
|
||||||
|
mock_delegate = MagicMock()
|
||||||
|
mock_researcher = MagicMock()
|
||||||
|
mock_reflector = MagicMock()
|
||||||
|
mock_synthesizer = MagicMock()
|
||||||
|
|
||||||
|
mock_analyzer.return_value = {"next_action": "plan"}
|
||||||
|
mock_planner.return_value = {
|
||||||
|
"checklist": [{"task": "Search news", "worker": "researcher"}],
|
||||||
|
"current_step": 0
|
||||||
|
}
|
||||||
|
mock_delegate.side_effect = [
|
||||||
|
{"next_action": "researcher"},
|
||||||
|
{"next_action": "summarize"}
|
||||||
|
]
|
||||||
|
mock_researcher.return_value = {"messages": [AIMessage(content="News found")]}
|
||||||
|
mock_reflector.return_value = {"current_step": 1, "next_action": "delegate"}
|
||||||
|
mock_synthesizer.return_value = {"messages": [AIMessage(content="Final News Summary")], "next_action": "end"}
|
||||||
|
|
||||||
|
app = create_workflow(
|
||||||
|
query_analyzer=mock_analyzer,
|
||||||
|
planner=mock_planner,
|
||||||
|
delegate=mock_delegate,
|
||||||
|
researcher_worker=mock_researcher,
|
||||||
|
reflector=mock_reflector,
|
||||||
|
synthesizer=mock_synthesizer
|
||||||
|
)
|
||||||
|
|
||||||
|
initial_state = AgentState(
|
||||||
|
messages=[HumanMessage(content="What's the news?")],
|
||||||
|
question="What's the news?",
|
||||||
|
analysis={},
|
||||||
|
next_action="",
|
||||||
|
iterations=0,
|
||||||
|
checklist=[],
|
||||||
|
current_step=0,
|
||||||
|
vfs={},
|
||||||
|
plots=[],
|
||||||
|
dfs={}
|
||||||
|
)
|
||||||
|
|
||||||
|
final_state = app.invoke(initial_state)
|
||||||
|
|
||||||
|
assert mock_researcher.called
|
||||||
|
assert "Final News Summary" in [m.content for m in final_state["messages"]]
|
||||||
|
|||||||
Reference in New Issue
Block a user