feat(code): report tracing gateway in dcode doctor (#4466)

`dcode doctor` now shows a `Gateway` line under Tracing indicating
whether traces route through the LangSmith managed gateway.

---

Brian asked to know, at a glance, whether `dcode` is tracing to the
LangSmith managed gateway or to a custom dev/staging endpoint. This adds
a `Gateway` line under the Tracing section of `dcode doctor` (shown when
tracing is enabled): `yes` when traces route through the LangSmith
managed/SaaS gateway (`*.smith.langchain.com`, including the default
`https://api.smith.langchain.com` when no custom endpoint is set), `no`
for a self-hosted/dev/staging endpoint. The existing `Endpoint` line
already surfaces the custom URL itself.

Assumption worth confirming: "gateway" is defined as any host under
`smith.langchain.com` (matches the codebase's existing gateway-host
convention). If LangChain's internal dev/staging uses a subdomain of
`smith.langchain.com`, it would read as `yes` — happy to narrow it if
that's not the intended cut.

Made by [Open
SWE](https://openswe.vercel.app/agents/61952749-6cc0-a57e-8fe4-c151d099735e)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
Mason Daugherty
2026-07-06 00:48:00 -04:00
committed by GitHub
parent b1b16cd114
commit a912427550
3 changed files with 228 additions and 12 deletions
+31 -10
View File
@@ -3164,8 +3164,8 @@ def _tracing_has_credentials_from(env: dict[str, str]) -> bool:
return has_key or _has_langsmith_profile_credentials(env)
def _has_langsmith_runs_endpoints_from(env: dict[str, str]) -> bool:
"""Return whether replica trace ingestion targets are configured.
def _langsmith_runs_endpoint_urls_from(env: dict[str, str]) -> tuple[str, ...]:
"""Return the replica trace ingestion URLs configured via runs-endpoints.
Mirrors the LangSmith SDK's accepted `LANGSMITH_RUNS_ENDPOINTS` shapes: a
JSON list of `{"api_url": "...", "api_key": "..."}` objects, or a JSON
@@ -3176,7 +3176,7 @@ def _has_langsmith_runs_endpoints_from(env: dict[str, str]) -> bool:
env: Environment mapping to read.
Returns:
`True` when a valid runs-endpoints configuration is present.
The configured replica ingestion URLs, in configuration order.
"""
raw = next(
(
@@ -3187,23 +3187,40 @@ def _has_langsmith_runs_endpoints_from(env: dict[str, str]) -> bool:
None,
)
if raw is None:
return False
return ()
try:
parsed = json.loads(raw)
except (TypeError, ValueError):
return False
return ()
if isinstance(parsed, list):
return any(
isinstance(item, dict)
return tuple(
item["api_url"]
for item in parsed
if isinstance(item, dict)
and isinstance(item.get("api_url"), str)
and isinstance(item.get("api_key"), str)
for item in parsed
)
if isinstance(parsed, dict):
return any(isinstance(value, str) for value in parsed.values())
return False
return tuple(
url
for url, api_key in parsed.items()
if isinstance(url, str) and isinstance(api_key, str)
)
return ()
def _has_langsmith_runs_endpoints_from(env: dict[str, str]) -> bool:
"""Return whether replica trace ingestion targets are configured.
Args:
env: Environment mapping to read.
Returns:
`True` when a valid runs-endpoints configuration is present.
"""
return bool(_langsmith_runs_endpoint_urls_from(env))
def _tracing_can_upload_from(env: dict[str, str]) -> bool:
@@ -3316,6 +3333,9 @@ class TracingStatus:
replica_project: str | None
"""Extra project agent runs are mirrored to, if configured."""
runs_endpoints: tuple[str, ...] = ()
"""Replica ingestion URLs from `LANGSMITH_RUNS_ENDPOINTS`, if any."""
def __post_init__(self) -> None:
"""Reject the contradictory enabled/explicitly-disabled pair.
@@ -3358,6 +3378,7 @@ def get_tracing_status() -> TracingStatus:
replica_project=_get_first_langsmith_replica_project(
_get_langsmith_replica_projects_from(env)
),
runs_endpoints=_langsmith_runs_endpoint_urls_from(env),
)
+76 -1
View File
@@ -274,6 +274,75 @@ def _sanitize_endpoint(endpoint: str) -> str:
return f"{parsed.scheme}://{netloc}"
_LANGSMITH_GATEWAY_HOST = "smith.langchain.com"
"""Host identifying LangSmith's managed (SaaS) tracing gateway.
Traces sent to an endpoint whose host is `smith.langchain.com` (or a subdomain
of it) route through the managed gateway; any other host is a self-hosted or
dev/staging target. `app.py` keeps the same constant for its model-gateway
key-mismatch check, but matches a raw-URL substring; this module matches the
parsed hostname exactly or by subdomain suffix so lookalike hosts such as
`smith.langchain.com.evil.example` are not treated as the gateway.
"""
def _endpoint_gateway_state(endpoint: str) -> str:
"""Classify a single tracing endpoint as gateway, non-gateway, or unknown.
Args:
endpoint: A configured tracing endpoint URL.
Returns:
`"yes"` when the endpoint's host is the LangSmith managed gateway (an
exact host or a subdomain), `"no"` for any other resolvable host,
and `"unknown"` when the endpoint cannot be parsed into a host — so
a typo'd or malformed URL is never silently reported as `"no"`.
"""
try:
host = urlsplit(endpoint.strip()).hostname or ""
except ValueError:
# urlsplit raises on bracket-malformed IPv6 (e.g. `http://[::1`); a
# diagnostic must degrade to "unknown" rather than crash `dcode doctor`.
return "unknown"
if not host:
return "unknown"
if host == _LANGSMITH_GATEWAY_HOST or host.endswith(f".{_LANGSMITH_GATEWAY_HOST}"):
return "yes"
return "no"
def _tracing_gateway_state(status: TracingStatus) -> str:
"""Report whether all trace ingestion targets are the managed gateway.
Considers both the primary endpoint and any replica ingestion URLs
(`LANGSMITH_RUNS_ENDPOINTS`), since a self-hosted replica means traces leave
for a custom target even when the primary endpoint is unset. With no target
configured, tracing falls back to the LangSmith SDK default
(`https://api.smith.langchain.com`), which is the managed gateway.
Args:
status: The resolved tracing status.
Returns:
`"yes"` when every configured target is the managed gateway (or none is
configured, i.e. the SDK default), `"no"` when any target is a
self-hosted or dev/staging host, and `"unknown"` when a target
cannot be parsed and none is a definite non-gateway host.
"""
states = [
_endpoint_gateway_state(target)
for target in (status.endpoint, *status.runs_endpoints)
if target
]
if not states:
return "yes"
if "no" in states:
return "no"
if "unknown" in states:
return "unknown"
return "yes"
def _format_tracing_project(status: TracingStatus) -> str:
"""Render the tracing project, marking the unconfigured default.
@@ -297,7 +366,11 @@ def _collect_tracing() -> DiagnosticSection:
value is never read or printed. The `Credentials` item is flagged as a
problem only when tracing is enabled without a key and without a custom
endpoint, mirroring the runtime's orphaned-tracing guard (a keyless
self-hosted endpoint is a valid, healthy setup).
self-hosted endpoint is a valid, healthy setup). When tracing is enabled, a
`Gateway` item reports whether traces route through LangSmith's managed
(SaaS) gateway (`yes`), a custom self-hosted/dev/staging endpoint (`no`), or
an endpoint that could not be parsed (`unknown`), accounting for both the
primary endpoint and any replica ingestion targets.
Returns:
The `Tracing` section.
@@ -323,6 +396,8 @@ def _collect_tracing() -> DiagnosticSection:
]
if status.endpoint:
items.append(DiagnosticItem("Endpoint", _sanitize_endpoint(status.endpoint)))
if status.enabled:
items.append(DiagnosticItem("Gateway", _tracing_gateway_state(status)))
if status.replica_project:
items.append(DiagnosticItem("Replica project", status.replica_project))
return DiagnosticSection(title="Tracing", items=items)
+121 -1
View File
@@ -103,7 +103,9 @@ class TestCollectTracing:
"replica_project": None,
}
defaults.update(kwargs)
status = TracingStatus(**defaults) # type: ignore[arg-type]
# `defaults` is intentionally heterogeneous (`dict[str, object]`), so the
# unpack can't be statically matched to each field's type.
status = TracingStatus(**defaults) # ty: ignore[invalid-argument-type]
with patch("deepagents_code.config.get_tracing_status", return_value=status):
return _collect_tracing()
@@ -184,6 +186,72 @@ class TestCollectTracing:
assert "secret" not in labels["Endpoint"]
assert "api_key" not in labels["Endpoint"]
def test_gateway_yes_for_default_endpoint(self) -> None:
"""No custom endpoint means the SDK default (managed gateway) is used."""
section = self._section(enabled=True, has_credentials=True, endpoint=None)
labels = {item.label: item.value for item in section.items}
assert labels["Gateway"] == "yes"
def test_gateway_yes_for_langsmith_host(self) -> None:
"""A `smith.langchain.com` endpoint routes through the managed gateway."""
section = self._section(
enabled=True,
has_credentials=True,
endpoint="https://api.smith.langchain.com",
)
labels = {item.label: item.value for item in section.items}
assert labels["Gateway"] == "yes"
# A configured endpoint surfaces both items; they must not interfere.
assert "Endpoint" in labels
def test_gateway_no_for_custom_endpoint(self) -> None:
"""A self-hosted/dev endpoint is not the LangSmith managed gateway."""
section = self._section(
enabled=True,
has_credentials=False,
endpoint="http://localhost:1984",
)
labels = {item.label: item.value for item in section.items}
assert labels["Gateway"] == "no"
def test_gateway_unknown_for_unparseable_endpoint(self) -> None:
"""An endpoint with no parseable host reports `unknown`, never `no`."""
section = self._section(
enabled=True,
has_credentials=True,
endpoint="not a url",
)
labels = {item.label: item.value for item in section.items}
assert labels["Gateway"] == "unknown"
def test_gateway_no_when_replica_endpoint_is_self_hosted(self) -> None:
"""A self-hosted replica target counts even with no primary endpoint."""
section = self._section(
enabled=True,
has_credentials=True,
endpoint=None,
runs_endpoints=("http://localhost:1984",),
)
labels = {item.label: item.value for item in section.items}
assert labels["Gateway"] == "no"
def test_gateway_yes_when_replica_endpoint_is_gateway(self) -> None:
"""Replica targets on the managed gateway keep the report `yes`."""
section = self._section(
enabled=True,
has_credentials=True,
endpoint=None,
runs_endpoints=("https://eu.api.smith.langchain.com",),
)
labels = {item.label: item.value for item in section.items}
assert labels["Gateway"] == "yes"
def test_gateway_absent_when_not_enabled(self) -> None:
"""The Gateway line only appears when tracing is enabled."""
section = self._section(enabled=False)
labels = {item.label: item.value for item in section.items}
assert "Gateway" not in labels
def test_replica_project_listed_when_set(self) -> None:
"""A configured replica project is surfaced as its own item."""
section = self._section(
@@ -195,6 +263,58 @@ class TestCollectTracing:
assert labels["Replica project"] == "replica"
class TestEndpointGatewayState:
"""Tests for the single-endpoint tracing gateway-host classifier."""
def test_exact_host_is_gateway(self) -> None:
from deepagents_code.doctor import _endpoint_gateway_state
assert _endpoint_gateway_state("https://smith.langchain.com") == "yes"
def test_regional_subdomain_is_gateway(self) -> None:
from deepagents_code.doctor import _endpoint_gateway_state
assert _endpoint_gateway_state("https://eu.api.smith.langchain.com") == "yes"
def test_whitespace_padded_endpoint_is_gateway(self) -> None:
"""A padded env value (a classic misconfiguration) still classifies."""
from deepagents_code.doctor import _endpoint_gateway_state
assert _endpoint_gateway_state(" https://smith.langchain.com ") == "yes"
def test_self_hosted_is_not_gateway(self) -> None:
from deepagents_code.doctor import _endpoint_gateway_state
assert _endpoint_gateway_state("http://localhost:1984") == "no"
def test_suffix_lookalike_host_is_not_gateway(self) -> None:
"""A host containing the domain as a substring is not the gateway."""
from deepagents_code.doctor import _endpoint_gateway_state
assert (
_endpoint_gateway_state("https://smith.langchain.com.evil.example") == "no"
)
def test_prefix_lookalike_host_is_not_gateway(self) -> None:
"""The leading-dot boundary rejects a host that only shares a suffix."""
from deepagents_code.doctor import _endpoint_gateway_state
assert _endpoint_gateway_state("https://notsmith.langchain.com") == "no"
def test_unparseable_endpoint_is_unknown(self) -> None:
"""A string with no parseable host is `unknown`, not a false `no`."""
from deepagents_code.doctor import _endpoint_gateway_state
assert _endpoint_gateway_state("not a url") == "unknown"
assert _endpoint_gateway_state("") == "unknown"
def test_bracket_malformed_ipv6_is_unknown(self) -> None:
"""A `urlsplit` `ValueError` degrades to `unknown` rather than crashing."""
from deepagents_code.doctor import _endpoint_gateway_state
assert _endpoint_gateway_state("http://[::1") == "unknown"
class TestCollectUpdates:
"""Tests for the Updates diagnostic section."""