Skip to content

[BUG] Ensure context truncation always makes measurable progress #1254

Description

@zoomote

Problem

Fallback context truncation can report success without reducing context. With a short history such as an assistant tool_use followed by one oversized user tool_result, the current 50% message calculation rounds down to zero removable messages. Zoo Code still emits a truncation event, leaves the oversized history unchanged, and retries into the same failure indefinitely.

The reproduced signal is Context Truncated with 0 messages removed while the recalculated context remains above the allowed input budget.

Scope

Make context recovery monotonic and bounded.

  • Treat recovery as successful only when the recalculated model-facing token count decreases.
  • When message-level truncation cannot remove a valid turn/tool pair, shrink the largest eligible textual tool-result block while preserving its tool identifier and result shape.
  • Recount after degradation and verify the result fits the target or makes measurable progress.
  • If protected content makes the target impossible, return a distinct actionable error instead of emitting another successful truncation event or retrying indefinitely.
  • Keep retries bounded.

Acceptance criteria

  • One-to-four-message histories cannot emit a successful zero-progress truncation result.
  • An oversized tool_use/tool_result pair is reduced without orphaning either side.
  • newContextTokensAfterTruncation is lower than the pre-recovery count whenever recovery reports success.
  • An impossible budget produces a controlled error and does not loop.
  • Focused tests reproduce the 4 MB tool-result case and verify bounded recovery.

Out of scope

  • Preventing individual tools from producing oversized results
  • Condensation-input sanitization
  • Full-output spill files or resource references
  • Aggregate budgeting across parallel tool calls

Estimate

1 story point. Independently mergeable and non-stacked.

Parent tracking issue: #648

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions