From c10b8e85cdbb0fa2bbf601885bc609d66512cfc3 Mon Sep 17 00:00:00 2001 From: drew Date: Tue, 16 Jun 2026 17:17:17 -0400 Subject: [PATCH] fix(tui): align materializer A2A steps with current event models --- .../tui_materializer_a2a_integration_steps.py | 80 +++++++++++-------- src/cleveragents/tui/_tui_events.py | 1 + src/cleveragents/tui/materializer.py | 10 +++ 3 files changed, 57 insertions(+), 34 deletions(-) diff --git a/features/steps/tui_materializer_a2a_integration_steps.py b/features/steps/tui_materializer_a2a_integration_steps.py index 71fe7cc05..b3464d759 100644 --- a/features/steps/tui_materializer_a2a_integration_steps.py +++ b/features/steps/tui_materializer_a2a_integration_steps.py @@ -7,7 +7,13 @@ from unittest.mock import Mock from behave import given, then, when -from cleveragents.cli.output.handles import ElementSnapshot +from cleveragents.cli.output.handles import ( + ElementClosed, + ElementCreated, + ElementUpdated, + SessionEnd, + TextBlock, +) from cleveragents.tui.a2a_integration import TuiA2aAdapter, TuiA2aIntegration from cleveragents.tui.materializer import TuiMaterializer @@ -60,8 +66,8 @@ def step_call_session_begin(context: Any) -> None: @then("the materializer should record a session_begin event") def step_verify_session_begin_event(context: Any) -> None: """Verify a session_begin event was recorded.""" - assert len(context.materializer._events) > 0, "Events should not be empty" - assert context.materializer._events[0]["type"] == "session_begin" + events = context.materializer.get_events() + assert any(e["type"] == "session_begin" for e in events) @then("the session should be marked as active") @@ -73,27 +79,27 @@ def step_verify_session_active(context: Any) -> None: @when("I call on_element_created with an element") def step_call_element_created(context: Any) -> None: """Call on_element_created with a mock element.""" - mock_event = Mock() - mock_element = Mock(spec=ElementSnapshot) - mock_element.id = "elem-1" - mock_element.type = "text" - mock_element.content = "Test content" - mock_element.metadata = {} - mock_event.element = mock_element - context.materializer.on_element_created(mock_event) + event = ElementCreated( + event_type="element_created", + handle_id="elem-1", + element_kind="text", + declaration_index=0, + initial_state=TextBlock(content="Test content"), + ) + context.materializer.on_element_created(event) @then("the materializer should record an element_created event") def step_verify_element_created_event(context: Any) -> None: """Verify an element_created event was recorded.""" - events = context.materializer._events + events = context.materializer.get_events() assert any(e["type"] == "element_created" for e in events) @then("the event should contain the element ID and type") def step_verify_element_event_content(context: Any) -> None: """Verify the element event contains ID and type.""" - events = context.materializer._events + events = context.materializer.get_events() element_event = next(e for e in events if e["type"] == "element_created") assert element_event["element_id"] == "elem-1" assert element_event["element_type"] == "text" @@ -102,27 +108,26 @@ def step_verify_element_event_content(context: Any) -> None: @when("I call on_element_updated with an element") def step_call_element_updated(context: Any) -> None: """Call on_element_updated with a mock element.""" - mock_event = Mock() - mock_element = Mock(spec=ElementSnapshot) - mock_element.id = "elem-1" - mock_element.type = "text" - mock_element.content = "Updated content" - mock_element.metadata = {} - mock_event.element = mock_element - context.materializer.on_element_updated(mock_event) + event = ElementUpdated( + event_type="element_updated", + handle_id="elem-1", + element_kind="text", + element_snapshot=TextBlock(content="Updated content"), + ) + context.materializer.on_element_updated(event) @then("the materializer should record an element_updated event") def step_verify_element_updated_event(context: Any) -> None: """Verify an element_updated event was recorded.""" - events = context.materializer._events + events = context.materializer.get_events() assert any(e["type"] == "element_updated" for e in events) @then("the event should contain the updated element data") def step_verify_updated_element_data(context: Any) -> None: """Verify the updated element event contains correct data.""" - events = context.materializer._events + events = context.materializer.get_events() element_event = next(e for e in events if e["type"] == "element_updated") assert element_event["element_id"] == "elem-1" @@ -130,22 +135,26 @@ def step_verify_updated_element_data(context: Any) -> None: @when("I call on_element_closed with an element ID") def step_call_element_closed(context: Any) -> None: """Call on_element_closed with an element ID.""" - mock_event = Mock() - mock_event.element_id = "elem-1" - context.materializer.on_element_closed(mock_event) + event = ElementClosed( + event_type="element_closed", + handle_id="elem-1", + element_kind="text", + final_state=TextBlock(content="Final content"), + ) + context.materializer.on_element_closed(event) @then("the materializer should record an element_closed event") def step_verify_element_closed_event(context: Any) -> None: """Verify an element_closed event was recorded.""" - events = context.materializer._events + events = context.materializer.get_events() assert any(e["type"] == "element_closed" for e in events) @then("the event should contain the element ID") def step_verify_element_closed_id(context: Any) -> None: """Verify the element_closed event contains the element ID.""" - events = context.materializer._events + events = context.materializer.get_events() element_event = next(e for e in events if e["type"] == "element_closed") assert element_event["element_id"] == "elem-1" @@ -153,16 +162,19 @@ def step_verify_element_closed_id(context: Any) -> None: @when("I call on_session_end with a session end event") def step_call_session_end(context: Any) -> None: """Call on_session_end with a mock session end event.""" - mock_event = Mock() - mock_event.status = "completed" - mock_event.timestamp = "2026-04-20T00:00:01Z" - context.materializer.on_session_end(mock_event) + event = SessionEnd( + event_type="session_end", + handle_id="session", + element_kind="session", + exit_code=0, + ) + context.materializer.on_session_end(event) @then("the materializer should record a session_end event") def step_verify_session_end_event(context: Any) -> None: """Verify a session_end event was recorded.""" - events = context.materializer._events + events = context.materializer.get_events() assert any(e["type"] == "session_end" for e in events) @@ -209,7 +221,7 @@ def step_call_get_error_output(context: Any) -> None: @then("the materializer should record an error event") def step_verify_error_event(context: Any) -> None: """Verify an error event was recorded.""" - events = context.materializer._events + events = context.materializer.get_events() assert any(e["type"] == "error" for e in events) diff --git a/src/cleveragents/tui/_tui_events.py b/src/cleveragents/tui/_tui_events.py index 0f205bcd6..4740e5059 100644 --- a/src/cleveragents/tui/_tui_events.py +++ b/src/cleveragents/tui/_tui_events.py @@ -23,6 +23,7 @@ if TYPE_CHECKING: class TuiWidgetEventType: """String constants for TUI widget event types.""" + SESSION_BEGIN: str = "session_begin" ELEMENT_CREATED: str = "element_created" ELEMENT_UPDATED: str = "element_updated" ELEMENT_CLOSED: str = "element_closed" diff --git a/src/cleveragents/tui/materializer.py b/src/cleveragents/tui/materializer.py index 5b4e21c5b..dc2803290 100644 --- a/src/cleveragents/tui/materializer.py +++ b/src/cleveragents/tui/materializer.py @@ -152,6 +152,16 @@ class TuiMaterializer: """Called when a new output session begins.""" self._session = session self._session_active = True + tui_event = TuiWidgetEvent( + event_type=TuiWidgetEventType.SESSION_BEGIN, + handle_id=str(getattr(session, "id", "")), + element_kind="session", + extra={ + "session_id": getattr(session, "id", None), + "timestamp": getattr(session, "timestamp", None), + }, + ) + self._emit(tui_event) def on_element_created(self, event: ElementCreated) -> None: """Called when a new element handle is created.