Skip to content

fix(agents): record artifact_delta from before/after agent callbacks - #7479

Open
AkshayShah03 wants to merge 1 commit into
google:mainfrom
AkshayShah03:fix/agent-callback-artifact-delta
Open

AkshayShah03 wants to merge 1 commit into
google:mainfrom
AkshayShah03:fix/agent-callback-artifact-delta

Conversation

@AkshayShah03

Copy link
Copy Markdown
Contributor

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

Problem:
BaseAgent._handle_agent_callbacks only returns an event when a callback returns content or callback_context.state.has_delta() is true. An artifact saved via callback_context.save_artifact() in a before_agent_callback / after_agent_callback that returns None is stored by the artifact service, but its artifact_delta is never put on any event. The session has no record of it, so Runner.rewind_async cannot revert it and event-based artifact surfacing (web UI, A2A) never sees it.

Solution:
Also emit the event when callback_context._event_actions.artifact_delta is non-empty. This matches the workflow node runner, which already checks both state and artifact deltas, and the model/tool callback paths, which already record artifacts saved there.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Added to tests/unittests/agents/test_base_agent.py:

  • test_run_async_before_agent_callback_records_artifact_delta
  • test_run_async_after_agent_callback_records_artifact_delta

Each saves an artifact from the callback (returning None) and asserts an event carries artifact_delta == {'<name>': 0}. Both fail on main (only the agent's own response event is produced) and pass with this change.

$ pytest tests/unittests/agents tests/unittests/flows tests/unittests/runners
2215 passed, 1 skipped, 5 xfailed

$ pytest tests/unittests -n auto
18347 passed, 4 failed

The 4 failures are in tests/unittests/models/test_litellm.py log-level assertions; they pass when run alone or as their own file, and with this change stashed, so they are unrelated to this PR.

pyink and isort report no changes.

Manual End-to-End (E2E) Tests:

Ran the reproduction script from #7478 through a real Runner with InMemorySessionService and InMemoryArtifactService:

  • on main: artifact_delta in session events: []
  • with this change: artifact_delta in session events: [{'report.txt': 0}]

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

_handle_agent_callbacks only emitted an event when a callback returned
content or changed state, so an artifact saved via
callback_context.save_artifact() in before_agent_callback or
after_agent_callback was stored but never recorded in a session event.
Rewind and event-based artifact surfacing therefore missed it. Also emit
the event when the callback context carries an artifact_delta.

Fixes google#7478
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Artifacts saved in before_agent_callback / after_agent_callback are never recorded in an event (artifact_delta dropped)

2 participants