From 838530ebe053e5193d4329c5a203ca3d096ff7be Mon Sep 17 00:00:00 2001 From: George Weale Date: Mon, 5 Jan 2026 12:25:30 -0800 Subject: [PATCH] fix: rehydration of EventActions in StorageEvent.to_event The change updates the `StorageEvent.to_event` method to use `EventActions.model_validate` when rehydrating the `actions` field. This ensures that nested models within `EventActions`, such as `EventCompaction`, are correctly reconstructed from the stored data Close #4047 Co-authored-by: George Weale PiperOrigin-RevId: 852408683 --- src/google/adk/sessions/schemas/v0.py | 6 ++- .../sessions/test_v0_storage_event.py | 50 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/unittests/sessions/test_v0_storage_event.py diff --git a/src/google/adk/sessions/schemas/v0.py b/src/google/adk/sessions/schemas/v0.py index 16a11218..a69c2924 100644 --- a/src/google/adk/sessions/schemas/v0.py +++ b/src/google/adk/sessions/schemas/v0.py @@ -310,7 +310,11 @@ class StorageEvent(Base): branch=self.branch, # This is needed as previous ADK version pickled actions might not have # value defined in the current version of the EventActions model. - actions=EventActions().model_copy(update=self.actions.model_dump()), + actions=( + EventActions.model_validate(self.actions.model_dump()) + if self.actions + else EventActions() + ), timestamp=self.timestamp.timestamp(), long_running_tool_ids=self.long_running_tool_ids, partial=self.partial, diff --git a/tests/unittests/sessions/test_v0_storage_event.py b/tests/unittests/sessions/test_v0_storage_event.py new file mode 100644 index 00000000..6ac62dde --- /dev/null +++ b/tests/unittests/sessions/test_v0_storage_event.py @@ -0,0 +1,50 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from datetime import datetime +from datetime import timezone + +from google.adk.events.event_actions import EventActions +from google.adk.events.event_actions import EventCompaction +from google.adk.sessions.schemas.v0 import StorageEvent +from google.genai import types + + +def test_storage_event_v0_to_event_rehydrates_compaction_model(): + compaction = EventCompaction( + start_timestamp=1.0, + end_timestamp=2.0, + compacted_content=types.Content( + role="user", + parts=[types.Part(text="compacted")], + ), + ) + actions = EventActions(compaction=compaction) + storage_event = StorageEvent( + id="event_id", + invocation_id="invocation_id", + author="author", + actions=actions, + session_id="session_id", + app_name="app_name", + user_id="user_id", + timestamp=datetime.fromtimestamp(3.0, tz=timezone.utc), + ) + + event = storage_event.to_event() + + assert event.actions is not None + assert isinstance(event.actions.compaction, EventCompaction) + assert event.actions.compaction.start_timestamp == 1.0 + assert event.actions.compaction.end_timestamp == 2.0