Skip to content

Commit a692e24

Browse files
authored
fix(langgraph): Remote Baggage (#5964)
Fix baggage propagation for opt-in distributed tracing when no additional headers are provided.
1 parent a566f1f commit a692e24

File tree

5 files changed

+31
-26
lines changed

5 files changed

+31
-26
lines changed

libs/langgraph/langgraph/pregel/remote.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -733,9 +733,9 @@ def stream(
733733
interrupt_after=interrupt_after,
734734
stream_subgraphs=subgraphs or stream is not None,
735735
if_not_exists="create",
736-
headers=_merge_tracing_headers(headers)
737-
if self.distributed_tracing
738-
else headers,
736+
headers=(
737+
_merge_tracing_headers(headers) if self.distributed_tracing else headers
738+
),
739739
params=params,
740740
**kwargs,
741741
):
@@ -842,9 +842,9 @@ async def astream(
842842
interrupt_after=interrupt_after,
843843
stream_subgraphs=subgraphs or stream is not None,
844844
if_not_exists="create",
845-
headers=_merge_tracing_headers(headers)
846-
if self.distributed_tracing
847-
else headers,
845+
headers=(
846+
_merge_tracing_headers(headers) if self.distributed_tracing else headers
847+
),
848848
params=params,
849849
**kwargs,
850850
):
@@ -996,11 +996,11 @@ async def ainvoke(
996996
def _merge_tracing_headers(headers: dict[str, str] | None) -> dict[str, str] | None:
997997
if rt := ls.get_current_run_tree():
998998
tracing_headers = rt.to_headers()
999-
baggage = tracing_headers.pop("baggage")
1000999
if headers:
10011000
if "baggage" in headers:
1002-
baggage = headers["baggage"] + "," + baggage
1003-
tracing_headers["baggage"] = baggage
1001+
tracing_headers["baggage"] = (
1002+
f"{headers['baggage']},{tracing_headers['baggage']}"
1003+
)
10041004
headers.update(tracing_headers)
10051005
else:
10061006
headers = tracing_headers

libs/langgraph/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "langgraph"
7-
version = "0.6.5"
7+
version = "0.6.6"
88
description = "Building stateful, multi-actor applications with LLMs"
99
authors = []
1010
requires-python = ">=3.9"

libs/langgraph/tests/test_remote_graph.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import re
22
import sys
3-
from typing import Annotated, Union
3+
from typing import Annotated, Optional, Union
44
from unittest.mock import AsyncMock, MagicMock
55

66
import langsmith as ls
@@ -1183,7 +1183,10 @@ async def test_remote_graph_stream_messages_tuple(
11831183
@pytest.mark.anyio
11841184
@pytest.mark.parametrize("distributed_tracing", [False, True])
11851185
@pytest.mark.parametrize("stream", [False, True])
1186-
async def test_include_headers(distributed_tracing: bool, stream: bool):
1186+
@pytest.mark.parametrize("headers", [None, {"foo": "bar"}])
1187+
async def test_include_headers(
1188+
distributed_tracing: bool, stream: bool, headers: Optional[dict[str, str]]
1189+
):
11871190
mock_async_client = MagicMock()
11881191
async_iter = MagicMock()
11891192
return_value = [
@@ -1213,20 +1216,22 @@ async def test_include_headers(distributed_tracing: bool, stream: bool):
12131216
async for _ in remote_pregel.astream(
12141217
{"input": {"messages": [{"type": "human", "content": "hello"}]}},
12151218
config,
1216-
headers={"foo": "bar"},
1219+
headers=headers,
12171220
):
12181221
pass
12191222

12201223
else:
12211224
await remote_pregel.ainvoke(
12221225
{"input": {"messages": [{"type": "human", "content": "hello"}]}},
12231226
config,
1224-
headers={"foo": "bar"},
1227+
headers=headers,
12251228
)
1226-
expected = {"foo": "bar"}
1229+
expected = headers.copy() if headers else None
12271230
if distributed_tracing:
1231+
if expected is None:
1232+
expected = {}
12281233
expected["langsmith-trace"] = AnyStr()
1229-
expected["baggage"] = AnyStr()
1234+
expected["baggage"] = AnyStr("langsmith-metadata=")
12301235

12311236
assert astream_mock.call_args.kwargs["headers"] == expected
12321237
stream_mock.assert_not_called()
@@ -1237,14 +1242,14 @@ async def test_include_headers(distributed_tracing: bool, stream: bool):
12371242
for _ in remote_pregel.stream(
12381243
{"input": {"messages": [{"type": "human", "content": "hello"}]}},
12391244
config,
1240-
headers={"foo": "bar"},
1245+
headers=headers,
12411246
):
12421247
pass
12431248

12441249
else:
12451250
remote_pregel.invoke(
12461251
{"input": {"messages": [{"type": "human", "content": "hello"}]}},
12471252
config,
1248-
headers={"foo": "bar"},
1253+
headers=headers,
12491254
)
12501255
assert stream_mock.call_args.kwargs["headers"] == expected

libs/langgraph/uv.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libs/prebuilt/uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)