Merge PR #1319
This commit is contained in:
commit
3a319bf890
2 changed files with 25 additions and 2 deletions
|
|
@ -278,15 +278,17 @@ func (al *AgentLoop) Run(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if response != "" {
|
if response != "" {
|
||||||
// Check if the message tool already sent a response during this round.
|
// Check if the message tool already sent a response to the SAME chat during this round.
|
||||||
// If so, skip publishing to avoid duplicate messages to the user.
|
// If so, skip publishing to avoid duplicate messages to the user.
|
||||||
|
// Only skip when the target chat_id matches — sending to a different chat
|
||||||
|
// (e.g. a newly created group) should not suppress the reply to the original chat.
|
||||||
// Use default agent's tools to check (message tool is shared).
|
// Use default agent's tools to check (message tool is shared).
|
||||||
alreadySent := false
|
alreadySent := false
|
||||||
defaultAgent := al.GetRegistry().GetDefaultAgent()
|
defaultAgent := al.GetRegistry().GetDefaultAgent()
|
||||||
if defaultAgent != nil {
|
if defaultAgent != nil {
|
||||||
if tool, ok := defaultAgent.Tools.Get("message"); ok {
|
if tool, ok := defaultAgent.Tools.Get("message"); ok {
|
||||||
if mt, ok := tool.(*tools.MessageTool); ok {
|
if mt, ok := tool.(*tools.MessageTool); ok {
|
||||||
alreadySent = mt.HasSentInRound()
|
alreadySent = mt.HasSentInRound() && mt.HasSentToChatID(msg.ChatID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package tools
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -11,6 +12,9 @@ type SendCallback func(channel, chatID, content string) error
|
||||||
type MessageTool struct {
|
type MessageTool struct {
|
||||||
sendCallback SendCallback
|
sendCallback SendCallback
|
||||||
sentInRound atomic.Bool // Tracks whether a message was sent in the current processing round
|
sentInRound atomic.Bool // Tracks whether a message was sent in the current processing 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 {
|
func NewMessageTool() *MessageTool {
|
||||||
|
|
@ -50,6 +54,9 @@ func (t *MessageTool) Parameters() map[string]any {
|
||||||
// Called by the agent loop at the start of each inbound message processing round.
|
// Called by the agent loop at the start of each inbound message processing round.
|
||||||
func (t *MessageTool) ResetSentInRound() {
|
func (t *MessageTool) ResetSentInRound() {
|
||||||
t.sentInRound.Store(false)
|
t.sentInRound.Store(false)
|
||||||
|
t.mu.Lock()
|
||||||
|
t.sentChatIDs = nil
|
||||||
|
t.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasSentInRound returns true if the message tool sent a message during the current round.
|
// HasSentInRound returns true if the message tool sent a message during the current round.
|
||||||
|
|
@ -57,6 +64,14 @@ func (t *MessageTool) HasSentInRound() bool {
|
||||||
return t.sentInRound.Load()
|
return t.sentInRound.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
func (t *MessageTool) SetSendCallback(callback SendCallback) {
|
||||||
t.sendCallback = callback
|
t.sendCallback = callback
|
||||||
}
|
}
|
||||||
|
|
@ -94,6 +109,12 @@ func (t *MessageTool) Execute(ctx context.Context, args map[string]any) *ToolRes
|
||||||
}
|
}
|
||||||
|
|
||||||
t.sentInRound.Store(true)
|
t.sentInRound.Store(true)
|
||||||
|
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
|
// Silent: user already received the message directly
|
||||||
return &ToolResult{
|
return &ToolResult{
|
||||||
ForLLM: fmt.Sprintf("Message sent to %s:%s", channel, chatID),
|
ForLLM: fmt.Sprintf("Message sent to %s:%s", channel, chatID),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue