From b7dd4b376a096f8e6cc5d08ac5195434955875bf Mon Sep 17 00:00:00 2001 From: Hugo Durand Date: Tue, 22 Sep 2026 14:38:19 -0400 Subject: [PATCH] feat(cli): tell the managed control plane apart from a self-hosted one --- libs/cli/langgraph_cli/host_backend.py | 7 ++++++ .../cli/tests/unit_tests/test_host_backend.py | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/libs/cli/langgraph_cli/host_backend.py b/libs/cli/langgraph_cli/host_backend.py index b5b64e215..bc9d2b635 100644 --- a/libs/cli/langgraph_cli/host_backend.py +++ b/libs/cli/langgraph_cli/host_backend.py @@ -37,6 +37,13 @@ class ControlPlaneEndpoints: return cls.from_langsmith_endpoint(langsmith_endpoint) return cls(CLOUD_CONTROL_PLANE_URL, CLOUD_DASHBOARD_URL) + @property + def is_cloud(self) -> bool: + hostname = urlparse(self.control_plane_url).hostname or "" + return hostname == CLOUD_CONTROL_PLANE_HOST or hostname.endswith( + f".{CLOUD_CONTROL_PLANE_HOST}" + ) + @classmethod def from_control_plane_url(cls, url: str) -> ControlPlaneEndpoints: control_plane_url = url.rstrip("/") diff --git a/libs/cli/tests/unit_tests/test_host_backend.py b/libs/cli/tests/unit_tests/test_host_backend.py index 4a3488bcf..cbd6272da 100644 --- a/libs/cli/tests/unit_tests/test_host_backend.py +++ b/libs/cli/tests/unit_tests/test_host_backend.py @@ -588,3 +588,27 @@ def test_list_listeners_asks_for_a_full_page(): assert c.list_listeners() == [{"id": "listener-1"}] assert seen["url"] == "https://api.example.com/v2/listeners?limit=100" + + +@pytest.mark.parametrize( + ("control_plane_url", "expected"), + [ + pytest.param("https://api.host.langchain.com", True, id="cloud"), + pytest.param("https://eu.api.host.langchain.com", True, id="cloud_region"), + pytest.param("https://dev.api.host.langchain.com", True, id="cloud_dev"), + pytest.param("https://smith.example.com/api-host", False, id="self_hosted"), + pytest.param( + "https://corp.example.com/langsmith/api-host", + False, + id="self_hosted_prefix", + ), + pytest.param("http://localhost:8080/api-host", False, id="local"), + pytest.param( + "https://evil-api.host.langchain.com", False, id="lookalike_needs_a_dot" + ), + ], +) +def test_is_cloud_recognises_the_managed_control_plane(control_plane_url, expected): + endpoints = ControlPlaneEndpoints.from_control_plane_url(control_plane_url) + + assert endpoints.is_cloud is expected