You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
AgentTool runs the wrapped agent without the parent App's events_compaction_config, so agent-as-tool history grows unbounded #7397
AgentTool.run_async builds a fresh Runner(app_name=..., agent=self.agent, session_service=InMemorySessionService(), ...) for the wrapped agent, without an App. The parent App's events_compaction_config therefore never applies inside the child run.
A wrapped agent that makes many tool calls (for example, a read-only code-navigation agent that greps and reads files) keeps growing its own history until the model server rejects the request because prompt + max_output_tokens exceeds the context window. The resulting ContextWindowExceededError is raised inside the tool call and propagates up, which aborts the parent invocation, even though the parent agent's own history is being compacted correctly.
Where
src/google/adk/tools/agent_tool.py: the Runner(...) construction in run_async (lines ~241-270 in v1.36.1; still constructed the same way on main, around line 265).
To reproduce (outline)
Create an App with EventsCompactionConfig(compaction_interval=5, overlap_size=2, token_threshold=14336, ...).
Root LlmAgent with an AgentTool wrapping a sub-agent whose tools return large outputs (e.g. file reads).
Use a model with a 32k context through LiteLlm (we used vLLM serving Gemma 4 31B, max_model_len=32768).
Let the sub-agent make many tool calls in one invocation: the root agent's events get compacted, but the child session is never compacted and eventually fails with ContextWindowExceededError.
Observed
With google-adk 1.36.1, LiteLlm -> vLLM (Gemma 4 31B, 32,768-token context) across about 130 agent sessions: all 8 context-overflow failures came from the AgentTool child, none from the root agent. Lowering the child's max_output_tokens only moves the failure point (from a ~24.6k-token prompt at 8192 output tokens to ~31.7k at 1024).
Expected behavior
One or more of:
child runs inherit the parent App's compaction (and context-caching) configuration;
AgentTool accepts an option to pass an App / EventsCompactionConfig for the child run;
a child context-window error is returned to the parent agent as a tool error instead of aborting the whole invocation.
Related
#3230 (expand explicit context caching to agent tools and sub agents) covers caching; this issue is about compaction.
Environment
google-adk 1.36.1 (checked against main as of 2026-10-03), Python 3.12, LiteLlm with an OpenAI-compatible vLLM 0.19.1 server.
Question for the maintainers: may I open a pull request with the fix below? If AgentTool changes are not wanted on main, would a PR against the v1 branch be preferred instead, where AgentTool is still the standard pattern?
Some additional context after digging further:
Precedent. The same gap was fixed for context caching in 9488408 ("propagate context cache config to the AgentTool sub-runner": the sub-runner "never received the parent App's context_cache_config, so context caching was silently off for every wrapped agent"). That change built the nested App with App.model_construct(...) and passed Runner(app=...), and it was rolled back the same day in 5835f5a. I could not find the reason for the rollback in the public history, so I wanted to check here before opening a PR.
AgentTool and single_turn. I see the AgentTool docstring on main now recommends mode='single_turn' sub-agents, which run inline in the parent's session and therefore already get compaction. The problem still affects AgentTool on main, which remains supported, and every 1.x release, where AgentTool is the standard agent-as-a-tool pattern. We hit it on 1.36.1.
It builds the nested App with the caller's token-threshold compaction settings (token_threshold, event_retention_size). The sliding-window trigger is left out, because it runs after the nested invocation finishes and the nested session is discarded when the tool returns. Building the App also removes this path's use of the deprecated Runner(plugins=...) argument. Verification:
A new unit test fails on main and passes with the fix.
tox on Python 3.10, 3.11, 3.12, 3.13 and 3.14: all environments pass (17404 passed in each; 17413 on 3.11).
All pre-commit hooks pass, with no new mypy errors.
A real-model run (gemini-3.1-flash-lite, token_threshold=2000, a wrapped agent reading four long chapters): the wrapped agent's prompt grows to 9 contents on main, and with the fix it is compacted at its 4th request.
If the earlier rollback points to a preferred approach, for example setting the config on the nested runner's app after construction instead of building the App, I'm happy to adapt the change for either branch.
Thanks for sharing the fix, @mahir-m01. I reviewed the current main implementation and your commit fd0f863. The configuration is lost when AgentTool creates the nested Runner, and your patch already addresses that path.
Would additional regression coverage or independent validation of your branch be useful? I can help cover no configuration, sliding-window-only configuration, preservation of the parent's configuration, and repeated or nested AgentTool calls, alongside the existing plugin-lifecycle tests. I have only reviewed the code so far; I have not independently reproduced the reported test results.
Could the maintainers also clarify whether this should target main or v1, and whether the earlier context-cache rollback affects the preferred way to configure the nested Runner? I would like to coordinate a complementary contribution with you before opening a PR.
@loyce-cheng thanks again for offering to help. If you spot other gaps in this area, for example an AgentTool nested inside another AgentTool, or how this interacts with the plugin lifecycle, a follow-up PR would be very welcome. Reviews and testing on #7401 are welcome too.
@mahir-m01 Reproduced on 2.11.0 with a mocked model: the same reader agent gets compacted as root but under AgentTool its request just keeps growing (1 -> 3 -> 5 -> 7 -> 9 contents) and no summary ever shows up.
Until #7401 is reviewed a workaround worth trying: add a small App plugin whose before_run_callback sets invocation_context.events_compaction_config when it's None to a copy of the App's config with compaction_interval/overlap_size set to None. AgentTool passes parent plugins to the child run by default so the child picks it up. On my side that keeps the child at 3 contents with the summary in place. Could you check whether that holds up on your vLLM/Gemma setup? It won't help if include_plugins=False.
For #7401 the open question is still why the context cache propagation (9488408) was reverted so please run the PR tests against v1 too in case maintainers want it there.
Activity
fix(tools): prevent agent tools from overflowing the context window
mahir-m01 commentedon Oct 3, 2026
Question for the maintainers: may I open a pull request with the fix below? If
AgentToolchanges are not wanted onmain, would a PR against thev1branch be preferred instead, whereAgentToolis still the standard pattern?Some additional context after digging further:
Precedent. The same gap was fixed for context caching in 9488408 ("propagate context cache config to the AgentTool sub-runner": the sub-runner "never received the parent App's context_cache_config, so context caching was silently off for every wrapped agent"). That change built the nested
AppwithApp.model_construct(...)and passedRunner(app=...), and it was rolled back the same day in 5835f5a. I could not find the reason for the rollback in the public history, so I wanted to check here before opening a PR.AgentTool and
single_turn. I see theAgentTooldocstring onmainnow recommendsmode='single_turn'sub-agents, which run inline in the parent's session and therefore already get compaction. The problem still affectsAgentToolonmain, which remains supported, and every 1.x release, whereAgentToolis the standard agent-as-a-tool pattern. We hit it on 1.36.1.A tested fix is ready on my fork: main...mahir-m01:adk-python:fix/agent-tool-nested-compaction
It builds the nested
Appwith the caller's token-threshold compaction settings (token_threshold,event_retention_size). The sliding-window trigger is left out, because it runs after the nested invocation finishes and the nested session is discarded when the tool returns. Building theAppalso removes this path's use of the deprecatedRunner(plugins=...)argument. Verification:mainand passes with the fix.toxon Python 3.10, 3.11, 3.12, 3.13 and 3.14: all environments pass (17404 passed in each; 17413 on 3.11).gemini-3.1-flash-lite,token_threshold=2000, a wrapped agent reading four long chapters): the wrapped agent's prompt grows to 9 contents onmain, and with the fix it is compacted at its 4th request.If the earlier rollback points to a preferred approach, for example setting the config on the nested runner's app after construction instead of building the
App, I'm happy to adapt the change for either branch.loyce-cheng commentedon Oct 4, 2026
Thanks for sharing the fix, @mahir-m01. I reviewed the current main implementation and your commit fd0f863. The configuration is lost when AgentTool creates the nested Runner, and your patch already addresses that path.
Would additional regression coverage or independent validation of your branch be useful? I can help cover no configuration, sliding-window-only configuration, preservation of the parent's configuration, and repeated or nested AgentTool calls, alongside the existing plugin-lifecycle tests. I have only reviewed the code so far; I have not independently reproduced the reported test results.
Could the maintainers also clarify whether this should target main or v1, and whether the earlier context-cache rollback affects the preferred way to configure the nested Runner? I would like to coordinate a complementary contribution with you before opening a PR.
fix(tools): prevent agent tools from overflowing the context window
mahir-m01 commentedon Oct 4, 2026
Thanks @loyce-cheng, good suggestions. I added tests for those cases:
AgentToolcalls: each nested run compacts its own history;EventsCompactionConfigstays unchanged.The PR is #7401, against
main. Happy to retarget it tov1if the maintainers prefer.mahir-m01 commentedon Oct 4, 2026
@loyce-cheng thanks again for offering to help. If you spot other gaps in this area, for example an
AgentToolnested inside anotherAgentTool, or how this interacts with the plugin lifecycle, a follow-up PR would be very welcome. Reviews and testing on #7401 are welcome too.surajksharma07 commentedon Oct 6, 2026
@mahir-m01 Reproduced on 2.11.0 with a mocked model: the same reader agent gets compacted as root but under AgentTool its request just keeps growing (1 -> 3 -> 5 -> 7 -> 9 contents) and no summary ever shows up.
Until #7401 is reviewed a workaround worth trying: add a small App plugin whose before_run_callback sets invocation_context.events_compaction_config when it's None to a copy of the App's config with compaction_interval/overlap_size set to None. AgentTool passes parent plugins to the child run by default so the child picks it up. On my side that keeps the child at 3 contents with the summary in place. Could you check whether that holds up on your vLLM/Gemma setup? It won't help if include_plugins=False.
For #7401 the open question is still why the context cache propagation (9488408) was reverted so please run the PR tests against v1 too in case maintainers want it there.
fix: compact AgentTool nested history at caller token threshold