diff --git a/libs/sdk-py/langgraph_sdk/auth/types.py b/libs/sdk-py/langgraph_sdk/auth/types.py index 84211878d..699c4ef2e 100644 --- a/libs/sdk-py/langgraph_sdk/auth/types.py +++ b/libs/sdk-py/langgraph_sdk/auth/types.py @@ -218,6 +218,8 @@ class BaseUser(typing.Protocol): class StudioUser: """A user object that's populated from authenticated requests from the LangGraph studio. + `ls_user_id` is the canonical LangSmith user ID when supplied by Agent Server. + Note: Studio auth can be disabled in your `langgraph.json` config. ```json @@ -250,10 +252,11 @@ class StudioUser: ``` """ - __slots__ = ("_is_authenticated", "_permissions", "username") + __slots__ = ("_is_authenticated", "_permissions", "ls_user_id", "username") def __init__(self, username: str, is_authenticated: bool = False) -> None: self.username = username + self.ls_user_id: str | None = None self._is_authenticated = is_authenticated self._permissions = ["authenticated"] if is_authenticated else [] diff --git a/libs/sdk-py/tests/test_auth.py b/libs/sdk-py/tests/test_auth.py index 82b243ce5..bf1014500 100644 --- a/libs/sdk-py/tests/test_auth.py +++ b/libs/sdk-py/tests/test_auth.py @@ -1,8 +1,22 @@ import pytest +from typing_extensions import assert_type from langgraph_sdk import Auth +def test_studio_user_langsmith_id() -> None: + def langsmith_id(user: object) -> str | None: + if isinstance(user, Auth.types.StudioUser): + return assert_type(user.ls_user_id, str | None) + return None + + user = Auth.types.StudioUser("login-user", is_authenticated=True) + assert langsmith_id(user) is None + user.ls_user_id = "langsmith-user" + assert langsmith_id(user) == "langsmith-user" + assert user.identity == "login-user" + + def test_handler_multiple_resources_and_actions() -> None: auth = Auth()