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.
This commit is contained in:
Teknium 2026-07-16 22:38:16 -07:00
parent 7041c56cdf
commit 779019ef7d
7 changed files with 100 additions and 1 deletions

View file

@ -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

View file

@ -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,

View file

@ -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)

View file

@ -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 []

View file

@ -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",

View file

@ -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 = []

View file

@ -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