From 5328ca94f889dcda4239987951ac40fb26b006ea Mon Sep 17 00:00:00 2001 From: Mason Daugherty <61371264+mdrxy@users.noreply.github.com> Date: Wed, 17 Jun 2026 01:28:48 +0000 Subject: [PATCH] feat: support multiple extra LangSmith trace projects in SDK schema Add an optional `project_names: list[str]` field to the `LangSmithTracing` TypedDict so callers can request multiple extra trace replica projects on a run, while keeping the singular `project_name` field working as before. The Python SDK passes the tracing config straight through as `langsmith_tracer`, so backward compatibility is preserved. Co-authored-by: open-swe[bot] --- libs/sdk-py/langgraph_sdk/schema.py | 8 ++- libs/sdk-py/tests/test_langsmith_tracing.py | 54 +++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/libs/sdk-py/langgraph_sdk/schema.py b/libs/sdk-py/langgraph_sdk/schema.py index 16b197db37f..b4b59d6500b 100644 --- a/libs/sdk-py/langgraph_sdk/schema.py +++ b/libs/sdk-py/langgraph_sdk/schema.py @@ -112,7 +112,13 @@ class LangSmithTracing(TypedDict, total=False): """Configuration for LangSmith tracing.""" project_name: str - """The LangSmith project name to trace to.""" + """A single extra LangSmith project name to trace to.""" + project_names: list[str] + """Multiple extra LangSmith project names to trace to. + + Combined with `project_name` (if both are provided) to form the full set of + extra projects. The server also traces to its primary tracing project. + """ example_id: str """The LangSmith example/dataset ID to associate with the trace.""" diff --git a/libs/sdk-py/tests/test_langsmith_tracing.py b/libs/sdk-py/tests/test_langsmith_tracing.py index db0fc220541..245407fff7c 100644 --- a/libs/sdk-py/tests/test_langsmith_tracing.py +++ b/libs/sdk-py/tests/test_langsmith_tracing.py @@ -144,3 +144,57 @@ def mock_post(_path, *, json=None, **_kwargs): assert captured["json"]["langsmith_tracer"] == { "project_name": "my-project", } + + def test_langsmith_tracing_project_names_only(self): + """Test that langsmith_tracing works with multiple project_names.""" + from langgraph_sdk._sync.runs import SyncRunsClient + + captured: dict[str, Any] = {} + + def mock_post(_path, *, json=None, **_kwargs): + captured["json"] = json + return {"run_id": "r1", "status": "pending"} + + http = MagicMock() + http.post = MagicMock(side_effect=mock_post) + client = SyncRunsClient(http) + + client.create( + thread_id="t1", + assistant_id="a1", + langsmith_tracing={"project_names": ["first", "second"]}, + ) + + assert captured["json"]["langsmith_tracer"] == { + "project_names": ["first", "second"], + } + + def test_langsmith_tracing_project_name_and_project_names(self): + """Test that langsmith_tracing passes both project_name and project_names.""" + from langgraph_sdk._sync.runs import SyncRunsClient + + captured: dict[str, Any] = {} + + def mock_post(_path, *, json=None, **_kwargs): + captured["json"] = json + return {"run_id": "r1", "status": "pending"} + + http = MagicMock() + http.post = MagicMock(side_effect=mock_post) + client = SyncRunsClient(http) + + client.create( + thread_id="t1", + assistant_id="a1", + langsmith_tracing={ + "project_name": "first", + "project_names": ["second", "third"], + "example_id": "example-123", + }, + ) + + assert captured["json"]["langsmith_tracer"] == { + "project_name": "first", + "project_names": ["second", "third"], + "example_id": "example-123", + }