Merge pull request #2823 from bogdanovich/fix/parent-session-tool-feedback-cleanup

fix(agent): dismiss tool feedback when outbound is skipped
This commit is contained in:
Mauro
2026-05-09 11:09:10 +02:00
committed by GitHub
2 changed files with 80 additions and 0 deletions
+10
View File
@@ -56,6 +56,16 @@ func (al *AgentLoop) PublishResponseIfNeeded(ctx context.Context, channel, chatI
}
if alreadySentToSameChat {
if al.channelManager != nil && channel != "" && chatID != "" {
dismissCtx, dismissCancel := context.WithTimeout(ctx, 5*time.Second)
al.channelManager.DismissToolFeedback(
dismissCtx,
channel,
chatID,
nil,
)
dismissCancel()
}
logger.DebugCF(
"agent",
"Skipped outbound (message tool already sent to same chat)",
+70
View File
@@ -57,6 +57,38 @@ func (f *fakeMediaChannel) SendMedia(ctx context.Context, msg bus.OutboundMediaM
return nil, nil
}
type recordingChannelManager struct {
dismissed []string
}
func (m *recordingChannelManager) GetChannel(name string) (channels.Channel, bool) {
return nil, false
}
func (m *recordingChannelManager) GetEnabledChannels() []string {
return nil
}
func (m *recordingChannelManager) InvokeTypingStop(channel, chatID string) {}
func (m *recordingChannelManager) SendMessage(ctx context.Context, msg bus.OutboundMessage) error {
return nil
}
func (m *recordingChannelManager) SendMedia(ctx context.Context, msg bus.OutboundMediaMessage) error {
return nil
}
func (m *recordingChannelManager) SendPlaceholder(ctx context.Context, channel, chatID string) bool {
return false
}
func (m *recordingChannelManager) DismissToolFeedback(
ctx context.Context, channel, chatID string, outboundCtx *bus.InboundContext,
) {
m.dismissed = append(m.dismissed, fmt.Sprintf("%s:%s", channel, chatID))
}
func newStartedTestChannelManager(
t *testing.T,
msgBus *bus.MessageBus,
@@ -214,6 +246,44 @@ func TestNewAgentLoop_DoesNotRegisterWebSearchTool_WhenNoReadyProviders(t *testi
}
}
func TestPublishResponseIfNeeded_DismissesToolFeedbackWhenMessageToolAlreadySent(t *testing.T) {
al, msgBus, provider, sessions, cleanup := newTestAgentLoop(t)
defer cleanup()
_ = msgBus
_ = provider
_ = sessions
cm := &recordingChannelManager{}
al.channelManager = cm
defaultAgent := al.registry.GetDefaultAgent()
if defaultAgent == nil {
t.Fatal("expected default agent")
}
mt := tools.NewMessageTool()
mt.SetSendCallback(func(ctx context.Context, channel, chatID, content, replyToMessageID string) error {
return nil
})
defaultAgent.Tools.Register(mt)
result := mt.Execute(
tools.WithToolSessionContext(context.Background(), "main", "session-1", nil),
map[string]any{
"content": "ack",
"channel": "telegram",
"chat_id": "-100123",
},
)
if result == nil || result.IsError {
t.Fatalf("message tool execute failed: %+v", result)
}
al.PublishResponseIfNeeded(context.Background(), "telegram", "-100123", "session-1", "final reply")
if got := cm.dismissed; len(got) != 1 || got[0] != "telegram:-100123" {
t.Fatalf("dismissed = %v, want [telegram:-100123]", got)
}
}
func TestProcessMessage_IncludesCurrentSenderInDynamicContext(t *testing.T) {
tmpDir, err := os.MkdirTemp("", "agent-test-*")
if err != nil {