NousResearch/hermes-agent

Strip blocked tools from delegated child agents

Cluster 43466 · agent. Data as of

Nothing open on GitHub. Fix merged in #47856. Check it covers your case.

The short answer

0open issues
0open PRs
5items grouped
Known?
Yes. 5 related items grouped here, 1 issue already closed.
Fix event
A fix was merged to main in PR #47856. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this resolved, deciding PR #52121. That is separate from the fix event.
Still open
Nothing open on GitHub.

These issues and PRs concern a bug where delegated child agents incorrectly inherit messaging and cronjob toolsets despite those tools being blocked. The work involves fixing tool-stripping logic and removing the agent-callable send_message tool.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #47856 refactor: remove agent-callable send_message tool

    merged to main

    files: gateway/session.py, hermes_cli/tools_config.py, tests/hermes_cli/test_tools_config.py, tests/tools/test_mcp_tool.py, tools/mcp_tool.py, tools/send_message_tool.py, toolsets.py, website/docs/reference/mcp-config-reference.md

    Show the diff
    • gateway/session.py
      @@ -386,9 +386,10 @@ def build_session_context_prompt(
               lines.append("")
               lines.append(
                   "**Platform notes:** You are running inside Yuanbao. "
      -            "You CAN send private (DM) messages via the send_message tool. "
      -            "Use target='yuanbao:direct:<account_id>' for DM "
      -            "and target='yuanbao:group:<group_code>' for group chat."
      +            "To send a private (DM) message to a user in the current group, "
      +            "use the yb_send_dm tool (look up the recipient by name or pass "
      +            "their user_id). Your normal reply is delivered to the group you "
      +            "are responding in."
               )
       
           # Connected platforms
    • hermes_cli/tools_config.py
      @@ -73,7 +73,6 @@
           ("clarify",         "❓ Clarifying Questions",      "clarify"),
           ("delegation",      "👥 Task Delegation",           "delegate_task"),
           ("cronjob",         "⏰ Cron Jobs",                 "create/list/update/pause/resume/run, with optional attached skills"),
      -    ("messaging",       "📨 Cross-Platform Messaging",  "send_message"),
           ("homeassistant",    "🏠 Home Assistant",           "smart home device control"),
           ("spotify",          "🎵 Spotify",                  "playback, search, playlists, library"),
           ("discord",         "💬 Discord (read/participate)", "fetch messages, search members, create thread"),
    • tests/hermes_cli/test_tools_config.py
      @@ -87,10 +87,6 @@ def test_gui_toolset_label_strips_leading_emoji():
           assert gui_toolset_label("Terminal & Processes") == "Terminal & Processes"
       
       
      -def test_configurable_toolsets_include_messaging():
      -    assert any(ts_key == "messaging" for ts_key, _, _ in CONFIGURABLE_TOOLSETS)
      -
      -
       def test_configurable_toolsets_include_context_engine():
           assert any(ts_key == "context_engine" for ts_key, _, _ in CONFIGURABLE_TOOLSETS)
       
      @@ -130,12 +126,6 @@ def test_get_platform_tools_context_engine_respects_explicit_empty_selection():
           assert "context_engine" not in enabled
       
       
      -def test_get_platform_tools_default_telegram_includes_messaging():
      -    enabled = _get_platform_tools({}, "telegram")
      -
      -    assert "messaging" in enabled
      -
      -
       def test_get_platform_tools_default_whatsapp_includes_web():
           enabled = _get_platform_tools({}, "whatsapp")
       
    • tests/tools/test_mcp_tool.py
      @@ -1884,7 +1884,7 @@ def test_default_timeout(self):
       
               server = MCPServerTask("test_srv")
               assert server.tool_timeout == _DEFAULT_TOOL_TIMEOUT
      -        assert server.tool_timeout == 120
      +        assert server.tool_timeout == 300
       
           def test_custom_timeout(self):
               """Server with timeout=180 in config gets 180."""
    • tools/mcp_tool.py
      @@ -17,7 +17,7 @@
               command: "npx"
               args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
               env: {}
      -        timeout: 120         # per-tool-call timeout in seconds (default: 120)
      +        timeout: 120         # per-tool-call timeout in seconds (default: 300)
               connect_timeout: 60  # initial connection timeout (default: 60)
             github:
               command: "npx"
      @@ -258,7 +258,7 @@ def _check_message_handler_support() -> bool:
       # Constants
       # ---------------------------------------------------------------------------
       
      -_DEFAULT_TOOL_TIMEOUT = 120      # seconds for tool calls
      +_DEFAULT_TOOL_TIMEOUT = 300      # seconds for tool calls
       _DEFAULT_CONNECT_TIMEOUT = 60    # seconds for initial connection per server
       _MAX_RECONNECT_RETRIES = 5
       _MAX_INITIAL_CONNECT_RETRIES = 3 # retries for the very first connection attempt
    • tools/send_message_tool.py
      @@ -1899,13 +1899,16 @@ async def _send_yuanbao(chat_id, message, media_files=None):
       
       
       # --- Registry ---
      -from tools.registry import registry, tool_error
      -
      -registry.register(
      -    name="send_message",
      -    toolset="messaging",
      -    schema=SEND_MESSAGE_SCHEMA,
      -    handler=send_message_tool,
      -    check_fn=_check_send_message,
      -    emoji="📨",
      -)
      +from tools.registry import tool_error
      +
      +# NOTE: ``send_message`` is intentionally NOT registered as an agent-callable
      +# model tool. The agent should not decide on its own to fire off cross-platform
      +# messages or reactions. The send engine in this module (``_send_to_platform``,
      +# ``_send_via_adapter``, ``_parse_target_ref``, the per-platform ``_send_*``
      +# helpers) remains the shared transport used by:
      +#   - cron delivery (cron/scheduler.py)
      +#   - the ``hermes send`` CLI command (hermes_cli/send_cmd.py)
      +#   - the gateway kanban notifier (dashboard-toggled, outside agent control)
      +#   - the standalone MCP server (mcp_serve.py), which is an opt-in surface
      +# Those callers import the helpers directly; none of them need the registry
      +# entry.
    • toolsets.py
      @@ -59,8 +59,6 @@
           "execute_code", "delegate_task",
           # Cronjob management
           "cronjob",
      -    # Cross-platform messaging (gated on gateway running via check_fn)
      -    "send_message",
           # Home Assistant smart home control (gated on HASS_TOKEN via check_fn)
           "ha_list_entities", "ha_get_state", "ha_list_services", "ha_call_service",
           # Kanban multi-agent coordination — only in schema when the agent is
      @@ -188,13 +186,7 @@
               "includes": []
           },
           
      -    "messaging": {
      -        "description": "Cross-platform messaging: send messages to Telegram, Discord, Slack, SMS, etc.",
      -        "tools": ["send_message"],
      -        "includes": []
      -    },
       
      -    
           "file": {
               "description": "File manipulation tools: read, write, patch (with fuzzy matching), and search (content + files)",
               "tools": ["read_file", "write_file", "patch", "search_files"],
      @@ -370,8 +362,10 @@
           # ==========================================================================
           # Full Hermes toolsets (CLI + messaging platforms)
           #
      -    # All platforms share the same core tools (including send_message,
      -    # which is gated on gateway running via its check_fn).
      +    # All platforms share the same core tools. Note: agents do NOT get an
      +    # agent-callable send_message tool — outbound platform messaging is handled
      +    # outside the agent loop (cron delivery, the gateway kanban notifier, and
      +    # the `hermes send` CLI), not by the model deciding to send on its own.
           # ==========================================================================
       
           "hermes-acp": {
    • website/docs/reference/mcp-config-reference.md
      @@ -54,8 +54,8 @@ mcp_servers:
       | `client_cert` | string or list | HTTP | mTLS client certificate. String = path to a PEM file containing cert + key. List `[cert, key]` = separate files. List `[cert, key, password]` = encrypted key |
       | `client_key` | string | HTTP | Path to the client private key, when `client_cert` is a string and the key is in a separate file |
       | `enabled` | bool | both | Skip the server entirely when false |
      -| `timeout` | number | both | Tool call timeout |
      -| `connect_timeout` | number | both | Initial connection timeout |
      +| `timeout` | number | both | Tool call timeout in seconds (default: `300`) |
      +| `connect_timeout` | number | both | Initial connection timeout in seconds (default: `60`) |
       | `supports_parallel_tool_calls` | bool | both | Allow tools from this server to run concurrently |
       | `tools` | mapping | both | Filtering and utility-tool policy |
       | `auth` | string | HTTP | Authentication method. Set to `oauth` to enable OAuth 2.1 with PKCE |
  • #52121 fix(delegate): strip cronjob toolset from delegated children (#43466)

    merged to main

    files: scripts/release.py, tests/tools/test_delegate.py, tools/delegate_tool.py

2 PRs closed without merging

From the close comments: done elsewhere 1 · superseded by another PR 1

  • #43474 fix(agent): strip messaging and cronjob toolsets from delegated children · done elsewhere → #47856, #43466
  • #43687 fix(delegate): strip messaging and cronjob toolsets from child agents · superseded by another PR → #43474
Closed issues · 1
  • Closed#43466delegate_task: _strip_blocked_tools doesn't strip 'messaging'/'cronjob', so children inherit send_message and cronjob despite DELEGATE_BLOCKED_TOOLS
How this cluster was grouped
  • Link evidence (structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
  • Pairwise link density 0.40: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
agent
Merged PRs
#47856, #52121
Closed issues
1
Attempts
2 PRs closed without merging
Fix link checked
24 Jun 2026

For your agent

The same facts, typed.