diff --git a/gateway/display_config.py b/gateway/display_config.py index 4d9daceeac1..58226ed48fe 100644 --- a/gateway/display_config.py +++ b/gateway/display_config.py @@ -32,7 +32,7 @@ from typing import Any _GLOBAL_DEFAULTS: dict[str, Any] = { "tool_progress": "all", - "tool_progress_style": "accumulate", # "accumulate" = edit single msg; "separate" = one msg per tool + "tool_progress_grouping": "accumulate", # "accumulate" = edit one bubble; "separate" = one msg per tool "show_reasoning": False, "tool_preview_length": 0, "streaming": None, # None = follow top-level streaming config @@ -239,7 +239,7 @@ def _normalise(setting: str, value: Any) -> Any: if isinstance(value, str): return value.lower() in {"true", "1", "yes", "on"} return bool(value) - if setting == "tool_progress_style": + if setting == "tool_progress_grouping": val = str(value).lower() return val if val in ("accumulate", "separate") else "accumulate" if setting == "tool_preview_length": diff --git a/gateway/run.py b/gateway/run.py index 687f898437f..470d71906c3 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -13624,8 +13624,8 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew if _env_tp and not _tool_progress_configured else (_resolved_tp or _env_tp or "all") ) - # Tool progress style: "accumulate" (edit single msg) or "separate" (one msg per tool) - progress_style = resolve_display_setting(user_config, platform_key, "tool_progress_style") or "accumulate" + # Tool progress grouping: "accumulate" (edit one bubble) or "separate" (one msg per tool) + progress_grouping = resolve_display_setting(user_config, platform_key, "tool_progress_grouping") or "accumulate" # Disable tool progress for webhooks - they don't support message editing, # so each progress line would be sent as a separate message. from gateway.config import Platform @@ -13932,7 +13932,7 @@ class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, Gatew progress_lines = [] # Accumulated tool lines for the CURRENT editable bubble progress_msg_id = None # ID of the current progress message to edit - can_edit = progress_style != "separate" # "separate" = one message per tool (pre-v0.9 behavior) + can_edit = progress_grouping != "separate" # "separate" = one message per tool (pre-v0.9 behavior) _last_edit_ts = 0.0 # Throttle edits to avoid Telegram flood control _PROGRESS_EDIT_INTERVAL = 1.5 # Minimum seconds between edits diff --git a/hermes_cli/config.py b/hermes_cli/config.py index f2ee3ea48af..4f801e2e9b4 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -1485,6 +1485,12 @@ DEFAULT_CONFIG = { "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) + # How gateway tool-progress is grouped on platforms that support message + # editing: "accumulate" (default) edits one bubble in place; "separate" + # sends one message per tool (the pre-v0.9 behavior, noisier). Only + # applies where tool_progress is already enabled. Per-platform override + # via display.platforms..tool_progress_grouping. + "tool_progress_grouping": "accumulate", # Auto-delete system-notice replies (e.g. "✨ New session started!", # "♻ Restarting gateway…", "⚡ Stopped…") after N seconds on platforms # that support message deletion (currently Telegram; other platforms diff --git a/tests/gateway/test_display_config.py b/tests/gateway/test_display_config.py index 3f295928288..06787407555 100644 --- a/tests/gateway/test_display_config.py +++ b/tests/gateway/test_display_config.py @@ -450,3 +450,63 @@ class TestCleanupProgress: } } assert resolve_display_setting(config, "telegram", "cleanup_progress") is True, val + + +class TestToolProgressGrouping: + """resolve_display_setting() for the tool_progress_grouping knob.""" + + def test_default_is_accumulate(self): + """No config anywhere → global default 'accumulate'.""" + from gateway.display_config import resolve_display_setting + + assert ( + resolve_display_setting({}, "telegram", "tool_progress_grouping") + == "accumulate" + ) + + def test_global_separate(self): + from gateway.display_config import resolve_display_setting + + config = {"display": {"tool_progress_grouping": "separate"}} + assert ( + resolve_display_setting(config, "discord", "tool_progress_grouping") + == "separate" + ) + + def test_platform_override_wins(self): + from gateway.display_config import resolve_display_setting + + config = { + "display": { + "tool_progress_grouping": "accumulate", + "platforms": {"discord": {"tool_progress_grouping": "separate"}}, + } + } + assert ( + resolve_display_setting(config, "discord", "tool_progress_grouping") + == "separate" + ) + # Other platforms still get the global value. + assert ( + resolve_display_setting(config, "telegram", "tool_progress_grouping") + == "accumulate" + ) + + def test_invalid_value_falls_back_to_accumulate(self): + """_normalise rejects anything outside accumulate|separate.""" + from gateway.display_config import resolve_display_setting + + config = {"display": {"tool_progress_grouping": "bogus"}} + assert ( + resolve_display_setting(config, "telegram", "tool_progress_grouping") + == "accumulate" + ) + + def test_case_insensitive(self): + from gateway.display_config import resolve_display_setting + + config = {"display": {"tool_progress_grouping": "SEPARATE"}} + assert ( + resolve_display_setting(config, "telegram", "tool_progress_grouping") + == "separate" + ) diff --git a/website/docs/user-guide/messaging/index.md b/website/docs/user-guide/messaging/index.md index d0129be29bb..ce61e73488d 100644 --- a/website/docs/user-guide/messaging/index.md +++ b/website/docs/user-guide/messaging/index.md @@ -320,6 +320,11 @@ Control how much tool activity is displayed in `~/.hermes/config.yaml`: display: tool_progress: all # off | new | all | verbose tool_progress_command: false # set to true to enable /verbose in messaging + # How progress is grouped on platforms that support message editing: + # accumulate (default) — edit one bubble in place as tools run + # separate — send one message per tool (pre-v0.9 style; noisier) + # Only applies where tool_progress is already enabled. + tool_progress_grouping: accumulate # accumulate | separate ``` When enabled, the bot sends status messages as it works: