Feat(tool): support streaming intermediate results with non live- #4170 - #6883
Open
Lin-Nikaido wants to merge 1 commit into
Open
Feat(tool): support streaming intermediate results with non live- #4170#6883Lin-Nikaido wants to merge 1 commit into
Lin-Nikaido wants to merge 1 commit into
Conversation
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.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
Problem:
Enable to will_continue-like function response in BaseLlmFlow.run_async method with streaming mode.
It expected the tool returns generator, and the runner.async_run method when streaming_mode: StreamingMode.SSE yields the generator result as each Event. also, the streaming_mode is not SSE there is no change.
Solution:
A clear and concise description of what you want to happen and why you choose
this solution.
Testing Plan
Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes.
Unit Tests:
Please include a summary of passed
pytestresults.run

pytest ./tests/unittests/flows/-> all passedrun full suite unittests
Failed 4 tests.
Note on the five test failures in a full
tests/unittestsrunA full-suite run reports five failures. None of them touch code this PR changes, and both causes are environment-dependent — one is a latent timing race that surfaces or not depending on filesystem timestamp granularity and per-test timing, the other depends on how the environment was installed. Details below in case they are useful upstream.
TestValidateAgentImport(3 failures) — staleimportlibdirectory cache;invalidate_caches()is never calledAll three fail the same way, with an import error for the temp package itself:
_validate_agent_import(src/google/adk/cli/cli_deploy.py:604-615) puts the parent of the agent directory onsys.pathand imports the package by name:There is no
importlib.invalidate_caches(). CPython caches aFileFinderpersys.pathentry insys.path_importer_cache, and that finder keeps a listing of the directory, refreshed only when the directory'sst_mtimediffers from the value it recorded.sys.pathis restored in thefinallyblock, butsys.path_importer_cacheis global and is not — so the finder forparent_diroutlives each call.Every test in the class gets its
tmp_pathunder the same pytest basetemp, soparent_diris the same directory for all of them and its finder is created once, on the first import. Inode timestamps are updated at kernel tick granularity, which measured 1 ms on this machine:So whenever two of these tests create their
tmp_pathwithin the same millisecond, the second one's directory is invisible to the cached finder and the import fails withModuleNotFoundErrorfor a package that is sitting on disk. That is order- and timing-dependent, which is why which tests fail varies between machines and why the whole class passes on slower ones (25/25 clean runs of the class here).Reduced repro, no pytest involved — it reproduces on any machine where consecutive iterations land inside one timestamp tick:
Result here: 119–129 failures out of 300 as written, 0 out of 300 with
importlib.invalidate_caches()uncommented.The fix is the one line CPython's docs prescribe for exactly this situation ("If you are dynamically importing a module that was created since the interpreter began execution … call
invalidate_caches()") — before theimport_modulecall atcli_deploy.py:615:Worth noting for prioritisation:
_validate_agent_importcurrently has no caller insrc/— the validation was removed from the deploy path and--skip-agent-import-validationis deprecated (cli_deploy.py:1334). So today the impact is confined to the flaky test class, and the race would only become user-visible if the function is wired back in. Not included in this PR — unrelated to the change here.test_entry_point_loads_only_allowlisted_packages[agent|runner]—httpx2, absent underconstraints-3.11.txtThe import chain is one hop:
google/genai/types.pyimports it insidetry: ... except ImportError: pass, purely to widen a type annotation:No ADK module imports
httpx2— this is the same optional-annotation pattern_ENTRY_POINT_PACKAGE_ALLOWLISTalready excuses foraiohttpandPIL:It shows up because
anthropic1.0.0 requireshttpx2unconditionally (Requires-Dist: httpx2<3,>=2.0.0;openaiandstarletterequire it only under extras), andpyproject.tomldeclaresanthropic>=0.78with no upper bound. CI never sees it becauseconstraints-3.11.txtpinsanthropic==0.117.0(line 81) and has nohttpx2entry, so theexcept ImportErrorbranch is taken there. Installing without the constraints file resolvesanthropicto 1.0.0 and pullshttpx2in.Cost, for whatever the allowlist decision is worth — most of
httpx2's dependency tree is shared withhttpx, which is already loaded:import httpximport httpx, httpx2httpx2from google.adk.agents import Agent(total)(
-X importtimereports 67.8 ms of self time for the module, but the in-process marginal cost withhttpxalready imported is ~23 ms, about 2% of entry-point import time.)The fix the failure message itself prescribes is one line —
'httpx2'in_ENTRY_POINT_PACKAGE_ALLOWLIST'sgoogle.genai.typesoptional-annotation block, alongsideaiohttpandPIL. Not included here for the same reason as above.Everything else passes; the per-PR counts are in the description.
Manual End-to-End (E2E) Tests:
yieldslike this.Checklist
Additional context
This PR is follow newest version from #