mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
feat: implement edit_message() for Telegram/Discord/Slack and fix fallback regression
Building on PR #288's edit_message() abstraction: - Telegram: edit_message_text() with MarkdownV2 + plain text fallback - Discord: channel.fetch_message() + msg.edit() with length capping - Slack: chat_update() via slack_bolt client Also fixes the fallback regression in send_progress_messages() where platforms that don't support editing would receive duplicated accumulated tool lines. Now uses a can_edit flag — after the first failed edit, falls back to sending individual lines (matching pre-PR behavior).
This commit is contained in:
parent
5702eba93b
commit
1708dcd2b2
4 changed files with 91 additions and 15 deletions
|
|
@ -207,6 +207,28 @@ class DiscordAdapter(BasePlatformAdapter):
|
|||
except Exception as e:
|
||||
return SendResult(success=False, error=str(e))
|
||||
|
||||
async def edit_message(
|
||||
self,
|
||||
chat_id: str,
|
||||
message_id: str,
|
||||
content: str,
|
||||
) -> SendResult:
|
||||
"""Edit a previously sent Discord message."""
|
||||
if not self._client:
|
||||
return SendResult(success=False, error="Not connected")
|
||||
try:
|
||||
channel = self._client.get_channel(int(chat_id))
|
||||
if not channel:
|
||||
channel = await self._client.fetch_channel(int(chat_id))
|
||||
msg = await channel.fetch_message(int(message_id))
|
||||
formatted = self.format_message(content)
|
||||
if len(formatted) > self.MAX_MESSAGE_LENGTH:
|
||||
formatted = formatted[:self.MAX_MESSAGE_LENGTH - 3] + "..."
|
||||
await msg.edit(content=formatted)
|
||||
return SendResult(success=True, message_id=message_id)
|
||||
except Exception as e:
|
||||
return SendResult(success=False, error=str(e))
|
||||
|
||||
async def send_voice(
|
||||
self,
|
||||
chat_id: str,
|
||||
|
|
|
|||
|
|
@ -156,6 +156,25 @@ class SlackAdapter(BasePlatformAdapter):
|
|||
print(f"[Slack] Send error: {e}")
|
||||
return SendResult(success=False, error=str(e))
|
||||
|
||||
async def edit_message(
|
||||
self,
|
||||
chat_id: str,
|
||||
message_id: str,
|
||||
content: str,
|
||||
) -> SendResult:
|
||||
"""Edit a previously sent Slack message."""
|
||||
if not self._app:
|
||||
return SendResult(success=False, error="Not connected")
|
||||
try:
|
||||
await self._app.client.chat_update(
|
||||
channel=chat_id,
|
||||
ts=message_id,
|
||||
text=content,
|
||||
)
|
||||
return SendResult(success=True, message_id=message_id)
|
||||
except Exception as e:
|
||||
return SendResult(success=False, error=str(e))
|
||||
|
||||
async def send_typing(self, chat_id: str) -> None:
|
||||
"""Slack doesn't have a direct typing indicator API for bots."""
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -219,6 +219,35 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
except Exception as e:
|
||||
return SendResult(success=False, error=str(e))
|
||||
|
||||
async def edit_message(
|
||||
self,
|
||||
chat_id: str,
|
||||
message_id: str,
|
||||
content: str,
|
||||
) -> SendResult:
|
||||
"""Edit a previously sent Telegram message."""
|
||||
if not self._bot:
|
||||
return SendResult(success=False, error="Not connected")
|
||||
try:
|
||||
formatted = self.format_message(content)
|
||||
try:
|
||||
await self._bot.edit_message_text(
|
||||
chat_id=int(chat_id),
|
||||
message_id=int(message_id),
|
||||
text=formatted,
|
||||
parse_mode=ParseMode.MARKDOWN_V2,
|
||||
)
|
||||
except Exception:
|
||||
# Fallback: retry without markdown formatting
|
||||
await self._bot.edit_message_text(
|
||||
chat_id=int(chat_id),
|
||||
message_id=int(message_id),
|
||||
text=content,
|
||||
)
|
||||
return SendResult(success=True, message_id=message_id)
|
||||
except Exception as e:
|
||||
return SendResult(success=False, error=str(e))
|
||||
|
||||
async def send_voice(
|
||||
self,
|
||||
chat_id: str,
|
||||
|
|
|
|||
|
|
@ -1950,30 +1950,36 @@ class GatewayRunner:
|
|||
|
||||
progress_lines = [] # Accumulated tool lines
|
||||
progress_msg_id = None # ID of the progress message to edit
|
||||
can_edit = True # False once an edit fails (platform doesn't support it)
|
||||
|
||||
while True:
|
||||
try:
|
||||
msg = progress_queue.get_nowait()
|
||||
progress_lines.append(msg)
|
||||
full_text = "\n".join(progress_lines)
|
||||
|
||||
if progress_msg_id is None:
|
||||
# First tool: send as new message
|
||||
result = await adapter.send(chat_id=source.chat_id, content=full_text)
|
||||
if result.success and result.message_id:
|
||||
progress_msg_id = result.message_id
|
||||
else:
|
||||
# Subsequent tools: try to edit, fall back to new message
|
||||
if can_edit and progress_msg_id is not None:
|
||||
# Try to edit the existing progress message
|
||||
full_text = "\n".join(progress_lines)
|
||||
result = await adapter.edit_message(
|
||||
chat_id=source.chat_id,
|
||||
message_id=progress_msg_id,
|
||||
content=full_text,
|
||||
)
|
||||
if not result.success:
|
||||
# Edit failed — send as new message and track it
|
||||
# Platform doesn't support editing — stop trying,
|
||||
# send just this new line as a separate message
|
||||
can_edit = False
|
||||
await adapter.send(chat_id=source.chat_id, content=msg)
|
||||
else:
|
||||
if can_edit:
|
||||
# First tool: send all accumulated text as new message
|
||||
full_text = "\n".join(progress_lines)
|
||||
result = await adapter.send(chat_id=source.chat_id, content=full_text)
|
||||
if result.success and result.message_id:
|
||||
progress_msg_id = result.message_id
|
||||
else:
|
||||
# Editing unsupported: send just this line
|
||||
result = await adapter.send(chat_id=source.chat_id, content=msg)
|
||||
if result.success and result.message_id:
|
||||
progress_msg_id = result.message_id
|
||||
|
||||
# Restore typing indicator
|
||||
await asyncio.sleep(0.3)
|
||||
|
|
@ -1989,8 +1995,8 @@ class GatewayRunner:
|
|||
progress_lines.append(msg)
|
||||
except Exception:
|
||||
break
|
||||
# Final edit with all remaining tools
|
||||
if progress_lines and progress_msg_id:
|
||||
# Final edit with all remaining tools (only if editing works)
|
||||
if can_edit and progress_lines and progress_msg_id:
|
||||
full_text = "\n".join(progress_lines)
|
||||
try:
|
||||
await adapter.edit_message(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue