-
Notifications
You must be signed in to change notification settings - Fork 4k
Description
Checked other resources
- This is a bug, not a usage question. For questions, please use the LangChain Forum (https://forum.langchain.com/).
- I added a clear and detailed title that summarizes the issue.
- I read what a minimal reproducible example is (https://stackoverflow.com/help/minimal-reproducible-example).
- I included a self-contained, minimal example that demonstrates the issue INCLUDING all the relevant imports. The code run AS IS to reproduce the issue.
Example Code
import asyncio
import re
from langgraph.graph import StateGraph, START, END
from langgraph.pregel import Pregel
from langgraph.pregel.remote import RemoteGraph
from langgraph.types import RunnableConfig
# Dummy node
def echo_node(state: dict) -> dict:
return state
# Build a simple in-memory graph
builder = StateGraph(dict)
builder.add_node("echo", echo_node)
builder.add_edge(START, "echo")
builder.add_edge("echo", END)
inmem_graph: Pregel = builder.compile()
# Assume we have deployed the same graph remotely and know its assistant_id/URL.
# For the minimal repro, you can plug in your own values here.
remote_graph = RemoteGraph(
"my_assistant_id",
url="https://my-langgraph-server",
)
uid_pattern = re.compile(
r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"
)
def monotonic_uid():
val = 0
while True:
val += 1
hexval = f"{val:032x}"
yield f"{hexval[:8]}-{hexval[8:12]}-{hexval[12:16]}-{hexval[16:20]}-{hexval[20:32]}"
async def main():
config: RunnableConfig = {"configurable": {"thread_id": "thread_1"}}
# Collect namespaces from RemoteGraph
remote_namespaces = []
uid_gen = monotonic_uid()
async for ns, messages in remote_graph.astream(
{"messages": [{"role": "user", "content": "hello"}]},
config,
stream_mode="messages",
subgraphs=True,
):
# Normalize UUIDs for comparison
ns = tuple(uid_pattern.sub(next(uid_gen), p) for p in ns)
remote_namespaces.append(ns)
# Collect namespaces from in-memory graph
inmem_namespaces = []
uid_gen = monotonic_uid()
async for ns, messages in inmem_graph.astream(
{"messages": [{"role": "user", "content": "hello"}]},
config,
stream_mode="messages",
subgraphs=True,
):
ns = tuple(uid_pattern.sub(next(uid_gen), p) for p in ns)
inmem_namespaces.append(ns)
print("Remote namespaces:", remote_namespaces)
print("In-memory namespaces:", inmem_namespaces)
asyncio.run(main())Error Message and Stack Trace (if applicable)
# TODO: Fix the namespace matching in the next api release.
# assert namespaces == inmem_namespacesDescription
I’m trying to use the langgraph library to stream from a remote graph using RemoteGraph.astream(..., subgraphs=True) and compare/debug its behavior against an equivalent in-memory Pregel graph.
I expect the namespaces emitted when subgraphs=True to match the in-memory graph semantics: caller namespace (when RemoteGraph is used as a subgraph) plus the remote graph’s internal namespace hierarchy, so that traces and tests like test_remote_graph_stream_messages_tuple can assert namespaces == inmem_namespaces.
Instead, RemoteGraph.astream parses mode/ns from chunk.event, then correctly prefixes ns with the caller namespace, but later re-parses mode/ns again from chunk.event inside the if subgraphs: block, overwriting the caller-prefixed ns. This causes the final namespaces yielded to differ from in-memory Pregel behavior and breaks namespace-based comparisons and observability for remote subgraphs.
System Info
python -m langchain_core.sys_info
or, if you use python3
python3 -m langchain_core.sys_info