From fa76e05de5979b678111443b35905d3519e57d1f Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 6 Jun 2024 16:25:01 -0400 Subject: [PATCH 1/3] x --- .../langchain_core/tracers/event_stream.py | 14 +++++--- .../runnables/test_runnable_events_v2.py | 36 +++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/libs/core/langchain_core/tracers/event_stream.py b/libs/core/langchain_core/tracers/event_stream.py index f519debaa14..cbe3d4f6c7e 100644 --- a/libs/core/langchain_core/tracers/event_stream.py +++ b/libs/core/langchain_core/tracers/event_stream.py @@ -118,12 +118,16 @@ def __init__( def _get_parent_ids(self, run_id: UUID) -> List[str]: """Get the parent IDs of a run (non-recursively) cast to strings.""" parent_ids = [] - parent_id = self.parent_map[run_id] - - while parent_id is not None: - parent_ids.append(str(parent_id)) - parent_id = self.parent_map[parent_id] + while parent_id := self.parent_map.get(run_id): + str_parent_id = str(parent_id) + if str_parent_id in parent_ids: + raise AssertionError( + f"Parent ID {parent_id} is already in the parent_ids list. " + f"This should never happen." + ) + parent_ids.append(str_parent_id) + run_id = parent_id return parent_ids def _send(self, event: StreamEvent, event_type: str) -> None: diff --git a/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py b/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py index 6c7357ff1b5..6b4505c4f4b 100644 --- a/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py +++ b/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py @@ -2081,6 +2081,42 @@ async def parent(x: str, config: RunnableConfig) -> str: ] +async def test_bad_parent_ids() -> None: + """Test handling of situation where a run id is duplicated in the run tree.""" + + # Type ignores in the code below need to be investigated. + # Looks like a typing issue when using RunnableLambda as a decorator + # with async functions. + @RunnableLambda # type: ignore + async def child(x: str) -> str: + return x + + @RunnableLambda # type: ignore + async def parent(x: str, config: RunnableConfig) -> str: + config["run_id"] = uuid.UUID(int=7) + return await child.ainvoke(x, config) # type: ignore + + bond = uuid.UUID(int=7) + events = await _collect_events( + parent.astream_events("hello", {"run_id": bond}, version="v2"), + with_nulled_ids=False, + ) + # Includes only a partial list of events since the run ID gets duplicated + # between parent and child run ID and the callback handler throws an exception. + # The exception does not get bubbled up to the user. + assert events == [ + { + "data": {"input": "hello"}, + "event": "on_chain_start", + "metadata": {}, + "name": "parent", + "parent_ids": [], + "run_id": "00000000-0000-0000-0000-000000000007", + "tags": [], + } + ] + + async def test_runnable_generator() -> None: """Test async events from sync lambda.""" From c4ca58d75cee9595953aa81adaca78f3c11faafe Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 6 Jun 2024 16:28:54 -0400 Subject: [PATCH 2/3] x --- .../tests/unit_tests/runnables/test_runnable_events_v2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py b/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py index 6b4505c4f4b..81924b14bce 100644 --- a/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py +++ b/libs/core/tests/unit_tests/runnables/test_runnable_events_v2.py @@ -2033,8 +2033,8 @@ async def parent(x: str, config: RunnableConfig) -> str: "metadata": {}, "name": "grandchild", "parent_ids": [ - "00000000-0000-0000-0000-000000000008", "00000000-0000-0000-0000-000000000007", + "00000000-0000-0000-0000-000000000008", ], "run_id": "00000000-0000-0000-0000-000000000009", "tags": [], @@ -2045,8 +2045,8 @@ async def parent(x: str, config: RunnableConfig) -> str: "metadata": {}, "name": "grandchild", "parent_ids": [ - "00000000-0000-0000-0000-000000000008", "00000000-0000-0000-0000-000000000007", + "00000000-0000-0000-0000-000000000008", ], "run_id": "00000000-0000-0000-0000-000000000009", "tags": [], From abf0ca122e2a2222a1c707c0dd1751e7335d0b95 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 6 Jun 2024 16:31:39 -0400 Subject: [PATCH 3/3] x --- libs/core/langchain_core/tracers/event_stream.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/core/langchain_core/tracers/event_stream.py b/libs/core/langchain_core/tracers/event_stream.py index cbe3d4f6c7e..c7839dca300 100644 --- a/libs/core/langchain_core/tracers/event_stream.py +++ b/libs/core/langchain_core/tracers/event_stream.py @@ -128,7 +128,10 @@ def _get_parent_ids(self, run_id: UUID) -> List[str]: ) parent_ids.append(str_parent_id) run_id = parent_id - return parent_ids + + # Return the parent IDs in reverse order, so that the first + # parent ID is the root and the last ID is the immediate parent. + return parent_ids[::-1] def _send(self, event: StreamEvent, event_type: str) -> None: """Send an event to the stream."""