From 2c98c59fca6c99b696988b97dfaeb885f652920c Mon Sep 17 00:00:00 2001 From: "open-swe[bot]" <215916821+open-swe[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 09:08:09 -0400 Subject: [PATCH] fix: populate assistant_id from config configurable instead of metadata (#7468) ## Description The `_build_server_info` function was reading `assistant_id` and `graph_id` from `config["metadata"]`, but the server puts these values in `config["configurable"]`. This updates the source to read from `configurable` consistently. ## Test Plan - [ ] Verify `server_info.assistant_id` and `server_info.graph_id` are correctly populated from `config["configurable"]` _Opened collaboratively by Sydney Runkle and open-swe._ Co-authored-by: open-swe[bot] Co-authored-by: Sydney Runkle <54324534+sydney-runkle@users.noreply.github.com> --- libs/langgraph/langgraph/pregel/main.py | 9 ++++----- libs/langgraph/tests/test_runtime.py | 17 ++++++++++------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/libs/langgraph/langgraph/pregel/main.py b/libs/langgraph/langgraph/pregel/main.py index 02d0ee11e..c440e77f9 100644 --- a/libs/langgraph/langgraph/pregel/main.py +++ b/libs/langgraph/langgraph/pregel/main.py @@ -3715,15 +3715,14 @@ def _coerce_checkpoint_values(payload: Any, mapper: Callable[[Any], Any]) -> Non def _build_server_info( config: RunnableConfig, parent_runtime: Runtime[Any] ) -> ServerInfo | None: - """Build ServerInfo from config metadata and configurable. + """Build ServerInfo from config configurable. - The server puts assistant_id/graph_id in config metadata and the + The server puts assistant_id/graph_id in config configurable and the authenticated user dict in configurable["langgraph_auth_user"]. """ - metadata = config.get("metadata") or {} configurable = config.get(CONF) or {} - assistant_id = metadata.get("assistant_id") - graph_id = metadata.get("graph_id") + assistant_id = configurable.get("assistant_id") + graph_id = configurable.get("graph_id") # Read authenticated user from configurable (set by LangGraph Server). # We prefer isinstance(BaseUser) but fall back to hasattr("identity") diff --git a/libs/langgraph/tests/test_runtime.py b/libs/langgraph/tests/test_runtime.py index 0796ddf9d..a85abe45f 100644 --- a/libs/langgraph/tests/test_runtime.py +++ b/libs/langgraph/tests/test_runtime.py @@ -501,13 +501,13 @@ async def test_execution_info_populated_in_graph_async() -> None: assert isinstance(info.node_first_attempt_time, float) -def test_server_info_from_metadata() -> None: - """server_info is built from assistant_id/graph_id in config metadata.""" +def test_server_info_from_configurable() -> None: + """server_info is built from assistant_id/graph_id in config configurable.""" captured: dict[str, Any] = {} compiled = _make_capture_graph(captured) compiled.invoke( {"message": "hi"}, - config={"metadata": {"assistant_id": "asst-abc", "graph_id": "my-graph"}}, + config={"configurable": {"assistant_id": "asst-abc", "graph_id": "my-graph"}}, ) si = captured["server_info"] assert si is not None @@ -516,8 +516,8 @@ def test_server_info_from_metadata() -> None: assert si.user is None -def test_server_info_none_without_metadata() -> None: - """server_info is None when no assistant_id/graph_id in metadata.""" +def test_server_info_none_without_configurable() -> None: + """server_info is None when no assistant_id/graph_id in configurable.""" captured: dict[str, Any] = {} compiled = _make_capture_graph(captured) compiled.invoke({"message": "hi"}) @@ -579,8 +579,11 @@ def test_server_info_user_from_auth_user() -> None: compiled.invoke( {"message": "hi"}, config={ - "configurable": {"langgraph_auth_user": proxy}, - "metadata": {"assistant_id": "asst-proxy", "graph_id": "graph-proxy"}, + "configurable": { + "langgraph_auth_user": proxy, + "assistant_id": "asst-proxy", + "graph_id": "graph-proxy", + }, }, ) si = captured["server_info"]