Tools Returning A Command Are Missing From Messages-streaming

by ADMIN 62 views

===========================================================

Problem Description

When using tools that return a command, the messages-streaming functionality is not working as expected. This issue is related to the fix implemented in #4111, which is not properly addressing the issue of tools returning an array of commands.

Example Code

The following code snippet demonstrates the issue:

from typing import Annotated, Any

from langchain_core.messages import ToolMessage
from langchain_core.runnables.config import RunnableConfig
from langchain_core.tools import tool
from langchain_core.tools.base import InjectedToolCallId
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from langgraph.prebuilt.chat_agent_executor import AgentState
from langgraph.types import Command

USER_INFO = [
    {"user_id": "1", "name": "Bob Dylan", "location": "New York, NY"},
    {"user_id": "2", "name": "Taylor Swift", "location": "Beverly Hills, CA"},
]

USER_ID_TO_USER_INFO = {info["user_id"]: info for info in USER_INFO}


class State(AgentState):
    # updated by the tool
    user_info: dict[str, Any]


def main() -> None:
    @tool
    def lookup_user_info(tool_call_id: Annotated[str, InjectedToolCallId], config: RunnableConfig):
        """Use this to look up user information to better assist them with their questions."""
        user_id = config.get("configurable", {}).get("user_id")
        if user_id is None:
            raise ValueError("Please provide user ID")

        if user_id not in USER_ID_TO_USER_INFO:
            raise ValueError(f"User '{user_id}' not found")

        user_info = USER_ID_TO_USER_INFO[user_id]
        return Command(
            update={
                # update the state keys
                "user_info": user_info,
                # update the message history
                "messages": [
                    ToolMessage(
                        "Successfully looked up user information", tool_call_id=tool_call_id
                    )
                ],
            }
        )

    def prompt(state: State):
        user_info = state.get("user_info")
        if user_info is None:
            return state["messages"]

        system_msg = (
            f"User name is {user_info['name']}. User lives in {user_info['location']}"
        )
        return [{"role": "system", "content": system_msg}] + state["messages"]

    model = ChatOpenAI(model="gpt-4o")

    agent = create_react_agent(
        model,
        # pass the tool that can update state
        [lookup_user_info],
        state_schema=State,
        # pass dynamic prompt function
        prompt=prompt,
    )

    agent_input = {"messages": [("user", "hi, where do I live?")]}
    agent_config = {"configurable": {"user_id": "1"}}

    invoke_result = agent.invoke(
        agent_input,
        agent_config,
    )

    # print(invoke_result)

    for chunk in agent.stream(agent_input, agent_config, stream_mode='messages'):
        print(chunk)


if __name__ == '__main__':
    main()

Error Message and Stack Trace

The error message is:

There are no streaming messages from the tool command response.

Description

The issue is that the lookup_user_info tool returns a command, but the messages-streaming functionality is not working as expected. This is because the fix implemented in #4111 is not properly addressing the issue of tools returning an array of commands.

System Info

System Information

OS: Darwin OS Version: Darwin Kernel Version 24.3.0: Thu Jan 2 20:24:16 PST 2025; root:xnu-11215.81.4~3/RELEASE_ARM64_T6000 Python Version: 3.11.11 (main, Mar 11 2025, 17:41:13) [Clang 20.1.0 ]

Package Information

langchain_core: 0.3.54 langchain: 0.3.23 langsmith: 0.3.32 langchain_anthropic: 0.3.12 langchain_groq: 0.3.2 langchain_text_splitters: 0.3.8 langgraph_sdk: 0.1.61

Optional packages not installed

langserve

Other Dependencies

anthropic<1,>=0.49.0: Installed. No version info available. async-timeout<5.0.0,>=4.0.0;: Installed. No version info available. groq<1,>=0.4.1: Installed. No version info available. httpx: 0.28.1 jsonpatch<2.0,>=1.33: Installed. No version info available. langchain-anthropic;: Installed. No version info available. langchain-aws;: Installed. No version info available. langchain-azure-ai;: Installed. No version info available. langchain-cohere;: Installed. No version info available. langchain-community;: Installed. No version info available. langchain-core<1.0.0,>=0.3.49: Installed. No version info available. langchain-core<1.0.0,>=0.3.51: Installed. No version info available. langchain-core<1.0.0,>=0.3.53: Installed. No version info available. langchain-deepseek;: Installed. No version info available. langchain-fireworks;: Installed. No version info available. langchain-google-genai;: Installed. No version info available. langchain-google-vertexai;: Installed. No version info available. langchain-groq;: Installed. No version info available. langchain-huggingface;: Installed. No version info available. langchain-mistralai;: Installed. No version info available. langchain-ollama;: Installed. No version info available. langchain-openai;: Installed. No version info available. langchain-perplexity;: Installed. No version info available. langchain-text-splitters<1.0.0,>=0.3.8: Installed. No version info available. langchain-together;: Installed. No version info available. langchain-xai;: Installed. No version info available. langsmith-pyo3: Installed. No version info available. langsmith<0.4,>=0.1.125: Installed. No version info available. langsmith<0.4,>=0.1.17: Installed. No version info available. openai-agents: Installed. No version info available. opentelemetry-api: 1.32.1 opentelemetry-exporter-otlp-proto-http: 1.32.1 opentelemetry-sdk: 1.32.1 orjson: 3.10.16 packaging: 24.2 packaging<25,>=23.2: Installed. No version info available. pydantic: 2.11.3 pydantic<3.0.0,>=2.5.2;: Installed. No version info available. pydantic<3.0.0,>=2.7.4: Installed. No version info available. pydantic<3.0.0,>=2.7.4;: Installed. No version info available. pytest: Installed. No version info available. PyYAML>=5.3: Installed. No version info available. requests: 2.32.3 requests-toolbelt: 1.0.0 requests<3,>=2: Installed. No version info available. rich: 14.0.0 SQLAlchemy<3,>=1.4: Installed. No version info available. tenacity!=8.4.0,<10.0.0,>=8.1.0: Installed. No version info available. typing-extensions>=4.7: Installed. No version info available. zstandard: 0.23.0

Solution

To fix this issue, we need to modify the lookup_user_info tool to return a single command instead of an array of commands. We can do this by changing the return statement to:

return Command(
    update={
        # update the state keys
        "user_info": user_info,
        # update the message history
        "messages": [
            ToolMessage(
                "Successfully looked up user information", tool_call_id=tool_call_id
            )
        ],
    }
)

This will ensure that the messages-streaming functionality works as expected.

Code Changes

The modified code is:

def lookup_user_info(tool_call_id: Annotated[str, InjectedToolCallId], config: RunnableConfig):
    """Use this to look up user information to better assist them with their questions."""
    user_id = config.get("configurable", {}).get("user_id")
    if user_id is None:
        raise ValueError("Please provide user ID")

    if user_id not in USER_ID_TO_USER_INFO:
        raise ValueError(f"User '{user_id}' not found")

    user_info = USER_ID_TO_USER_INFO[user_id]
    return Command(
        update={
            # update<br/>
# Tools Returning a Command are Missing from Messages-Streaming: Q&A

## Q: What is the issue with tools returning a command?

A: The issue is that tools returning a command are missing from messages-streaming. This means that when a tool returns a command, the messages-streaming functionality is not working as expected.

## Q: What is the cause of this issue?

A: The cause of this issue is that the fix implemented in #4111 is not properly addressing the issue of tools returning an array of commands.

## Q: How can I reproduce this issue?

A: To reproduce this issue, you can use the example code provided in the problem description. This code demonstrates the issue and can be used to reproduce it.

## Q: What are the system requirements for this issue?

A: The system requirements for this issue are:

* OS: Darwin
* OS Version: Darwin Kernel Version 24.3.0
* Python Version: 3.11.11

## Q: What packages are required to reproduce this issue?

A: The packages required to reproduce this issue are:

* langchain_core: 0.3.54
* langchain: 0.3.23
* langsmith: 0.3.32
* langchain_anthropic: 0.3.12
* langchain_groq: 0.3.2
* langchain_text_splitters: 0.3.8
* langgraph_sdk: 0.1.61

## Q: How can I fix this issue?

A: To fix this issue, you need to modify the `lookup_user_info` tool to return a single command instead of an array of commands. You can do this by changing the return statement to:
```python
return Command(
    update={
        # update the state keys
        "user_info": user_info,
        # update the message history
        "messages": [
            ToolMessage(
                "Successfully looked up user information", tool_call_id=tool_call_id
            )
        ],
    }
)

This will ensure that the messages-streaming functionality works as expected.

Q: What are the benefits of fixing this issue?

A: The benefits of fixing this issue are:

  • Improved functionality of messages-streaming
  • Better user experience
  • Increased efficiency

Q: Are there any known limitations or workarounds for this issue?

A: Yes, there are known limitations and workarounds for this issue. The limitations are:

  • The fix implemented in #4111 is not properly addressing the issue of tools returning an array of commands.
  • The modified code requires changes to the lookup_user_info tool.

The workarounds are:

  • Use the modified code to fix the issue.
  • Implement a custom solution to handle tools returning an array of commands.

Q: How can I get help with this issue?

A: You can get help with this issue by:

  • Checking the documentation and resources provided by the project maintainers.
  • Asking questions on the project's discussion forum or support channel.
  • Reaching out to the project maintainers directly.

Q: What are the next steps for this issue?

A: The next steps for this issue are:

  • Implement the fix in the lookup_user_info tool.
  • Test the fix to ensure it works as expected.
  • Review and refine the fix as needed.

By following these steps, you can resolve the issue and ensure that the messages-streaming functionality works as expected.