Skip to content

[bug] agenttool SkipSummarization terminates the parent agent loop #892

@effati

Description

@effati

Required information

Describe the bug:

When an agenttool is configured with SkipSummarization: true, the parent agent's flow loop terminates immediately after the tool returns. The parent never makes a follow-up LLM call to process the tool result.

The root cause: agenttool.Run() sets ctx.Actions().SkipSummarization = true on the tool context (line 129 in tool/agenttool/agent_tool.go). This propagates to the function response event. Then in base_flow.go, IsFinalResponse() returns true when Actions.SkipSummarization is set, causing the outer for loop to exit.

The flag conflates two concerns:

  1. "Don't LLM-summarize the sub-agent output" (what the name suggests)
  2. "This is a terminal event, stop the parent loop" (the actual effect via IsFinalResponse())

Steps to reproduce:

  1. Create a parent agent with tools including an agenttool
  2. Configure the agenttool with &agenttool.Config{SkipSummarization: true}
  3. Have the parent call the agenttool as part of a multi-step workflow (parent expects to act on the result)
  4. The parent streams text, calls the agenttool, tool executes successfully, then the session ends silently with no further LLM call
subAgent, _ := llmagent.New(llmagent.Config{...})
subTool := agenttool.New(subAgent, &agenttool.Config{SkipSummarization: true})

parentAgent, _ := llmagent.New(llmagent.Config{
    Tools: []tool.Tool{subTool, otherTools...},
    // parent is instructed to call subTool, then use the result to call otherTools
})

Expected behavior:

After the agenttool returns, the parent agent should make another LLM call with the tool result in context, allowing it to continue its workflow (e.g., call other tools with the sub-agent's output).

Observed behavior:

The parent's flow loop exits. No error is returned. The session ends as if the agent completed normally. In a streaming setup this looks like the response just stops mid-conversation after the tool call.

Environment details:

  • ADK Library Version: v0.2.0
  • OS: macOS / Linux
  • Go Version: 1.24

Model information:

  • claude-sonnet-4-6 (not model-specific, the bug is in the runner loop)

Optional information

Regression: Unknown, likely present since SkipSummarization was added to IsFinalResponse().

How often has this issue occurred?: Always (100%)

Minimal reproduction code:

The relevant code path in tool/agenttool/agent_tool.go:

// Line 127-131
if t.skipSummarization {
    if actions := toolCtx.Actions(); actions != nil {
        actions.SkipSummarization = true
    }
}

Then in session/session.go:

func (e *Event) IsFinalResponse() bool {
    if (e.Actions.SkipSummarization) || len(e.LongRunningToolIDs) > 0 {
        return true  // terminates the parent loop
    }
    return !hasFunctionCalls(&e.LLMResponse) && ...
}

And in internal/llminternal/base_flow.go:

func (f *Flow) Run(ctx agent.InvocationContext) iter.Seq2[*session.Event, error] {
    return func(yield func(*session.Event, error) bool) {
        for {
            for ev, err := range f.runOneStep(ctx) { ... }
            if lastEvent == nil || lastEvent.IsFinalResponse() {
                return  // parent stops here
            }
        }
    }
}

Suggested fix: Decouple the two behaviors. SkipSummarization should only control whether the sub-agent output gets LLM-summarized before being returned. It should not affect IsFinalResponse(). The function response event from a tool call should never be considered "final" on its own since the parent still needs to process it.

Metadata

Metadata

Labels

bugSomething isn't working

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions