2 Commits
Author SHA1 Message Date
fchengyan 4e99816a87 fix(channels): deliver NO_REPLY placeholder cleanup signal to channels (#1586)
The agent loop signals silent replies (NO_REPLY, cancelled runs, suppressed
errors) by publishing an outbound message with empty content plus the inbound
routing metadata (placeholder_key / local_key). Slack, Telegram and Discord
each implement an empty-content branch in Send() that deletes their streamed
'Thinking...' placeholder — the partial draft left visible in the thread when
delivery is suppressed.

deliverOutbound skipped every text-only empty outbound, so that cleanup
signal never reached channel.Send and the stray partial draft stayed
published (issue #1475). Pass the signal through when placeholder routing
metadata is present; keep skipping bare empty messages so channels without
an empty-content branch never render empty bubbles.

Fixes #1475
2026-09-29 07:07:12 +02:00
Duc Nguyen aa15317d5b fix: resolve Zalo group by name + notify origin on failed forward (#1395)
* fix: resolve Zalo group name to real chat ID, notify origin on failed forward

Two related root causes behind "forward message to group by name" silently
failing while the agent reports success:

1. No tool let the agent resolve a group's display name (e.g. "Ban Dieu
   Hanh") to the chat ID the message tool actually requires. sessions_list
   only exposes session keys (numeric group IDs), never human-readable
   names, so the agent had no reliable way to turn a name into a real
   target and ended up passing the display name itself as `target`.

   Adds zalo_list_groups, wrapping the already-used (dashboard picker)
   protocol.FetchGroups behind the same optional-interface pattern as
   list_group_members/GroupMemberProvider (GroupListProvider on
   channels.Manager, gated to zalo_personal via RequiredChannelTypes).

2. When the resulting send fails downstream (e.g. Zalo rejects a bad
   chat_id), dispatchOutbound only ever retried/notified media failures on
   the same (already-broken) destination, and dropped text-only failures
   entirely — even though message.go's own postCrossTargetNotice comment
   states forwards must never announce a fake delivery. Because the bus
   publish is fire-and-forget, the tool had already returned "sent" and
   announced success to the origin chat before the real send was even
   attempted.

   message.go now tags cross-target forwards with origin channel/chat in
   OutboundMessage.Metadata; dispatchOutbound uses it to notify the ORIGIN
   chat with the real failure instead of silently dropping it or retrying
   against the same invalid target.

* test: cover forward-origin metadata tagging and dispatch failure notice

Extracts dispatchOutbound's error branch into handleSendFailure so it can
be unit tested without driving the consumer loop/goroutine, and adds
coverage for: forward failures notifying the origin chat (not the broken
destination), pre-existing non-forward media/text-only behavior staying
unchanged, message.go tagging cross-target group forwards with origin
metadata alongside group_id, and the new zalo_list_groups tool/Manager
delegator.
2026-07-08 23:23:08 +07:00