From ce56b4551402ba2b6463edda94f38ae315056dbb Mon Sep 17 00:00:00 2001 From: stablegenius49 <16443023+stablegenius49@users.noreply.github.com> Date: Wed, 11 Mar 2026 12:46:56 -0700 Subject: [PATCH] fix(gateway): support quick commands from GatewayConfig --- gateway/config.py | 9 +++++++++ gateway/run.py | 5 ++++- tests/test_quick_commands.py | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/gateway/config.py b/gateway/config.py index e45eede7c..613527a84 100644 --- a/gateway/config.py +++ b/gateway/config.py @@ -151,6 +151,9 @@ class GatewayConfig: # Reset trigger commands reset_triggers: List[str] = field(default_factory=lambda: ["/new", "/reset"]) + + # User-defined quick commands (slash commands that bypass the agent loop) + quick_commands: Dict[str, Any] = field(default_factory=dict) # Storage paths sessions_dir: Path = field(default_factory=lambda: get_hermes_home() / "sessions") @@ -218,6 +221,7 @@ class GatewayConfig: p.value: v.to_dict() for p, v in self.reset_by_platform.items() }, "reset_triggers": self.reset_triggers, + "quick_commands": self.quick_commands, "sessions_dir": str(self.sessions_dir), "always_log_local": self.always_log_local, } @@ -252,12 +256,17 @@ class GatewayConfig: if "sessions_dir" in data: sessions_dir = Path(data["sessions_dir"]) + quick_commands = data.get("quick_commands", {}) + if not isinstance(quick_commands, dict): + quick_commands = {} + return cls( platforms=platforms, default_reset_policy=default_policy, reset_by_type=reset_by_type, reset_by_platform=reset_by_platform, reset_triggers=data.get("reset_triggers", ["/new", "/reset"]), + quick_commands=quick_commands, sessions_dir=sessions_dir, always_log_local=data.get("always_log_local", True), ) diff --git a/gateway/run.py b/gateway/run.py index 5bac7da55..2e02a9b3a 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -1013,7 +1013,10 @@ class GatewayRunner: # User-defined quick commands (bypass agent loop, no LLM call) if command: - quick_commands = self.config.get("quick_commands", {}) + if isinstance(self.config, dict): + quick_commands = self.config.get("quick_commands", {}) or {} + else: + quick_commands = getattr(self.config, "quick_commands", {}) or {} if command in quick_commands: qcmd = quick_commands[command] if qcmd.get("type") == "exec": diff --git a/tests/test_quick_commands.py b/tests/test_quick_commands.py index 67e93c1d0..e53f7a3e4 100644 --- a/tests/test_quick_commands.py +++ b/tests/test_quick_commands.py @@ -146,3 +146,20 @@ class TestGatewayQuickCommands: result = await runner._handle_message(event) assert result is not None assert "timed out" in result.lower() + + @pytest.mark.asyncio + async def test_gateway_config_object_supports_quick_commands(self): + from gateway.config import GatewayConfig + from gateway.run import GatewayRunner + + runner = GatewayRunner.__new__(GatewayRunner) + runner.config = GatewayConfig( + quick_commands={"limits": {"type": "exec", "command": "echo ok"}} + ) + runner._running_agents = {} + runner._pending_messages = {} + runner._is_user_authorized = MagicMock(return_value=True) + + event = self._make_event("limits") + result = await runner._handle_message(event) + assert result == "ok"