ToolNode returns Command.goto cause wrong graph in studio

Hello team, I am building a demo of deep research team.

@tool
async def call_planner(tool_call_id: Annotated[str, InjectedToolCallId], user_query: str) -> Command:
    """Call the planner to handle deep research requests."""
    tool_message = ToolMessage(
        content=f"Delegate to planner: {user_query}",
        tool_call_id=tool_call_id,
    )
    return Command(
        goto="planner",
        update={"messages": [tool_message]},
    )

@tool
async def write_research_plan(
    tool_call_id: Annotated[str, InjectedToolCallId], research_plan: Plan
) -> Command:
    """ Tool to write/save the research plan generated by the planner."""
    tool_message = ToolMessage(
        content=f"Research plan created.",
        tool_call_id=tool_call_id,
    )
    return Command(
        update={"messages": [tool_message], "current_plan": research_plan},
    )

graph = StateGraph(DeepResearchState)

graph.add_edge(START, "coordinator")
graph.add_node("coordinator", coordinator_node)
coordinator_tools = ToolNode(tools=[call_planner])
graph.add_node("coordinator_tools", coordinator_tools)
graph.add_conditional_edges(
    "coordinator", tools_condition, {"tools": "coordinator_tools", END: END}
)
graph.add_node("planner", planner_node)
planner_tools = ToolNode(tools=[write_research_plan])
graph.add_node("planner_tools", planner_tools)
graph.add_conditional_edges(
    "planner", tools_condition, {"tools": "planner_tools", END: END}
)

agent = graph.compile()

The idea is coordinator can use call_planner (which is in coordinator_tools) to delegate to planner.
The graph works fine, but it looks weird in the studio. Is there anything I might have missed in my code, or could this be a bug? Thanks for your time.

hi @FlyingCarlos

try this:


graph.add_node("coordinator_tools", coordinator_tools, destinations=("planner",))
graph.add_node("coordinator_tools", coordinator_tools, destinations={"planner": "delegate"})

or Command[Literal["planner"]]

from typing import Literal

def coordinator_tools_node(state: DeepResearchState) -> Command[Literal["planner"]]:
    ...
    return Command(goto="planner", update=...)
1 Like