feat: add tool_display config to control tool call visibility in Discord#263
Closed
white1033 wants to merge 9 commits intoopenabdev:mainfrom
Closed
feat: add tool_display config to control tool call visibility in Discord#263white1033 wants to merge 9 commits intoopenabdev:mainfrom
white1033 wants to merge 9 commits intoopenabdev:mainfrom
Conversation
… ToolDisplay - render() now takes a ToolDisplay arg and applies compact_title() in Compact mode - compose_display() now takes a ToolDisplay arg and skips tool lines in None mode - Added TDD tests for all three modes (Full, Compact, None) and the empty-tools edge case - Call sites in stream_prompt still pass old 2-arg signature (will be fixed in Task 4)
…se_display call sites
… (claude-agent-acp)
…lt, invalid value)
Collaborator
|
Closing in favor of #253 (merged), which addresses the core truncation issue by collapsing tool lines during streaming when count exceeds 3. The If you'd like to add additional display modes ( |
Collaborator
|
Superseded by #253 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What problem does this solve?
Tool call lines in Discord messages contain the full ACP title string, which often includes complete shell commands, file paths, or URL arguments. In public or shared channels this is noisy and can inadvertently expose sensitive paths, tokens embedded in arguments, or internal infrastructure details.
Closes #216
At a Glance
Prior Art & Industry Research
Hermes Agent:
acp_adapter/tools.py → build_tool_title()uses a"verb: primary_arg"format and truncates long commands at 80 characters (e.g."terminal: curl -s ..."→"terminal: curl -s…"). This is essentially the same compact label pattern — Hermes chose brevity by default too. Separately,agent/display.pyexposesset_tool_preview_max_len()/get_tool_preview_max_len()as a runtime-configurable integer cap (0 = unlimited). Hermes does not expose a "none" (hide entirely) mode.OpenClaw:
OpenClaw separates tool event transport from display via ACP
ToolCallStart/ToolCallProgressevents streamed throughsrc/channels/draft-stream-controls.ts. Display decisions are made at the channel layer, not inside the event emitter — which is the same decoupling this PR achieves by threadingtool_displaythroughstream_prompt()rather than hard-coding it at the call site. OpenClaw does not expose a user-facing config option for tool verbosity.Other references:
Proposed Solution
Add a
tool_displayfield to[reactions]inconfig.toml:Three modes:
fullRunning: curl -s "https://..."compactRunningor ✅curlnoneImplementation:
ToolDisplayenum inconfig.rswithserde rename_all = "lowercase"compact_title()helper with URL-safe heuristic (detects://to skip URL colons)ToolEntry::render()andcompose_display()acceptToolDisplay;Noneskips the tool blocktool_displayplumbed throughstream_prompt()to all fourcompose_display()call sitesconfigmap.yamlandvalues.yamlupdated; default is"compact"Files changed
src/config.rsToolDisplayenum; addtool_displayfield toReactionsConfig; add deserialization testssrc/discord.rsToolDisplay; addcompact_title()with URL-safe heuristic; updateToolEntry::render,compose_display,stream_prompt; add 7 unit testsconfig.toml.exampletool_display = "compact"under[reactions]charts/openab/values.yamltoolDisplay: "compact"to reactions blockcharts/openab/templates/configmap.yamltool_displayfrom Helm valuesk8s/configmap.yamltool_display = "compact"to static manifestWhy this approach?
Enum over boolean: A boolean
hide_tools: trueonly handles two states. The third state (compact) turns out to be the most practically useful — users want to know a tool ran without reading its full arguments. Hermes Agent's experience confirms this: theirbuild_tool_title()truncates by default because full titles are rarely useful to end users.compactas default (notfull): Changing the default is a mild breaking change in appearance, but leavingfullas default would mean most users never benefit from the fix. Thecompactoutput is still informative — it signals that a tool ran — without exposing arguments.URL-safe heuristic in
compact_title(): The two ACP title formats ("Verb: command"from Kiro and raw-command from claude-agent-acp) collide on colon as separator vs URL scheme. A simplesplit(':')[0]would garble"curl https://..."into"curl https". The heuristic checks whether the character after:is/to skip URL colons.Alternatives Considered
Boolean
hide_tool_lines: true— Only two states. Loses thecompactmiddle ground that is most useful in practice. Rejected.Keep
fullas default, opt-in tocompact— Avoids the appearance change but means existing deployments stay noisy. The whole point of the PR is to fix the default experience. Rejected.Server-side truncation at a character limit (like Hermes'
tool_preview_max_len) — An integer cap is less expressive than named modes and harder to reason about (tool_preview_max_len = 10vstool_display = "compact"). Named modes also let us add new behaviors later without a config format change. Rejected.Strip tool lines in the Discord message formatter rather than in
compose_display()— Would require post-processing rendered markdown, which is fragile. Keeping the decision incompose_display()keeps it close to where tool entries are assembled. Rejected.Validation
Automated (36 tests, all passing)
cargo test— 36 tests, 0 failurestool_display = "full"shows complete title —compose_display_full_shows_complete_titletool_display = "compact"shows short label only —compose_display_compact_shows_only_prefixtool_display = "none"hides all tool lines —compose_display_none_hides_all_tool_linestool_displayin config) =compact—tool_display_defaults_to_compacttool_display_deserializes_all_modestool_display_rejects_invalid_valuecompact_title_url_in_command_not_truncated"Verb: command"format extracts label —compact_title_verb_colon_formatcompact_title_raw_command_formatcompose_display_empty_tools_no_blank_linetool_display = "compact"— verified viahelm template