Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
"""Tests for plugin message injection across CLI and gateway hosts."""
|
||||
|
||||
from queue import SimpleQueue
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import yaml
|
||||
|
||||
from hermes_cli.plugins import PluginContext, PluginManager, PluginManifest
|
||||
|
||||
|
||||
def _context(name: str = "notify-plugin") -> tuple[PluginContext, PluginManager]:
|
||||
manager = PluginManager()
|
||||
manifest = PluginManifest(name=name, key=name, source="user")
|
||||
return PluginContext(manifest, manager), manager
|
||||
|
||||
|
||||
def _write_plugin_config(tmp_path, monkeypatch, entry: dict) -> None:
|
||||
hermes_home = tmp_path / "hermes"
|
||||
hermes_home.mkdir()
|
||||
(hermes_home / "config.yaml").write_text(
|
||||
yaml.safe_dump({"plugins": {"entries": {"notify-plugin": entry}}})
|
||||
)
|
||||
monkeypatch.setenv("HERMES_HOME", str(hermes_home))
|
||||
|
||||
|
||||
def test_cli_idle_injection_keeps_existing_queue_behaviour():
|
||||
context, manager = _context()
|
||||
cli = SimpleNamespace(
|
||||
_agent_running=False,
|
||||
_pending_input=SimpleQueue(),
|
||||
_interrupt_queue=SimpleQueue(),
|
||||
)
|
||||
manager._cli_ref = cli
|
||||
|
||||
assert context.inject_message("new input") is True
|
||||
assert cli._pending_input.get_nowait() == "new input"
|
||||
assert cli._interrupt_queue.empty()
|
||||
|
||||
|
||||
def test_cli_running_injection_keeps_existing_interrupt_behaviour():
|
||||
context, manager = _context()
|
||||
cli = SimpleNamespace(
|
||||
_agent_running=True,
|
||||
_pending_input=SimpleQueue(),
|
||||
_interrupt_queue=SimpleQueue(),
|
||||
)
|
||||
manager._cli_ref = cli
|
||||
|
||||
assert context.inject_message("status", "system") is True
|
||||
assert cli._interrupt_queue.get_nowait() == "[system] status"
|
||||
assert cli._pending_input.empty()
|
||||
|
||||
|
||||
def test_gateway_injection_requires_session_key(tmp_path, monkeypatch):
|
||||
_write_plugin_config(
|
||||
tmp_path,
|
||||
monkeypatch,
|
||||
{"allow_gateway_injection": True},
|
||||
)
|
||||
context, manager = _context()
|
||||
injector = MagicMock(return_value=True)
|
||||
manager.set_gateway_message_injector(object(), injector)
|
||||
|
||||
assert context.inject_message("wake up") is False
|
||||
injector.assert_not_called()
|
||||
|
||||
|
||||
def test_gateway_injection_requires_explicit_permission(tmp_path, monkeypatch):
|
||||
_write_plugin_config(tmp_path, monkeypatch, {})
|
||||
context, manager = _context()
|
||||
injector = MagicMock(return_value=True)
|
||||
manager.set_gateway_message_injector(object(), injector)
|
||||
|
||||
assert (
|
||||
context.inject_message(
|
||||
"wake up",
|
||||
session_key="agent:main:telegram:dm:42",
|
||||
)
|
||||
is False
|
||||
)
|
||||
injector.assert_not_called()
|
||||
|
||||
|
||||
def test_gateway_injection_does_not_treat_string_as_permission(tmp_path, monkeypatch):
|
||||
_write_plugin_config(
|
||||
tmp_path,
|
||||
monkeypatch,
|
||||
{"allow_gateway_injection": "false"},
|
||||
)
|
||||
context, manager = _context()
|
||||
injector = MagicMock(return_value=True)
|
||||
manager.set_gateway_message_injector(object(), injector)
|
||||
|
||||
assert (
|
||||
context.inject_message(
|
||||
"wake up",
|
||||
session_key="agent:main:telegram:dm:42",
|
||||
)
|
||||
is False
|
||||
)
|
||||
injector.assert_not_called()
|
||||
|
||||
|
||||
def test_gateway_injection_fails_closed_when_config_cannot_be_read():
|
||||
context, manager = _context()
|
||||
injector = MagicMock(return_value=True)
|
||||
manager.set_gateway_message_injector(object(), injector)
|
||||
|
||||
with patch(
|
||||
"hermes_cli.plugins.load_config_readonly",
|
||||
side_effect=OSError("config unavailable"),
|
||||
):
|
||||
assert (
|
||||
context.inject_message(
|
||||
"wake up",
|
||||
session_key="agent:main:telegram:dm:42",
|
||||
)
|
||||
is False
|
||||
)
|
||||
|
||||
injector.assert_not_called()
|
||||
|
||||
|
||||
def test_gateway_injection_requires_live_host(tmp_path, monkeypatch):
|
||||
_write_plugin_config(
|
||||
tmp_path,
|
||||
monkeypatch,
|
||||
{"allow_gateway_injection": True},
|
||||
)
|
||||
context, manager = _context()
|
||||
|
||||
assert manager.has_gateway_message_injector is False
|
||||
assert (
|
||||
context.inject_message(
|
||||
"wake up",
|
||||
session_key="agent:main:telegram:dm:42",
|
||||
)
|
||||
is False
|
||||
)
|
||||
|
||||
|
||||
def test_gateway_injection_passes_host_owned_plugin_identity(tmp_path, monkeypatch):
|
||||
_write_plugin_config(
|
||||
tmp_path,
|
||||
monkeypatch,
|
||||
{"allow_gateway_injection": True},
|
||||
)
|
||||
context, manager = _context()
|
||||
injector = MagicMock(return_value=True)
|
||||
manager.set_gateway_message_injector(object(), injector)
|
||||
|
||||
result = context.inject_message(
|
||||
"wake up",
|
||||
role="system",
|
||||
session_key="agent:main:telegram:dm:42",
|
||||
)
|
||||
|
||||
assert result is True
|
||||
injector.assert_called_once_with(
|
||||
session_key="agent:main:telegram:dm:42",
|
||||
content="[system] wake up",
|
||||
plugin_id="notify-plugin",
|
||||
)
|
||||
|
||||
|
||||
def test_gateway_injection_returns_host_rejection(tmp_path, monkeypatch):
|
||||
_write_plugin_config(
|
||||
tmp_path,
|
||||
monkeypatch,
|
||||
{"allow_gateway_injection": True},
|
||||
)
|
||||
context, manager = _context()
|
||||
manager.set_gateway_message_injector(
|
||||
object(),
|
||||
MagicMock(return_value=False),
|
||||
)
|
||||
|
||||
assert (
|
||||
context.inject_message(
|
||||
"wake up",
|
||||
session_key="agent:main:telegram:dm:42",
|
||||
)
|
||||
is False
|
||||
)
|
||||
|
||||
|
||||
def test_gateway_injection_fails_closed_on_host_exception(tmp_path, monkeypatch):
|
||||
_write_plugin_config(
|
||||
tmp_path,
|
||||
monkeypatch,
|
||||
{"allow_gateway_injection": True},
|
||||
)
|
||||
context, manager = _context()
|
||||
injector = MagicMock(side_effect=RuntimeError("gateway unavailable"))
|
||||
manager.set_gateway_message_injector(object(), injector)
|
||||
|
||||
assert (
|
||||
context.inject_message(
|
||||
"wake up",
|
||||
session_key="agent:main:telegram:dm:42",
|
||||
)
|
||||
is False
|
||||
)
|
||||
Reference in New Issue
Block a user