@@ -427,6 +427,7 @@ async fn emit_end_and_archive(
427427 }
428428 }
429429 }
430+ remove_huddle_agents ( ephemeral_channel_id, state) . await ;
430431 if !ephemeral_channel_id. is_empty ( ) {
431432 if let Ok ( uuid) = parse_channel_uuid ( ephemeral_channel_id) {
432433 if let Ok ( archive_builder) = events:: build_archive ( uuid) {
@@ -438,6 +439,38 @@ async fn emit_end_and_archive(
438439 }
439440}
440441
442+ /// Best-effort agent removal before archiving an ended huddle.
443+ ///
444+ /// Archive should make the ephemeral channel unavailable on its own, but removing
445+ /// bot-role members first prevents an agent-only huddle from lingering if the
446+ /// archive publish is delayed or rejected.
447+ async fn remove_huddle_agents ( ephemeral_channel_id : & str , state : & AppState ) {
448+ if ephemeral_channel_id. is_empty ( ) {
449+ return ;
450+ }
451+ let Ok ( eph_uuid) = parse_channel_uuid ( ephemeral_channel_id) else {
452+ return ;
453+ } ;
454+
455+ let agent_pubkeys = match fetch_channel_members ( ephemeral_channel_id, Some ( "bot" ) , state) . await
456+ {
457+ Ok ( pubkeys) => pubkeys,
458+ Err ( e) => {
459+ eprintln ! ( "buzz-desktop: fetch huddle agents for cleanup failed: {e}" ) ;
460+ return ;
461+ }
462+ } ;
463+
464+ for pubkey in agent_pubkeys {
465+ let Ok ( remove_builder) = events:: build_remove_member ( eph_uuid, & pubkey) else {
466+ continue ;
467+ } ;
468+ if let Err ( e) = submit_event ( remove_builder, state) . await {
469+ eprintln ! ( "buzz-desktop: remove huddle agent {pubkey} failed: {e}" ) ;
470+ }
471+ }
472+ }
473+
441474/// Leave the current huddle.
442475///
443476/// Steps:
0 commit comments