compressor: split in-flight turn in midturn mode + flush incrementally
Two related fixes for long autonomous turns in planning profiles (navi_code):

A1 — partition_messages turn-based branch held the in-flight (current) turn
verbatim when turns > keep_recent, so midturn compression was shallow
(e.g. 150 -> 141 messages). Now, when keep_recent_messages is set, the
in-flight turn is split like partition_current_turn_messages: head (user
request) + tail (recent tool steps) kept, middle summarized. The adaptive
swap is disabled in midturn mode (it could move the in-flight turn into
old_turns and summarize the current request whole). First branch
(len(turns) <= keep_recent) is untouched, so locked-in midturn tests hold.

B1 — agent.run_stream had no try/finally around the for-loop, so an
asyncio.CancelledError (server restart/shutdown) unwound the stack with no
flush: all in-memory turn messages (sequence_number < 0) were lost, only the
user message survived. Add incremental save() after planning, after the
assistant tool-call decision, and after each tool result, so a crash loses at
most the single in-flight tool call, not the whole turn. B2 (try/except
safety-net) was dropped: B1 leaves no window where an append is unsaved.

Tests: midturn split with many turns (partition + compress_session), and
crash/cancel persistence via a snapshot session store that mirrors the DB
boundary.

Co-Authored-By: Claude <noreply@anthropic.com>
1 parent b8bb30d commit c65c6648b9241cadd5c78191fbfc27aa46c58873
@Eugene Sukhodolskiy Eugene Sukhodolskiy authored 1 day ago
Showing 4 changed files
View
navi/core/agent.py
View
navi/core/compressor.py
View
tests/unit/core/test_agent.py
View
tests/unit/core/test_compressor.py