mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
feat(gateway): add ignored_threads config for Telegram
This commit is contained in:
parent
1acf81fdf5
commit
2cfd2dafc6
3 changed files with 75 additions and 2 deletions
|
|
@ -625,6 +625,11 @@ def load_gateway_config() -> GatewayConfig:
|
|||
if isinstance(frc, list):
|
||||
frc = ",".join(str(v) for v in frc)
|
||||
os.environ["TELEGRAM_FREE_RESPONSE_CHATS"] = str(frc)
|
||||
ignored_threads = telegram_cfg.get("ignored_threads")
|
||||
if ignored_threads is not None and not os.getenv("TELEGRAM_IGNORED_THREADS"):
|
||||
if isinstance(ignored_threads, list):
|
||||
ignored_threads = ",".join(str(v) for v in ignored_threads)
|
||||
os.environ["TELEGRAM_IGNORED_THREADS"] = str(ignored_threads)
|
||||
if "reactions" in telegram_cfg and not os.getenv("TELEGRAM_REACTIONS"):
|
||||
os.environ["TELEGRAM_REACTIONS"] = str(telegram_cfg["reactions"]).lower()
|
||||
|
||||
|
|
|
|||
|
|
@ -1991,6 +1991,27 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
return {str(part).strip() for part in raw if str(part).strip()}
|
||||
return {part.strip() for part in str(raw).split(",") if part.strip()}
|
||||
|
||||
def _telegram_ignored_threads(self) -> set[int]:
|
||||
raw = self.config.extra.get("ignored_threads")
|
||||
if raw is None:
|
||||
raw = os.getenv("TELEGRAM_IGNORED_THREADS", "")
|
||||
|
||||
if isinstance(raw, list):
|
||||
values = raw
|
||||
else:
|
||||
values = str(raw).split(",")
|
||||
|
||||
ignored: set[int] = set()
|
||||
for value in values:
|
||||
text = str(value).strip()
|
||||
if not text:
|
||||
continue
|
||||
try:
|
||||
ignored.add(int(text))
|
||||
except (TypeError, ValueError):
|
||||
logger.warning("[%s] Ignoring invalid Telegram thread id: %r", self.name, value)
|
||||
return ignored
|
||||
|
||||
def _compile_mention_patterns(self) -> List[re.Pattern]:
|
||||
"""Compile optional regex wake-word patterns for group triggers."""
|
||||
patterns = self.config.extra.get("mention_patterns")
|
||||
|
|
@ -2102,6 +2123,13 @@ class TelegramAdapter(BasePlatformAdapter):
|
|||
"""
|
||||
if not self._is_group_chat(message):
|
||||
return True
|
||||
thread_id = getattr(message, "message_thread_id", None)
|
||||
if thread_id is not None:
|
||||
try:
|
||||
if int(thread_id) in self._telegram_ignored_threads():
|
||||
return False
|
||||
except (TypeError, ValueError):
|
||||
logger.warning("[%s] Ignoring non-numeric Telegram message_thread_id: %r", self.name, thread_id)
|
||||
if str(getattr(getattr(message, "chat", None), "id", "")) in self._telegram_free_response_chats():
|
||||
return True
|
||||
if not self._telegram_require_mention():
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from unittest.mock import AsyncMock
|
|||
from gateway.config import Platform, PlatformConfig, load_gateway_config
|
||||
|
||||
|
||||
def _make_adapter(require_mention=None, free_response_chats=None, mention_patterns=None):
|
||||
def _make_adapter(require_mention=None, free_response_chats=None, mention_patterns=None, ignored_threads=None):
|
||||
from gateway.platforms.telegram import TelegramAdapter
|
||||
|
||||
extra = {}
|
||||
|
|
@ -15,6 +15,8 @@ def _make_adapter(require_mention=None, free_response_chats=None, mention_patter
|
|||
extra["free_response_chats"] = free_response_chats
|
||||
if mention_patterns is not None:
|
||||
extra["mention_patterns"] = mention_patterns
|
||||
if ignored_threads is not None:
|
||||
extra["ignored_threads"] = ignored_threads
|
||||
|
||||
adapter = object.__new__(TelegramAdapter)
|
||||
adapter.platform = Platform.TELEGRAM
|
||||
|
|
@ -28,7 +30,16 @@ def _make_adapter(require_mention=None, free_response_chats=None, mention_patter
|
|||
return adapter
|
||||
|
||||
|
||||
def _group_message(text="hello", *, chat_id=-100, reply_to_bot=False, entities=None, caption=None, caption_entities=None):
|
||||
def _group_message(
|
||||
text="hello",
|
||||
*,
|
||||
chat_id=-100,
|
||||
thread_id=None,
|
||||
reply_to_bot=False,
|
||||
entities=None,
|
||||
caption=None,
|
||||
caption_entities=None,
|
||||
):
|
||||
reply_to_message = None
|
||||
if reply_to_bot:
|
||||
reply_to_message = SimpleNamespace(from_user=SimpleNamespace(id=999))
|
||||
|
|
@ -37,6 +48,7 @@ def _group_message(text="hello", *, chat_id=-100, reply_to_bot=False, entities=N
|
|||
caption=caption,
|
||||
entities=entities or [],
|
||||
caption_entities=caption_entities or [],
|
||||
message_thread_id=thread_id,
|
||||
chat=SimpleNamespace(id=chat_id, type="group"),
|
||||
reply_to_message=reply_to_message,
|
||||
)
|
||||
|
|
@ -69,6 +81,14 @@ def test_free_response_chats_bypass_mention_requirement():
|
|||
assert adapter._should_process_message(_group_message("hello everyone", chat_id=-201)) is False
|
||||
|
||||
|
||||
def test_ignored_threads_drop_group_messages_before_other_gates():
|
||||
adapter = _make_adapter(require_mention=False, free_response_chats=["-200"], ignored_threads=[31, "42"])
|
||||
|
||||
assert adapter._should_process_message(_group_message("hello everyone", chat_id=-200, thread_id=31)) is False
|
||||
assert adapter._should_process_message(_group_message("hello everyone", chat_id=-200, thread_id=42)) is False
|
||||
assert adapter._should_process_message(_group_message("hello everyone", chat_id=-200, thread_id=99)) is True
|
||||
|
||||
|
||||
def test_regex_mention_patterns_allow_custom_wake_words():
|
||||
adapter = _make_adapter(require_mention=True, mention_patterns=[r"^\s*chompy\b"])
|
||||
|
||||
|
|
@ -108,3 +128,23 @@ def test_config_bridges_telegram_group_settings(monkeypatch, tmp_path):
|
|||
assert __import__("os").environ["TELEGRAM_REQUIRE_MENTION"] == "true"
|
||||
assert json.loads(__import__("os").environ["TELEGRAM_MENTION_PATTERNS"]) == [r"^\s*chompy\b"]
|
||||
assert __import__("os").environ["TELEGRAM_FREE_RESPONSE_CHATS"] == "-123"
|
||||
|
||||
|
||||
def test_config_bridges_telegram_ignored_threads(monkeypatch, tmp_path):
|
||||
hermes_home = tmp_path / ".hermes"
|
||||
hermes_home.mkdir()
|
||||
(hermes_home / "config.yaml").write_text(
|
||||
"telegram:\n"
|
||||
" ignored_threads:\n"
|
||||
" - 31\n"
|
||||
" - \"42\"\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
monkeypatch.setenv("HERMES_HOME", str(hermes_home))
|
||||
monkeypatch.delenv("TELEGRAM_IGNORED_THREADS", raising=False)
|
||||
|
||||
config = load_gateway_config()
|
||||
|
||||
assert config is not None
|
||||
assert __import__("os").environ["TELEGRAM_IGNORED_THREADS"] == "31,42"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue