fix(channel): preserve interrupted user context in cached turn normalization

This commit is contained in:
Chummy 2026-02-20 16:07:11 +08:00
parent e7ccb573fa
commit 7c2c370180

View file

@ -284,6 +284,18 @@ fn normalize_cached_channel_turns(turns: Vec<ChatMessage>) -> Vec<ChatMessage> {
normalized.push(turn);
expecting_user = true;
}
// Interrupted channel turns can produce consecutive user messages
// (no assistant persisted yet). Merge instead of dropping.
(false, "user") | (true, "assistant") => {
if let Some(last_turn) = normalized.last_mut() {
if !turn.content.is_empty() {
if !last_turn.content.is_empty() {
last_turn.content.push_str("\n\n");
}
last_turn.content.push_str(&turn.content);
}
}
}
_ => {}
}
}
@ -2735,6 +2747,38 @@ mod tests {
assert!(!should_skip_memory_context_entry("telegram_123_45", "hi"));
}
#[test]
fn normalize_cached_channel_turns_merges_consecutive_user_turns() {
let turns = vec![
ChatMessage::user("forwarded content"),
ChatMessage::user("summarize this"),
];
let normalized = normalize_cached_channel_turns(turns);
assert_eq!(normalized.len(), 1);
assert_eq!(normalized[0].role, "user");
assert!(normalized[0].content.contains("forwarded content"));
assert!(normalized[0].content.contains("summarize this"));
}
#[test]
fn normalize_cached_channel_turns_merges_consecutive_assistant_turns() {
let turns = vec![
ChatMessage::user("first user"),
ChatMessage::assistant("assistant part 1"),
ChatMessage::assistant("assistant part 2"),
ChatMessage::user("next user"),
];
let normalized = normalize_cached_channel_turns(turns);
assert_eq!(normalized.len(), 3);
assert_eq!(normalized[0].role, "user");
assert_eq!(normalized[1].role, "assistant");
assert_eq!(normalized[2].role, "user");
assert!(normalized[1].content.contains("assistant part 1"));
assert!(normalized[1].content.contains("assistant part 2"));
}
#[test]
fn compact_sender_history_keeps_recent_truncated_messages() {
let mut histories = HashMap::new();