@@ -275,13 +275,31 @@ func (s *Session) GetMessages(a *agent.Agent) []chat.Message {
275275 }
276276 }
277277
278- trimmed := trimMessages (messages )
278+ maxItems := a .NumHistoryItems ()
279+ if maxItems <= 0 {
280+ maxItems = maxMessages
281+ }
282+
283+ trimmed := trimMessages (messages , maxItems )
284+
285+ systemCount := 0
286+ conversationCount := 0
287+ for i := range trimmed {
288+ if trimmed [i ].Role == chat .MessageRoleSystem {
289+ systemCount ++
290+ } else {
291+ conversationCount ++
292+ }
293+ }
279294
280295 slog .Debug ("Retrieved messages for agent" ,
281296 "agent" , a .Name (),
282297 "session_id" , s .ID ,
283298 "total_messages" , len (messages ),
284- "trimmed_messages" , len (trimmed ))
299+ "trimmed_total" , len (trimmed ),
300+ "system_messages" , systemCount ,
301+ "conversation_messages" , conversationCount ,
302+ "max_history_items" , maxItems )
285303
286304 return trimmed
287305}
@@ -304,32 +322,51 @@ func (s *Session) GetMostRecentAgentFilename() string {
304322}
305323
306324// trimMessages ensures we don't exceed the maximum number of messages while maintaining
307- // consistency between assistant messages and their tool call results
308- func trimMessages (messages []chat.Message ) []chat.Message {
309- if len (messages ) <= maxMessages {
325+ // consistency between assistant messages and their tool call results.
326+ // System messages are always preserved and not counted against the limit.
327+ func trimMessages (messages []chat.Message , maxItems int ) []chat.Message {
328+ // Separate system messages from conversation messages
329+ var systemMessages []chat.Message
330+ var conversationMessages []chat.Message
331+
332+ for i := range messages {
333+ if messages [i ].Role == chat .MessageRoleSystem {
334+ systemMessages = append (systemMessages , messages [i ])
335+ } else {
336+ conversationMessages = append (conversationMessages , messages [i ])
337+ }
338+ }
339+
340+ // If conversation messages fit within limit, return all messages
341+ if len (conversationMessages ) <= maxItems {
310342 return messages
311343 }
312344
313345 // Keep track of tool call IDs that need to be removed
314346 toolCallsToRemove := make (map [string ]bool )
315347
316- // Calculate how many messages we need to remove
317- toRemove := len (messages ) - maxMessages
348+ // Calculate how many conversation messages we need to remove
349+ toRemove := len (conversationMessages ) - maxItems
318350
319351 // Start from the beginning (oldest messages)
320352 for i := range toRemove {
321353 // If this is an assistant message with tool calls, mark them for removal
322- if messages [i ].Role == chat .MessageRoleAssistant {
323- for _ , toolCall := range messages [i ].ToolCalls {
354+ if conversationMessages [i ].Role == chat .MessageRoleAssistant {
355+ for _ , toolCall := range conversationMessages [i ].ToolCalls {
324356 toolCallsToRemove [toolCall .ID ] = true
325357 }
326358 }
327359 }
328360
329- // Filter messages keeping only those we want to keep
330- result := make ([]chat.Message , 0 , maxMessages )
331- for i := toRemove ; i < len (messages ); i ++ {
332- msg := messages [i ]
361+ // Combine system messages with trimmed conversation messages
362+ result := make ([]chat.Message , 0 , len (systemMessages )+ maxItems )
363+
364+ // Add all system messages first
365+ result = append (result , systemMessages ... )
366+
367+ // Add the most recent conversation messages
368+ for i := toRemove ; i < len (conversationMessages ); i ++ {
369+ msg := conversationMessages [i ]
333370
334371 // Skip tool messages that correspond to removed assistant messages
335372 if msg .Role == chat .MessageRoleTool && toolCallsToRemove [msg .ToolCallID ] {
0 commit comments