fix: include tool messages in summary context (#778)
Previously, the summarizeSession function only retained user and assistant messages when generating summaries, filtering out tool and function messages. This caused conversation summaries to contain only initial user messages because assistant responses with tool calls and tool results were excluded from the summary context. This change allows 'tool' and 'function' role messages to be included in the summarization process, providing complete conversation context during summarization and preventing the loss of important assistant responses and tool interactions.
This commit is contained in:
parent
9549b0b9f6
commit
f212b12d4d
1 changed files with 41 additions and 4 deletions
|
|
@ -571,7 +571,7 @@ func (al *AgentLoop) processSystemMessage(
|
||||||
UserMessage: fmt.Sprintf("[System: %s] %s", msg.SenderID, msg.Content),
|
UserMessage: fmt.Sprintf("[System: %s] %s", msg.SenderID, msg.Content),
|
||||||
DefaultResponse: "Background task completed.",
|
DefaultResponse: "Background task completed.",
|
||||||
EnableSummary: false,
|
EnableSummary: false,
|
||||||
SendResponse: true,
|
SendResponse: false, // Prevent duplicate responses caused by system message processing
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1157,8 +1157,8 @@ func (al *AgentLoop) forceCompression(agent *AgentInstance, sessionKey string) {
|
||||||
newHistory = append(newHistory, history[len(history)-1]) // Last message
|
newHistory = append(newHistory, history[len(history)-1]) // Last message
|
||||||
|
|
||||||
// Update session
|
// Update session
|
||||||
agent.Sessions.SetHistory(sessionKey, newHistory)
|
// Update session with sanitized history to ensure tool pair integrity
|
||||||
agent.Sessions.Save(sessionKey)
|
agent.Sessions.SetHistory(sessionKey, sanitizeToolPairs(newHistory))
|
||||||
|
|
||||||
logger.WarnCF("agent", "Forced compression executed", map[string]any{
|
logger.WarnCF("agent", "Forced compression executed", map[string]any{
|
||||||
"session_key": sessionKey,
|
"session_key": sessionKey,
|
||||||
|
|
@ -1275,7 +1275,7 @@ func (al *AgentLoop) summarizeSession(agent *AgentInstance, sessionKey string) {
|
||||||
omitted := false
|
omitted := false
|
||||||
|
|
||||||
for _, m := range toSummarize {
|
for _, m := range toSummarize {
|
||||||
if m.Role != "user" && m.Role != "assistant" {
|
if m.Role != "user" && m.Role != "assistant" && m.Role != "tool" && m.Role != "function" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
msgTokens := len(m.Content) / 2
|
msgTokens := len(m.Content) / 2
|
||||||
|
|
@ -1502,3 +1502,40 @@ func extractParentPeer(msg bus.InboundMessage) *routing.RoutePeer {
|
||||||
}
|
}
|
||||||
return &routing.RoutePeer{Kind: parentKind, ID: parentID}
|
return &routing.RoutePeer{Kind: parentKind, ID: parentID}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sanitizeToolPairs removes malformed tool_call/tool_result pairs from message histories. It ensures
|
||||||
|
// that all tool_use IDs referenced in tool results have corresponding tool_use blocks in
|
||||||
|
// assistant messages, and removes orphaned tool_result messages that don't pair with a
|
||||||
|
// prior tool_call in the same session history.
|
||||||
|
func sanitizeToolPairs(messages []providers.Message) []providers.Message {
|
||||||
|
// Build map of expected tool call IDs
|
||||||
|
expectedToolCallIDs := make(map[string]bool)
|
||||||
|
var sanitized []providers.Message
|
||||||
|
|
||||||
|
for _, msg := range messages {
|
||||||
|
if msg.Role == "assistant" && len(msg.ToolCalls) > 0 {
|
||||||
|
// Record all tool call IDs in assistant messages
|
||||||
|
for _, call := range msg.ToolCalls {
|
||||||
|
expectedToolCallIDs[call.ID] = true
|
||||||
|
}
|
||||||
|
sanitized = append(sanitized, msg)
|
||||||
|
} else if msg.Role == "tool" {
|
||||||
|
// Verify this tool result has a corresponding tool call
|
||||||
|
if expectedToolCallIDs[msg.ToolCallID] {
|
||||||
|
// Valid pairing: tool result has corresponding tool call
|
||||||
|
sanitized = append(sanitized, msg)
|
||||||
|
// Remove the ID after use to avoid reuse of stale ID
|
||||||
|
delete(expectedToolCallIDs, msg.ToolCallID)
|
||||||
|
} else {
|
||||||
|
// Invalid: orphaned tool result without matching tool call
|
||||||
|
// Skip this message rather than including it
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Regular messages (user/assistant without tools/other) - always include
|
||||||
|
sanitized = append(sanitized, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sanitized
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue