|
1 | 1 | use crate::api::Message; |
2 | 2 |
|
| 3 | +const MAX_MESSAGES: usize = 50; |
| 4 | + |
3 | 5 | /// Manages conversation history for the REPL |
4 | 6 | pub struct ConversationHistory { |
5 | 7 | messages: Vec<Message>, |
@@ -67,16 +69,26 @@ Your goal is to help users with coding tasks efficiently and accurately."#, |
67 | 69 | } |
68 | 70 | } |
69 | 71 |
|
| 72 | + fn trim_if_needed(&mut self) { |
| 73 | + if self.messages.len() > MAX_MESSAGES { |
| 74 | + let remove_count = self.messages.len() - MAX_MESSAGES; |
| 75 | + self.messages.drain(0..remove_count); |
| 76 | + } |
| 77 | + } |
| 78 | + |
70 | 79 | pub fn add_user_message(&mut self, content: String) { |
71 | 80 | self.messages.push(Message::user(content)); |
| 81 | + self.trim_if_needed(); |
72 | 82 | } |
73 | 83 |
|
74 | 84 | pub fn add_assistant_with_blocks(&mut self, blocks: Vec<crate::api::MessageContentBlock>) { |
75 | 85 | self.messages.push(Message::assistant_with_blocks(blocks)); |
| 86 | + self.trim_if_needed(); |
76 | 87 | } |
77 | 88 |
|
78 | 89 | pub fn add_tool_results(&mut self, results: Vec<crate::api::MessageContentBlock>) { |
79 | 90 | self.messages.push(Message::user_with_tool_results(results)); |
| 91 | + self.trim_if_needed(); |
80 | 92 | } |
81 | 93 |
|
82 | 94 | pub fn messages(&self) -> &[Message] { |
@@ -105,3 +117,49 @@ impl Default for ConversationHistory { |
105 | 117 | Self::new() |
106 | 118 | } |
107 | 119 | } |
| 120 | + |
| 121 | +#[cfg(test)] |
| 122 | +mod tests { |
| 123 | + use super::*; |
| 124 | + use crate::api::MessageContentBlock; |
| 125 | + |
| 126 | + #[test] |
| 127 | + fn test_message_limit_trimming() { |
| 128 | + let mut history = ConversationHistory::new(); |
| 129 | + |
| 130 | + for i in 0..60 { |
| 131 | + history.add_user_message(format!("Message {}", i)); |
| 132 | + } |
| 133 | + |
| 134 | + assert_eq!(history.messages().len(), 50); |
| 135 | + |
| 136 | + if let crate::api::MessageContent::Text { content } = &history.messages()[0].content { |
| 137 | + assert_eq!(content, "Message 10"); |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + #[test] |
| 142 | + fn test_message_limit_with_blocks() { |
| 143 | + let mut history = ConversationHistory::new(); |
| 144 | + |
| 145 | + for i in 0..30 { |
| 146 | + history.add_user_message(format!("User {}", i)); |
| 147 | + history.add_assistant_with_blocks(vec![ |
| 148 | + MessageContentBlock::Text { text: format!("Assistant {}", i) } |
| 149 | + ]); |
| 150 | + } |
| 151 | + |
| 152 | + assert_eq!(history.messages().len(), 50); |
| 153 | + } |
| 154 | + |
| 155 | + #[test] |
| 156 | + fn test_no_trimming_below_limit() { |
| 157 | + let mut history = ConversationHistory::new(); |
| 158 | + |
| 159 | + for i in 0..20 { |
| 160 | + history.add_user_message(format!("Message {}", i)); |
| 161 | + } |
| 162 | + |
| 163 | + assert_eq!(history.messages().len(), 20); |
| 164 | + } |
| 165 | +} |
0 commit comments