Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions gateway/platforms/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,17 @@ async def edit_message(
"""
return SendResult(success=False, error="Not supported")

async def delete_message(
self,
chat_id: str,
message_id: str,
) -> bool:
"""
Delete a previously sent message. Optional — platforms that don't
support deletion return False.
"""
return False

async def send_typing(self, chat_id: str, metadata=None) -> None:
"""
Send a typing indicator.
Expand Down
26 changes: 25 additions & 1 deletion gateway/platforms/telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,9 @@ async def send(
]

message_ids = []
thread_id = self._metadata_thread_id(metadata)
thread_id = metadata.get("thread_id") if metadata else None
silent = metadata.get("silent", False) if metadata else False
no_preview = metadata.get("no_preview", False) if metadata else False

try:
from telegram.error import NetworkError as _NetErr
Expand Down Expand Up @@ -1030,6 +1032,8 @@ async def send(
parse_mode=ParseMode.MARKDOWN_V2,
reply_to_message_id=reply_to_id,
message_thread_id=effective_thread_id,
disable_notification=silent,
disable_web_page_preview=no_preview,
**self._link_preview_kwargs(),
)
except Exception as md_error:
Expand All @@ -1043,6 +1047,8 @@ async def send(
parse_mode=None,
reply_to_message_id=reply_to_id,
message_thread_id=effective_thread_id,
disable_notification=silent,
disable_web_page_preview=no_preview,
**self._link_preview_kwargs(),
)
else:
Expand Down Expand Up @@ -1208,6 +1214,24 @@ async def edit_message(
)
return SendResult(success=False, error=str(e))

async def delete_message(
self,
chat_id: str,
message_id: str,
) -> bool:
"""Delete a previously sent Telegram message."""
if not self._bot:
return False
try:
await self._bot.delete_message(
chat_id=int(chat_id),
message_id=int(message_id),
)
return True
except Exception as e:
logger.debug("[%s] Failed to delete message %s: %s", self.name, message_id, e)
return False

async def send_update_prompt(
self, chat_id: str, prompt: str, default: str = "",
session_key: str = "",
Expand Down
28 changes: 27 additions & 1 deletion gateway/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -9226,6 +9226,7 @@ def _run_still_current() -> bool:
last_tool = [None] # Mutable container for tracking in closure
last_progress_msg = [None] # Track last message for dedup
repeat_count = [0] # How many times the same message repeated
progress_msg_id_holder = [None] # Track progress message ID for deletion

def progress_callback(event_type: str, tool_name: str = None, preview: str = None, args: dict = None, **kwargs):
"""Callback invoked by agent on tool lifecycle events."""
Expand Down Expand Up @@ -9303,7 +9304,12 @@ def progress_callback(event_type: str, tool_name: str = None, preview: str = Non
_progress_thread_id = source.thread_id or event_message_id
else:
_progress_thread_id = source.thread_id
_progress_metadata = {"thread_id": _progress_thread_id} if _progress_thread_id else None
# Silent mode: tool progress messages are sent without notification
# so the user isn't spammed with sounds/vibrations for every tool call.
# Link preview disabled to keep progress messages compact.
_progress_metadata = {"silent": True, "no_preview": True}
if _progress_thread_id:
_progress_metadata["thread_id"] = _progress_thread_id

async def send_progress_messages():
if not progress_queue:
Expand Down Expand Up @@ -9398,6 +9404,7 @@ async def send_progress_messages():
result = await adapter.send(chat_id=source.chat_id, content=msg, metadata=_progress_metadata)
if result.success and result.message_id:
progress_msg_id = result.message_id
progress_msg_id_holder[0] = progress_msg_id

_last_edit_ts = time.monotonic()

Expand Down Expand Up @@ -10627,6 +10634,25 @@ async def _notify_long_running():
# Stop progress sender, interrupt monitor, and notification task
if progress_task:
progress_task.cancel()

# Auto-delete progress message after agent finishes (if enabled)
_delete_progress = False
try:
_display_cfg = user_config.get("display", {})
if isinstance(_display_cfg, dict):
_delete_progress = _display_cfg.get("delete_progress_messages", False)
except Exception:
pass
if _delete_progress and progress_msg_id_holder[0]:
try:
adapter = self.adapters.get(source.platform)
if adapter:
await adapter.delete_message(
chat_id=source.chat_id,
message_id=progress_msg_id_holder[0],
)
except Exception:
pass
interrupt_monitor.cancel()
_notify_task.cancel()

Expand Down
1 change: 1 addition & 0 deletions hermes_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ def _ensure_hermes_home_managed(home: Path):
"tool_progress_overrides": {}, # DEPRECATED — use display.platforms instead
"tool_preview_length": 0, # Max chars for tool call previews (0 = no limit, show full paths/commands)
"platforms": {}, # Per-platform display overrides: {"telegram": {"tool_progress": "all"}, "slack": {"tool_progress": "off"}}
"delete_progress_messages": False, # Auto-delete progress messages after final response
},

# Web dashboard settings
Expand Down