feat: add /debug slash command for all platforms
Adds /debug as a slash command available in CLI, Telegram, Discord, Slack, and all other gateway platforms. Uploads debug report + full logs to paste services and returns shareable URLs. - commands.py: CommandDef in Info category (no cli_only/gateway_only) - gateway/run.py: async handler with run_in_executor for blocking I/O - cli.py: dispatch in process_command to run_debug_share
This commit is contained in:
10
cli.py
10
cli.py
@@ -5391,6 +5391,8 @@ class HermesCLI:
|
|||||||
self._show_usage()
|
self._show_usage()
|
||||||
elif canonical == "insights":
|
elif canonical == "insights":
|
||||||
self._show_insights(cmd_original)
|
self._show_insights(cmd_original)
|
||||||
|
elif canonical == "debug":
|
||||||
|
self._handle_debug_command()
|
||||||
elif canonical == "paste":
|
elif canonical == "paste":
|
||||||
self._handle_paste_command()
|
self._handle_paste_command()
|
||||||
elif canonical == "image":
|
elif canonical == "image":
|
||||||
@@ -6305,6 +6307,14 @@ class HermesCLI:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f" ❌ Compression failed: {e}")
|
print(f" ❌ Compression failed: {e}")
|
||||||
|
|
||||||
|
def _handle_debug_command(self):
|
||||||
|
"""Handle /debug — upload debug report + logs and print paste URLs."""
|
||||||
|
from hermes_cli.debug import run_debug_share
|
||||||
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
args = SimpleNamespace(lines=200, expire=7, local=False)
|
||||||
|
run_debug_share(args)
|
||||||
|
|
||||||
def _show_usage(self):
|
def _show_usage(self):
|
||||||
"""Show rate limits (if available) and session token usage."""
|
"""Show rate limits (if available) and session token usage."""
|
||||||
if not self.agent:
|
if not self.agent:
|
||||||
|
|||||||
@@ -2757,6 +2757,9 @@ class GatewayRunner:
|
|||||||
if canonical == "update":
|
if canonical == "update":
|
||||||
return await self._handle_update_command(event)
|
return await self._handle_update_command(event)
|
||||||
|
|
||||||
|
if canonical == "debug":
|
||||||
|
return await self._handle_debug_command(event)
|
||||||
|
|
||||||
if canonical == "title":
|
if canonical == "title":
|
||||||
return await self._handle_title_command(event)
|
return await self._handle_title_command(event)
|
||||||
|
|
||||||
@@ -6428,6 +6431,61 @@ class GatewayRunner:
|
|||||||
Platform.FEISHU, Platform.WECOM, Platform.WECOM_CALLBACK, Platform.WEIXIN, Platform.BLUEBUBBLES, Platform.LOCAL,
|
Platform.FEISHU, Platform.WECOM, Platform.WECOM_CALLBACK, Platform.WEIXIN, Platform.BLUEBUBBLES, Platform.LOCAL,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
async def _handle_debug_command(self, event: MessageEvent) -> str:
|
||||||
|
"""Handle /debug — upload debug report + logs and return paste URLs."""
|
||||||
|
import asyncio
|
||||||
|
from hermes_cli.debug import (
|
||||||
|
_capture_dump, collect_debug_report, _read_full_log,
|
||||||
|
upload_to_pastebin,
|
||||||
|
)
|
||||||
|
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
|
||||||
|
# Run blocking I/O (dump capture, log reads, uploads) in a thread.
|
||||||
|
def _collect_and_upload():
|
||||||
|
dump_text = _capture_dump()
|
||||||
|
report = collect_debug_report(log_lines=200, dump_text=dump_text)
|
||||||
|
agent_log = _read_full_log("agent")
|
||||||
|
gateway_log = _read_full_log("gateway")
|
||||||
|
|
||||||
|
if agent_log:
|
||||||
|
agent_log = dump_text + "\n\n--- full agent.log ---\n" + agent_log
|
||||||
|
if gateway_log:
|
||||||
|
gateway_log = dump_text + "\n\n--- full gateway.log ---\n" + gateway_log
|
||||||
|
|
||||||
|
urls = {}
|
||||||
|
failures = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
urls["Report"] = upload_to_pastebin(report)
|
||||||
|
except Exception as exc:
|
||||||
|
return f"✗ Failed to upload debug report: {exc}"
|
||||||
|
|
||||||
|
if agent_log:
|
||||||
|
try:
|
||||||
|
urls["agent.log"] = upload_to_pastebin(agent_log)
|
||||||
|
except Exception:
|
||||||
|
failures.append("agent.log")
|
||||||
|
|
||||||
|
if gateway_log:
|
||||||
|
try:
|
||||||
|
urls["gateway.log"] = upload_to_pastebin(gateway_log)
|
||||||
|
except Exception:
|
||||||
|
failures.append("gateway.log")
|
||||||
|
|
||||||
|
lines = ["**Debug report uploaded:**", ""]
|
||||||
|
label_width = max(len(k) for k in urls)
|
||||||
|
for label, url in urls.items():
|
||||||
|
lines.append(f"`{label:<{label_width}}` {url}")
|
||||||
|
|
||||||
|
if failures:
|
||||||
|
lines.append(f"\n_(failed to upload: {', '.join(failures)})_")
|
||||||
|
|
||||||
|
lines.append("\nShare these links with the Hermes team for support.")
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
return await loop.run_in_executor(None, _collect_and_upload)
|
||||||
|
|
||||||
async def _handle_update_command(self, event: MessageEvent) -> str:
|
async def _handle_update_command(self, event: MessageEvent) -> str:
|
||||||
"""Handle /update command — update Hermes Agent to the latest version.
|
"""Handle /update command — update Hermes Agent to the latest version.
|
||||||
|
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ COMMAND_REGISTRY: list[CommandDef] = [
|
|||||||
cli_only=True, args_hint="<path>"),
|
cli_only=True, args_hint="<path>"),
|
||||||
CommandDef("update", "Update Hermes Agent to the latest version", "Info",
|
CommandDef("update", "Update Hermes Agent to the latest version", "Info",
|
||||||
gateway_only=True),
|
gateway_only=True),
|
||||||
|
CommandDef("debug", "Upload debug report (system info + logs) and get shareable links", "Info"),
|
||||||
|
|
||||||
# Exit
|
# Exit
|
||||||
CommandDef("quit", "Exit the CLI", "Exit",
|
CommandDef("quit", "Exit the CLI", "Exit",
|
||||||
|
|||||||
Reference in New Issue
Block a user