Skip to content

Commit 3cd6cbe

Browse files
committed
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
1 parent f724079 commit 3cd6cbe

3 files changed

Lines changed: 69 additions & 0 deletions

File tree

cli.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5391,6 +5391,8 @@ def process_command(self, command: str) -> bool:
53915391
self._show_usage()
53925392
elif canonical == "insights":
53935393
self._show_insights(cmd_original)
5394+
elif canonical == "debug":
5395+
self._handle_debug_command()
53945396
elif canonical == "paste":
53955397
self._handle_paste_command()
53965398
elif canonical == "image":
@@ -6305,6 +6307,14 @@ def _manual_compress(self, cmd_original: str = ""):
63056307
except Exception as e:
63066308
print(f" ❌ Compression failed: {e}")
63076309

6310+
def _handle_debug_command(self):
6311+
"""Handle /debug — upload debug report + logs and print paste URLs."""
6312+
from hermes_cli.debug import run_debug_share
6313+
from types import SimpleNamespace
6314+
6315+
args = SimpleNamespace(lines=200, expire=7, local=False)
6316+
run_debug_share(args)
6317+
63086318
def _show_usage(self):
63096319
"""Show rate limits (if available) and session token usage."""
63106320
if not self.agent:

gateway/run.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2757,6 +2757,9 @@ async def _handle_message(self, event: MessageEvent) -> Optional[str]:
27572757
if canonical == "update":
27582758
return await self._handle_update_command(event)
27592759

2760+
if canonical == "debug":
2761+
return await self._handle_debug_command(event)
2762+
27602763
if canonical == "title":
27612764
return await self._handle_title_command(event)
27622765

@@ -6428,6 +6431,61 @@ async def _handle_deny_command(self, event: MessageEvent) -> str:
64286431
Platform.FEISHU, Platform.WECOM, Platform.WECOM_CALLBACK, Platform.WEIXIN, Platform.BLUEBUBBLES, Platform.LOCAL,
64296432
})
64306433

6434+
async def _handle_debug_command(self, event: MessageEvent) -> str:
6435+
"""Handle /debug — upload debug report + logs and return paste URLs."""
6436+
import asyncio
6437+
from hermes_cli.debug import (
6438+
_capture_dump, collect_debug_report, _read_full_log,
6439+
upload_to_pastebin,
6440+
)
6441+
6442+
loop = asyncio.get_running_loop()
6443+
6444+
# Run blocking I/O (dump capture, log reads, uploads) in a thread.
6445+
def _collect_and_upload():
6446+
dump_text = _capture_dump()
6447+
report = collect_debug_report(log_lines=200, dump_text=dump_text)
6448+
agent_log = _read_full_log("agent")
6449+
gateway_log = _read_full_log("gateway")
6450+
6451+
if agent_log:
6452+
agent_log = dump_text + "\n\n--- full agent.log ---\n" + agent_log
6453+
if gateway_log:
6454+
gateway_log = dump_text + "\n\n--- full gateway.log ---\n" + gateway_log
6455+
6456+
urls = {}
6457+
failures = []
6458+
6459+
try:
6460+
urls["Report"] = upload_to_pastebin(report)
6461+
except Exception as exc:
6462+
return f"✗ Failed to upload debug report: {exc}"
6463+
6464+
if agent_log:
6465+
try:
6466+
urls["agent.log"] = upload_to_pastebin(agent_log)
6467+
except Exception:
6468+
failures.append("agent.log")
6469+
6470+
if gateway_log:
6471+
try:
6472+
urls["gateway.log"] = upload_to_pastebin(gateway_log)
6473+
except Exception:
6474+
failures.append("gateway.log")
6475+
6476+
lines = ["**Debug report uploaded:**", ""]
6477+
label_width = max(len(k) for k in urls)
6478+
for label, url in urls.items():
6479+
lines.append(f"`{label:<{label_width}}` {url}")
6480+
6481+
if failures:
6482+
lines.append(f"\n_(failed to upload: {', '.join(failures)})_")
6483+
6484+
lines.append("\nShare these links with the Hermes team for support.")
6485+
return "\n".join(lines)
6486+
6487+
return await loop.run_in_executor(None, _collect_and_upload)
6488+
64316489
async def _handle_update_command(self, event: MessageEvent) -> str:
64326490
"""Handle /update command — update Hermes Agent to the latest version.
64336491

hermes_cli/commands.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class CommandDef:
154154
cli_only=True, args_hint="<path>"),
155155
CommandDef("update", "Update Hermes Agent to the latest version", "Info",
156156
gateway_only=True),
157+
CommandDef("debug", "Upload debug report (system info + logs) and get shareable links", "Info"),
157158

158159
# Exit
159160
CommandDef("quit", "Exit the CLI", "Exit",

0 commit comments

Comments
 (0)