mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-30 01:41:43 +00:00
feat(matrix): reaction-based exec approval + mention_user_id
Add Matrix reaction-based exec approval (✅/❎) and mention_user_id support for push notifications in muted rooms. - matrix.py: _MatrixApprovalPrompt, send_exec_approval, reaction approval handling, bot seed reaction redaction, mention pill in send - base.py: inject mention_user_id into send metadata - run.py: inject mention_user_id into status thread metadata - tests for approval prompt registration and reaction resolution
This commit is contained in:
parent
6c70ac8eef
commit
38a6bada92
4 changed files with 206 additions and 3 deletions
58
tests/gateway/test_matrix_exec_approval.py
Normal file
58
tests/gateway/test_matrix_exec_approval.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import types
|
||||
|
||||
import pytest
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from gateway.config import PlatformConfig
|
||||
|
||||
|
||||
class TestMatrixExecApprovalReactions:
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_exec_approval_registers_prompt_and_seeds_reactions(self, monkeypatch):
|
||||
monkeypatch.setenv("MATRIX_ALLOWED_USERS", "@liizfq:liizfq.top")
|
||||
from gateway.platforms.matrix import MatrixAdapter
|
||||
|
||||
adapter = MatrixAdapter(PlatformConfig(enabled=True, token="tok", extra={"homeserver": "https://matrix.example.org"}))
|
||||
adapter._client = types.SimpleNamespace()
|
||||
adapter.send = AsyncMock(return_value=types.SimpleNamespace(success=True, message_id="$evt1"))
|
||||
adapter._send_reaction = AsyncMock(return_value="$r")
|
||||
|
||||
result = await adapter.send_exec_approval(
|
||||
chat_id="!room:example.org",
|
||||
command="rm -rf /tmp/test",
|
||||
session_key="sess-1",
|
||||
description="dangerous",
|
||||
)
|
||||
|
||||
assert result.success is True
|
||||
assert adapter._approval_prompt_by_session["sess-1"] == "$evt1"
|
||||
assert adapter._approval_prompts_by_event["$evt1"].session_key == "sess-1"
|
||||
assert adapter._send_reaction.await_count == 2
|
||||
emojis = [call.args[2] for call in adapter._send_reaction.await_args_list]
|
||||
assert emojis == ["✅", "❎"]
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_reaction_resolves_pending_approval(self, monkeypatch):
|
||||
monkeypatch.setenv("MATRIX_ALLOWED_USERS", "@liizfq:liizfq.top")
|
||||
from gateway.platforms.matrix import MatrixAdapter, _MatrixApprovalPrompt
|
||||
|
||||
adapter = MatrixAdapter(PlatformConfig(enabled=True, token="tok", extra={"homeserver": "https://matrix.example.org"}))
|
||||
adapter._approval_prompts_by_event["$target"] = _MatrixApprovalPrompt(
|
||||
session_key="sess-1", chat_id="!room:example.org", message_id="$target"
|
||||
)
|
||||
adapter._approval_prompt_by_session["sess-1"] = "$target"
|
||||
|
||||
content = {"m.relates_to": {"event_id": "$target", "key": "✅"}}
|
||||
event = types.SimpleNamespace(
|
||||
sender="@liizfq:liizfq.top",
|
||||
event_id="$react1",
|
||||
room_id="!room:example.org",
|
||||
content=content,
|
||||
)
|
||||
|
||||
with patch("tools.approval.resolve_gateway_approval", return_value=1) as mock_resolve:
|
||||
await adapter._on_reaction(event)
|
||||
|
||||
mock_resolve.assert_called_once_with("sess-1", "once")
|
||||
assert "$target" not in adapter._approval_prompts_by_event
|
||||
assert "sess-1" not in adapter._approval_prompt_by_session
|
||||
Loading…
Add table
Add a link
Reference in a new issue