# How to stream from graph with ReactAgent?

**URL:** <https://forum.langchain.com/t/how-to-stream-from-graph-with-reactagent/1538>\
**Category:** LangGraph\
**Tags:** python-help\
**Created:** [September 15, 2025, 5:55pm UTC](https://forum.langchain.com/t/how-to-stream-from-graph-with-reactagent/1538 "2025-09-15T17:55:36Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jerson-censys](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/jerson-censys/32/961_2.png) [@jerson-censys](https://forum.langchain.com/u/jerson-censys)\
**Post date:** [September 15, 2025, 5:55pm UTC](https://forum.langchain.com/t/how-to-stream-from-graph-with-reactagent/1538/1 "2025-09-15T17:55:36Z")

</div>

I’m trying to stream a graph that contains React agents equipped with tools. I followed the documentation and specified that I want different types of stream mode: `stream_mode=["messages", "updates", "custom"]`. For some reason, nothing gets streamed from `“messages”`. I’m only able to capture events of type `“Updates”`. Here is my implementation:

```python
 async for stream_mode, chunk in self.graph.astream(
                initial_state.model_dump(),
                config=config,
                stream_mode=["messages", "updates", "custom"],
            ):
                if stream_mode == "messages":
                    # chunk is a tuple (message_chunk, metadata) for messages mode
                    message_chunk, metadata = chunk
                    logger.info(f"Messages stream event - message_chunk: {message_chunk}, metadata: {metadata}")

                    # Start content block if not already started
                    if not content_started:
                        current_content_block_id = str(uuid.uuid4())
                        content_start_event = ContentBlockStartEvent(
                            block_id=current_content_block_id,
                            content_type="text",
                        )
                        yield self._format_sse_event(content_start_event)
                        content_started = True

                    # Stream text content tokens
                    if hasattr(message_chunk, "content") and message_chunk.content:
                        content_delta_event = ContentBlockDeltaEvent(
                            block_id=current_content_block_id,
                            delta=message_chunk.content,
                        )
                        yield self._format_sse_event(content_delta_event)

                        # Save content to database
                        if initial_state.current_message_id:
                            await self._save_streaming_text_content(
                                message_id=initial_state.current_message_id,
                                text_chunk=message_chunk.content,
                            )

                # Handle graph node completions and responses
                elif stream_mode == "updates":
                    logger.info(f"Node completed with output keys: {chunk}")

                # Handle custom streaming data from tools/nodes
                elif stream_mode == "custom":
                    logger.debug(f"Custom stream event: {chunk}")

```

Graph:

```python
class Graph:
    def __init__ (self) -> None:
        self.graph_builder = StateGraph(ChatState)
        self._setup_nodes()
        self._setup_edges()

        memory = MemorySaver()
        self.graph = self.graph_builder.compile(checkpointer=memory)

    def _setup_nodes(self) -> None:
        """Set up the nodes for the graph."""
        from project.agents.x_agent.agent import x_agent
        from project.agents.a_agent.agent import a_agent
        from project.agents.y_agent.agent import y_agent

        self.graph_builder.add_node("x_agent", x_agent)
        self.graph_builder.add_node("a_agent", a_agent)
        self.graph_builder.add_node("y_agent", y_agent)

    def _setup_edges(self) -> None:
        """Set up the edges for the graph according to the new workflow."""
        # Start with supervisor for routing
        self.graph_builder.add_edge(START, "a_agent")

        self.graph_builder.add_conditional_edges(
            "a_agent",
            self._route_to_agent,
            {
                "other": "y_agent",
                "general": "x_agent",
                "error": END,
            },
        )

        # Both specialized agents go to END
        self.graph_builder.add_edge("y_agent", END)
        self.graph_builder.add_edge("x_agent", END)

    def _route_to_agent(self, state: ChatState) -> str:
        """Route to the appropriate agent based on supervisor decision."""
        if state.errors:
            return "error"

        if state.selected_agent == "y_agent":
            return "y_agent"

        if state.selected_agent == "x_agent":
            return "x_agent"

        return "x_agent"

def get_graph(): # noqa: ANN201
    """Get the graph instance."""
    return Graph().graph

```

x\_agent and y\_agent are defined the same way:

```python
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.runnables import RunnableConfig
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

MODEL_NAME = "x-model"

@traceable(
    run_type="llm",
    metadata={
        "agent": "x_agent",
        "ls_model_name": MODEL_NAME,
        "ls_provider": "x-provider",
    },
)
async def x_agent(state: ChatState, config: RunnableConfig) -> ChatState:
    try:
        mcp_tools = await get_tools(state.id)

        llm = ChatOpenAI(
            model=MODEL_NAME,
            base_url=settings.BASE_LLM_ENDPOINT,
            api_key=SecretStr(settings.BASE_LLM_API_KEY),
            streaming=True, # Enable streaming
            temperature=0.1,
        )

        agent = create_react_agent(
            model=llm,
            tools=mcp_tools,
        )

        messages = []
        messages.append(SystemMessage(content=system_prompt))

        for hist_msg in state.conversation_history:
            if hist_msg["role"] == "user":
                messages.append(HumanMessage(content=hist_msg["content"]))
            elif hist_msg["role"] == "assistant":
                from langchain_core.messages import AIMessage

                ai_msg = AIMessage(content=hist_msg.get("content", ""))

                if "tool_calls" in hist_msg:
                    ai_msg.tool_calls = hist_msg["tool_calls"]

                messages.append(ai_msg)

        current_user_message = user_prompt.format(user_question=state.user_prompt)
        messages.append(HumanMessage(content=current_user_message))

        llm_response = await agent.ainvoke({"messages": messages}, config=config)

        return state.model_copy(
            update={
                "agent_response": llm_response,
                "agent_data": {
                    "agent_type": "x_agent",
                    "tools_available": len(mcp_tools),
                    "streaming_enabled": True,
                },
            },
        )

    except (ValueError, ConnectionError, RuntimeError) as e:
        error_message = f"x_agent failed with error: {e}"
        logger.error(error_message, exc_info=True)

        return state.model_copy(update={"errors": [*state.errors, error_message]})

```

When I run this I only get two SSE events streamed:

```json
data: {"type": "message_start", "timestamp": "2025-09-15T10:21:08.691839", "message_id": "uuid-x", "conversation_id": "uuid-x"}

data: {"type": "message_stop", "timestamp": "2025-09-15T10:21:14.778332", "message_id": "uuid-x", "stop_reason": "complete", "usage": {"input_tokens": 0, "output_tokens": 0, "total_tokens": 0}}

```

In my terminal I get:

```shell
2025-09-15 10:21:14.777 | INFO | _stream_graph_execution:349 - Node completed with output keys: 
{
    "state": {
        "user_prompt": "hello!",
        "conversation_history": [{"role": "user", "content": "hello!"}],
        "next_task": None,
        "selected_agent": "x_agent",
        "agent_response": {
            "messages": [
                SystemMessage(
                    ...(system_prompt),
                ),
                HumanMessage(
                    content="hello!",
                    additional_kwargs={},
                    response_metadata={},
                    id="uuid_1",
                ),
                HumanMessage(
                    content='\nAnalyze this question',
                    additional_kwargs={},
                    response_metadata={},
                    id="uuid_2",
                ),
                AIMessage(
                    content="Hello! how can I help you?",
                    additional_kwargs={},
                    response_metadata={
                        "finish_reason": "stop",
                        "model_name": "x-model",
                        "system_fingerprint": "xxxx",
                    },
                    id="uuid_3",
                    usage_metadata={
                        "input_tokens": 6741,
                        "output_tokens": 127,
                        "total_tokens": 6868,
                        "input_token_details": {"audio": 0, "cache_read": 0},
                        "output_token_details": {"audio": 0, "reasoning": 0},
                    },
                ),
            ]
        },
        "agent_data": {
            "agent_type": "x_agent",
            "tools_available": 10,
            "streaming_enabled": True,
        },
        "response_content": "",
        "tool_calls": [],
        "citations": [],
        "token_usage": None,
        "errors": [],
        "created_at": datetime.datetime(
            2025, 9, 15, 17, 21, 9, 156410, tzinfo=datetime.timezone.utc
        ),
        "updated_at": None,
    }
}

```

What am I doing wrong? Is this related to this issue: [When using create\_react\_agent with tools, executing astream with stream\_mode="messages" does not produce streaming output. · Issue #5249 · langchain-ai/langgraph · GitHub](https://github.com/langchain-ai/langgraph/issues/5249)

My langgraph and python version are:

```auto
    "langgraph>=0.6.7",

```

`python 3.13.5`

---

<div class="post-metadata">

**Author:** ![catherine-langchain](https://avatars.discourse-cdn.com/v4/letter/c/3be4f8/32.png) [@catherine-langchain](https://forum.langchain.com/u/catherine-langchain)\
**Post date:** [September 16, 2025, 1:14am UTC](https://forum.langchain.com/t/how-to-stream-from-graph-with-reactagent/1538/2 "2025-09-16T01:14:04Z")

</div>

hey @jerson-censys ! Are you streaming with subgraph=True?

---

<div class="post-metadata">

**Author:** ![pawel-twardziak](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/pawel-twardziak/32/960_2.png) [@pawel-twardziak](https://forum.langchain.com/u/pawel-twardziak)\
**Post date:** [September 16, 2025, 3:58pm UTC](https://forum.langchain.com/t/how-to-stream-from-graph-with-reactagent/1538/3 "2025-09-16T15:58:30Z")

</div>

Hi @jerson-censys

have you tried that configuration:

async for stream\_mode, chunk in self.graph.astream(  
initial\_state.model\_dump(),  
config=config,  
stream\_mode=[“messages”, “updates”, “custom”],  
subgraphs=True, # this is the key  
):

---

<div class="post-metadata">

**Author:** ![Jameskanyiri](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/jameskanyiri/32/993_2.png) [@Jameskanyiri](https://forum.langchain.com/u/Jameskanyiri)\
**Post date:** [September 17, 2025, 6:06am UTC](https://forum.langchain.com/t/how-to-stream-from-graph-with-reactagent/1538/4 "2025-09-17T06:06:43Z")

</div>

> [@jerson-censys](#):
>
> For some reason, nothing gets streamed from `“messages”`. I’m only able to capture events of type `“Updates”`. Here is my implementation.

I would suggest you first try with a minimal code with stream\_mode=”messages” and confirm that it is working end-to-end

If that works it means the issue is the agent configuration.

If it works, then the issue might be with how you handle multiple modes or how you process stream\_mode, chunk tuples.

what I have tried and it works

`from langgraph.prebuilt import create_react_agent`

```python
def get_weather(city: str) -> str:
    """Get the weather in a given city"""
    return f"The weather in {city} is sunny"

```

```python
agent = create_react_agent(
    model="openai:gpt-4o-mini",
    tools=[get_weather],
    prompt="You are a helpful assistant that can answer questions and help with tasks.",
)

```

```python
input = {"messages": [{"role": "user", "content": "what is the weather in sf"}]}

async for stream_mode, chunk in agent.astream(input, stream_mode=["messages", "updates"]):
    if stream_mode == "messages":
        message_chunk, metadata = chunk
        print(f"Message Chunk: {message_chunk}")
    elif stream_mode == "updates":
        update_chunk = chunk
        print(f"Update Chunk: {update_chunk}")

```

 ![image](https://canada1.discourse-cdn.com/flex007/uploads/langchain/original/1X/0ecc8064b85bb89c1d4873243b3612f459a26570.png)

---

<div class="post-metadata">

**Author:** ![jerson-censys](https://yyz1.discourse-cdn.com/flex007/user_avatar/forum.langchain.com/jerson-censys/32/961_2.png) [@jerson-censys](https://forum.langchain.com/u/jerson-censys)\
**Post date:** [September 17, 2025, 5:24pm UTC](https://forum.langchain.com/t/how-to-stream-from-graph-with-reactagent/1538/5 "2025-09-17T17:24:08Z")

</div>

Thanks guys I tried `subgraphs=True` and it works not, I also change the way I return the result from the LLM call inside the node.  
Instead of returning:

```python
// Iniside the node:
        result = await agent.ainvoke({"messages": messages}, config)

        return state.model_copy(
            update={
                "messages": result

```

I change it to:

```auto
        result = await agent.ainvoke({"messages": messages}, config)

        return state.model_copy(
            update={
                "messages": result["messages"],

```

That + the `subgraphs=True` fixed it.
