Skip to content

Tool-pair summarization is too aggressive for large context models #7415

@angiejones

Description

@angiejones

Problem

Tool-pair summarization (maybe_summarize_tool_pair) fires after 10 tool calls (GOOSE_TOOL_CALL_CUTOFF default) regardless of context window size or token usage. On a 1M context model at 7% usage, it still summarizes one tool pair every turn — destroying detailed tool outputs the user has plenty of room for.

Three issues:

1. Fixed cutoff ignores context window size

The default of 10 was reasonable for 128K models but is far too aggressive for 200K-1M models. A session doing code editing hits 10 tool calls in minutes.

2. One-per-turn cadence

Once the cutoff is exceeded, it summarizes the oldest tool pair on every subsequent turn indefinitely. A 400-message session triggers hundreds of summarization calls.

3. Summaries inject as Role::User with no framing

The summary is set to Role::User with MessageMetadata::agent_only(). The agent interprets it as something the user said. When a summary describes a past error (e.g., "A shell command was executed to check if gh was installed, but it was not found"), the agent responds to it as a current problem — even if it was resolved 200 messages ago. Users have to repeatedly tell goose to ignore its own summaries.

Observed impact

In multiple 200-400 message sessions on Claude Opus 4.6 (1M context):

  • Compaction summaries about resolved errors kept resurfacing as "ghost" messages
  • Agent repeatedly responded to stale summaries instead of the user's actual message
  • Users had to say "that's the compaction message, ignore it" multiple times per session

Suggested fixes

  1. Scale cutoff with context window — e.g., context_limit / 10_000 clamped to 10-100
  2. Batch summarization — when cutoff is exceeded, summarize N oldest pairs at once, then don't fire again until the cutoff is exceeded again (instead of one-per-turn forever)
  3. Fix summary framing — either don't use Role::User, or wrap summaries with clear framing so the agent knows it's a historical record, not a current user message

Workaround

# In config or environment
GOOSE_TOOL_CALL_CUTOFF: 200

Related

References

  • crates/goose/src/context_mgmt/mod.rstool_id_to_summarize(), summarize_tool_call()
  • crates/goose/src/agents/agent.rstool_call_cut_off, maybe_summarize_tool_pair usage
  • Introduced in Summarize old tool calls #6119 (2026-01-28)

Metadata

Metadata

Labels

p1Priority 1 - High (supports roadmap)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions