From 58f8db66d34b60a03a840c52951114a9e8ee4d82 Mon Sep 17 00:00:00 2001 From: openhands Date: Tue, 25 Feb 2025 04:31:38 +0000 Subject: [PATCH] Add Event.parents property to track event provenance --- openhands/events/event.py | 17 ++++++++++++++ tests/unit/test_event_parents.py | 39 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 tests/unit/test_event_parents.py diff --git a/openhands/events/event.py b/openhands/events/event.py index 9d7af19160ca..1426e4ca40fe 100644 --- a/openhands/events/event.py +++ b/openhands/events/event.py @@ -1,11 +1,18 @@ from dataclasses import dataclass from datetime import datetime from enum import Enum +from typing import List from openhands.events.tool import ToolCallMetadata from openhands.llm.metrics import Metrics +@dataclass +class ParentEvent: + id: int + method: str + + class EventSource(str, Enum): AGENT = 'agent' USER = 'user' @@ -107,3 +114,13 @@ def tool_call_metadata(self) -> ToolCallMetadata | None: @tool_call_metadata.setter def tool_call_metadata(self, value: ToolCallMetadata) -> None: self._tool_call_metadata = value + + @property + def parents(self) -> List[ParentEvent] | None: + if hasattr(self, '_parents'): + return self._parents # type: ignore[attr-defined] + return None + + @parents.setter + def parents(self, value: List[ParentEvent]) -> None: + self._parents = value diff --git a/tests/unit/test_event_parents.py b/tests/unit/test_event_parents.py new file mode 100644 index 000000000000..ca5c1116581e --- /dev/null +++ b/tests/unit/test_event_parents.py @@ -0,0 +1,39 @@ +import pytest + +from openhands.events.event import Event, ParentEvent + + +def test_event_parents_property(): + # Test initial state + event = Event() + assert event.parents is None + + # Test setting and getting parents + parent_events = [ + ParentEvent(id=1, method="process_a"), + ParentEvent(id=2, method="process_b") + ] + event.parents = parent_events + + # Verify parents are set correctly + assert event.parents is not None + assert len(event.parents) == 2 + assert event.parents[0].id == 1 + assert event.parents[0].method == "process_a" + assert event.parents[1].id == 2 + assert event.parents[1].method == "process_b" + + +def test_parent_event_dataclass(): + # Test ParentEvent creation + parent = ParentEvent(id=1, method="test_method") + assert parent.id == 1 + assert parent.method == "test_method" + + # Test equality + parent2 = ParentEvent(id=1, method="test_method") + assert parent == parent2 + + # Test different values + parent3 = ParentEvent(id=2, method="other_method") + assert parent != parent3 \ No newline at end of file