mirror of
https://github.com/langchain-ai/langchain.git
synced 2026-10-05 09:25:14 +03:00
x
This commit is contained in:
1 parent
1662cea3be
commit
3cc58f959b
2 files changed
+98
-1
No files matched your search
@@ -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()
|
||||
|
||||
Reference in new issue
Block a user