@@ -534,6 +534,53 @@ async def test_metadata_field_mapping(
534534 assert retrieved_none .metadata == {}
535535
536536
537+ @pytest .mark .asyncio
538+ async def test_metadata_empty_transitions (
539+ vertex_store : VertexTaskStore ,
540+ ) -> None :
541+ """Test that updating metadata between {} and None does not generate events."""
542+ task_id = 'task-metadata-empty-test'
543+
544+ # Step 1: Create task with metadata={}
545+ task = Task (
546+ id = task_id ,
547+ context_id = 'session-meta-empty' ,
548+ status = TaskStatus (state = TaskState .submitted ),
549+ kind = 'task' ,
550+ metadata = {},
551+ )
552+ await vertex_store .save (task )
553+
554+ full_name = f'{ vertex_store ._agent_engine_resource_id } /a2aTasks/{ task_id } '
555+
556+ # Get initial event sequence number
557+ stored_task_before = (
558+ await vertex_store ._client .aio .agent_engines .a2a_tasks .get (full_name )
559+ )
560+ initial_seq = stored_task_before .next_event_sequence_number
561+
562+ # Step 2: Update metadata to None
563+ updated_task = task .model_copy (deep = True )
564+ updated_task .metadata = None
565+ await vertex_store .save (updated_task )
566+
567+ # Step 3: Update back to {}
568+ task_back = updated_task .model_copy (deep = True )
569+ task_back .metadata = {}
570+ await vertex_store .save (task_back )
571+
572+ # Verify that retrieved task still has {} (due to mapping)
573+ retrieved = await vertex_store .get (task_id )
574+ assert retrieved is not None
575+ assert retrieved .metadata == {}
576+
577+ # Verify that next_event_sequence_number did NOT increase (no events generated)
578+ stored_task_after = (
579+ await vertex_store ._client .aio .agent_engines .a2a_tasks .get (full_name )
580+ )
581+ assert stored_task_after .next_event_sequence_number == initial_seq
582+
583+
537584@pytest .mark .asyncio
538585async def test_update_task_status_details (
539586 vertex_store : VertexTaskStore ,
0 commit comments