# NousResearch/hermes-agent · TUI /compress command missing before/after summary

## Open now

- Nothing open on GitHub.

These issues and fixes address the TUI not displaying a before/after compression summary after running /compress. Changes aim to bring TUI behavior to parity with CLI feedback.

## TL;DR

- 3 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 1 merged PR(s), 1 PR(s) closed without merging.
- A fix was merged to main in PR #50303. Verify it addresses your case.
- **Recommended:** read PR #50303 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `unresolved`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.67`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #46686: TUI/Desktop: /compress doesn't show the before/after summary

## Prior & competing PRs

- **#50303: fix(tui): /compress shows a before/after summary (#46686)**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`
  - files: `tests/test_tui_gateway_server.py`, `tui_gateway/server.py`
  - fix hunks:
  - `tests/test_tui_gateway_server.py`

    ```diff
    @@ -4968,7 +4968,8 @@ def _fake_apply_model(sid, session, arg):
     def test_mirror_slash_compress_does_not_prelock_history(monkeypatch):
         """Regression guard: /compress side effect must not hold history_lock
         when calling _compress_session_history (the helper snapshots under
    -    the same non-reentrant lock internally)."""
    +    the same non-reentrant lock internally). It also returns a before/after
    +    summary string (#46686)."""
         import types
     
         seen = {"compress": False, "sync": False}
    ```

    ```diff
    @@ -4977,7 +4978,9 @@ def test_mirror_slash_compress_does_not_prelock_history(monkeypatch):
         def _fake_compress(session, focus_topic=None, **_kw):
             seen["compress"] = True
             assert not session["history_lock"].locked()
    -        return (0, {"total": 0})
    +        # Simulate a real compaction shrinking the transcript.
    +        session["history"] = [{"role": "user", "content": "summary"}]
    +        return (1, {"total": 0})
     
         def _fake_sync(_sid, _session):
             seen["sync"] = True
    ```

    ```diff
    @@ -4988,14 +4991,20 @@ def _fake_sync(_sid, _session):
         monkeypatch.setattr(server, "_emit", lambda *args: emitted.append(args))
     
         session = _session(running=False)
    -    session["agent"] = types.SimpleNamespace(model="x")
    +    session["history"] = [
    +        {"role": "user", "content": f"m{i}"} for i in range(6)
    +    ]
    +    session["agent"] = types.SimpleNamespace(model="x", _cached_system_prompt="", tools=None)
     
         warning = server._mirror_slash_side_effects("sid", session, "/compress")
     
    -    assert warning == ""
    +    # Now returns a before/after summary (was "" before #46686).
         assert seen["compress"]
         assert seen["sync"]
         assert ("session.info", "sid", {"model": "x"}) in emitted
    +    assert "Compressed:" in warning
    +    assert "6 → 1 messages" in warning
    +    assert "tokens" in warning
     
     
     # ---------------------------------------------------------------------------
    ```
  - `tui_gateway/server.py`

    ```diff
    @@ -9806,9 +9806,49 @@ def _mirror_slash_side_effects(sid: str, session: dict, command: str) -> str:
                 agent.ephemeral_system_prompt = new_prompt or None
                 agent._cached_system_prompt = None
             elif name == "compress" and agent:
    +            # Mirror the session.compress RPC: build a before/after summary so
    +            # the user gets feedback (#46686). The slash path previously just
    +            # compressed + emitted session.info and returned "", so the TUI
    +            # showed no "compressed N → M messages / ~X → ~Y tokens" stats
    +            # while CLI and gateway both did.
    +            from agent.manual_compression_feedback import summarize_manual_compression
    +            from agent.model_metadata import estimate_request_tokens_rough
    +
    +            with session["history_lock"]:
    +                _before_messages = list(session.get("history", []))
    +            _before_count = len(_before_messages)
    +            _sys_prompt = getattr(agent, "_cached_system_prompt", "") or ""
    +            _tools = getattr(agent, "tools", None) or None
    +            _before_tokens = (
    +                estimate_request_tokens_rough(
    +                    _before_messages, system_prompt=_sys_prompt, tools=_tools
    +                )
    +                if _before_count
    +                else 0
    +            )
    +
                 _compress_session_history(session, arg)
                 _sync_session_key_after_compress(sid, session)
    +
    +            with session["history_lock"]:
    +                _after_messages = list(session.get("history", []))
    +            _sys_prompt_after = getattr(agent, "_cached_system_prompt", "") or _sys_prompt
    +            _tools_after = getattr(agent, "tools", None) or _tools
    +            _after_tokens = (
    +                estimate_request_tokens_rough(
    +                    _after_messages, system_prompt=_sys_prompt_after, tools=_tools_after
    +                )
    +                if _after_messages
    +                else 0
    +            )
                 _emit("session.info", sid, _session_info(agent, session))
    +            _fb = summarize_manual_compression(
    +                _before_messages, _after_messages, _before_tokens, _after_tokens
    +            )
    +            _lines = [_fb["headline"], _fb["token_line"]]
    +            if _fb.get("note"):
    +                _lines.append(_fb["note"])
    +            return "\n".join(_lines)
             elif name == "fast" and agent:
                 mode = arg.lower()
                 if mode in {"fast", "on"}:
    ```
- **#46702: fix(tui): show compression summary in _mirror_slash_side_effects**. closed without merge
  - maintainer direction: category `merged_via`; implication `superseded`; refs `#50303`

## Fix status

- Merged to main in PR #50303 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-06-21`.
