WhatsApp++ for Hermes Agent: edit, delete, react, and star WhatsApp messages through the local Baileys bridge.
Project description
WhatsApp++ for Hermes Agent
Advanced WhatsApp message controls for Hermes Agent: edit bot-sent messages, delete/revoke messages for everyone, react/unreact, and star/unstar messages through the local Baileys WhatsApp bridge.
This repo packages the local Pulse Labs prototype of a Hermes plugin named whatsapp-plusplus with a tool named whatsapp_plusplus.
What it is
Hermes Agent can already send WhatsApp messages and returns WhatsApp message_id values. WhatsApp++ adds the missing follow-up controls that make Hermes more useful in real chats and group threads:
- edit a Hermes/bot-sent message
- delete/revoke a Hermes/bot-sent message for everyone, when WhatsApp allows it
- react to a message with an emoji
- clear a reaction
- star or unstar a message locally for the connected WhatsApp account
It is especially useful when Hermes is operating through WhatsApp groups and needs to correct, clean up, or acknowledge messages without adding more clutter.
Who it is for
- Hermes Desktop users running the bundled WhatsApp/Baileys bridge
- teams using Hermes as a WhatsApp bot in group chats
- agencies and operators who want an assistant that can clean up its own messages after corrections
- developers experimenting with safer agent-side message controls
This is not a WhatsApp automation platform by itself. It is a small Hermes plugin plus bridge patch that exposes controls for an already-paired Hermes WhatsApp bridge.
How it works
There are two pieces:
-
Hermes plugin
- installs as the pip package
wpp-hermes - exposes public CLI commands named
wpp-hermesandwhatsapp-plusplus - exposes a Hermes plugin entry point named
whatsapp-plusplus - optionally writes a tiny
~/.hermes/plugins/whatsapp-plusplus/CLI visibility shim - registers one tool:
whatsapp_plusplus - sends local HTTP requests to the WhatsApp bridge, defaulting to
http://127.0.0.1:3000
- installs as the pip package
-
Baileys bridge endpoints
- adds/uses
POST /edit - adds
POST /delete - adds
POST /react - adds
POST /star
- adds/uses
The plugin does not talk to WhatsApp directly. Hermes calls the plugin, the plugin calls the local bridge, and the bridge uses Baileys to operate as the connected WhatsApp bot account.
Actions exposed to Hermes
Tool: whatsapp_plusplus
Arguments:
action: one ofedit,delete_for_everyone,react,unreact,star,unstarchat_id: WhatsApp chat JID, for example120363...@g.usmessage_id: WhatsApp message key/id returned by Hermes or WhatsAppmessage: replacement text foreditemoji: emoji forreactfrom_me: whether the message was sent by the connected bot account; defaults to trueparticipant: optional participant JID for group messages, especially whenfrom_me=falsesafety_ack: required exact valueUSER_EXPLICITLY_REQUESTED_THISforeditanddelete_for_everyone
Safety model
WhatsApp++ deliberately makes edit/delete harder than react/star.
The plugin refuses to run edit or delete_for_everyone unless Hermes passes:
safety_ack=USER_EXPLICITLY_REQUESTED_THIS
Hermes should only pass that value when the user explicitly asks to edit or delete that exact message in the current conversation.
Safety & Security Disclaimer
This plugin gives an AI agent real control over visible WhatsApp history from the connected bot account. That is powerful, but it means a misconfigured, compromised, or poorly instructed agent could potentially:
- send something the user did not intend, then edit it after the fact
- delete a message to hide evidence of a mistake or unwanted action
- clean up context in a group thread in a way that changes what other people can see
- react to messages in ways that imply approval or agreement
- star sensitive messages on the bot account for later retrieval
The safety acknowledgement is a guardrail, not a cryptographic permission system. Any agent that has this tool in its available tool list and decides to pass the acknowledgement string can technically attempt the action. Treat this plugin like a moderation/admin tool: only enable it for agents and chats where you trust the model, prompt, runtime, and operators.
Recommended guardrails:
- keep edit/delete disabled or unavailable unless you actually need them
- require explicit user wording such as "edit that message" or "delete that for everyone"
- log every edit/delete action with
chat_id,message_id, timestamp, and requesting user - prefer corrected follow-up messages over editing history
- never allow autonomous/background jobs to edit or delete without human approval
- use a dedicated bot WhatsApp account, not a personal account
- test in a private chat before using in production groups
Important limits:
- delete-for-everyone can fail due to WhatsApp message age/type/permission limits
- deleting leaves a WhatsApp deleted-message placeholder
- edits change visible chat history and should not be used silently
- reactions are visible to the chat
- starring is local to the connected WhatsApp bot account
- the tool needs a real
chat_idandmessage_id; do not guess
Install
One-line agent prompt: install this version
Paste this to Hermes:
Install Pulse Labs WhatsApp++ for Hermes with `uvx wpp-hermes install`, then run `uvx wpp-hermes doctor` and `uvx wpp-hermes verify`. The installer puts the pip package into Hermes Desktop's Python with uv pip install, patches the bundled WhatsApp bridge, writes the Hermes plugin shim, and enables the plugin. Restart only the WhatsApp bridge or Hermes Gateway/Desktop session after install.
Short install from PyPI
WhatsApp++ is distributed as the PyPI package wpp-hermes. Hermes Desktop includes uv, so the short install uses uvx to run a temporary bootstrap CLI. The bootstrap then uses uv pip install --python <Hermes Python> wpp-hermes so the actual Hermes plugin lands in the same Python environment that runs Hermes.
uvx wpp-hermes install
That one command installs the package into Hermes Desktop, patches the local WhatsApp bridge, writes a small ~/.hermes/plugins/whatsapp-plusplus Hermes CLI visibility shim, and enables the plugin in Hermes config.
The public CLI names are wpp-hermes and whatsapp-plusplus. The Hermes plugin is still registered as a pip entry point named whatsapp-plusplus, and the Hermes tool is still named whatsapp_plusplus. The shim exists because current hermes plugins list/enable commands may only scan directory plugins. If the installer finds the older copied ~/.hermes/plugins/whatsapp_plusplus directory-plugin, it archives that directory under ~/.hermes/plugin_backups/ to avoid duplicate plugin entries; pass --keep-legacy-dir to keep it.
Then restart Hermes Gateway or restart only the WhatsApp bridge so the new bridge endpoints are live. Start a fresh Hermes session after enabling the plugin.
Useful follow-up commands:
uvx wpp-hermes --version
uvx wpp-hermes install --help
uvx wpp-hermes doctor
uvx wpp-hermes verify
doctorprints the detected Hermes home, Hermes Python, bridge path, config path, uv path, plugin enabled state, shim state, Hermes-Python entry point state, bridge endpoint state, andnode --checkresult.verifyperforms the same checks without mutating files and exits non-zero if the install does not look ready.
Install from GitLab/source
Use this when testing unreleased changes from the repository instead of the latest PyPI release:
uvx --from git+https://gitlab.com/pulse-labs/whatsapp-plusplus-hermes.git wpp-hermes install --package-spec git+https://gitlab.com/pulse-labs/whatsapp-plusplus-hermes.git
Manual install
If you prefer to see each step, this is what wpp-hermes install does:
HERMES_PY="C:/Users/you/AppData/Local/hermes/hermes-agent/venv/Scripts/python.exe"
uv pip install --python "$HERMES_PY" wpp-hermes
"$HERMES_PY" -m pulse_labs_whatsapp_plusplus_hermes.installer --enable
On macOS app-style installs, the Hermes home may be:
HERMES_HOME="$HOME/Library/Application Support/hermes"
On macOS/Linux Hermes CLI installs, the Python path is usually:
HERMES_PY="$HOME/.hermes/hermes-agent/venv/bin/python"
If auto-detection fails, pass the path explicitly:
uvx wpp-hermes install --hermes-python "$HERMES_PY"
If uv is missing on a raw CLI/server environment, install it first from Astral's uv instructions, then rerun the installer. Hermes Desktop normally includes uv, but standalone macOS/Linux shells may not.
Source checkout install
Clone the repo:
git clone https://gitlab.com/pulse-labs/whatsapp-plusplus-hermes.git
cd whatsapp-plusplus-hermes
Install/edit the local checkout into Hermes' Python environment:
HERMES_PY="C:/Users/you/AppData/Local/hermes/hermes-agent/venv/Scripts/python.exe"
uv pip install --python "$HERMES_PY" -e .
"$HERMES_PY" -m pulse_labs_whatsapp_plusplus_hermes.cli enable
Custom Hermes home or bridge path
wpp-hermes install --hermes-home "C:/Users/you/AppData/Local/hermes" --bridge "C:/Users/you/AppData/Local/hermes/hermes-agent/scripts/whatsapp-bridge/bridge.js"
Different bridge URL
The plugin defaults to http://127.0.0.1:3000. Override it with:
export WHATSAPP_PLUSPLUS_BRIDGE_URL=http://127.0.0.1:3000
Publishing
wpp-hermes is published on PyPI and supports the clean public install path:
uvx wpp-hermes --help
uvx wpp-hermes install --help
uvx wpp-hermes doctor
uvx wpp-hermes verify
Maintainer releases are handled by GitLab CI/CD trusted publishing, not long-lived PyPI tokens. TestPyPI and PyPI each need their own trusted publisher configured for this GitLab project:
- Package/project name:
wpp-hermes - Namespace:
pulse-labs - Project/repository name:
whatsapp-plusplus-hermes - Top-level pipeline file:
.gitlab-ci.yml - TestPyPI environment:
testpypi - PyPI environment:
pypi
Release sequence:
git checkout main
git pull --ff-only origin main
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push origin vX.Y.Z
GitLab creates manual publish jobs for version tags. Run publish-testpypi first, verify the TestPyPI package, then run publish-pypi.
TestPyPI verification:
uvx --index https://test.pypi.org/simple/ --from wpp-hermes wpp-hermes --help
If that fails only because dependencies such as PyYAML>=6.0 are not available on TestPyPI, verify with PyPI as the dependency fallback:
uvx --index https://test.pypi.org/simple/ --index-strategy unsafe-best-match --from wpp-hermes wpp-hermes --help
Final public PyPI verification:
uvx wpp-hermes --help
uvx wpp-hermes install --help
uvx wpp-hermes doctor
uvx wpp-hermes verify
Rebuild from scratch
For security-sensitive users who would rather have their local agent write the plugin and bridge patch from a prompt instead of installing prewritten package code, keep this option. Review the generated files before enabling edit/delete in any real chat.
One-line agent prompt: rebuild from scratch
Paste this to Hermes:
Rebuild WhatsApp++ for Hermes from scratch: create a Hermes plugin exposing a whatsapp_plusplus tool with actions edit/delete_for_everyone/react/unreact/star/unstar, require safety_ack=USER_EXPLICITLY_REQUESTED_THIS for edit/delete, patch the local Baileys WhatsApp bridge with /delete, /react, and /star endpoints using Baileys message keys, and verify with py_compile, node --check, hermes plugins list, bridge health, and a disposable WhatsApp smoke test only after I explicitly approve edit/delete tests.
Usage examples
Delete a bot-sent message for everyone:
{
"action": "delete_for_everyone",
"chat_id": "120363000000000000@g.us",
"message_id": "3EB0ABC123",
"from_me": true,
"safety_ack": "USER_EXPLICITLY_REQUESTED_THIS"
}
React to a message:
{
"action": "react",
"chat_id": "120363000000000000@g.us",
"message_id": "3EB0ABC123",
"emoji": "✅",
"from_me": true
}
Star a message locally:
{
"action": "star",
"chat_id": "120363000000000000@g.us",
"message_id": "3EB0ABC123",
"from_me": true
}
Verification checklist
After install:
"$HERMES_PY" -m py_compile -q src/pulse_labs_whatsapp_plusplus_hermes/*.py scripts/install.py # source checkout only
"$HERMES_PY" -m pulse_labs_whatsapp_plusplus_hermes.installer --help
node --check "$HOME/AppData/Local/hermes/hermes-agent/scripts/whatsapp-bridge/bridge.js"
hermes plugins list --plain --no-bundled | grep whatsapp-plusplus
Bridge endpoint checks should return HTTP 400 for missing required fields, not 404:
curl -i -X POST http://127.0.0.1:3000/delete -H 'Content-Type: application/json' -d '{}'
curl -i -X POST http://127.0.0.1:3000/react -H 'Content-Type: application/json' -d '{}'
curl -i -X POST http://127.0.0.1:3000/star -H 'Content-Type: application/json' -d '{}'
macOS compatibility
wpp-hermes is a pure-Python wheel plus a JavaScript bridge patch, so one package artifact works across macOS Intel and Apple Silicon. The package has been verified on:
- macOS 15.7.3 Intel x86_64
- macOS 15.7.7 Apple Silicon arm64
The verified macOS checks are:
python3 -m py_compile src/pulse_labs_whatsapp_plusplus_hermes/*.py src/wpp_hermes_cli/*.py scripts/install.py
uv build
python3 -m venv .venv-test
.venv-test/bin/python -m pip install dist/wpp_hermes-*.whl
.venv-test/bin/wpp-hermes --help
.venv-test/bin/wpp-hermes --version
.venv-test/bin/wpp-hermes installer-help
.venv-test/bin/wpp-hermes doctor --hermes-home /tmp/wpp-hermes-empty-home
uvx --from dist/wpp_hermes-*.whl wpp-hermes --help
uvx --from dist/wpp_hermes-*.whl wpp-hermes install --help
For full installer validation on macOS, use a temporary Hermes home and a throwaway bridge file before patching a real Hermes Desktop install. The remote Intel and Apple Silicon validation for this package used that safe flow: it verified wheel install, CLI behavior, shim/config writes, throwaway bridge patching, and node --check; it did not mutate a real Hermes Desktop profile unless you explicitly run uvx wpp-hermes install against that Desktop install.
Bridge endpoint details
POST /delete
{ "chatId": "...", "messageId": "...", "fromMe": true, "participant": "optional" }
Calls Baileys:
sock.sendMessage(chatId, { delete: key })
POST /react
{ "chatId": "...", "messageId": "...", "emoji": "✅", "fromMe": true, "participant": "optional" }
Calls Baileys:
sock.sendMessage(chatId, { react: { text: emoji || '', key } })
POST /star
{ "chatId": "...", "messageId": "...", "star": true, "fromMe": true }
Calls Baileys:
sock.chatModify({ star: { messages: [{ id: messageId, fromMe }], star } }, chatId)
Repo layout
src/pulse_labs_whatsapp_plusplus_hermes/ pip-installable Hermes plugin package + installer
plugin/whatsapp_plusplus/ directory-plugin copy for manual installs/reference
scripts/install.py source-checkout wrapper around the package installer
pyproject.toml uv/pip package metadata and Hermes entry point
README.md public docs
LICENSE MIT license
License
MIT License. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wpp_hermes-0.4.0.tar.gz.
File metadata
- Download URL: wpp_hermes-0.4.0.tar.gz
- Upload date:
- Size: 52.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c671c05efcba4a8b96f1fde13c5c001470e23a730a0314f6d2e08f75bf2f36e
|
|
| MD5 |
d847471c4529dfccb6753702d0c3f5aa
|
|
| BLAKE2b-256 |
1f6fdf25db1e5ad24da93fbe56337d266f104687f022772b63f6c4a528c89391
|
File details
Details for the file wpp_hermes-0.4.0-py3-none-any.whl.
File metadata
- Download URL: wpp_hermes-0.4.0-py3-none-any.whl
- Upload date:
- Size: 19.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35af4f2e0e05d1bbee74cb8aee2ba28c5944fb37f78dc6014db7abd3d44ca68d
|
|
| MD5 |
e5e1f2a35137eb48f6184eaad30a0c3c
|
|
| BLAKE2b-256 |
90999a1beb40a3a27c3265ca6289ce7959fc9634b523baf9b0ab443505bda1b7
|