chore: core tracing

This commit is contained in:
Will Fu-Hinthorn
2026-04-06 14:41:36 -07:00
parent cf647b6d14
commit 94c90d5899
5 changed files with 133 additions and 45 deletions

View File

@@ -6,7 +6,7 @@ import logging
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
from collections.abc import Sequence
from collections.abc import Mapping, Sequence
from uuid import UUID
from tenacity import RetryCallState
@@ -948,6 +948,7 @@ class BaseCallbackManager(CallbackManagerMixin):
inheritable_tags: list[str] | None = None,
metadata: dict[str, Any] | None = None,
inheritable_metadata: dict[str, Any] | None = None,
tracing_metadata: Mapping[str, str] | None = None,
) -> None:
"""Initialize callback manager.
@@ -959,6 +960,9 @@ class BaseCallbackManager(CallbackManagerMixin):
inheritable_tags: The inheritable tags.
metadata: The metadata.
inheritable_metadata: The inheritable metadata.
tracing_metadata: Per-invocation default metadata merged into every run
started by this manager. Keys already present in a run's metadata
are not overwritten.
"""
self.handlers: list[BaseCallbackHandler] = handlers
self.inheritable_handlers: list[BaseCallbackHandler] = (
@@ -969,6 +973,7 @@ class BaseCallbackManager(CallbackManagerMixin):
self.inheritable_tags = inheritable_tags or []
self.metadata = metadata or {}
self.inheritable_metadata = inheritable_metadata or {}
self.tracing_metadata: Mapping[str, str] | None = tracing_metadata
def copy(self) -> Self:
"""Return a copy of the callback manager."""
@@ -980,6 +985,7 @@ class BaseCallbackManager(CallbackManagerMixin):
inheritable_tags=self.inheritable_tags.copy(),
metadata=self.metadata.copy(),
inheritable_metadata=self.inheritable_metadata.copy(),
tracing_metadata=self.tracing_metadata,
)
def merge(self, other: BaseCallbackManager) -> Self:

View File

