This commit is contained in:
Eugene Yurtsev committed 2026-08-18 12:30:24 -04:00
1 parent 1662cea3be
commit 3cc58f959b
2 files changed
+98 -1

No files matched your search

+17 -1
View File
@@ -350,13 +350,29 @@ class _TracerCore(ABC):
return llm_run
def _attach_gateway_metadata(self, run: Run, response: LLMResult) -> None:
"""Promote LangSmith gateway metadata from the response to run metadata."""
"""Promote LangSmith gateway metadata from the response to run metadata.
When a request is routed through the LangSmith gateway, the resolved
provider and model may differ from the static values captured in the
run's `ls_provider` / `ls_model_name` at start time. When the gateway
reports them, they take precedence so the trace reflects what actually
served the request.
"""
gateway_metadata = _extract_gateway_metadata(response)
if gateway_metadata is None:
return
metadata = run.extra.setdefault("metadata", {})
metadata[_GATEWAY_RUN_METADATA_KEY] = gateway_metadata
provider = gateway_metadata.get("provider")
if provider:
metadata["ls_provider"] = provider
# Route-based calls report the served model as `selected_model`; simple
# calls report it as `model`.
model = gateway_metadata.get("selected_model") or gateway_metadata.get("model")
if model:
metadata["ls_model_name"] = model
def _errored_llm_run(
self, error: BaseException, run_id: UUID, response: LLMResult | None = None
) -> Run:
@@ -192,6 +192,87 @@ def test_complete_llm_run_attaches_gateway_metadata() -> None:
assert completed_run.extra["metadata"]["ls_gateway_info"] == gateway_info
def test_complete_llm_run_gateway_metadata_overrides_ls_params() -> None:
"""Gateway provider/model override the static `ls_*` run metadata."""
tracer = MockTracerCore()
run = _make_run("test-gateway-override-run-id")
run.extra = {"metadata": {"ls_provider": "openai", "ls_model_name": "gpt-5.6"}}
tracer.run_map[str(run.id)] = run
gateway_info = {"provider": "anthropic", "model": "claude-opus-5"}
response = LLMResult(
generations=[
[
ChatGeneration(
message=AIMessage(content="Test"),
generation_info={GATEWAY_METADATA_RESPONSE_KEY: gateway_info},
)
]
]
)
completed_run = tracer._complete_llm_run(response=response, run_id=run.id)
metadata = completed_run.extra["metadata"]
assert metadata["ls_provider"] == "anthropic"
assert metadata["ls_model_name"] == "claude-opus-5"
assert metadata["ls_gateway_info"] == gateway_info
def test_complete_llm_run_gateway_metadata_prefers_selected_model() -> None:
"""`selected_model` (route-based served model) wins over `model`."""
tracer = MockTracerCore()
run = _make_run("test-gateway-selected-model-run-id")
run.extra = {"metadata": {"ls_model_name": "gpt-5.6"}}
tracer.run_map[str(run.id)] = run
gateway_info = {
"provider": "openai",
"model": "gpt-5.6",
"selected_model": "gpt-5.6-mini",
}
response = LLMResult(
generations=[
[
ChatGeneration(
message=AIMessage(content="Test"),
generation_info={GATEWAY_METADATA_RESPONSE_KEY: gateway_info},
)
]
]
)
completed_run = tracer._complete_llm_run(response=response, run_id=run.id)
assert completed_run.extra["metadata"]["ls_model_name"] == "gpt-5.6-mini"
def test_complete_llm_run_gateway_metadata_preserves_ls_params_when_absent() -> None:
"""Static `ls_*` values are kept when the gateway omits provider/model."""
tracer = MockTracerCore()
run = _make_run("test-gateway-partial-run-id")
run.extra = {"metadata": {"ls_provider": "openai", "ls_model_name": "gpt-5.6"}}
tracer.run_map[str(run.id)] = run
gateway_info = {"outcome": "success"}
response = LLMResult(
generations=[
[
ChatGeneration(
message=AIMessage(content="Test"),
generation_info={GATEWAY_METADATA_RESPONSE_KEY: gateway_info},
)
]
]
)
completed_run = tracer._complete_llm_run(response=response, run_id=run.id)
metadata = completed_run.extra["metadata"]
assert metadata["ls_provider"] == "openai"
assert metadata["ls_model_name"] == "gpt-5.6"
def test_complete_llm_run_no_gateway_metadata() -> None:
"""No gateway metadata is attached when the response carries none."""
tracer = MockTracerCore()