fix(tools): track all sent chat_ids to avoid missed duplicate suppression
Replace single sentChatID (atomic.Value) with a set of chat_ids so that when the message tool sends to multiple chats in one round, the final reply is correctly suppressed for any chat that was already sent to.
This commit is contained in:
parent
5fb488ca31
commit
f02c3a35ed
2 changed files with 21 additions and 9 deletions
|
|
@ -346,7 +346,7 @@ func (al *AgentLoop) Run(ctx context.Context) error {
|
|||
if defaultAgent != nil {
|
||||
if tool, ok := defaultAgent.Tools.Get("message"); ok {
|
||||
if mt, ok := tool.(*tools.MessageTool); ok {
|
||||
alreadySent = mt.HasSentInRound() && mt.SentToChatID() == msg.ChatID
|
||||
alreadySent = mt.HasSentInRound() && mt.HasSentToChatID(msg.ChatID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package tools
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
|
|
@ -11,7 +12,9 @@ type SendCallback func(channel, chatID, content string) error
|
|||
type MessageTool struct {
|
||||
sendCallback SendCallback
|
||||
sentInRound atomic.Bool // Tracks whether a message was sent in the current processing round
|
||||
sentChatID atomic.Value // Tracks the chat_id that the message was sent to in the current round
|
||||
|
||||
mu sync.Mutex // protects sentChatIDs
|
||||
sentChatIDs map[string]struct{} // All chat_ids the message tool sent to in the current round
|
||||
}
|
||||
|
||||
func NewMessageTool() *MessageTool {
|
||||
|
|
@ -51,7 +54,9 @@ func (t *MessageTool) Parameters() map[string]any {
|
|||
// Called by the agent loop at the start of each inbound message processing round.
|
||||
func (t *MessageTool) ResetSentInRound() {
|
||||
t.sentInRound.Store(false)
|
||||
t.sentChatID.Store("")
|
||||
t.mu.Lock()
|
||||
t.sentChatIDs = nil
|
||||
t.mu.Unlock()
|
||||
}
|
||||
|
||||
// HasSentInRound returns true if the message tool sent a message during the current round.
|
||||
|
|
@ -59,10 +64,12 @@ func (t *MessageTool) HasSentInRound() bool {
|
|||
return t.sentInRound.Load()
|
||||
}
|
||||
|
||||
// SentToChatID returns the chat_id that the message was sent to in the current round.
|
||||
func (t *MessageTool) SentToChatID() string {
|
||||
v, _ := t.sentChatID.Load().(string)
|
||||
return v
|
||||
// HasSentToChatID returns true if the message tool sent to the given chat_id in this round.
|
||||
func (t *MessageTool) HasSentToChatID(chatID string) bool {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
_, ok := t.sentChatIDs[chatID]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (t *MessageTool) SetSendCallback(callback SendCallback) {
|
||||
|
|
@ -102,7 +109,12 @@ func (t *MessageTool) Execute(ctx context.Context, args map[string]any) *ToolRes
|
|||
}
|
||||
|
||||
t.sentInRound.Store(true)
|
||||
t.sentChatID.Store(chatID)
|
||||
t.mu.Lock()
|
||||
if t.sentChatIDs == nil {
|
||||
t.sentChatIDs = make(map[string]struct{})
|
||||
}
|
||||
t.sentChatIDs[chatID] = struct{}{}
|
||||
t.mu.Unlock()
|
||||
// Silent: user already received the message directly
|
||||
return &ToolResult{
|
||||
ForLLM: fmt.Sprintf("Message sent to %s:%s", channel, chatID),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue