Skip to content

feat(gateway): render terminal tool calls as native bash code blocks on markdown platforms#41215

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-97ca6b73
Jun 8, 2026
Merged

feat(gateway): render terminal tool calls as native bash code blocks on markdown platforms#41215
teknium1 merged 1 commit into
mainfrom
hermes/hermes-97ca6b73

Conversation

@teknium1

@teknium1 teknium1 commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Tool-progress renders a terminal call's command in a ```bash fenced code block — full command, no quotes, no label, no truncation — on every platform that renders markdown code blocks, instead of the flat terminal: "cmd…" line.

Changes

  • gateway/platforms/base.py: new BasePlatformAdapter.supports_code_blocks capability flag (default False).
  • telegram / slack / matrix / whatsapp / feishu / weixin and plugins/platforms/discord: set supports_code_blocks = True (each renders fenced blocks).
  • gateway/run.py (progress_callback): when the resolved adapter reports supports_code_blocks and the tool is terminal, emit ```bash\n{command}\n``` for both all/new and verbose modes. Gated on the capability — not a hardcoded platform list — so plugin adapters (Discord lives in plugins/platforms/) opt in by setting the flag. Falls back to the existing line when the command arg is missing/blank, and plain-text platforms are unchanged.

Validation

Case Result
Capable adapter (TG/Discord/Slack/Matrix/WA/Feishu/Weixin) + terminal ```bash full command, no truncation
Capable adapter, verbose mode same fenced block
Plain-text adapter (default False) unchanged terminal: "cmd…" line
Adapter missing the attr safe fallback (getattr default False)
Capable adapter, non-terminal tool unchanged
Capable adapter, blank/missing command safe fallback
  • E2E: ran the real format_message() of all seven markdown adapters on the produced line — fence preserved, no body escaping, command intact.
  • Base default asserted False; gating logic tested across all six cases above.
  • py_compile clean on all touched files; rebased onto current origin/main (diff is exactly the 9 changed files, +44/−3).

Infographic

terminal-bash-code-blocks-all-markdown-platforms

@github-actions

github-actions Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-97ca6b73 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 10030 on HEAD, 10030 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 5196 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@teknium1 teknium1 force-pushed the hermes/hermes-97ca6b73 branch from 324a0ca to 80b87fe Compare June 7, 2026 12:12
@teknium1 teknium1 changed the title feat(telegram): render terminal tool calls as native bash code blocks feat(gateway): render terminal tool calls as native bash code blocks on markdown platforms Jun 7, 2026
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/gateway Gateway runner, session dispatch, delivery labels Jun 7, 2026
@teknium1 teknium1 force-pushed the hermes/hermes-97ca6b73 branch from 80b87fe to 850c590 Compare June 7, 2026 13:24
…on markdown platforms

Tool-progress now shows a terminal command in a ```bash fenced block —
full command, no surrounding quotes, no label, no 40-char truncation —
instead of the noisy `terminal: "cmd…"` line, on every platform that
renders markdown code blocks (Telegram, Slack, Matrix, WhatsApp, Feishu,
Weixin, Discord). Plain-text platforms keep the compact preview line.

Gated on a new `BasePlatformAdapter.supports_code_blocks` capability
(default False) rather than a hardcoded platform list, so plugin adapters
(Discord lives in plugins/platforms/) opt in by setting the flag. Applies
to both all/new and verbose progress modes, with a safe fallback when the
command arg is missing or blank.
@teknium1 teknium1 force-pushed the hermes/hermes-97ca6b73 branch from 850c590 to e945770 Compare June 7, 2026 17:06
@teknium1 teknium1 merged commit dde9c0d into main Jun 8, 2026
23 checks passed
@teknium1 teknium1 deleted the hermes/hermes-97ca6b73 branch June 8, 2026 00:29
@teknium1

teknium1 commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Infographic

merged-terminal-bash-code-blocks

