mirror of
https://github.com/hwchase17/langchain.git
synced 2026-04-12 15:33:17 +00:00
chore: core tracing
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user