fix: also support the .continue edge case for session crashing checkpointing

This commit is contained in:
2026-08-27 12:55:26 -06:00
parent 3d640b9efa
commit ee45e42013
+19 -1
View File
@@ -180,7 +180,7 @@ impl Session {
pub fn has_interrupted_error_checkpoint(&self) -> bool { pub fn has_interrupted_error_checkpoint(&self) -> bool {
self.messages.last().is_some_and(|message| { self.messages.last().is_some_and(|message| {
message.role.is_assistant() message.role.is_assistant()
&& matches!(&message.content, MessageContent::Text(text) if text == INTERRUPTED_RESPONSE_TEXT) && matches!(&message.content, MessageContent::Text(text) if text.ends_with(INTERRUPTED_RESPONSE_TEXT))
}) })
} }
@@ -998,6 +998,24 @@ mod tests {
assert!(session.has_interrupted_error_checkpoint()); assert!(session.has_interrupted_error_checkpoint());
} }
#[test]
fn session_detects_checkpoint_appended_by_crashed_continue_turn() {
// A crash during a `.continue` turn appends the sentinel to the
// previous assistant text (add_message's continue_output branch)
// instead of pushing a standalone checkpoint message.
let mut session = Session::default();
session.messages.push(Message::new(
MessageRole::User,
MessageContent::Text("hi".to_string()),
));
session.messages.push(Message::new(
MessageRole::Assistant,
MessageContent::Text(format!("partial answer{INTERRUPTED_RESPONSE_TEXT}")),
));
assert!(session.has_interrupted_error_checkpoint());
}
#[test] #[test]
fn session_interrupted_checkpoint_with_tool_calls_survives_yaml_round_trip() { fn session_interrupted_checkpoint_with_tool_calls_survives_yaml_round_trip() {
let mut session = Session::default(); let mut session = Session::default();