|
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> |
|---|
|
|
| navi/core/agent.py |
|---|
| navi/core/compressor.py |
|---|
| tests/unit/core/test_agent.py |
|---|
| tests/unit/core/test_compressor.py |
|---|