feat: preserve last assistant message during compaction

When context window compaction occurs, the last assistant message is now
preserved in addition to the system prompt, README, and summary. This
improves continuity after compaction by keeping the LLM's most recent
response, which often contains important context about what was just
done or what comes next.

New message order after compaction:
[System Prompt] -> [README/AGENTS.md] -> [ACD Stub?] -> [Summary] -> [Last Assistant] -> [Latest User?]

Changes:
- Add last_assistant_message field to PreservedMessages struct
- Modify extract_preserved_messages() to find last assistant message
- Modify reset_with_summary_and_stub() to include last assistant message
- Add comprehensive integration tests using MockProvider

Tests cover edge cases:
- No assistant message exists
- Tool-call-only assistant messages (still preserved)
- Multiple assistant messages (only last one preserved)
- No trailing user message
This commit is contained in:
Dhanji R. Prasanna
2026-01-23 09:54:03 +05:30
parent dfdc21c3cf
commit 5d0d532b47
2 changed files with 411 additions and 0 deletions

View File

@@ -298,6 +298,11 @@ Format this as a detailed but concise summary that can be used to resume the con
format!("Previous conversation summary:\n\n{}", summary),
));
// Add the last assistant message if present (preserves continuity)
if let Some(assistant_msg) = preserved.last_assistant_message {
self.add_message(assistant_msg);
}
// Add the latest user message if provided
if let Some(user_msg) = latest_user_message {
self.add_message(Message::new(MessageRole::User, user_msg));
@@ -326,9 +331,18 @@ Format this as a detailed but concise summary that can be used to resume the con
}
});
// Find the last assistant message in the conversation
let last_assistant_message = self
.conversation_history
.iter()
.rev()
.find(|m| matches!(m.role, MessageRole::Assistant))
.cloned();
PreservedMessages {
system_prompt,
readme,
last_assistant_message,
}
}
@@ -725,6 +739,7 @@ Format this as a detailed but concise summary that can be used to resume the con
struct PreservedMessages {
system_prompt: Option<Message>,
readme: Option<Message>,
last_assistant_message: Option<Message>,
}
impl ThinResult {