Skip to content

feat(tools): add notification_tool for desktop/system notifications#170

Closed
ygd58 wants to merge 36 commits into
NousResearch:mainfrom
ygd58:main
Closed

feat(tools): add notification_tool for desktop/system notifications#170
ygd58 wants to merge 36 commits into
NousResearch:mainfrom
ygd58:main

Conversation

@ygd58

@ygd58 ygd58 commented Feb 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a new notification_tool that lets Hermes send desktop notifications and play alert sounds — no messaging platform (Telegram/Discord) required.

Motivation

Hermes runs long tasks but had no way to alert the user when finished unless a gateway was running. This tool fills that gap using OS built-ins only.

Changes

  • tools/notification_tool.py (new): two tools — notify and notify_sound
  • toolsets.py: registered notification toolset
  • model_tools.py: added to tool discovery

Tools added

  • notify — desktop notification (Linux: notify-send, macOS: osascript, Windows: PowerShell toast)
  • notify_sound — system alert sound (paplay/afplay/PowerShell)

Notes

  • Zero new dependencies (OS built-ins only)
  • Graceful fallback if backend not available
  • Works great with the existing cron system

ygd58 added 29 commits February 26, 2026 11:13
This script provides functions to search Notion pages by title and retrieve database schema properties.
Adds a function to fetch model metadata from Hugging Face.
Added operational guidelines for Hugging Face model expertise.
This function executes a Python code snippet in a secure subprocess, capturing output or errors. It includes error handling for timeouts and system errors.
Added operational guidelines for the Autonomous Code Verification Skill.
This skill enables Hermes to autonomously extend its own capabilities by writing new Python tools from scratch, testing them, and registering them without human intervention.
This script fetches current weather data for any city using the Open-Meteo API without requiring an API key. It includes geocoding functionality to convert city names to geographic coordinates.
This file contains a suite of tests for the weather tool, checking various scenarios including valid and invalid city inputs, temperature units, and response structure.
Added documentation for the Adventure Log and self-tool building capabilities of Hermes Agent, including installation instructions and test results.
Introduced a self-tool builder skill for Hermes that enables autonomous tool creation, testing, and registration without human intervention. Includes demo tools and tests.
Implemented the mcp-server command for Hermes CLI with options for HTTP transport, host, and port.
Implemented the mcp-server command for the CLI, allowing users to start the Hermes MCP Server with HTTP options.
Implement session analytics for the /stats command, reading from the session database and rendering a summary.
Removed docstrings from several functions to streamline code.
@teknium1

Copy link
Copy Markdown
Contributor

This does look interesting and useful - I see you've made a lot of extra commits - would you say its ready for review now?

@ygd58

ygd58 commented Feb 28, 2026

Copy link
Copy Markdown
Contributor Author

This does look interesting and useful - I see you've made a lot of extra commits - would you say its ready for review now?

Yes, it's ready for review! The relevant commits are the last 3:

feat(tools): add notification_tool with desktop/system notifications
feat(tools): register notification toolset
feat(tools): discover notification_tool on startup

The earlier commits in the branch are unrelated work from my fork. The actual changes are clean — one new file (tools/notification_tool.py) and two small modifications (toolsets.py, model_tools.py). Happy to clean up the branch history if needed!

@teknium1

teknium1 commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Hey @ygd58 — this is Hermes-Agent (Teknium's AI assistant) doing code review on this PR. The notification concept is great — alerting users when long tasks finish is a real gap, especially for CLI users. However, there are several blocking issues that mean this needs a ground-up rebuild rather than fixes on top. I'll break them down:


1. Stale Branch (blocker)

The PR touches 22 files but only 3 are relevant to notifications (notification_tool.py, toolsets.py, model_tools.py). The rest are unrelated additions (SELF_TOOL_BUILDER.md, ADVENTURE.md, code_sandbox.py, github_intel.py, hf_intel.py, notion_pro.py, pomodoro_tool.py, weather.py, etc.). This can't be merged without pulling in a large amount of unreviewed code.

2. Wrong Registration Pattern (blocker — tool won't load)

The PR uses a def register(registry) wrapper function, but the codebase uses module-level registration at import time:

# What the PR does:
def register(registry):
    registry.register(name=..., description=..., parameters=..., handler=...)

# What the codebase actually expects (see tools/tts_tool.py, tools/terminal_tool.py, etc.):
from tools.registry import registry

registry.register(
    name="tool_name",
    toolset="toolset_name",    # required, missing from PR
    schema={...},              # full OpenAI-format schema dict, not separate params
    handler=lambda args, **kw: ...,
    check_fn=check_function,
)

The tool would fail to load entirely because _discover_tools() does importlib.import_module() and expects module-level registry.register() calls.

3. Handler Signature Mismatch (blocker)

PR handlers: handle_notify(title, message, urgency="normal")
Registry dispatches: entry.handler(args, **kwargs) where args is a dict

Even if registration worked, every call would crash with a TypeError. Existing tools use lambda wrappers:

handler=lambda args, **kw: handle_notify(
    title=args.get("title", ""),
    message=args.get("message", ""),
    urgency=args.get("urgency", "normal"),
)

4. Remote Machine / SSH (design issue)

This is the big conceptual problem. Hermes often runs on remote machines via SSH — which is exactly the scenario where "long-running task finished" notifications are most wanted. But:

  • notify-send requires D-Bus + display server (X11/Wayland)
  • osascript requires a macOS GUI session
  • afplay/paplay require audio output

Over SSH, none of these work. The check_fn would return False (good — graceful degradation), but the tool becomes unavailable in its primary use case. A rebuilt version should consider alternatives for remote scenarios (e.g., terminal bell \a, or integration with the existing send_message gateway tool).

5. Command Injection Vulnerability (security)

_esc() does basic quote replacement:

def _esc(s: str) -> str:
    return s.replace("'", "\\'").replace('"', '\\"')

This is interpolated directly into shell commands:

  • macOS: osascript -e 'display notification "{_esc(msg)}"' — AppleScript has different escaping rules; backslash-single-quote doesn't work in AppleScript
  • Windows: PowerShell -Command "...InnerText = '{_esc(title)}'" — single-quoted PowerShell strings don't process backslash escapes at all, so a title containing ' breaks out of the string and allows arbitrary PowerShell execution

User-controlled input should never be interpolated into shell command strings. Use subprocess.run() with list args where possible, or proper platform-specific escaping.

6. Platform Compatibility Issues

  • Linux: Sound files hardcoded to /usr/share/sounds/freedesktop/ and /usr/share/sounds/ubuntu/ paths — won't exist on Fedora, Arch, Alpine, etc.
  • macOS: Escaping broken (see above), but otherwise sound paths are correct (/System/Library/Sounds/)
  • Windows: Toast notification via Windows Runtime APIs is fragile, and the escaping issue makes it unsafe with special characters

Recommendation

The concept is solid and we'd love to have notification support. I'm opening a separate issue to track this as a feature request. A clean rebuild should:

  1. Use the correct tools/registry.py registration pattern (see any existing tool for reference)
  2. Use safe argument passing (no string interpolation into shell commands)
  3. Consider remote/SSH scenarios (terminal bell fallback, gateway integration)
  4. Be on a fresh branch off current main (only the notification files)
  5. Include tests

Thanks for the contribution and the idea! 🙏

@teknium1

teknium1 commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

#318

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants