feat(gateway): rename to tool_progress_grouping, add config/docs/tests

Follow-up to salvaged PR #41620:
- Rename tool_progress_style -> tool_progress_grouping (clearer intent)
- Add display.tool_progress_grouping to DEFAULT_CONFIG (accumulate default)
- Document in messaging docs incl. 'separate is noisier, only where progress enabled'
- Add resolver tests (default/global/override/invalid/case)
This commit is contained in:
teknium 2026-06-16 05:39:15 -07:00 committed by Teknium
parent fc956b9db6
commit 6373aba80f
5 changed files with 76 additions and 5 deletions

View file

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

View file

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

View file

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

View file

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

View file

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