Revert "Match OpenClaw Telegram UX: reactions, hide tool events"

This reverts commit a536ddca5e.
This commit is contained in:
Wylabb
2026-04-08 01:44:02 +02:00
parent a536ddca5e
commit aaccab1bbd
2 changed files with 156 additions and 54 deletions
+156 -31
View File
@@ -209,7 +209,6 @@ impl TelegramGateway {
let delivery = self.spawn_delivery_task(
profile.profile_id.as_str().to_string(),
message.chat.id,
message.message_id,
turn_id,
worker.base_url,
);
@@ -511,7 +510,6 @@ impl TelegramGateway {
&self,
profile_id: String,
chat_id: i64,
user_message_id: i64,
turn_id: String,
worker_base_url: String,
) -> impl std::future::Future<Output = ()> + Send + 'static {
@@ -546,19 +544,42 @@ impl TelegramGateway {
}
};
// Set thinking reaction on user message and start typing indicator
let _ = api.set_message_reaction(chat_id, user_message_id, &["\u{1f914}"]).await; // 🤔
let mut status_message = match api.send_message(chat_id, "Thinking...", None).await {
Ok(message) => Some(TrackedMessage::new(
chat_id,
message.message_id,
"Thinking...",
)),
Err(error) => {
eprintln!("failed to send initial Telegram message: {error}");
None
}
};
let typing_done = Arc::new(std::sync::atomic::AtomicBool::new(false));
let typing_handle = spawn_typing_loop(api.clone(), chat_id, typing_done.clone());
let mut text_buffer = String::new();
let mut text_messages: Vec<TrackedMessage> = Vec::new();
let mut text_messages = status_message
.clone()
.map(|message| vec![message])
.unwrap_or_default();
while let Some(next_event) = receiver.recv().await {
let event = match next_event {
Ok(event) => event,
Err(error) => {
eprintln!("worker stream failed: {error}");
let _ = api.set_message_reaction(chat_id, user_message_id, &["\u{1f631}"]).await; // 😱
let text = format!("Worker stream failed: {error}");
if let Some(message_handle) = &mut status_message {
let _ = api
.edit_message_text(
message_handle.chat_id,
message_handle.message_id,
&text,
None,
)
.await;
} else {
let _ = api.send_message(chat_id, &text, None).await;
}
break;
}
};
@@ -573,15 +594,50 @@ impl TelegramGateway {
eprintln!("failed to sync Telegram text output: {error}");
}
}
// Tool events: update reaction silently, no text to user
WorkerTurnEvent::ToolUse { .. } => {
let _ = api.set_message_reaction(chat_id, user_message_id, &["\u{1f525}"]).await; // 🔥
WorkerTurnEvent::ToolUse { name, .. } => {
if text_buffer.is_empty() {
if let Some(message) = &mut status_message {
let text = format!("Running tool: {name}");
if let Err(error) = api
.edit_message_text(
message.chat_id,
message.message_id,
&text,
None,
)
.await
{
eprintln!("failed to edit tool status message: {error}");
} else {
message.last_text = text;
}
}
}
}
WorkerTurnEvent::ToolResult { .. } => {
// Silent — back to thinking
let _ = api.set_message_reaction(chat_id, user_message_id, &["\u{1f914}"]).await; // 🤔
WorkerTurnEvent::ToolResult {
tool_name,
is_error,
..
} => {
if is_error && text_buffer.is_empty() {
if let Some(message) = &mut status_message {
let text = format!("Tool `{tool_name}` returned an error.");
if let Err(error) = api
.edit_message_text(
message.chat_id,
message.message_id,
&text,
None,
)
.await
{
eprintln!("failed to edit error status message: {error}");
} else {
message.last_text = text;
}
}
}
}
// Approvals still need to be shown — user must decide
WorkerTurnEvent::ApprovalRequested { request } => {
let keyboard =
approval_keyboard(&turn_id, &request.approval_id, &request.tool_name);
@@ -589,9 +645,15 @@ impl TelegramGateway {
.send_message(
chat_id,
&format!(
"Approval required\nTool: {}\nInput: {}",
"Approval required\nTool: {}\nCurrent mode: {}\nRequired mode: {}\nInput: {}\n{}",
request.tool_name,
&request.input[..request.input.len().min(200)],
request.current_mode,
request.required_mode,
request.input,
request
.reason
.as_deref()
.map_or(String::new(), |value| format!("Reason: {value}"))
),
Some(&keyboard),
)
@@ -615,15 +677,58 @@ impl TelegramGateway {
}
}
}
// Internal events: silent
WorkerTurnEvent::AutoCompaction { .. } => {}
WorkerTurnEvent::TaskCreated { .. } => {}
WorkerTurnEvent::TaskUpdated { .. } => {}
WorkerTurnEvent::TaskStopped { .. } => {}
WorkerTurnEvent::AgentSpawned { .. } => {}
WorkerTurnEvent::TeamCreated { .. } => {}
WorkerTurnEvent::TeamDeleted { .. } => {}
WorkerTurnEvent::MailboxMessage { .. } => {}
WorkerTurnEvent::AutoCompaction {
removed_message_count,
} => {
let note = format!(
"Context was compacted automatically after removing {} older messages.",
removed_message_count
);
let _ = api.send_message(chat_id, &note, None).await;
}
WorkerTurnEvent::TaskCreated { task_list_id, task } => {
let _ = api
.send_message(
chat_id,
&render_task_created_notice(&task_list_id, &task),
None,
)
.await;
}
WorkerTurnEvent::TaskUpdated { task_list_id, task } => {
let _ = api
.send_message(
chat_id,
&render_task_updated_notice(&task_list_id, &task),
None,
)
.await;
}
WorkerTurnEvent::TaskStopped { task } => {
let _ = api
.send_message(chat_id, &render_task_stopped_notice(&task), None)
.await;
}
WorkerTurnEvent::AgentSpawned { agent } => {
let _ = api
.send_message(chat_id, &render_agent_spawned_notice(&agent), None)
.await;
}
WorkerTurnEvent::TeamCreated { team } => {
let _ = api
.send_message(chat_id, &render_team_created_notice(&team), None)
.await;
}
WorkerTurnEvent::TeamDeleted { team_name } => {
let _ = api
.send_message(chat_id, &render_team_deleted_notice(&team_name), None)
.await;
}
WorkerTurnEvent::MailboxMessage { message } => {
let _ = api
.send_message(chat_id, &render_mailbox_message_notice(&message), None)
.await;
}
WorkerTurnEvent::Completed {
final_text,
generated_files,
@@ -634,9 +739,18 @@ impl TelegramGateway {
let _ =
sync_text_messages(&api, chat_id, &mut text_messages, &text_buffer)
.await;
} else if text_buffer.is_empty() && generated_files.is_empty() {
if let Some(message) = &mut status_message {
let _ = api
.edit_message_text(
message.chat_id,
message.message_id,
"Done.",
None,
)
.await;
}
}
// Clear reaction (done)
let _ = api.set_message_reaction(chat_id, user_message_id, &[]).await;
let miniapp_base = miniapp_base_url.as_deref();
let feed_items = if miniapp_base.is_some() {
match client.list_feed(Some(&turn_id)).await {
@@ -754,10 +868,21 @@ impl TelegramGateway {
profile_id,
chat_id,
);
let _ = api.set_message_reaction(chat_id, user_message_id, &["\u{1f631}"]).await; // 😱
let _ = api
.send_message(chat_id, &format!("Request failed: {message}"), None)
.await;
if let Some(message_handle) = &mut status_message {
let text = format!("Request failed: {message}");
let _ = api
.edit_message_text(
message_handle.chat_id,
message_handle.message_id,
&text,
None,
)
.await;
} else {
let _ = api
.send_message(chat_id, &format!("Request failed: {message}"), None)
.await;
}
break;
}
}
@@ -166,29 +166,6 @@ impl TelegramApi {
.map(|_| ())
}
/// Set a reaction emoji on a message. Pass an empty slice to remove all reactions.
pub async fn set_message_reaction(
&self,
chat_id: i64,
message_id: i64,
emoji: &[&str],
) -> Result<(), TelegramApiError> {
let reaction: Vec<serde_json::Value> = emoji
.iter()
.map(|e| json!({"type": "emoji", "emoji": e}))
.collect();
self.post_json_value(
"setMessageReaction",
&json!({
"chat_id": chat_id,
"message_id": message_id,
"reaction": reaction,
}),
)
.await
.map(|_| ())
}
pub async fn get_file(&self, file_id: &str) -> Result<TelegramFile, TelegramApiError> {
self.post_json("getFile", &json!({ "file_id": file_id }))
.await