agogo233 added a commit to agogo233/hermes-agent that referenced this pull request Jun 8, 2026
* upstream/main: (430 commits)
  fix(yuanbao): bound ws.close() so an idle server can't stall shutdown ~5s (NousResearch#40607)
  docs: add Urdu translation of README (NousResearch#40578)
  fix(hindsight): send only new-turn delta on append retains instead of whole session (NousResearch#40605)
  feat(gateway): render terminal tool calls as native bash code blocks on markdown platforms (NousResearch#41215)
  feat(desktop): stop the chat viewport from following streaming output (NousResearch#41414)
  chore(release): map AlchemistChaos co-author email for NousResearch#40135 salvage
  fix(desktop): recover chat after sleep/wake by revalidating a stale remote backend
  fix(web): make _has_env config-aware so SEARXNG_URL auto-detect honors Hermes config
  fix(web): honor Hermes config-aware SEARXNG_URL lookup
  install.sh: hint at root-owned npm cache when desktop npm install fails (NousResearch#39688)
  fix(tools): percent-encode non-ascii URL components
  fix(skills): browse shows full catalog, not first 5000 (NousResearch#41413)
  feat(desktop+gateway): remote media relay — attach images/PDFs and display gateway images over the network
  feat(desktop): full tool-backend config (pickers + per-backend settings) in Settings (NousResearch#41232)
  hardening(api-server): scan cron prompts on REST create/update for parity with the agent tool
  fix: skip MCP preflight content-type probe on reconnect when already ready (NousResearch#40604)
  fix(kanban): sweep deferred scratch parent on non-scratch child completion + tests
  fix: defer scratch workspace cleanup when task has active children (NousResearch#33774)
  feat(onboarding): opt-in structured profile-build path on first contact (NousResearch#41114)
  feat(compression): temporal anchoring in compaction summaries (NousResearch#41102)
  test(discord): align clarify/model-picker tests with fail-closed component auth (NousResearch#41338)
  chore(release): map Dusk1e and LaPhilosophie for approval fail-closed salvage (NousResearch#33844, NousResearch#33866, NousResearch#30964)
  fix(discord): fail closed for component button auth when no allowlist set
  fix(feishu): fail closed for update prompt card actions
  fix(slack): re-check gateway auth on approval and slash-confirm buttons
  fix: guard int(os.getenv()) casts against malformed env vars (NousResearch#40598)
  fix: respect Honcho env var fallback in doctor and honcho status
  chore(release): add synapsesx to AUTHOR_MAP for NousResearch#40495 salvage
  fix(research): keep tool_call/tool_response pairs intact when compressing trajectories
  fix(simplex): accept display name in SIMPLEX_ALLOWED_USERS
  fix(desktop): make the running-turn timer per-session (NousResearch#41182)
  test(approval): regression for shell-escape denylist bypass (NousResearch#36846, NousResearch#36847)
  fix(security): strip shell escapes in denylist normalizer; fail-closed on missing approval module
  fix(stream+output-cap): guard empty streams and parse OpenRouter output-cap errors (NousResearch#40589)
  fix(desktop): bootstrap falls back to installed agent install.sh on GitHub 404
  feat(dashboard): change UI font from the theme picker, independent of theme (NousResearch#41145)
  fix(cli): return bool (not None) when a destructive-slash confirmation is cancelled (NousResearch#40583)
  fix(desktop): preserve configured base_url on same-provider model switch (NousResearch#41121)
  fix(desktop): stop bare-URL autolinker swallowing trailing emphasis asterisks (NousResearch#41093)
  fix(cron): bound the desktop run-history query to one job (NousResearch#41088)
  fix(desktop): scope in-session /model switch per-session, stop process-env leak (NousResearch#41120)
  chore: map bmoore210 author email for PR NousResearch#40550 salvage
  fix(desktop): scope session list to active profile + longer timeout
  fix: harden gateway startup and turn persistence
  fix(computer_use): honor custom vision routing
  fix(aux): honor model.default_headers on auxiliary client too (NousResearch#40033)
  fix(agent): honor model.default_headers for custom OpenAI-compatible providers (NousResearch#40033)
  docs(i18n): port deep-audit corrections to zh-Hans mirror (NousResearch#41104)
  fix(compression): don't overwrite the -1 post-compression sentinel in preflight seed (NousResearch#36718)
  chore(release): map singhsanidhya741@gmail.com to sanidhyasin (NousResearch#41094)
  ...
GodsBoy added a commit to GodsBoy/hermes-agent that referenced this pull request Jun 8, 2026
… messaging chats

NousResearch#41215 rendered a terminal tool call as a native ```bash fenced block on
markdown platforms (Telegram, WhatsApp, Slack, and others), showing the full
command with no truncation, in both all/new and verbose modes. That posted
complete shell commands (heredocs, internal paths, destructive commands) into
the chat before the final answer, visible to everyone in it.

This restores the prior behavior: terminal progress shows the short, truncated
preview line that every other tool already uses, capped at tool_preview_length.
The supports_code_blocks capability flag is left in place for future use.
CLI/TUI rendering is a separate path and was unaffected.

Adds a regression test asserting terminal progress renders as a truncated
preview, not a fenced bash block, even on a markdown-capable gateway.

Fixes NousResearch#41955
teknium1 pushed a commit that referenced this pull request Jun 8, 2026
… messaging chats

#41215 rendered a terminal tool call as a native ```bash fenced block on
markdown platforms (Telegram, WhatsApp, Slack, and others), showing the full
command with no truncation, in both all/new and verbose modes. That posted
complete shell commands (heredocs, internal paths, destructive commands) into
the chat before the final answer, visible to everyone in it.

This restores the prior behavior: terminal progress shows the short, truncated
preview line that every other tool already uses, capped at tool_preview_length.
The supports_code_blocks capability flag is left in place for future use.
CLI/TUI rendering is a separate path and was unaffected.

Adds a regression test asserting terminal progress renders as a truncated
preview, not a fenced bash block, even on a markdown-capable gateway.

Fixes #41955
teknium1 added a commit that referenced this pull request Jun 9, 2026
… chat (#42576)

Terminal tool progress on markdown-capable gateways (Telegram, Slack,
Discord, WhatsApp, Matrix, Weixin, Feishu) renders the full command in a
fenced code block again, in all/new AND verbose modes — gated on the
adapter's supports_code_blocks capability. Plain-text platforms keep the
short truncated preview.

No language tag is emitted: Slack mrkdwn renders a '```bash' fence with
'bash' as a literal first code line, so a bare '```' fence is used, which
renders correctly on every platform that supports blocks.

This restores the #41215 feature (removed in #41950 due to the command
showing in group chats) as the default. For a personal assistant the
command display is desired; the group-chat concern is a preference, not a
vulnerability.
a249169329-cpu pushed a commit to a249169329-cpu/hermes-agent that referenced this pull request Jun 9, 2026
… messaging chats

NousResearch#41215 rendered a terminal tool call as a native ```bash fenced block on
markdown platforms (Telegram, WhatsApp, Slack, and others), showing the full
command with no truncation, in both all/new and verbose modes. That posted
complete shell commands (heredocs, internal paths, destructive commands) into
the chat before the final answer, visible to everyone in it.

This restores the prior behavior: terminal progress shows the short, truncated
preview line that every other tool already uses, capped at tool_preview_length.
The supports_code_blocks capability flag is left in place for future use.
CLI/TUI rendering is a separate path and was unaffected.

Adds a regression test asserting terminal progress renders as a truncated
preview, not a fenced bash block, even on a markdown-capable gateway.

Fixes NousResearch#41955
a249169329-cpu pushed a commit to a249169329-cpu/hermes-agent that referenced this pull request Jun 9, 2026
… chat (NousResearch#42576)

Terminal tool progress on markdown-capable gateways (Telegram, Slack,
Discord, WhatsApp, Matrix, Weixin, Feishu) renders the full command in a
fenced code block again, in all/new AND verbose modes — gated on the
adapter's supports_code_blocks capability. Plain-text platforms keep the
short truncated preview.

No language tag is emitted: Slack mrkdwn renders a '```bash' fence with
'bash' as a literal first code line, so a bare '```' fence is used, which
renders correctly on every platform that supports blocks.

This restores the NousResearch#41215 feature (removed in NousResearch#41950 due to the command
showing in group chats) as the default. For a personal assistant the
command display is desired; the group-chat concern is a preference, not a
vulnerability.
wachoo pushed a commit to wachoo/hermes-agent that referenced this pull request Jun 10, 2026
… messaging chats

NousResearch#41215 rendered a terminal tool call as a native ```bash fenced block on
markdown platforms (Telegram, WhatsApp, Slack, and others), showing the full
command with no truncation, in both all/new and verbose modes. That posted
complete shell commands (heredocs, internal paths, destructive commands) into
the chat before the final answer, visible to everyone in it.

This restores the prior behavior: terminal progress shows the short, truncated
preview line that every other tool already uses, capped at tool_preview_length.
The supports_code_blocks capability flag is left in place for future use.
CLI/TUI rendering is a separate path and was unaffected.

Adds a regression test asserting terminal progress renders as a truncated
preview, not a fenced bash block, even on a markdown-capable gateway.

Fixes NousResearch#41955
wachoo pushed a commit to wachoo/hermes-agent that referenced this pull request Jun 10, 2026
… chat (NousResearch#42576)

Terminal tool progress on markdown-capable gateways (Telegram, Slack,
Discord, WhatsApp, Matrix, Weixin, Feishu) renders the full command in a
fenced code block again, in all/new AND verbose modes — gated on the
adapter's supports_code_blocks capability. Plain-text platforms keep the
short truncated preview.

No language tag is emitted: Slack mrkdwn renders a '```bash' fence with
'bash' as a literal first code line, so a bare '```' fence is used, which
renders correctly on every platform that supports blocks.

This restores the NousResearch#41215 feature (removed in NousResearch#41950 due to the command
showing in group chats) as the default. For a personal assistant the
command display is desired; the group-chat concern is a preference, not a
vulnerability.
changman pushed a commit to changman/hermes-agent that referenced this pull request Jun 10, 2026
…on markdown platforms (NousResearch#41215)

Tool-progress now shows a terminal command in a ```bash fenced block —
full command, no surrounding quotes, no label, no 40-char truncation —
instead of the noisy `terminal: "cmd…"` line, on every platform that
renders markdown code blocks (Telegram, Slack, Matrix, WhatsApp, Feishu,
Weixin, Discord). Plain-text platforms keep the compact preview line.

Gated on a new `BasePlatformAdapter.supports_code_blocks` capability
(default False) rather than a hardcoded platform list, so plugin adapters
(Discord lives in plugins/platforms/) opt in by setting the flag. Applies
to both all/new and verbose progress modes, with a safe fallback when the
command arg is missing or blank.
changman pushed a commit to changman/hermes-agent that referenced this pull request Jun 10, 2026
… messaging chats

NousResearch#41215 rendered a terminal tool call as a native ```bash fenced block on
markdown platforms (Telegram, WhatsApp, Slack, and others), showing the full
command with no truncation, in both all/new and verbose modes. That posted
complete shell commands (heredocs, internal paths, destructive commands) into
the chat before the final answer, visible to everyone in it.

This restores the prior behavior: terminal progress shows the short, truncated
preview line that every other tool already uses, capped at tool_preview_length.
The supports_code_blocks capability flag is left in place for future use.
CLI/TUI rendering is a separate path and was unaffected.

Adds a regression test asserting terminal progress renders as a truncated
preview, not a fenced bash block, even on a markdown-capable gateway.

Fixes NousResearch#41955
changman pushed a commit to changman/hermes-agent that referenced this pull request Jun 10, 2026
… chat (NousResearch#42576)

Terminal tool progress on markdown-capable gateways (Telegram, Slack,
Discord, WhatsApp, Matrix, Weixin, Feishu) renders the full command in a
fenced code block again, in all/new AND verbose modes — gated on the
adapter's supports_code_blocks capability. Plain-text platforms keep the
short truncated preview.

No language tag is emitted: Slack mrkdwn renders a '```bash' fence with
'bash' as a literal first code line, so a bare '```' fence is used, which
renders correctly on every platform that supports blocks.

This restores the NousResearch#41215 feature (removed in NousResearch#41950 due to the command
showing in group chats) as the default. For a personal assistant the
command display is desired; the group-chat concern is a preference, not a
vulnerability.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants