# OpenAI context blew up mid-task: the agent-loop compaction fix

## The symptom

An agent works for dozens of turns, then `400 context_length_exceeded` kills the run near the end, exactly when the most context has accumulated. Retrying the same request fails identically. The task was fine; the history outgrew the window.

## Confirm the cause

Log token counts per turn. The growth is always one of:

1. **Unbounded history replay.** Every turn resends all previous turns. Growth is linear in turns and the failure arrives suddenly at the window edge.
2. **Tool results accumulating.** Big tool outputs (file reads, search results, command output) appended every turn. A few large results dominate the count.
3. **Hidden token costs.** Tool definitions, images, and structured output schemas all consume input tokens. The text you see is not the whole bill.

## The fix

1. **Pre-call guard.** Count tokens before every call (tiktoken on the exact message list). If the count exceeds 80 percent of the model's window, compact before sending instead of letting the API reject it.
2. **Compact, do not just truncate.** Summarize the conversation so far into a short brief (goal, key decisions, current state, open items) and continue from the brief plus recent turns. Naive truncation loses the goal; summarization keeps it.
3. **Cap tool result size.** Truncate or summarize large tool outputs before appending them. A 50k-token file read should enter history as a summary, not verbatim.
4. **Sliding window as backstop.** Keep the instructions plus the last N turns always; compact everything older.

## Verify the fix

Run the longest task you have and confirm token counts stay flat-ish after compaction kicks in, with no 400s in the logs. A 400 in production now means the guard has a hole, not that the task was too long.