use std::sync::Arc;
use std::time::Duration;
use teloxide::Bot;
use teloxide::types::{ChatAction, ChatId, ThreadId};
use tokio_util::sync::CancellationToken;
use uuid::Uuid;
use crate::brain::agent::service::background_tasks::BackgroundTaskManager;
use super::send::chat_action_in_thread;
const TICK: Duration = Duration::from_secs(4);
pub(crate) fn spawn_typing(
bot: Bot,
chat_id: ChatId,
thread_id: Option<ThreadId>,
cancel: CancellationToken,
background: Option<Arc<BackgroundTaskManager>>,
session_id: Uuid,
) {
tokio::spawn(async move {
loop {
tokio::select! {
_ = cancel.cancelled() => break,
_ = tokio::time::sleep(TICK) => {
let _ = chat_action_in_thread(&bot, chat_id, thread_id, ChatAction::Typing)
.await;
}
}
}
keep_typing_while_detached(bot, chat_id, thread_id, background, session_id).await;
});
}
pub(crate) fn spawn_typing_after_turn(
bot: Bot,
chat_id: ChatId,
thread_id: Option<ThreadId>,
cancel: CancellationToken,
background: Option<Arc<BackgroundTaskManager>>,
session_id: Uuid,
) {
tokio::spawn(async move {
cancel.cancelled().await;
keep_typing_while_detached(bot, chat_id, thread_id, background, session_id).await;
});
}
async fn keep_typing_while_detached(
bot: Bot,
chat_id: ChatId,
thread_id: Option<ThreadId>,
background: Option<Arc<BackgroundTaskManager>>,
session_id: Uuid,
) {
let Some(manager) = background else {
return;
};
while manager.running_for(session_id) > 0 {
let _ = chat_action_in_thread(&bot, chat_id, thread_id, ChatAction::Typing).await;
tokio::time::sleep(TICK).await;
}
}