Skip to content

Commit b26e838

Browse files
committed
fix: Append metadata and context id when processing TaskStatusUpdateEvent, and add more error logs
1. Fix the bug that during TaskManager.save_task_event, metadata from the updated task event is lost 2. During EventQueue processing, if any of the processing asyncio task failed with an unexpected exception, this exception is silently caught but never exposed to user or logged in the console. Add more error logs to make errors visible during debugging.
1 parent 4050b81 commit b26e838

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

src/a2a/server/events/event_consumer.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ async def consume_all(self) -> AsyncGenerator[Event]:
138138
# python 3.12 and get a queue empty error on an open queue
139139
if self.queue.is_closed():
140140
break
141+
except Exception as e:
142+
logger.debug(f'Stopping event consumption due to exception: {e}')
143+
self._exception = e
144+
continue
141145

142146
def agent_task_callback(self, agent_task: asyncio.Task[None]) -> None:
143147
"""Callback to handle exceptions from the agent's execution task.

src/a2a/server/request_handlers/default_request_handler.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,9 @@ async def on_message_send(
248248
raise ServerError(
249249
InternalError(message='Task ID mismatch in agent response')
250250
)
251-
251+
except Exception as e:
252+
logger.error(f'Agent execution failed. Error: {e}')
253+
raise e
252254
finally:
253255
if interrupted:
254256
# TODO: Track this disconnected cleanup task.

src/a2a/server/tasks/task_manager.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,12 @@ async def save_task_event(
130130
task.history = [task.status.message]
131131
else:
132132
task.history.append(task.status.message)
133-
133+
if event.contextId:
134+
task.contextId = event.contextId
135+
if event.metadata:
136+
if not task.metadata:
137+
task.metadata = {}
138+
task.metadata.update(event.metadata)
134139
task.status = event.status
135140
else:
136141
logger.debug('Appending artifact to task %s', task.id)

tests/server/tasks/test_task_manager.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,29 @@ async def test_save_task_event_artifact_update(
127127
updated_task.artifacts = [new_artifact]
128128
mock_task_store.save.assert_called_once_with(updated_task)
129129

130+
@pytest.mark.asyncio
131+
async def test_save_task_event_metadata_contextid_update(
132+
task_manager: TaskManager, mock_task_store: AsyncMock
133+
) -> None:
134+
"""Test saving an metadata and context update for an existing task."""
135+
initial_task = Task(**MINIMAL_TASK)
136+
mock_task_store.get.return_value = initial_task
137+
new_metadata = {"meta_key_test": "meta_value_test"}
138+
new_context_id = 'new_context_id'
139+
140+
event = TaskStatusUpdateEvent(
141+
taskId=MINIMAL_TASK['id'],
142+
contextId=new_context_id,
143+
metadata=new_metadata,
144+
status=TaskStatus(state=TaskState.working),
145+
final=False,
146+
)
147+
await task_manager.save_task_event(event)
148+
149+
updated_task = mock_task_store.save.call_args.args[0]
150+
assert updated_task.metadata == new_metadata
151+
assert updated_task.contextId == new_context_id
152+
130153

131154
@pytest.mark.asyncio
132155
async def test_ensure_task_existing(

0 commit comments

Comments
 (0)