Compare commits

...
Author SHA1 Message Date
damocles
b68d91269f refactor(#2629): fix stale self-filter doc comments + flatten the sender-check let-chain 2026-07-22 17:51:34 +02:00
bitburner
71cc545cb2 fix(#2629): exclude agent's own messages from unread sweep
Gate the unread sweep on sender: skip rooms where the latest unread message
was sent by the agent itself. This prevents self-authored messages from
triggering an unread notification and causing a self-wake loop.

Fixes: #2629
2026-07-22 17:49:45 +02:00
2 changed files with 19 additions and 4 deletions

View file

@ -890,6 +890,7 @@ pub async fn collect_unread_with_ids(
) -> Vec<(matrix_sdk::ruma::OwnedRoomId, crate::protocol::RoomUnread)> {
use crate::protocol::RoomUnread;
let mut result = Vec::new();
let own_user_id = client.user_id();
for room in client.joined_rooms() {
let count =
u32::try_from(room.unread_notification_counts().notification_count).unwrap_or(u32::MAX);
@ -902,6 +903,16 @@ pub async fn collect_unread_with_ids(
} else {
(None, None)
};
// Skip a single-unread room whose newest event is the agent's own
// message: after a rebuild the read receipt may not have advanced
// past it yet, so `notification_count` can still report 1 — without
// this the agent self-wakes on its own message. Only reachable on the
// count==1 path, where `last_sender` is populated.
if let (Some(sender), Some(own_id)) = (&last_sender, own_user_id)
&& sender.as_str() == own_id.as_str()
{
continue;
}
result.push((
room.room_id().to_owned(),
RoomUnread {

View file

@ -9,8 +9,10 @@
//!
//! Todo summaries stay short: `sweep_unread` pushes the per-room unread
//! summary (`wake::format_unread_summary`); the message stays unread
//! server-side so the agent fetches detail via `read_room`. Self-sent
//! messages never raise an unread notification, so they never wake.
//! server-side so the agent fetches detail via `read_room`. A self-authored
//! newest message can still read as unread after a rebuild (the read receipt
//! lags), so `collect_unread_with_ids` filters those rooms out — the agent
//! never wakes on its own message.
use std::collections::HashSet;
@ -33,8 +35,10 @@ use crate::{handlers, wake};
/// `Some(name)` only in multi-account mode, prepended so the agent knows
/// which account to `read_room` on.
///
/// Self-sent messages don't raise an unread notification server-side, so
/// no explicit self-filter is needed here.
/// Rooms whose newest unread event is the agent's own message are filtered
/// out by `collect_unread_with_ids` (after a rebuild a stale read receipt can
/// otherwise leave a self-authored message counted as unread and self-wake
/// the agent).
pub async fn sweep_unread(
client: &Client,
notified: &Mutex<HashSet<OwnedRoomId>>,