fix(telegram): preserve topic metadata on overflow edits

This commit is contained in:
Maxim Esipov 2026-05-17 19:10:13 +03:00 committed by Teknium
parent c66efcff32
commit 3ec28f34ca
5 changed files with 172 additions and 30 deletions

View file

@ -99,6 +99,21 @@ class SmallLimitProgressAdapter(ProgressCaptureAdapter):
return SendResult(success=True, message_id=message_id)
class MetadataEditProgressCaptureAdapter(ProgressCaptureAdapter):
async def edit_message(
self, chat_id, message_id, content, *, finalize: bool = False, metadata=None
) -> SendResult:
self.edits.append(
{
"chat_id": chat_id,
"message_id": message_id,
"content": content,
"metadata": metadata,
}
)
return SendResult(success=True, message_id=message_id)
class NonEditingProgressCaptureAdapter(ProgressCaptureAdapter):
SUPPORTS_MESSAGE_EDITING = False
@ -277,6 +292,44 @@ async def test_run_agent_progress_stays_in_originating_topic(monkeypatch, tmp_pa
assert all(call["metadata"] == {"thread_id": "17585"} for call in adapter.typing)
@pytest.mark.asyncio
async def test_run_agent_progress_edits_keep_originating_topic_metadata(monkeypatch, tmp_path):
monkeypatch.setenv("HERMES_TOOL_PROGRESS_MODE", "all")
fake_dotenv = types.ModuleType("dotenv")
fake_dotenv.load_dotenv = lambda *args, **kwargs: None
monkeypatch.setitem(sys.modules, "dotenv", fake_dotenv)
fake_run_agent = types.ModuleType("run_agent")
fake_run_agent.AIAgent = FakeAgent
monkeypatch.setitem(sys.modules, "run_agent", fake_run_agent)
adapter = MetadataEditProgressCaptureAdapter()
runner = _make_runner(adapter)
gateway_run = importlib.import_module("gateway.run")
monkeypatch.setattr(gateway_run, "_hermes_home", tmp_path)
monkeypatch.setattr(gateway_run, "_resolve_runtime_agent_kwargs", lambda: {"api_key": "fake"})
source = SessionSource(
platform=Platform.TELEGRAM,
chat_id="-1001",
chat_type="group",
thread_id="17585",
)
result = await runner._run_agent(
message="hello",
context_prompt="",
history=[],
source=source,
session_id="sess-progress-edit-topic",
session_key="agent:main:telegram:group:-1001:17585",
)
assert result["final_response"] == "done"
assert adapter.edits
assert all(call["metadata"] == {"thread_id": "17585"} for call in adapter.edits)
@pytest.mark.asyncio
async def test_run_agent_progress_does_not_use_event_message_id_for_telegram_dm(monkeypatch, tmp_path):
"""Telegram DM progress must not reuse event message id as thread metadata."""

View file

@ -809,6 +809,33 @@ class TestEditMessageStreamingSafety:
# Continuations were sent threaded as replies for visual grouping.
assert adapter._bot.send_message.await_count == len(result.continuation_message_ids)
@pytest.mark.asyncio
async def test_message_too_long_continuations_preserve_topic_metadata(self):
"""Overflow continuations should stay in the originating Telegram topic."""
adapter = TelegramAdapter(PlatformConfig(enabled=True, token="fake-token"))
adapter._bot = MagicMock()
adapter._bot.edit_message_text = AsyncMock()
sent_kwargs = []
async def _fake_send(**kwargs):
sent_kwargs.append(kwargs)
return SimpleNamespace(message_id=1000 + len(sent_kwargs))
adapter._bot.send_message = AsyncMock(side_effect=_fake_send)
result = await adapter.edit_message(
"-100123",
"456",
"x" * 6000,
finalize=False,
metadata={"thread_id": "17585"},
)
assert result.success is True
assert sent_kwargs, "expected at least one overflow continuation"
assert all(kwargs.get("message_thread_id") == 17585 for kwargs in sent_kwargs)
assert sent_kwargs[0]["reply_to_message_id"] == 456
# =========================================================================
# Telegram guest mention gating
# =========================================================================