From dd1dd78312e3db7f92b37fb3b4750fbe35de7115 Mon Sep 17 00:00:00 2001 From: Slavi Pantaleev Date: Fri, 13 Sep 2024 21:40:24 +0300 Subject: [PATCH] Rework typing notifications Previously, the bot only had rudimentary typing notification support. It used to send a single notification when starting a long task and did not bother with notifications anymore. By default matrix-rust-sdk gives these notifications a validity of 4 seconds, so it would expire shortly. If the bot takes longer to respond, you'd see the typing notification expire and wonder if a response is coming. Another edge case is the bot sending an answer quicker and the typing notice still being on. Some clients (like element-web) seem to hide the typing notice when a new message comes, so they don't experience this as problematic. The reworked typing notification system should be robust: - typing notices are sent continuously, until the bot finishes doing work - if the bot is performing multiple actions in a room (even for different people), typing notices would continue to be sent until the bot becomes idle - as soon as the bot becomes idle, a "not typing anymore" notice is sent to clear the state --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/bot/messaging.rs | 7 +++++++ src/bot/reacting.rs | 7 +++++++ src/controller/agent/create/mod.rs | 4 ---- src/controller/chat_completion/mod.rs | 4 ---- src/controller/image/generation.rs | 4 ---- src/controller/utils/text_to_speech.rs | 2 -- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f42f9fd..2004624 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2122,9 +2122,9 @@ dependencies = [ [[package]] name = "mxlink" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3a0be3d60a77da93df2ab59f09ad7e12fd9ed072c70f57e9adb01b662040fa" +checksum = "195f0bd9764068de3e3e446bbac81a54489ff51674d80e387057b805c7dab96c" dependencies = [ "base64 0.22.1", "chacha20poly1305", diff --git a/Cargo.toml b/Cargo.toml index ebfe1a4..0893e53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ base64 = "0.22.*" # We'd rather not depend on this, but we cannot use the ruma-events EventContent macro without it. matrix-sdk = { version = "0.7.1", default-features = false } mxidwc = "1.0.*" -mxlink = "1.1.*" +mxlink = "1.2.*" etke_openai_api_rust = "0.1.*" quick_cache = "0.6.*" regex = "1.10.*" diff --git a/src/bot/messaging.rs b/src/bot/messaging.rs index 11967be..61498bd 100644 --- a/src/bot/messaging.rs +++ b/src/bot/messaging.rs @@ -317,6 +317,13 @@ impl Messaging { let start_time = std::time::Instant::now(); + let _typing_notice_guard = self + .bot + .matrix_link() + .rooms() + .start_typing_notice(message_context.room()) + .await; + let event_span = tracing::error_span!("message_controller", ?controller_type); crate::controller::dispatch_controller(&controller_type, &message_context, &self.bot) diff --git a/src/bot/reacting.rs b/src/bot/reacting.rs index 019a377..0c4b4bd 100644 --- a/src/bot/reacting.rs +++ b/src/bot/reacting.rs @@ -244,6 +244,13 @@ impl Reacting { tracing::info!("Handling reaction via reaction controller"); + let _typing_notice_guard = self + .bot + .matrix_link() + .rooms() + .start_typing_notice(message_context.room()) + .await; + let event_span = tracing::error_span!("reaction_controller"); crate::controller::reaction::handle( diff --git a/src/controller/agent/create/mod.rs b/src/controller/agent/create/mod.rs index e97d82f..ea382b1 100644 --- a/src/controller/agent/create/mod.rs +++ b/src/controller/agent/create/mod.rs @@ -100,8 +100,6 @@ pub async fn handle_room_local( return Ok(()); }; - message_context.room().typing_notice(true).await?; - if !try_to_ping_agent_or_complain(bot, message_context, &parsed_config.agent).await { return Ok(()); } @@ -215,8 +213,6 @@ pub async fn handle_global( return Ok(()); }; - message_context.room().typing_notice(true).await?; - if !try_to_ping_agent_or_complain(bot, message_context, &parsed_config.agent).await { return Ok(()); } diff --git a/src/controller/chat_completion/mod.rs b/src/controller/chat_completion/mod.rs index 171c093..59ceb92 100644 --- a/src/controller/chat_completion/mod.rs +++ b/src/controller/chat_completion/mod.rs @@ -337,8 +337,6 @@ async fn handle_stage_text_generation( ) .await?; - _ = message_context.room().typing_notice(true).await; - let prefixes_to_strip = match controller_type { ChatCompletionControllerType::ViaText { prefixes_to_strip } => prefixes_to_strip.clone(), ChatCompletionControllerType::ViaAudio => vec![], @@ -498,8 +496,6 @@ async fn handle_stage_speech_to_text_actual_transcribing( .get_media_content(&media_request, true) .await?; - _ = message_context.room().typing_notice(true).await; - let span = tracing::debug_span!( "speech_to_text_generation", agent_id = agent.identifier().as_string() diff --git a/src/controller/image/generation.rs b/src/controller/image/generation.rs index 4e58b8c..e0924a9 100644 --- a/src/controller/image/generation.rs +++ b/src/controller/image/generation.rs @@ -56,8 +56,6 @@ pub async fn handle_image( original_prompt.to_owned() }; - message_context.room().typing_notice(true).await?; - let span = tracing::debug_span!( "image_generation", agent_id = agent.identifier().as_string() @@ -139,8 +137,6 @@ pub async fn handle_sticker( return Ok(()); }; - message_context.room().typing_notice(true).await?; - let span = tracing::debug_span!( "sticker_generation", agent_id = agent.identifier().as_string() diff --git a/src/controller/utils/text_to_speech.rs b/src/controller/utils/text_to_speech.rs index 28e74f9..e55f81e 100644 --- a/src/controller/utils/text_to_speech.rs +++ b/src/controller/utils/text_to_speech.rs @@ -18,8 +18,6 @@ pub async fn generate_and_send_tts_for_message( text_message_event_id: &OwnedEventId, text_content: &str, ) -> bool { - _ = message_context.room().typing_notice(true).await; - let reaction_event_response = bot .reacting() .react_no_fail(