mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-01 07:01:41 +00:00
fix(matrix): implement thread_require_mention to prevent multi-agent reply loops
In multi-agent shared Matrix rooms, multiple bots all participating in the same thread could trigger infinite reply loops — each bot's reply re-engaged the others because they were all in the bot-thread set. Discord has a `thread_require_mention` opt-in for this; Matrix didn't. Add `_parse_thread_require_mention(config)` (mirrors Discord's pattern). In `_resolve_message_context`, when enabled and the message is in a bot-participated thread (not a free-response room), require @mention before processing. Salvage of @justemu's 2-commit stack (#27996). Fixes #27995.
This commit is contained in:
parent
e2a1a2bf13
commit
276e6cc52d
1 changed files with 37 additions and 0 deletions
|
|
@ -380,6 +380,7 @@ class MatrixAdapter(BasePlatformAdapter):
|
|||
self._require_mention: bool = os.getenv(
|
||||
"MATRIX_REQUIRE_MENTION", "true"
|
||||
).lower() not in {"false", "0", "no"}
|
||||
self._thread_require_mention: bool = self._parse_thread_require_mention(config)
|
||||
free_rooms_raw = config.extra.get("free_response_rooms")
|
||||
if free_rooms_raw is None:
|
||||
free_rooms_raw = os.getenv("MATRIX_FREE_RESPONSE_ROOMS", "")
|
||||
|
|
@ -468,6 +469,27 @@ class MatrixAdapter(BasePlatformAdapter):
|
|||
self._processed_events_set.add(event_id)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _parse_thread_require_mention(config) -> bool:
|
||||
"""Parse thread_require_mention from config.extra or env var.
|
||||
|
||||
Handles both YAML booleans and string values (``\"true\"``, ``\"false\"``,
|
||||
``\"yes\"``, ``\"no\"``, ``\"on\"``, ``\"off\"``, ``\"1\"``, ``\"0\"``).
|
||||
Falls back to ``MATRIX_THREAD_REQUIRE_MENTION`` env var, default ``false``.
|
||||
Mirrors Discord adapter's parsing pattern.
|
||||
"""
|
||||
configured = config.extra.get("thread_require_mention")
|
||||
if configured is not None:
|
||||
if isinstance(configured, bool):
|
||||
return configured
|
||||
if isinstance(configured, str):
|
||||
return configured.lower() not in {"false", "0", "no", "off"}
|
||||
# int, float, etc. — truthiness fallback
|
||||
return bool(configured)
|
||||
return os.getenv(
|
||||
"MATRIX_THREAD_REQUIRE_MENTION", "false"
|
||||
).lower() in {"true", "1", "yes", "on"}
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# E2EE helpers
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -1701,6 +1723,21 @@ class MatrixAdapter(BasePlatformAdapter):
|
|||
)
|
||||
return None
|
||||
|
||||
# Thread-level @mention gating: even in a bot-participated thread,
|
||||
# require @mention when thread_require_mention is enabled.
|
||||
# Prevents infinite reply loops in multi-agent shared rooms
|
||||
# where multiple bots all participate in the same thread.
|
||||
elif (self._thread_require_mention and in_bot_thread
|
||||
and not is_free_room):
|
||||
if not is_mentioned:
|
||||
logger.debug(
|
||||
"Matrix: ignoring message %s in thread %s — "
|
||||
"no @mention (thread_require_mention=true)",
|
||||
event_id,
|
||||
thread_id,
|
||||
)
|
||||
return None
|
||||
|
||||
# DM mention-thread.
|
||||
if is_dm and not thread_id and self._dm_mention_threads and is_mentioned:
|
||||
thread_id = event_id
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue