Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion libs/sdk-py/langgraph_sdk/schema.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Data models for interacting with the LangGraph API."""

from __future__ import annotations
Expand Down Expand Up @@ -112,7 +112,13 @@
"""Configuration for LangSmith tracing."""

project_name: str

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

str | list[str]? so we don't break

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think keeping project_name: str unchanged is the backward-compatible path. The new multi-project field is project_names: list[str]; the server-side change normalizes/dedupes project_name and project_names. Typing project_name as str | list[str] would imply the server accepts a list under the existing singular key, which isn’t the intended API shape unless we also support that server-side.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw i thought this was deleted i just can't see

"""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."""

Expand Down
54 changes: 54 additions & 0 deletions libs/sdk-py/tests/test_langsmith_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
}
Loading