Skip to content

fix: run on_event callbacks for before_run early exits - #7008

Open
jaywang172 wants to merge 1 commit into
google:mainfrom
jaywang172:fix/before-run-early-exit-event-callback
Open

fix: run on_event callbacks for before_run early exits#7008
jaywang172 wants to merge 1 commit into
google:mainfrom
jaywang172:fix/before-run-early-exit-event-callback

Conversation

@jaywang172

@jaywang172 jaywang172 commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Link to Issue or Description of Change

Problem:

before_run_callback may halt a run by returning types.Content. The runner
converts that content into an event, but the early-exit paths currently persist
and yield the event without invoking on_event_callback.

This affects legacy agent execution, node / LlmAgent execution, and live
execution. It means event plugins used for logging, auditing, redaction, or
metadata enrichment do not observe these runner-produced responses.

Solution:

Route early-exit events through the same private event-processing step used by
normal runner events:

metadata → on_event_callback → merge

before persistence and yielding. Keeping this processing in a private Runner
helper prevents the normal and early-exit paths from drifting while introducing
no public API.

Before:

before_run → early-exit Event → persist / yield

After:

before_run → early-exit Event → on_event_callback → merge → persist / yield

Persistence eligibility remains based on the original event, preserving the
existing live-event persistence policy.

Testing Plan

Unit Tests:

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

Added a parameterized regression test for legacy async, node async, and live
runner execution. It verifies that:

  • on_event_callback is invoked for the early-exit event;
  • callback modifications appear in the yielded event;
  • the same modifications appear in the persisted session event;
  • existing event merge semantics are preserved.

Validation:

  • related runner/plugin tests: 164 passed;
  • regression tests: passed on Python 3.10, 3.11, 3.12, 3.13, and 3.14;
  • full unit suite on current main (c7ffcfa8): 13,959 passed,
    85 skipped, 27 xfailed, 2 xpassed, and 24 subtests passed;
  • pre-commit: passed;
  • git diff --check: passed;
  • wheel and sdist builds: passed.

No Google API key or Application Default Credentials are required.

Manual End-to-End (E2E) Tests:

Ran a local Runner smoke test with InMemorySessionService. A plugin returned
content from before_run_callback, replaced the synthesized event in
on_event_callback, and the script verified that the processed event was both
yielded and persisted. The early exit prevented any model request.

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 (N/A; no dependencies).

Additional context

This is a focused runtime lifecycle fix. It does not change plugin ordering,
event merge behavior, or any public API.

Route synthesized before_run early-exit events through the same private event-processing helper used by normal runner events. This keeps on_event callback modifications aligned between yielded and persisted events across legacy, node, and live execution.

Fixes google#7007
@jaywang172
jaywang172 force-pushed the fix/before-run-early-exit-event-callback branch from 4a87c8e to 7b088bc Compare September 4, 2026 08:36
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.

before_run early-exit events bypass on_event_callback

2 participants