Skip to content

Context integrity: pair-safe truncation, persisted compaction, team-loop result budgets #114

Description

@hellodk

Problem

  1. context-manager.ts fitMessages drops "oldest middle" messages without regard to tool-call pairing — splitting an assistant tool_use from its tool_result hard-errors on Anthropic-style APIs (agent-controller.ts:577-637 consumes this every iteration).
  2. Compaction output is never persisted back into history: fitWithSummary runs from full history EVERY iteration → repeated summarize LLM calls, unbounded growth within a turn.
  3. tool-calling-loop.ts pushes FULL result.output into history (:284-289) while truncateForMetrics truncates only for metrics — one large read_file blows small local-model windows; that loop has MAX_ITERATIONS=4 and no fitting at all.

Acceptance criteria

  • Truncation is pair-safe: an assistant message containing tool_use blocks is only dropped together with its corresponding tool_result messages (atomic groups)
  • Compaction result is persisted: once a turn's history is compacted+summarized, subsequent iterations reuse the compacted form (no re-summarize per iteration)
  • TeamLoop/tool-loop truncates oversized tool outputs before history insertion (budget-aware, e.g. 4k chars default with head+tail preservation)

Tests required

  • Failing test first: dropping range that would split a pair instead extends the drop to keep pairs atomic
  • Failing test first: second iteration with unchanged history performs zero additional summarize LLM calls
  • Failing test first: 100KB tool result enters team-loop history truncated to budget with ellipsis marker

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priority — next sprintbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions