Skip to content

fix: filter thinking parts from agenttool result#696

Open
dmora wants to merge 1 commit intogoogle:mainfrom
dmora:fix/agenttool-strip-thought-parts
Open

fix: filter thinking parts from agenttool result#696
dmora wants to merge 1 commit intogoogle:mainfrom
dmora:fix/agenttool-strip-thought-parts

Conversation

@dmora
Copy link
Copy Markdown
Contributor

@dmora dmora commented Apr 1, 2026

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

2. Or, if no issue exists, describe the change:

Problem:
agenttool.Run() collects all Part.Text from the sub-agent's final response without checking Part.Thought. When thinking models (Gemini 2.5/3 with IncludeThoughts: true) are used as sub-agents, their internal reasoning tokens leak into the tool result map[string]any that the calling agent sees.

This is the same class of bug fixed for remoteagent in #655.

Compare agenttool.Run() (before this fix):

for _, part := range lastContent.Parts {
    if part != nil && part.Text != "" {
        textParts = append(textParts, part.Text)
    }
}

With genai.GenerateContentResponse.Text() which correctly filters thoughts:

if part.Text != "" {
    if part.Thought {
        continue
    }
    texts = append(texts, part.Text)
}

Solution:
Add && !part.Thought to the text extraction loop in agenttool.Run(), matching the genai.Text() behavior.

Testing Plan

Unit Tests:

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

New tests added:

  • TestAgentTool_Run_FiltersThoughtParts — mixed thought + text parts, with edge case {Text: "", Thought: true}, verifies only non-thought text is returned
  • TestAgentTool_Run_AllThoughtPartsReturnsEmpty — all-thought response returns empty map
  • TestAgentTool_Run_FiltersThoughtParts_WithOutputSchema — thought parts mixed with JSON output, verifies clean unmarshalling when OutputSchema is set
$ go test ./tool/agenttool/ -v
--- PASS: TestAgentTool_Declaration (0.00s)
--- PASS: TestAgentTool_DeclarationWithoutSchema (0.00s)
--- PASS: TestAgentTool_Run_InputValidation (0.00s)
--- PASS: TestAgentTool_Run_OutputValidation (0.00s)
--- PASS: TestAgentTool_Run_Successful (0.00s)
--- PASS: TestAgentTool_Run_WithoutSchema (0.00s)
--- PASS: TestAgentTool_Run_FiltersThoughtParts (0.00s)
--- PASS: TestAgentTool_Run_AllThoughtPartsReturnsEmpty (0.00s)
--- PASS: TestAgentTool_Run_FiltersThoughtParts_WithOutputSchema (0.00s)
--- PASS: TestAgentTool_Run_EmptyModelResponse (0.00s)
--- PASS: TestAgentTool_Run_SkipSummarization (0.00s)
PASS
ok  google.golang.org/adk/tool/agenttool  0.278s

Manual End-to-End (E2E) Tests:

Verified locally with a real Gemini 2.5 Flash model with ThinkingConfig{IncludeThoughts: true, ThinkingBudget: 2048}. The sub-agent was asked "What is 7 * 8?" and the tool result contained only "56" — no thinking tokens leaked through.

Also verified that reverting the fix causes the mock test to fail with thinking text concatenated into the result:

- "56"
+ "The user is asking about multiplication. 7 times 8 equals 56.\n56\nLet me double-check: 7 * 8 = 56. Yes, that's correct."

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.

Additional context

Aligned with how genai.GenerateContentResponse.Text() handles thought parts in types.go.

Generated with Claude Code

agenttool.Run() collects all Part.Text without checking Part.Thought,
leaking thinking tokens into the tool result map. This mirrors the fix
applied to remoteagent in google#655 and aligns with genai.Text() behavior.
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.

agenttool: Run() leaks thinking parts into tool result

1 participant