@@ -269,6 +269,8 @@ def handle_event(
**kwargs: The keyword arguments to pass to the event handler
"""
# Pop tracing_metadata; only forwarded to handlers that opt in.
tracing_metadata = kwargs.pop("_tracing_metadata", None)
coros: list[Coroutine[Any, Any, Any]] = []
try:
@@ -278,7 +280,16 @@ def handle_event(
if ignore_condition_name is None or not getattr(
handler, ignore_condition_name
):
event = getattr(handler, event_name)(*args, **kwargs)
handler_kwargs = (
{
**kwargs,
"tracing_metadata": tracing_metadata,
}
if tracing_metadata
and getattr(handler, "_accepts_tracing_metadata", False)
else kwargs
)
event = getattr(handler, event_name)(*args, **handler_kwargs)
if asyncio.iscoroutine(event):
coros.append(event)
except NotImplementedError as e:
@@ -370,6 +381,10 @@ async def _ahandle_event_for_handler(
*args: Any,
**kwargs: Any,
) -> None:
# Pop tracing_metadata; only forwarded to handlers that opt in.
tracing_metadata = kwargs.pop("_tracing_metadata", None)
if tracing_metadata and getattr(handler, "_accepts_tracing_metadata", False):
kwargs = {**kwargs, "tracing_metadata": tracing_metadata}
try:
if ignore_condition_name is None or not getattr(handler, ignore_condition_name):
event = getattr(handler, event_name)
@@ -466,6 +481,7 @@ class BaseRunManager(RunManagerMixin):
inheritable_tags: list[str] | None = None,
metadata: dict[str, Any] | None = None,
inheritable_metadata: dict[str, Any] | None = None,
tracing_metadata: Mapping[str, str] | None = None,
) -> None:
"""Initialize the run manager.
@@ -478,6 +494,8 @@ class BaseRunManager(RunManagerMixin):
inheritable_tags: The list of inheritable tags.
metadata: The metadata.
inheritable_metadata: The inheritable metadata.
tracing_metadata: Per-invocation default metadata merged into runs
started by tracer handlers.
"""
self.run_id = run_id
@@ -488,6 +506,7 @@ class BaseRunManager(RunManagerMixin):
self.inheritable_tags = inheritable_tags or []
self.metadata = metadata or {}
self.inheritable_metadata = inheritable_metadata or {}
self.tracing_metadata: Mapping[str, str] | None = tracing_metadata
@classmethod
def get_noop_manager(cls) -> Self:
@@ -578,6 +597,7 @@ class ParentRunManager(RunManager):
manager.set_handlers(self.inheritable_handlers)
manager.add_tags(self.inheritable_tags)
manager.add_metadata(self.inheritable_metadata)
manager.tracing_metadata = self.tracing_metadata
if tag is not None:
manager.add_tags([tag], inherit=False)
return manager
@@ -662,6 +682,7 @@ class AsyncParentRunManager(AsyncRunManager):
manager.set_handlers(self.inheritable_handlers)
manager.add_tags(self.inheritable_tags)
manager.add_metadata(self.inheritable_metadata)
manager.tracing_metadata = self.tracing_metadata
if tag is not None:
manager.add_tags([tag], inherit=False)
return manager
@@ -1335,6 +1356,7 @@ class CallbackManager(BaseCallbackManager):
parent_run_id=self.parent_run_id,
tags=self.tags,
metadata=self.metadata,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
@@ -1348,6 +1370,7 @@ class CallbackManager(BaseCallbackManager):
inheritable_tags=self.inheritable_tags,
metadata=self.metadata,
inheritable_metadata=self.inheritable_metadata,
tracing_metadata=self.tracing_metadata,
)
)
@@ -1389,6 +1412,7 @@ class CallbackManager(BaseCallbackManager):
parent_run_id=self.parent_run_id,
tags=self.tags,
metadata=self.metadata,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
@@ -1402,6 +1426,7 @@ class CallbackManager(BaseCallbackManager):
inheritable_tags=self.inheritable_tags,
metadata=self.metadata,
inheritable_metadata=self.inheritable_metadata,
tracing_metadata=self.tracing_metadata,
)
)
@@ -1438,6 +1463,7 @@ class CallbackManager(BaseCallbackManager):
parent_run_id=self.parent_run_id,
tags=self.tags,
metadata=self.metadata,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
@@ -1450,6 +1476,7 @@ class CallbackManager(BaseCallbackManager):
inheritable_tags=self.inheritable_tags,
metadata=self.metadata,
inheritable_metadata=self.inheritable_metadata,
tracing_metadata=self.tracing_metadata,
)
@override
@@ -1498,6 +1525,7 @@ class CallbackManager(BaseCallbackManager):
tags=self.tags,
metadata=self.metadata,
inputs=inputs,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
@@ -1510,6 +1538,7 @@ class CallbackManager(BaseCallbackManager):
inheritable_tags=self.inheritable_tags,
metadata=self.metadata,
inheritable_metadata=self.inheritable_metadata,
tracing_metadata=self.tracing_metadata,
)
@override
@@ -1546,6 +1575,7 @@ class CallbackManager(BaseCallbackManager):
parent_run_id=self.parent_run_id,
tags=self.tags,
metadata=self.metadata,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
@@ -1558,6 +1588,7 @@ class CallbackManager(BaseCallbackManager):
inheritable_tags=self.inheritable_tags,
metadata=self.metadata,
inheritable_metadata=self.inheritable_metadata,
tracing_metadata=self.tracing_metadata,
)
def on_custom_event(
@@ -1615,7 +1646,7 @@ class CallbackManager(BaseCallbackManager):
inheritable_metadata: dict[str, Any] | None = None,
local_metadata: dict[str, Any] | None = None,
*,
langsmith_metadata: Mapping[str, str] | None = None,
tracing_metadata: Mapping[str, str] | None = None,
) -> CallbackManager:
"""Configure the callback manager.
@@ -1627,8 +1658,8 @@ class CallbackManager(BaseCallbackManager):
local_tags: The local tags.
inheritable_metadata: The inheritable metadata.
local_metadata: The local metadata.
langsmith_metadata: Default metadata applied to any
`LangChainTracer` handlers via `set_defaults`.
tracing_metadata: Default metadata merged into runs started by
tracer handlers. Existing run metadata keys are not overwritten.
Returns:
The configured callback manager.
@@ -1642,7 +1673,7 @@ class CallbackManager(BaseCallbackManager):
inheritable_metadata,
local_metadata,
verbose=verbose,
langsmith_metadata=langsmith_metadata,
tracing_metadata=tracing_metadata,
)
@@ -1831,6 +1862,7 @@ class AsyncCallbackManager(BaseCallbackManager):
parent_run_id=self.parent_run_id,
tags=self.tags,
metadata=self.metadata,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
)
@@ -1846,6 +1878,7 @@ class AsyncCallbackManager(BaseCallbackManager):
parent_run_id=self.parent_run_id,
tags=self.tags,
metadata=self.metadata,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
)
@@ -1860,6 +1893,7 @@ class AsyncCallbackManager(BaseCallbackManager):
inheritable_tags=self.inheritable_tags,
metadata=self.metadata,
inheritable_metadata=self.inheritable_metadata,
tracing_metadata=self.tracing_metadata,
)
)
@@ -1914,6 +1948,7 @@ class AsyncCallbackManager(BaseCallbackManager):
parent_run_id=self.parent_run_id,
tags=self.tags,
metadata=self.metadata,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
if handler.run_inline:
@@ -1931,6 +1966,7 @@ class AsyncCallbackManager(BaseCallbackManager):
inheritable_tags=self.inheritable_tags,
metadata=self.metadata,
inheritable_metadata=self.inheritable_metadata,
tracing_metadata=self.tracing_metadata,
)
)
@@ -1975,6 +2011,7 @@ class AsyncCallbackManager(BaseCallbackManager):
parent_run_id=self.parent_run_id,
tags=self.tags,
metadata=self.metadata,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
@@ -1987,6 +2024,7 @@ class AsyncCallbackManager(BaseCallbackManager):
inheritable_tags=self.inheritable_tags,
metadata=self.metadata,
inheritable_metadata=self.inheritable_metadata,
tracing_metadata=self.tracing_metadata,
)
@override
@@ -2023,6 +2061,7 @@ class AsyncCallbackManager(BaseCallbackManager):
parent_run_id=self.parent_run_id,
tags=self.tags,
metadata=self.metadata,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
@@ -2035,6 +2074,7 @@ class AsyncCallbackManager(BaseCallbackManager):
inheritable_tags=self.inheritable_tags,
metadata=self.metadata,
inheritable_metadata=self.inheritable_metadata,
tracing_metadata=self.tracing_metadata,
)
async def on_custom_event(
@@ -2115,6 +2155,7 @@ class AsyncCallbackManager(BaseCallbackManager):
parent_run_id=self.parent_run_id,
tags=self.tags,
metadata=self.metadata,
_tracing_metadata=self.tracing_metadata,
**kwargs,
)
@@ -2127,6 +2168,7 @@ class AsyncCallbackManager(BaseCallbackManager):
inheritable_tags=self.inheritable_tags,
metadata=self.metadata,
inheritable_metadata=self.inheritable_metadata,
tracing_metadata=self.tracing_metadata,
)
@classmethod
@@ -2140,7 +2182,7 @@ class AsyncCallbackManager(BaseCallbackManager):
inheritable_metadata: dict[str, Any] | None = None,
local_metadata: dict[str, Any] | None = None,
*,
langsmith_metadata: Mapping[str, str] | None = None,
tracing_metadata: Mapping[str, str] | None = None,
) -> AsyncCallbackManager:
"""Configure the async callback manager.
@@ -2152,8 +2194,8 @@ class AsyncCallbackManager(BaseCallbackManager):
local_tags: The local tags.
inheritable_metadata: The inheritable metadata.
local_metadata: The local metadata.
langsmith_metadata: Default metadata applied to any
`LangChainTracer` handlers via `set_defaults`.
tracing_metadata: Default metadata merged into runs started by
tracer handlers. Existing run metadata keys are not overwritten.
Returns:
The configured async callback manager.
@@ -2167,7 +2209,7 @@ class AsyncCallbackManager(BaseCallbackManager):
inheritable_metadata,
local_metadata,
verbose=verbose,
langsmith_metadata=langsmith_metadata,
tracing_metadata=tracing_metadata,
)
@@ -2314,7 +2356,7 @@ def _configure(
local_metadata: dict[str, Any] | None = None,
*,
verbose: bool = False,
langsmith_metadata: Mapping[str, str] | None = None,
tracing_metadata: Mapping[str, str] | None = None,
) -> T:
"""Configure the callback manager.
@@ -2327,8 +2369,8 @@ def _configure(
inheritable_metadata: The inheritable metadata.
local_metadata: The local metadata.
verbose: Whether to enable verbose mode.
langsmith_metadata: Default metadata applied to any
`LangChainTracer` handlers via `set_defaults`.
tracing_metadata: Default metadata merged into runs started by
tracer handlers. Existing run metadata keys are not overwritten.
Raises:
RuntimeError: If `LANGCHAIN_TRACING` is set but `LANGCHAIN_TRACING_V2` is not.
@@ -2349,7 +2391,7 @@ def _configure(
from langchain_core.tracers.stdout import ConsoleCallbackHandler # noqa: PLC0415
tracing_context = get_tracing_context()
tracing_metadata = tracing_context["metadata"]
context_metadata = tracing_context["metadata"]
tracing_tags = tracing_context["tags"]
run_tree: Run | None = tracing_context["parent"]
parent_run_id = None if run_tree is None else run_tree.id
@@ -2386,6 +2428,7 @@ def _configure(
inheritable_tags=inheritable_callbacks.inheritable_tags.copy(),
metadata=inheritable_callbacks.metadata.copy(),
inheritable_metadata=inheritable_callbacks.inheritable_metadata.copy(),
tracing_metadata=(inheritable_callbacks.tracing_metadata),
)
local_handlers_ = (
local_callbacks
@@ -2400,8 +2443,8 @@ def _configure(
if inheritable_metadata or local_metadata:
callback_manager.add_metadata(inheritable_metadata or {})
callback_manager.add_metadata(local_metadata or {}, inherit=False)
if tracing_metadata:
callback_manager.add_metadata(tracing_metadata.copy())
if context_metadata:
callback_manager.add_metadata(context_metadata.copy())
if tracing_tags:
callback_manager.add_tags(tracing_tags.copy())
@@ -2492,10 +2535,8 @@ def _configure(
for handler in callback_manager.handlers
):
callback_manager.add_handler(var_handler, inheritable)
if langsmith_metadata:
for handler in callback_manager.handlers:
if isinstance(handler, LangChainTracer):
handler.set_defaults(metadata=langsmith_metadata)
if tracing_metadata:
callback_manager.tracing_metadata = tracing_metadata
return callback_manager

View File

@@ -33,6 +33,9 @@ logger = logging.getLogger(__name__)
class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
"""Base interface for tracers."""
# Opt in to receiving per-invocation tracing_metadata via handle_event.
_accepts_tracing_metadata = True
@abstractmethod
def _persist_run(self, run: Run) -> None:
"""Persist a run."""
@@ -59,6 +62,7 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
parent_run_id: UUID | None = None,
metadata: dict[str, Any] | None = None,
name: str | None = None,
tracing_metadata: dict[str, str] | None = None,
**kwargs: Any,
) -> Run:
"""Start a trace for a chat model run.
@@ -77,6 +81,8 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
parent_run_id: The parent run ID.
metadata: The metadata for the run.
name: The name of the run.
tracing_metadata: Per-invocation default metadata to merge
into the run. Existing run metadata keys are not overwritten.
**kwargs: Additional arguments.
Returns:
@@ -92,6 +98,9 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
name=name,
**kwargs,
)
if tracing_metadata:
existing = chat_model_run.extra.get("metadata") or {}
chat_model_run.extra["metadata"] = {**tracing_metadata, **existing}
self._start_trace(chat_model_run)
self._on_chat_model_start(chat_model_run)
return chat_model_run
@@ -106,6 +115,7 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
parent_run_id: UUID | None = None,
metadata: dict[str, Any] | None = None,
name: str | None = None,
tracing_metadata: dict[str, str] | None = None,
**kwargs: Any,
) -> Run:
"""Start a trace for an LLM run.
@@ -118,6 +128,8 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
parent_run_id: The parent run ID.
metadata: The metadata for the run.
name: The name of the run.
tracing_metadata: Per-invocation default metadata to merge
into the run. Existing run metadata keys are not overwritten.
**kwargs: Additional arguments.
Returns:
@@ -133,6 +145,9 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
name=name,
**kwargs,
)
if tracing_metadata:
existing = llm_run.extra.get("metadata") or {}
llm_run.extra["metadata"] = {**tracing_metadata, **existing}
self._start_trace(llm_run)
self._on_llm_start(llm_run)
return llm_run
@@ -260,6 +275,7 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
metadata: dict[str, Any] | None = None,
run_type: str | None = None,
name: str | None = None,
tracing_metadata: dict[str, str] | None = None,
**kwargs: Any,
) -> Run:
"""Start a trace for a chain run.
@@ -273,6 +289,8 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
metadata: The metadata for the run.
run_type: The type of the run.
name: The name of the run.
tracing_metadata: Per-invocation default metadata to merge
into the run. Existing run metadata keys are not overwritten.
**kwargs: Additional arguments.
Returns:
@@ -289,6 +307,9 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
name=name,
**kwargs,
)
if tracing_metadata:
existing = chain_run.extra.get("metadata") or {}
chain_run.extra["metadata"] = {**tracing_metadata, **existing}
self._start_trace(chain_run)
self._on_chain_start(chain_run)
return chain_run
@@ -362,6 +383,7 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
metadata: dict[str, Any] | None = None,
name: str | None = None,
inputs: dict[str, Any] | None = None,
tracing_metadata: dict[str, str] | None = None,
**kwargs: Any,
) -> Run:
"""Start a trace for a tool run.
@@ -375,6 +397,8 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
metadata: The metadata for the run.
name: The name of the run.
inputs: The inputs for the tool.
tracing_metadata: Per-invocation default metadata to merge
into the run. Existing run metadata keys are not overwritten.
**kwargs: Additional arguments.
Returns:
@@ -391,6 +415,9 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
inputs=inputs,
**kwargs,
)
if tracing_metadata:
existing = tool_run.extra.get("metadata") or {}
tool_run.extra["metadata"] = {**tracing_metadata, **existing}
self._start_trace(tool_run)
self._on_tool_start(tool_run)
return tool_run
@@ -451,6 +478,7 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
tags: list[str] | None = None,
metadata: dict[str, Any] | None = None,
name: str | None = None,
tracing_metadata: dict[str, str] | None = None,
**kwargs: Any,
) -> Run:
"""Run when the `Retriever` starts running.
@@ -463,6 +491,8 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
tags: The tags for the run.
metadata: The metadata for the run.
name: The name of the run.
tracing_metadata: Per-invocation default metadata to merge
into the run. Existing run metadata keys are not overwritten.
**kwargs: Additional arguments.
Returns:
@@ -478,6 +508,9 @@ class BaseTracer(_TracerCore, BaseCallbackHandler, ABC):
name=name,
**kwargs,
)
if tracing_metadata:
existing = retrieval_run.extra.get("metadata") or {}
retrieval_run.extra["metadata"] = {**tracing_metadata, **existing}
self._start_trace(retrieval_run)
self._on_retriever_start(retrieval_run)
return retrieval_run

View File

@@ -201,6 +201,7 @@ class LangChainTracer(BaseTracer):
parent_run_id: UUID | None = None,
metadata: dict[str, Any] | None = None,
name: str | None = None,
tracing_metadata: dict[str, str] | None = None,
**kwargs: Any,
) -> Run:
"""Start a trace for an LLM run.
@@ -213,6 +214,7 @@ class LangChainTracer(BaseTracer):
parent_run_id: The parent run ID.
metadata: The metadata.
name: The name.
tracing_metadata: Per-invocation default metadata.
**kwargs: Additional keyword arguments.
Returns:
@@ -233,6 +235,9 @@ class LangChainTracer(BaseTracer):
tags=tags,
name=name,
)
if tracing_metadata:
existing = chat_model_run.extra.get("metadata") or {}
chat_model_run.extra["metadata"] = {**tracing_metadata, **existing}
self._start_trace(chat_model_run)
self._on_chat_model_start(chat_model_run)
return chat_model_run
@@ -427,6 +432,7 @@ class LangChainTracer(BaseTracer):
def _patch_missing_metadata(self: LangChainTracer, run: Run) -> None:
# Apply constructor-set tracing_metadata as defaults (fill-not-overwrite).
if not self.tracing_metadata:
return
metadata = run.metadata

View File

@@ -681,42 +681,44 @@ class TestTracerMetadataThroughInvoke:
assert md["config_key"] == "config_val"
class TestLangsmithMetadataInConfigure:
"""Tests for `langsmith_metadata` parameter in `CallbackManager.configure()`."""
class TestTracingMetadataInConfigure:
"""Tests for `tracing_metadata` parameter in `CallbackManager.configure()`."""
def test_langsmith_metadata_applied_via_configure(self) -> None:
"""langsmith_metadata flows through configure to LangChainTracer."""
def test_tracing_metadata_applied_via_configure(self) -> None:
"""tracing_metadata flows through configure to the CallbackManager."""
tracer = _create_tracer_with_mocked_client()
cm = CallbackManager.configure(
inheritable_callbacks=[tracer],
langsmith_metadata={"env": "prod", "service": "api"},
tracing_metadata={"env": "prod", "service": "api"},
)
# The tracer should have set_defaults called with the metadata
lc_tracers = [h for h in cm.handlers if isinstance(h, LangChainTracer)]
assert len(lc_tracers) == 1
assert lc_tracers[0].tracing_metadata == {"env": "prod", "service": "api"}
# Metadata is stored on the manager, not mutated on the shared tracer.
assert cm.tracing_metadata == {"env": "prod", "service": "api"}
# The shared tracer instance is NOT mutated.
assert tracer.tracing_metadata is None
def test_langsmith_metadata_does_not_overwrite_tracer_metadata(self) -> None:
"""Tracer's own metadata takes precedence over langsmith_metadata."""
def test_tracing_metadata_does_not_overwrite_tracer_metadata(self) -> None:
"""Tracer's own metadata takes precedence over tracing_metadata."""
tracer = _create_tracer_with_mocked_client(metadata={"env": "staging"})
CallbackManager.configure(
cm = CallbackManager.configure(
inheritable_callbacks=[tracer],
langsmith_metadata={"env": "prod", "service": "api"},
tracing_metadata={"env": "prod", "service": "api"},
)
assert tracer.tracing_metadata == {"env": "staging", "service": "api"}
# The shared tracer instance is NOT mutated.
assert tracer.tracing_metadata == {"env": "staging"}
# Per-invocation defaults are on the manager.
assert cm.tracing_metadata == {"env": "prod", "service": "api"}
def test_langsmith_metadata_end_to_end(self) -> None:
"""langsmith_metadata in configure propagates to posted runs."""
def test_tracing_metadata_end_to_end(self) -> None:
"""tracing_metadata in configure propagates to posted runs."""
tracer = _create_tracer_with_mocked_client()
@RunnableLambda
def my_func(x: int) -> int:
return x
# Use langsmith_metadata through the config callbacks path
cm = CallbackManager.configure(
inheritable_callbacks=[tracer],
langsmith_metadata={"env": "prod"},
tracing_metadata={"env": "prod"},
)
my_func.invoke(1, {"callbacks": cm})
@@ -725,8 +727,8 @@ class TestLangsmithMetadataInConfigure:
md = posts[0].get("extra", {}).get("metadata", {})
assert md["env"] == "prod"
def test_langsmith_metadata_does_not_affect_non_tracer_handlers(self) -> None:
"""langsmith_metadata only applies to LangChainTracer, not other handlers."""
def test_tracing_metadata_does_not_affect_non_tracer_handlers(self) -> None:
"""tracing_metadata only applies to tracer handlers, not other handlers."""
tracer = _create_tracer_with_mocked_client()
received_metadata: list[dict[str, Any]] = []
@@ -738,7 +740,7 @@ class TestLangsmithMetadataInConfigure:
capture = MetadataCapture()
cm = CallbackManager.configure(
inheritable_callbacks=[tracer, capture],
langsmith_metadata={"tracer_only": "yes"},
tracing_metadata={"tracer_only": "yes"},
)
@RunnableLambda
@@ -747,7 +749,7 @@ class TestLangsmithMetadataInConfigure:
my_func.invoke(1, {"callbacks": cm})
# Non-tracer handler should NOT see langsmith_metadata
# Non-tracer handler should NOT see tracing_metadata
assert len(received_metadata) >= 1
for md in received_metadata:
assert "tracer_only" not in md
@@ -759,11 +761,11 @@ class TestLangsmithMetadataInConfigure:
post_md = post.get("extra", {}).get("metadata", {})
assert post_md["tracer_only"] == "yes"
def test_no_langsmith_metadata_is_noop(self) -> None:
"""Passing langsmith_metadata=None does not alter tracer state."""
def test_no_tracing_metadata_is_noop(self) -> None:
"""Passing tracing_metadata=None does not alter tracer state."""
tracer = _create_tracer_with_mocked_client()
CallbackManager.configure(
inheritable_callbacks=[tracer],
langsmith_metadata=None,
tracing_metadata=None,
)
assert tracer.tracing_metadata is None