From 779019ef7d3b9f51870a280874cc9c684b7283d7 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Thu, 16 Jul 2026 22:38:16 -0700 Subject: [PATCH] feat(agent): add display.show_commentary toggle for Codex commentary channel Commentary delivery is on by default; users who find the extra mid-turn narration noisy can set display.show_commentary: false to restore the previous behavior (commentary routed to the reasoning channel, visible only with show_reasoning). - hermes_cli/config.py: display.show_commentary default true - agent/agent_init.py: wire config -> agent.show_commentary - run_agent.py: gate structured commentary extraction on the flag - agent/codex_runtime.py: gate live-stream commentary callback (falls back to legacy reasoning-channel routing when off) - docs + 2 tests (interim path off, live stream fallback) Also adds AUTHOR_MAP entries for davidrobertson and 100yenadmin. --- agent/agent_init.py | 13 ++++ agent/codex_runtime.py | 5 +- hermes_cli/config.py | 6 ++ run_agent.py | 4 ++ scripts/release.py | 2 + .../test_run_agent_codex_responses.py | 68 +++++++++++++++++++ website/docs/user-guide/configuration.md | 3 + 7 files changed, 100 insertions(+), 1 deletion(-) diff --git a/agent/agent_init.py b/agent/agent_init.py index b7d286af5e49..d6ee3e727116 100644 --- a/agent/agent_init.py +++ b/agent/agent_init.py @@ -1359,6 +1359,19 @@ def init_agent( except Exception: _agent_cfg = {} + # Codex commentary visibility (display.show_commentary, default true). + # When true, completed Codex phase=commentary messages are delivered as + # visible mid-turn updates through the interim message path. When false, + # commentary falls back to the reasoning channel (visible only with + # show_reasoning enabled). + agent.show_commentary = True + try: + _display_section = _agent_cfg.get("display", {}) + if isinstance(_display_section, dict): + agent.show_commentary = bool(_display_section.get("show_commentary", True)) + except Exception: + agent.show_commentary = True + # LM Studio can either be explicitly preloaded through LM Studio's # management API (the historical Hermes behavior) or left to LM Studio's # just-in-time / Auto-Evict chat-completions path. Keep the default diff --git a/agent/codex_runtime.py b/agent/codex_runtime.py index 99406ba9e0ec..9cd5f7f5d85e 100644 --- a/agent/codex_runtime.py +++ b/agent/codex_runtime.py @@ -940,7 +940,10 @@ def run_codex_stream(agent, api_kwargs: dict, client: Any = None, on_first_delta on_reasoning_delta=_on_reasoning_delta, on_commentary_message=( _on_commentary_message - if getattr(agent, "interim_assistant_callback", None) is not None + if ( + getattr(agent, "interim_assistant_callback", None) is not None + and getattr(agent, "show_commentary", True) + ) else None ), on_first_delta=on_first_delta, diff --git a/hermes_cli/config.py b/hermes_cli/config.py index b9663d94bdd2..d5b349c6b033 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -1906,6 +1906,12 @@ DEFAULT_CONFIG = { "last_lines": 2, }, "interim_assistant_messages": True, # Gateway: show natural mid-turn assistant status messages + # Codex Responses models narrate progress in a dedicated commentary + # channel. When true (default), completed commentary messages are + # delivered as visible mid-turn updates via the interim message path. + # When false, commentary falls back to the reasoning channel and is + # only visible when show_reasoning is enabled. + "show_commentary": True, "tool_progress_command": False, # Enable /verbose command in messaging gateway "tool_progress_overrides": {}, # DEPRECATED — use display.platforms instead "tool_preview_length": 0, # Max chars for tool call previews (0 = no limit, show full paths/commands) diff --git a/run_agent.py b/run_agent.py index 8e7947fb08d2..c0ef49cbe740 100644 --- a/run_agent.py +++ b/run_agent.py @@ -4766,6 +4766,10 @@ class AIAgent: commentary through the interim assistant callback before tool calls run. ``phase=analysis`` remains hidden because it is provider scratchpad. """ + if not getattr(self, "show_commentary", True): + # display.show_commentary=false — commentary stays on the + # reasoning channel (pre-commentary-channel behavior). + return [] items = assistant_msg.get("codex_message_items") if not isinstance(items, list): return [] diff --git a/scripts/release.py b/scripts/release.py index 9a217938b3aa..0a7224fe6367 100755 --- a/scripts/release.py +++ b/scripts/release.py @@ -371,6 +371,8 @@ AUTHOR_MAP = { "rasitakyol@hotmail.com": "rasitakyol", "thatgfsj@gmail.com": "Thatgfsj", "141703117+seagpt@users.noreply.github.com": "seagpt", + "dr@nevernet.com": "davidrobertson", + "eva@100yen.org": "100yenadmin", "yakimenkoleksander228@gmail.com": "doxe0x", "a54983334@163.com": "Code-suphub", "78542984+Code-suphub@users.noreply.github.com": "Code-suphub", diff --git a/tests/run_agent/test_run_agent_codex_responses.py b/tests/run_agent/test_run_agent_codex_responses.py index 382f864634ff..5f73ae58dd6e 100644 --- a/tests/run_agent/test_run_agent_codex_responses.py +++ b/tests/run_agent/test_run_agent_codex_responses.py @@ -2421,6 +2421,74 @@ def test_interim_commentary_redacts_secrets_from_codex_commentary_items(monkeypa assert "Using credential" in observed[0] +def test_interim_commentary_respects_show_commentary_off(monkeypatch): + """display.show_commentary=false keeps commentary off the interim path.""" + agent = _build_agent(monkeypatch) + agent.show_commentary = False + observed = [] + agent.interim_assistant_callback = ( + lambda text, *, already_streamed=False: observed.append(text) + ) + + agent._emit_interim_assistant_message({ + "role": "assistant", + "content": "", + "codex_message_items": [ + { + "type": "message", + "role": "assistant", + "phase": "commentary", + "content": [ + {"type": "output_text", "text": "I'll inspect the repo first."} + ], + }, + ], + }) + + assert observed == [] + + +def test_run_codex_stream_show_commentary_off_falls_back_to_reasoning(monkeypatch): + """With show_commentary=false the live stream keeps the legacy behavior: + commentary deltas flow to the reasoning channel and the interim callback + stays silent.""" + agent = _build_agent(monkeypatch) + agent.show_commentary = False + delivered = [] + reasoning_streamed = [] + agent.interim_assistant_callback = ( + lambda text, *, already_streamed=False: delivered.append(text) + ) + agent.reasoning_callback = reasoning_streamed.append + commentary_item = SimpleNamespace( + type="message", + phase="commentary", + status="completed", + content=[SimpleNamespace(type="output_text", text="I'll inspect the repo first.")], + ) + + def _fake_create(**kwargs): + return _FakeCreateStream([ + SimpleNamespace( + type="response.output_item.added", + item=SimpleNamespace(type="message", phase="commentary"), + ), + SimpleNamespace(type="response.output_text.delta", delta="I'll inspect the repo first."), + SimpleNamespace(type="response.output_item.done", item=commentary_item), + SimpleNamespace( + type="response.completed", + response=SimpleNamespace(status="completed"), + ), + ]) + + agent.client = SimpleNamespace(responses=SimpleNamespace(create=_fake_create)) + + agent._run_codex_stream(_codex_request_kwargs()) + + assert delivered == [] + assert reasoning_streamed == ["I'll inspect the repo first."] + + def test_interim_commentary_deduplicates_identical_items_in_one_response(monkeypatch): agent = _build_agent(monkeypatch) observed = [] diff --git a/website/docs/user-guide/configuration.md b/website/docs/user-guide/configuration.md index 500840a03165..5297a39f11d3 100644 --- a/website/docs/user-guide/configuration.md +++ b/website/docs/user-guide/configuration.md @@ -1474,6 +1474,7 @@ display: platforms: {} # Per-platform display overrides (see below) tool_progress_overrides: {} # DEPRECATED — use display.platforms instead interim_assistant_messages: true # Gateway: send natural mid-turn assistant updates as separate messages + show_commentary: true # Codex models: deliver commentary-channel progress narration as visible mid-turn updates skin: default # Built-in or custom CLI skin (see user-guide/features/skins) personality: "kawaii" # Legacy cosmetic field still surfaced in some summaries compact: false # Compact output mode (less whitespace) @@ -1590,6 +1591,8 @@ Signal is listed as a valid platform key because the setting can be saved per pl `interim_assistant_messages` is gateway-only. When enabled, Hermes sends completed mid-turn assistant updates as separate chat messages. This is independent from `tool_progress` and does not require gateway streaming. +`show_commentary` (default `true`) controls Codex Responses models' commentary channel — the polished progress narration these models produce alongside their private reasoning. When enabled, each completed commentary message is delivered as a visible mid-turn update (on the gateway this also requires `interim_assistant_messages`). Set it to `false` if the extra narration annoys you: commentary then falls back to the reasoning channel and is only shown when `show_reasoning` is enabled. + ## Privacy ```yaml