@@ -508,6 +508,53 @@ async def test_metadata_field_mapping(
508508 assert retrieved_none .metadata == {}
509509
510510
511+ @pytest .mark .asyncio
512+ async def test_metadata_empty_transitions (
513+ vertex_store : VertexTaskStore ,
514+ ) -> None :
515+ """Test that updating metadata between {} and None does not generate events."""
516+ task_id = 'task-metadata-empty-test'
517+
518+ # Step 1: Create task with metadata={}
519+ task = Task (
520+ id = task_id ,
521+ context_id = 'session-meta-empty' ,
522+ status = TaskStatus (state = TaskState .submitted ),
523+ kind = 'task' ,
524+ metadata = {},
525+ )
526+ await vertex_store .save (task )
527+
528+ full_name = f'{ vertex_store ._agent_engine_resource_id } /a2aTasks/{ task_id } '
529+
530+ # Get initial event sequence number
531+ stored_task_before = (
532+ await vertex_store ._client .aio .agent_engines .a2a_tasks .get (full_name )
533+ )
534+ initial_seq = stored_task_before .next_event_sequence_number
535+
536+ # Step 2: Update metadata to None
537+ updated_task = task .model_copy (deep = True )
538+ updated_task .metadata = None
539+ await vertex_store .save (updated_task )
540+
541+ # Step 3: Update back to {}
542+ task_back = updated_task .model_copy (deep = True )
543+ task_back .metadata = {}
544+ await vertex_store .save (task_back )
545+
546+ # Verify that retrieved task still has {} (due to mapping)
547+ retrieved = await vertex_store .get (task_id )
548+ assert retrieved is not None
549+ assert retrieved .metadata == {}
550+
551+ # Verify that next_event_sequence_number did NOT increase (no events generated)
552+ stored_task_after = (
553+ await vertex_store ._client .aio .agent_engines .a2a_tasks .get (full_name )
554+ )
555+ assert stored_task_after .next_event_sequence_number == initial_seq
556+
557+
511558@pytest .mark .asyncio
512559async def test_update_task_status_details (
513560 vertex_store : VertexTaskStore ,
0 commit comments