Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions libs/core/langchain_core/callbacks/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -965,28 +965,29 @@ def merge(self, other: BaseCallbackManager) -> Self:
# ['tag2', 'tag1']
```
""" # noqa: E501
manager = self.__class__(
# Combine handlers and inheritable_handlers separately, using sets
# to deduplicate (order not preserved)
combined_handlers = list(set(self.handlers) | set(other.handlers))
combined_inheritable = list(
set(self.inheritable_handlers) | set(other.inheritable_handlers)
)

return self.__class__(
parent_run_id=self.parent_run_id or other.parent_run_id,
handlers=[],
inheritable_handlers=[],
handlers=combined_handlers,
inheritable_handlers=combined_inheritable,
tags=list(set(self.tags + other.tags)),
inheritable_tags=list(set(self.inheritable_tags + other.inheritable_tags)),
metadata={
**self.metadata,
**other.metadata,
},
inheritable_metadata={
**self.inheritable_metadata,
**other.inheritable_metadata,
},
)

handlers = self.handlers + other.handlers
inheritable_handlers = self.inheritable_handlers + other.inheritable_handlers

for handler in handlers:
manager.add_handler(handler)

for handler in inheritable_handlers:
manager.add_handler(handler, inherit=True)
return manager

@property
def is_async(self) -> bool:
"""Whether the callback manager is async."""
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import pytest

from langchain_core.callbacks.base import BaseCallbackHandler, BaseCallbackManager


Expand All @@ -17,9 +15,6 @@ def test_remove_handler() -> None:
manager.remove_handler(handler2)


@pytest.mark.xfail(
reason="TODO: #32028 merge() incorrectly mixes handlers and inheritable_handlers"
)
def test_merge_preserves_handler_distinction() -> None:
"""Test that merging managers preserves the distinction between handlers.

Expand Down