{"repo":"NousResearch/hermes-agent","public_id":"44456","display_label":"'/compress' command not routed correctly in Desktop TUI","summary":"Multiple bug reports and fix attempts address the same issue: the /compress command in the Desktop/TUI interface fails because command.dispatch does not route it to the correct handler, instead returning a 'not a quick/plugin/skill command' error. The members represent the bug and various proposed or competing fixes for this routing gap.","subsystem":"apps/desktop","counts":{"members":13,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":4,"merged_prs":2,"attempt_prs":7},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":60921},"resolution":{"state":"partially_resolved","by":"pr-60921,pr-68229"},"freshness":{"state":"verified","last_verified_at":"2026-07-22T20:40:07+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_PARTIAL","link_density":0.14307692307692305},"fix_edges":[{"issue_number":44456,"pr_number":68229,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true},{"issue_number":60603,"pr_number":60921,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true}],"members":[{"kind":"issue","number":44456,"title":"[Bug]: Desktop /compress returns \"not a quick/plugin/skill command: compress\" — TUI command.dispatch doesn't redirect built-ins to slash.exec","url":null,"state":"closed"},{"kind":"issue","number":46556,"title":"Desktop GUI: /compress command not recognized (routed to quick/plugin/skill handler)","url":null,"state":"closed"},{"kind":"issue","number":60603,"title":"[Bug]: When using Hermes Desktop, if you want to actively compress the context during a conversation, you can use the '/compress' command, but it will display '/compress·error: not a quick/plugin/skill command: compress'","url":null,"state":"closed"},{"kind":"issue","number":60705,"title":"Desktop: /compress fails with 'not a quick/plugin/skill command: compress'","url":null,"state":"closed"},{"kind":"pr","number":44462,"title":"fix(desktop): route /compress via session.compress and stop masking slash.exec errors behind \"not a quick/plugin/skill command\"","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#44456","number":44456}],"category":"stale_abandoned","implication":"active"},"merged":false},{"kind":"pr","number":44464,"title":"fix(tui-gateway): route /compress through command.dispatch for Desktop/TUI","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#44462","number":44462},{"kind":"pr","value":"#44462","number":44462}],"category":"superseded_by_pr","implication":"superseded"},"merged":false,"is_fix_pr":true,"fix_tier":"suggested","fix_detail_withheld":true},{"kind":"pr","number":44554,"title":"fix(tui): route /compress command to session.compress handler (#44456)","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#44462","number":44462},{"kind":"pr","value":"#44456","number":44456}],"category":"superseded_by_pr","implication":"superseded"},"merged":false},{"kind":"pr","number":53664,"title":"fix(desktop): route /compress through session.rpc (superseded)","url":null,"state":"closed","close_reason":{"category":"silent_close","implication":"active"},"merged":false},{"kind":"pr","number":60644,"title":"fix(desktop): register /compress command in TUI gateway dispatch so Desktop can invoke it","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#60921","number":60921},{"kind":"pr","value":"#60834","number":60834},{"kind":"pr","value":"#60603","number":60603}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":60834,"title":"fix(tui): route /compress through command.dispatch with server-side compression","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#60644","number":60644},{"kind":"pr","value":"#60603","number":60603},{"kind":"pr","value":"#60644","number":60644}],"category":"superseded_by_pr","implication":"superseded"},"merged":false,"is_fix_pr":true,"fix_tier":"suggested","fix_detail_withheld":true},{"kind":"pr","number":60921,"title":"fix(desktop): register /compress in TUI gateway command.dispatch (salvage #60644)","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["tui_gateway/server.py"],"fix_hunks":[{"file":"tui_gateway/server.py","hunks":["@@ -11428,6 +11428,8 @@ def _(rid, params: dict) -> dict:\n         \"moa\",\n         \"undo\",\n         \"learn\",\n+        \"compress\",\n+        \"compact\",\n     }\n )\n ","@@ -12013,6 +12015,72 @@ def _(rid, params: dict) -> dict:\n                 },\n             )\n \n+    if name in {\"compress\", \"compact\"}:\n+        if not session:\n+            return _err(rid, 4001, \"no active session to compress\")\n+        if session.get(\"running\"):\n+            return _err(\n+                rid, 4009, \"session busy — /interrupt the current turn before /compress\"\n+            )\n+        sid = params.get(\"session_id\", \"\")\n+        try:\n+            from agent.manual_compression_feedback import summarize_manual_compression\n+            from agent.model_metadata import estimate_request_tokens_rough\n+\n+            with session[\"history_lock\"]:\n+                before_messages = list(session.get(\"history\", []))\n+                history_version = int(session.get(\"history_version\", 0))\n+            before_count = len(before_messages)\n+            _agent = session[\"agent\"]\n+            _sys_prompt = getattr(_agent, \"_cached_system_prompt\", \"\") or \"\"\n+            _tools = getattr(_agent, \"tools\", None) or None\n+            before_tokens = (\n+                estimate_request_tokens_rough(\n+                    before_messages, system_prompt=_sys_prompt, tools=_tools\n+                )\n+                if before_count\n+                else 0\n+            )\n+            removed, usage = _compress_session_history(\n+                session,\n+                arg.strip() or None,\n+                approx_tokens=[redacted:secret-assignment]\n+                before_messages=before_messages,\n+                history_version=history_version,\n+            )\n+            with session[\"history_lock\"]:\n+                after_messages = list(session.get(\"history\", []))\n+            after_count = len(after_messages)\n+            _sys_prompt_after = (\n+                getattr(_agent, \"_cached_system_prompt\", \"\") or _sys_prompt\n+            )\n+            _tools_after = getattr(_agent, \"tools\", None) or _tools\n+            after_tokens = (\n+                estimate_request_tokens_rough(\n+                    after_messages,\n+                    system_prompt=_sys_prompt_after,\n+                    tools=_tools_after,\n+                )\n+                if after_count\n+                else 0\n+            )\n+            _sync_session_key_after_compress(sid, session)\n+            summary = summarize_manual_compression(\n+                before_messages, after_messages, before_tokens, after_tokens\n+            )\n+            _emit(\"session.info\", sid, _session_info(session.get(\"agent\"), session))\n+            return _ok(\n+                rid,\n+                {\n+                    \"type\": \"exec\",\n+                    \"output\": \"\\n\".join(\n+                        filter(None, [summary[\"headline\"], summary[\"token_line\"], summary.get(\"note\")])\n+                    ),\n+                },\n+            )\n+        except Exception as exc:\n+            return _err(rid, 5009, f\"compress failed: {exc}\")\n+\n     return _err(rid, 4018, f\"not a quick/plugin/skill command: {name}\")\n \n \n"]}]},{"kind":"pr","number":68229,"title":"fix(desktop): salvage /compress cluster — session.compress RPC + dedicated RPC routing","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["apps/desktop/src/app/session/hooks/use-prompt-actions/index.test.tsx","apps/desktop/src/app/session/hooks/use-prompt-actions/index.ts","apps/desktop/src/app/session/hooks/use-prompt-actions/slash.ts","apps/desktop/src/app/session/hooks/use-prompt-actions/utils.test.ts","apps/desktop/src/app/session/hooks/use-prompt-actions/utils.ts","apps/desktop/src/app/settings/toolset-config-panel.test.tsx","apps/desktop/src/app/settings/toolset-config-panel.tsx","apps/desktop/src/app/types.ts","apps/desktop/src/lib/desktop-git.test.ts","apps/desktop/src/lib/desktop-git.ts","apps/desktop/src/lib/desktop-slash-commands.test.ts","apps/desktop/src/lib/desktop-slash-commands.ts","apps/shared/src/json-rpc-gateway.ts","tests/test_tui_gateway_server.py","tests/tui_gateway/test_compute_host_phase1.py","tui_gateway/compute_host.py","tui_gateway/host_supervisor.py","tui_gateway/server.py"]},{"kind":"pr","number":69545,"title":"fix(desktop): salvage /compress cluster — session.compress RPC + dedicated-RPC routing","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"41e00dcf87","number":0},{"kind":"pr","value":"#68229","number":68229}],"category":"implemented_elsewhere","implication":"superseded"},"merged":false}],"trust":{"default_tier":"verified","includes_suggested":false}}