How to persist intermediate subagent messages in deep agents (survive page reload)?

We’re using create_deep_agent with SubAgentMiddleware and streaming to a React frontend via useStream.

During a run, everything works correctly. The useStream hook’s subagents property accumulates intermediate messages (tool calls, results, streamed tokens) for each subagent. We render these in the UI grouped by subagent.

The problem: On page reload, the subagents map in useStream is empty. The thread’s checkpoint only contains the parent graph’s state — which has just the collapsed ToolMessage returned by the task tool. The subagent intermediate messages that were accumulated client-side during streaming are gone.

The frontend docs mention “State reconstruction — Restore subagent state from thread history on page reload” and reconnectOnMount, but in practice the subagents property comes back empty after reload.

Question: Is there a supported way to reconstruct/persist the subagents state in useStream from thread history on page reload?

The reason I am asking is because during a live run the UI displays the subagents’ progress via their tool calls and I would like to persist that.

Hi @iss44

have you tried reconnectOnMount param Frontend - Docs by LangChain ?

oh, you have tried that…

I’m continuing digging…

so maybe streamResumable Frontend - Docs by LangChain ?

Hi pawel, I am using streamResumable, I think my issue is related to the following github issues and PRs. I don’t think there is a solution yet so I am trying to fork the deepagents ‘middleware/subagents’ and try to find a workaround.

https://github.com/langchain-ai/deepagents/pull/735

Hey @iss44 ,

what you’re seeing is completely normal.

The subagents data in useStream comes from live streaming events. Those events are not saved in the thread checkpoint. When you reload the page, only the final graph state is restored — not the intermediate subagent steps — so the map is empty.

Nothing is broken :slightly_smiling_face:

If you want subagent progress to persist after reload, you need to explicitly store it yourself (for example, in a database or as part of the graph state). By default, streaming progress is treated as temporary UI state, not long-term memory.

Think of it like live logs vs saved state — logs disappear unless you choose to store them.

Hi Bitcot, thanks for the reply. I see what you mean. From what have dug through I can see that the subagents are not part of the graph itself, they are invoked through a closure by the deep_agent’s task tool. This is why they don’t have a checkpointer to persist their messages. We can also see that the subagents middleware returns only the last message of the subagent itself to the main deep agent.

Now this is all fine, what I am trying to get to work (as others seem to be) is to persist what is relevant for the UI. In most cases this is subagent tool calls that the UI displays. These, along with the overall subagent state, can very conveniently be found in the returned useStream result, usually called stream in stream.subagents. You are very correct to point out that the details of these objects are live stream events and they are accessible while the subagent is streaming, however once the overall agent returns, the details are lost.

Two questions arise from here:

  1. What is the intended way of persisting the UI state of the subagent execution?
  2. Is there an intended way of storing these details ourselves given that such messages are sequential? (the docs specify State reconstruction — Restore subagent state from thread history on page reload in the beginning of Frontend - Docs by LangChain

Thanks again to everyone here

hi @iss44

could you try out that changes feat(subagents): persist subagent transcript via checkpoints by pawel-twardziak · Pull Request #1496 · langchain-ai/deepagents · GitHub ?

Thanks @iss44 for flagging this.

This is a current known limitation that we are in process of fixing. Thanks @pawel-twardziak for taking an initial stab at it. I think the final solution is a bit more embedded into LangGraph and how we want to elevate sub agent states within threads.

I will post updates in here as soon as I have them. Thanks!

2 Likes

hi @christian-bromann sure thing :slight_smile: I’m just reacting when things raise :slight_smile:

Thanks @christian-bromann, great to hear this is being worked on! Looking forward to the updates. Is there a temporary approach you’d recommend as a stopgap until the official fix lands?

And thanks @pawel-twardziak for the PR and for jumping on this — it was really helpful in pointing us in the right direction. We’re exploring the approach you suggested as a temporary solution: embedding the subagent transcript in ToolMessage.artifact and rehydrating from that on the frontend.

1 Like