Skip to content

Commit b44fa8f

Browse files
authored
fix: Don't generate empty metadata change events in VertexTaskStore (#962)
For #751
1 parent ead75f9 commit b44fa8f

2 files changed

Lines changed: 53 additions & 1 deletion

File tree

src/a2a/contrib/tasks/vertex_task_store.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,12 @@ def _get_status_details_change_event(
109109
def _get_metadata_change_event(
110110
self, previous_task: Task, task: Task, event_sequence_number: int
111111
) -> vertexai_types.TaskEvent | None:
112-
if task.metadata != previous_task.metadata:
112+
# We generate metadata change events if the metadata was changed.
113+
# We don't generate events if the metadata was changed from
114+
# one empty value to another, e.g. {} to None.
115+
if task.metadata != previous_task.metadata and (
116+
task.metadata or previous_task.metadata
117+
):
113118
return vertexai_types.TaskEvent(
114119
event_data=vertexai_types.TaskEventData(
115120
metadata_change=vertexai_types.TaskMetadataChange(

tests/contrib/tasks/test_vertex_task_store.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
512559
async def test_update_task_status_details(
513560
vertex_store: VertexTaskStore,

0 commit comments

Comments
 (0)