From 176f405310446bb4bc971bb558ace6d75e6b4534 Mon Sep 17 00:00:00 2001 From: Bossiara13 <236771060+DmitryBykov-ISPO@users.noreply.github.com> Date: Thu, 23 Apr 2026 02:15:41 +0300 Subject: [PATCH] feat(core): pop_last_user helper on conversation history used by llm fallback to roll back the user turn when the api call fails, so the next attempt does not leave a dangling user message in the history. --- crates/jarvis-core/src/llm/history.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/crates/jarvis-core/src/llm/history.rs b/crates/jarvis-core/src/llm/history.rs index 522fc3b..7d2af8d 100644 --- a/crates/jarvis-core/src/llm/history.rs +++ b/crates/jarvis-core/src/llm/history.rs @@ -50,6 +50,14 @@ impl ConversationHistory { self.turns.clear(); } + pub fn pop_last_user(&mut self) -> Option { + if matches!(self.turns.last(), Some(m) if m.role == "user") { + self.turns.pop() + } else { + None + } + } + fn truncate(&mut self) { if self.turns.len() > self.max_turns { let drop = self.turns.len() - self.max_turns; @@ -102,6 +110,21 @@ mod tests { assert_eq!(snap[1].content, "b"); } + #[test] + fn pop_last_user_only_pops_a_trailing_user_turn() { + let mut h = ConversationHistory::new("sys", 4); + h.push_user("u1"); + h.push_assistant("a1"); + assert!(h.pop_last_user().is_none()); + h.push_user("u2"); + let popped = h.pop_last_user().expect("trailing user turn should pop"); + assert_eq!(popped.role, "user"); + assert_eq!(popped.content, "u2"); + let snap = h.snapshot(); + assert_eq!(snap.len(), 1 + 2); + assert_eq!(snap[2].content, "a1"); + } + #[test] fn clear_removes_turns_but_not_system() { let mut h = ConversationHistory::new("sys", 4);