From aea466b2b98e407075bc6331ab7973e1e7e36ee6 Mon Sep 17 00:00:00 2001 From: Anton Bogdanovich <27antonb@gmail.com> Date: Wed, 6 May 2026 17:36:21 -0700 Subject: [PATCH] fix(agents): dismiss subagent topic feedback --- pkg/agent/subturn.go | 2 +- pkg/channels/manager.go | 20 +++++++++++++------- pkg/channels/manager_test.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/pkg/agent/subturn.go b/pkg/agent/subturn.go index fa9b356bd..e37da9a9e 100644 --- a/pkg/agent/subturn.go +++ b/pkg/agent/subturn.go @@ -453,7 +453,7 @@ func spawnSubTurn( dismissCtx, childTS.channel, childTS.chatID, - childTS.opts.InboundContext, + childTS.opts.Dispatch.InboundContext, childID, ) dismissCancel() diff --git a/pkg/channels/manager.go b/pkg/channels/manager.go index 2c648842d..e88241d0b 100644 --- a/pkg/channels/manager.go +++ b/pkg/channels/manager.go @@ -218,17 +218,23 @@ func dismissTrackedToolFeedbackMessageForSession( dismissTrackedToolFeedbackMessage(ctx, ch, chatID, outboundCtx) return } - trackedChatID := resolveOutboundChatID(ch, chatID, outboundCtx) - if trackedChatID == "" { - return - } - trackedChatID += "#session:" + sessionKey + resolvedChatID := resolveOutboundChatID(ch, chatID, outboundCtx) if cleaner, ok := ch.(toolFeedbackMessageCleaner); ok { - cleaner.DismissToolFeedbackMessage(ctx, trackedChatID) + for _, candidate := range candidateChatIDs(chatID, resolvedChatID) { + if candidate == "" { + continue + } + cleaner.DismissToolFeedbackMessage(ctx, candidate+"#session:"+sessionKey) + } return } if tracker, ok := ch.(toolFeedbackMessageTracker); ok { - tracker.ClearToolFeedbackMessage(trackedChatID) + for _, candidate := range candidateChatIDs(chatID, resolvedChatID) { + if candidate == "" { + continue + } + tracker.ClearToolFeedbackMessage(candidate + "#session:" + sessionKey) + } } } diff --git a/pkg/channels/manager_test.go b/pkg/channels/manager_test.go index 5aeabc888..f902484f3 100644 --- a/pkg/channels/manager_test.go +++ b/pkg/channels/manager_test.go @@ -898,6 +898,7 @@ type mockMessageEditor struct { recordedContent string clearedChatID string dismissedChatID string + dismissedChatIDs []string } func (m *mockMessageEditor) EditMessage(ctx context.Context, chatID, messageID, content string) error { @@ -916,6 +917,7 @@ func (m *mockMessageEditor) ClearToolFeedbackMessage(chatID string) { func (m *mockMessageEditor) DismissToolFeedbackMessage(_ context.Context, chatID string) { m.dismissedChatID = chatID + m.dismissedChatIDs = append(m.dismissedChatIDs, chatID) } func (m *mockMessageEditor) FinalizeToolFeedbackMessage( @@ -958,6 +960,34 @@ func (m *mockResolvedToolFeedbackEditor) ToolFeedbackMessageChatID( return chatID } +func TestDismissToolFeedbackForSession_UsesResolvedTopicScopedKey(t *testing.T) { + m := newTestManager() + ch := &mockResolvedToolFeedbackEditor{ + resolveChatIDFn: func(chatID string, outboundCtx *bus.InboundContext) string { + if chatID != "-100123" { + t.Fatalf("chatID = %q, want -100123", chatID) + } + if outboundCtx == nil || outboundCtx.TopicID != "6" { + t.Fatalf("unexpected outbound context: %+v", outboundCtx) + } + return "-100123/6" + }, + } + m.channels["telegram"] = ch + + m.DismissToolFeedbackForSession( + context.Background(), + "telegram", + "-100123", + &bus.InboundContext{Channel: "telegram", ChatID: "-100123", TopicID: "6"}, + "subturn-1", + ) + + if len(ch.dismissedChatIDs) == 0 || ch.dismissedChatIDs[0] != "-100123/6#session:subturn-1" { + t.Fatalf("dismissed chatIDs = %v, want topic-scoped session key first", ch.dismissedChatIDs) + } +} + type mockPreparedToolFeedbackEditor struct { mockMessageEditor prepareFn func(content string) string