|
compression: fix auto-compress no-op on few-huge-messages + honest status
Root cause: the compression gate (should_compress) measures tokens, but the partition measures message/turn count, and CompressionStarted was emitted before the attempt. For navi_code's "few very large messages" shape (one big file read = 1 user + assistant + 1 huge tool result, 66k tokens in 3 messages) the gate fired, the UI showed "compression", but partition returned to_summarize=[] -> compress_context None -> nothing shrank. The agent kept going until the window overflowed. It wasn't running "during" compression — there was no compression, just a no-op the user mistook for one. A. Per-message head/tail truncation in context_builder.build(): oversized tool/assistant messages (over context_message_token_budget, 0=num_ctx//6) are capped head+marker+tail in the LLM view only (model_copy — stored history and reloads are never affected). A single huge tool result can no longer alone blow the window; user/system messages are never truncated. B. Token-budget hard-truncate fallback in compress_session: when partition no-ops but tokens exceed the threshold, drop oldest turns to num_ctx*0.5. _hard_truncate is now token-aware (was a fixed message-count floor that no-oped on <=6 messages even when huge). New would_compress() predicts compress_session's real outcome with no LLM call. C. Honest CompressionStarted: _compression_events_midturn/_preturn emit it only after would_compress() confirms the partition (or token-budget fallback) can actually shrink the stored context — no more "compression" status with no ContextCompressed to follow. Bonus: post-turn CompressionWorker now passes keep_recent_messages= max(12, context_keep_recent*2), matching the midturn path, so a single long autonomous turn compresses post-turn too (was always a no-op). Tests (+14): would_compress agreement, token-budget fallback, token-aware hard_truncate, build() truncation (preserves user, no mutation, head+tail), agent no-CompressionStarted-when-nothing-to-compress, worker single-long-turn. Co-Authored-By: Claude <noreply@anthropic.com> |
|---|
|
|
| navi/config.py |
|---|
| navi/core/agent.py |
|---|
| navi/core/compressor.py |
|---|
| navi/core/context_builder.py |
|---|
| navi/workers/compressor.py |
|---|
| tests/unit/core/test_agent.py |
|---|
| tests/unit/core/test_compressor.py |
|---|
| tests/unit/core/test_context_builder.py |
|---|
| tests/unit/workers/test_compression_worker.py 0 → 100644 |
|---|