fix(runners): honor before_run_callback early-exit for Workflow runs#6032
Open
garyzava wants to merge 1 commit into
Open
fix(runners): honor before_run_callback early-exit for Workflow runs#6032garyzava wants to merge 1 commit into
garyzava wants to merge 1 commit into
Conversation
In the Workflow run path (_run_node_async), the before_run plugin callback was awaited but its return value was discarded, so a callback returning a Content (the documented signal to halt the run) was ignored and execution continued into the workflow. Capture the callback result and, when it is a Content, emit it as the early-exit event and stop — matching the existing behavior of the non-workflow run path. Adds a regression test: a plugin whose before_run_callback returns Content halts the workflow and the node never executes. Fixes google#6013
Collaborator
🔍 ADK Pull Request Analysis: PR #6032Title: fix(runners): honor before_run_callback early-exit for Workflow runs Executive Summary
Detailed Findings & Analysis1. Objectives & Impact ("What does it do?")
2. Justification & Value ("Is it a valid and useful change?")
3. Principle & Style Alignment Checklist ("Does it follow rules?")
Summary of Triage & Findings
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
In the Workflow run path (
Runner._run_node_async), thebefore_runplugincallback was awaited but its return value was discarded. Per the plugin contract,
returning a
Contentfrombefore_run_callbackshould halt the run and end itwith that content — but for Workflow root agents the value was ignored and
execution continued into the workflow.
This captures the callback result and, when it is a
Content, emits it as theearly-exit event and stops — matching the existing behavior of the non-workflow
run path (
run_async).Fixes #6013
What changed
src/google/adk/runners.py— in_run_node_async, capturerun_before_run_callback(...)'s result; if it's atypes.Content, build theearly-exit
Event, append it (subject to_should_append_event), yield it, andreturn — instead of unconditionally proceeding. Mirrors the non-workflow path.
tests/unittests/workflow/test_workflow_failures.py— regression test: a pluginwhose
before_run_callbackreturnsContenthalts the workflow and the nodenever executes.
Why this approach
The non-workflow path already implements the documented early-exit contract
(capture the result, emit an early-exit event, skip execution). This change makes
the Workflow path consistent with it rather than introducing new behavior, so the
fix is minimal and the intended semantics are unambiguous.
How I tested
The new test (
test_workflow_halts_when_before_run_callback_returns_content)fails before the change (the node executes; no early-exit event) and passes
after. Existing workflow-failure tests and the non-workflow plugin tests
(
tests/unittests/test_runners.py -k plugin) still pass.pyinkandisortreport no changes.
Backward compatibility
No behavior change when
before_run_callbackreturnsNone(the common case) —the workflow runs exactly as before. Only the documented halt-on-
Contentcase isaffected, and it now matches the non-workflow path.