mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-08 03:01:47 +00:00
fix(tui): harden plugin slash exec errors
This commit is contained in:
parent
7e780f4832
commit
21c7c9f0ca
2 changed files with 81 additions and 11 deletions
|
|
@ -421,6 +421,69 @@ def test_slash_exec_handles_plugin_commands_in_live_gateway(server):
|
||||||
assert worker.calls == []
|
assert worker.calls == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_slash_exec_plugin_lookup_failure_falls_back_to_worker(server):
|
||||||
|
"""Plugin discovery failures must not break ordinary slash-worker commands."""
|
||||||
|
sid = "test-session"
|
||||||
|
|
||||||
|
class Worker:
|
||||||
|
def __init__(self):
|
||||||
|
self.calls = []
|
||||||
|
|
||||||
|
def run(self, cmd):
|
||||||
|
self.calls.append(cmd)
|
||||||
|
return f"worker:{cmd}"
|
||||||
|
|
||||||
|
worker = Worker()
|
||||||
|
server._sessions[sid] = {"session_key": sid, "agent": None, "slash_worker": worker}
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"hermes_cli.plugins.get_plugin_command_handler",
|
||||||
|
side_effect=RuntimeError("discovery boom"),
|
||||||
|
):
|
||||||
|
resp = server.handle_request({
|
||||||
|
"id": "r-plugin-lookup-failure",
|
||||||
|
"method": "slash.exec",
|
||||||
|
"params": {"command": "help", "session_id": sid},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert "error" not in resp
|
||||||
|
assert resp["result"] == {"output": "worker:help"}
|
||||||
|
assert worker.calls == ["help"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_slash_exec_plugin_handler_error_returns_output(server):
|
||||||
|
"""Plugin handler failures return slash output so the TUI does not redispatch."""
|
||||||
|
sid = "test-session"
|
||||||
|
|
||||||
|
class Worker:
|
||||||
|
def __init__(self):
|
||||||
|
self.calls = []
|
||||||
|
|
||||||
|
def run(self, cmd):
|
||||||
|
self.calls.append(cmd)
|
||||||
|
return f"worker:{cmd}"
|
||||||
|
|
||||||
|
def handler(arg):
|
||||||
|
raise RuntimeError(f"handler boom: {arg}")
|
||||||
|
|
||||||
|
worker = Worker()
|
||||||
|
server._sessions[sid] = {"session_key": sid, "agent": None, "slash_worker": worker}
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"hermes_cli.plugins.get_plugin_command_handler",
|
||||||
|
lambda name: handler if name == "plugin-cmd" else None,
|
||||||
|
):
|
||||||
|
resp = server.handle_request({
|
||||||
|
"id": "r-plugin-handler-error",
|
||||||
|
"method": "slash.exec",
|
||||||
|
"params": {"command": "plugin-cmd hello", "session_id": sid},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert "error" not in resp
|
||||||
|
assert resp["result"] == {"output": "Plugin command error: handler boom: hello"}
|
||||||
|
assert worker.calls == []
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("cmd", ["retry", "queue hello", "q hello", "steer fix the test", "plan"])
|
@pytest.mark.parametrize("cmd", ["retry", "queue hello", "q hello", "steer fix the test", "plan"])
|
||||||
def test_slash_exec_rejects_pending_input_commands(server, cmd):
|
def test_slash_exec_rejects_pending_input_commands(server, cmd):
|
||||||
"""slash.exec must reject commands that use _pending_input in the CLI."""
|
"""slash.exec must reject commands that use _pending_input in the CLI."""
|
||||||
|
|
|
||||||
|
|
@ -5189,19 +5189,26 @@ def _(rid, params: dict) -> dict:
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
plugin_handler = None
|
||||||
|
resolve_plugin_command_result = None
|
||||||
|
if _cmd_base:
|
||||||
try:
|
try:
|
||||||
from hermes_cli.plugins import (
|
from hermes_cli.plugins import (
|
||||||
get_plugin_command_handler,
|
get_plugin_command_handler,
|
||||||
resolve_plugin_command_result,
|
resolve_plugin_command_result,
|
||||||
)
|
)
|
||||||
|
|
||||||
if _cmd_base:
|
|
||||||
plugin_handler = get_plugin_command_handler(_cmd_base)
|
plugin_handler = get_plugin_command_handler(_cmd_base)
|
||||||
if plugin_handler:
|
except Exception:
|
||||||
|
plugin_handler = None
|
||||||
|
resolve_plugin_command_result = None
|
||||||
|
|
||||||
|
if plugin_handler and resolve_plugin_command_result:
|
||||||
|
try:
|
||||||
result = resolve_plugin_command_result(plugin_handler(_cmd_arg))
|
result = resolve_plugin_command_result(plugin_handler(_cmd_arg))
|
||||||
return _ok(rid, {"output": str(result or "(no output)")})
|
return _ok(rid, {"output": str(result or "(no output)")})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return _err(rid, 4018, f"plugin command error: {e}")
|
return _ok(rid, {"output": f"Plugin command error: {e}"})
|
||||||
|
|
||||||
worker = session.get("slash_worker")
|
worker = session.get("slash_worker")
|
||||||
if not worker:
|
if not worker:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue