Skip to content

Commit e106020

Browse files
authored
fix: Append metadata and context id when processing TaskStatusUpdateE… (#238)
…vent, 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. # Description Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [x] Follow the [`CONTRIBUTING` Guide](https://github.com/a2aproject/a2a-python/blob/main/CONTRIBUTING.md). - [x] Make your Pull Request title in the <https://www.conventionalcommits.org/> specification. - Important Prefixes for [release-please](https://github.com/googleapis/release-please): - `fix:` which represents bug fixes, and correlates to a [SemVer](https://semver.org/) patch. - `feat:` represents a new feature, and correlates to a SemVer minor. - `feat!:`, or `fix!:`, `refactor!:`, etc., which represent a breaking change (indicated by the `!`) and will result in a SemVer major. - [ ] Ensure the tests and linter pass (Run `nox -s format` from the repository root to format) - [ ] Appropriate docs were updated (if necessary) Fixes #<issue_number_goes_here> 🦕
1 parent 4050b81 commit e106020

File tree

4 files changed

+32
-2
lines changed

4 files changed

+32
-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.error(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
252254
finally:
253255
if interrupted:
254256
# TODO: Track this disconnected cleanup task.

src/a2a/server/tasks/task_manager.py

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

tests/server/tasks/test_task_manager.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,27 @@ 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_update(
132+
task_manager: TaskManager, mock_task_store: AsyncMock
133+
) -> None:
134+
"""Test saving an updated metadata 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+
139+
event = TaskStatusUpdateEvent(
140+
taskId=MINIMAL_TASK['id'],
141+
contextId=MINIMAL_TASK['contextId'],
142+
metadata=new_metadata,
143+
status=TaskStatus(state=TaskState.working),
144+
final=False,
145+
)
146+
await task_manager.save_task_event(event)
147+
148+
updated_task = mock_task_store.save.call_args.args[0]
149+
assert updated_task.metadata == new_metadata
150+
130151

131152
@pytest.mark.asyncio
132153
async def test_ensure_task_existing(

0 commit comments

Comments
 (0)