mirror of
https://github.com/hwchase17/langchain.git
synced 2025-05-03 22:28:04 +00:00
[Core] Tracing: update parent run_tree's child_runs (#21049)
This commit is contained in:
parent
86fe484e24
commit
ab55f6996d
@ -41,6 +41,7 @@ from langchain_core.callbacks.base import (
|
||||
)
|
||||
from langchain_core.callbacks.stdout import StdOutCallbackHandler
|
||||
from langchain_core.messages import BaseMessage, get_buffer_string
|
||||
from langchain_core.tracers.schemas import Run
|
||||
from langchain_core.utils.env import env_var_is_set
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -1994,15 +1995,22 @@ def _configure(
|
||||
callback_manager.add_handler(tracer_v2, True)
|
||||
else:
|
||||
try:
|
||||
handler = LangChainTracer(project_name=tracer_project)
|
||||
handler = LangChainTracer(
|
||||
project_name=tracer_project,
|
||||
client=run_tree.client if run_tree is not None else None,
|
||||
)
|
||||
callback_manager.add_handler(handler, True)
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
"Unable to load requested LangChainTracer."
|
||||
" To disable this warning,"
|
||||
" unset the LANGCHAIN_TRACING_V2 environment variables.",
|
||||
e,
|
||||
f"{repr(e)}",
|
||||
)
|
||||
if run_tree is not None:
|
||||
for handler in callback_manager.handlers:
|
||||
if isinstance(handler, LangChainTracer):
|
||||
handler.run_map[str(run_tree.id)] = cast(Run, run_tree)
|
||||
for var, inheritable, handler_class, env_var in _configure_hooks:
|
||||
create_one = (
|
||||
env_var is not None
|
||||
|
@ -1,4 +1,5 @@
|
||||
"""Base interfaces for tracing runs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
@ -102,9 +103,10 @@ class BaseTracer(BaseCallbackHandler, ABC):
|
||||
parent_run = self.run_map.get(str(run.parent_run_id))
|
||||
if parent_run:
|
||||
self._add_child_run(parent_run, run)
|
||||
parent_run.child_execution_order = max(
|
||||
parent_run.child_execution_order, run.child_execution_order
|
||||
)
|
||||
if hasattr(parent_run, "child_execution_order"):
|
||||
parent_run.child_execution_order = max(
|
||||
parent_run.child_execution_order, run.child_execution_order
|
||||
)
|
||||
run.trace_id = parent_run.trace_id
|
||||
if parent_run.dotted_order:
|
||||
run.dotted_order = (
|
||||
@ -135,7 +137,7 @@ class BaseTracer(BaseCallbackHandler, ABC):
|
||||
logger.debug(f"Parent run with UUID {run.parent_run_id} not found.")
|
||||
elif (
|
||||
run.child_execution_order is not None
|
||||
and parent_run.child_execution_order is not None
|
||||
and getattr(parent_run, "child_execution_order", None) is not None
|
||||
and run.child_execution_order > parent_run.child_execution_order
|
||||
):
|
||||
parent_run.child_execution_order = run.child_execution_order
|
||||
@ -151,10 +153,11 @@ class BaseTracer(BaseCallbackHandler, ABC):
|
||||
if parent_run is None:
|
||||
logger.debug(f"Parent run with UUID {parent_run_id} not found.")
|
||||
return 1
|
||||
if parent_run.child_execution_order is None:
|
||||
raise TracerException(
|
||||
f"Parent run with UUID {parent_run_id} has no child execution order."
|
||||
if getattr(parent_run, "child_execution_order", None) is None:
|
||||
logger.debug(
|
||||
f"Parent run with UUID {parent_run_id} has no child_execution_order."
|
||||
)
|
||||
return 1
|
||||
|
||||
return parent_run.child_execution_order + 1
|
||||
|
||||
|
@ -1,16 +1,21 @@
|
||||
"""Test Tracer classes."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, List
|
||||
from unittest.mock import MagicMock
|
||||
from uuid import uuid4
|
||||
|
||||
import langsmith
|
||||
import pytest
|
||||
from freezegun import freeze_time
|
||||
from langsmith import Client, traceable
|
||||
|
||||
from langchain_core.callbacks import CallbackManager
|
||||
from langchain_core.messages import HumanMessage
|
||||
from langchain_core.outputs import LLMResult
|
||||
from langchain_core.runnables import chain as as_runnable
|
||||
from langchain_core.tracers.base import BaseTracer, TracerException
|
||||
from langchain_core.tracers.schemas import Run
|
||||
|
||||
@ -627,3 +632,33 @@ def test_tracer_nested_runs_on_error() -> None:
|
||||
assert len(tracer.runs) == 3
|
||||
for run in tracer.runs:
|
||||
_compare_run_with_error(run, compare_run)
|
||||
|
||||
|
||||
def _get_mock_client() -> Client:
|
||||
mock_session = MagicMock()
|
||||
client = Client(session=mock_session, api_key="test")
|
||||
return client
|
||||
|
||||
|
||||
def test_traceable_to_tracing() -> None:
|
||||
has_children = False
|
||||
|
||||
def _collect_run(run: Any) -> None:
|
||||
nonlocal has_children
|
||||
has_children = bool(run.child_runs)
|
||||
|
||||
@as_runnable
|
||||
def foo(x: int) -> int:
|
||||
return x + 1
|
||||
|
||||
@traceable
|
||||
def some_parent(a: int, b: int) -> int:
|
||||
return foo.invoke(a) + foo.invoke(b)
|
||||
|
||||
mock_client_ = _get_mock_client()
|
||||
with langsmith.run_helpers.tracing_context(enabled=True):
|
||||
result = some_parent(
|
||||
1, 2, langsmith_extra={"client": mock_client_, "on_end": _collect_run}
|
||||
)
|
||||
assert result == 5
|
||||
assert has_children, "Child run not collected"
|
||||
|
@ -2,11 +2,13 @@ import threading
|
||||
import time
|
||||
import unittest
|
||||
import unittest.mock
|
||||
import uuid
|
||||
from typing import Any, Dict
|
||||
from uuid import UUID
|
||||
|
||||
import pytest
|
||||
from langsmith import Client
|
||||
from langsmith.run_trees import RunTree
|
||||
|
||||
from langchain_core.outputs import LLMResult
|
||||
from langchain_core.tracers.langchain import LangChainTracer
|
||||
@ -59,6 +61,24 @@ def test_example_id_assignment_threadsafe() -> None:
|
||||
assert example_ids == expected_example_ids
|
||||
|
||||
|
||||
def test_tracer_with_run_tree_parent() -> None:
|
||||
mock_session = unittest.mock.MagicMock()
|
||||
client = Client(session=mock_session, api_key="test")
|
||||
parent = RunTree(name="parent", inputs={"input": "foo"}, client=client)
|
||||
run_id = uuid.uuid4()
|
||||
tracer = LangChainTracer(client=client)
|
||||
tracer.run_map[str(parent.id)] = parent # type: ignore
|
||||
tracer.on_chain_start(
|
||||
{"name": "child"}, {"input": "bar"}, run_id=run_id, parent_run_id=parent.id
|
||||
)
|
||||
tracer.on_chain_end({}, run_id=run_id)
|
||||
assert parent.child_runs
|
||||
assert len(parent.child_runs) == 1
|
||||
assert parent.child_runs[0].id == run_id
|
||||
assert parent.child_runs[0].trace_id == parent.id
|
||||
assert parent.child_runs[0].parent_run_id == parent.id
|
||||
|
||||
|
||||
def test_log_lock() -> None:
|
||||
"""Test that example assigned at callback start/end is honored."""
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user