mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-10 03:22:05 +00:00
Completes the Windows-gating coverage for the built-in skills/ tree. Every
bundled SKILL.md now carries an explicit platforms: declaration so the
loader (agent.skill_utils.skill_matches_platform) can skip-load skills
that don't fit the current OS.
74 skills declared cross-platform (platforms: [linux, macos, windows]):
Creative (16): ascii-art, ascii-video, architecture-diagram, baoyu-comic,
baoyu-infographic, claude-design, creative-ideation, design-md,
excalidraw, humanizer, manim-video, p5js, pixel-art,
popular-web-designs, pretext, sketch, songwriting-and-ai-music,
touchdesigner-mcp
Autonomous agents: claude-code, codex, hermes-agent, opencode
Data/devops: jupyter-live-kernel, kanban-orchestrator, kanban-worker,
webhook-subscriptions, dogfood, codebase-inspection
GitHub: github-auth, github-code-review, github-issues,
github-pr-workflow, github-repo-management
Media: gif-search, heartmula, songsee, spotify, youtube-content
MCP / email / gaming / notes / smart-home: native-mcp, himalaya,
pokemon-player, obsidian, openhue
mlops (non-broken): weights-and-biases, huggingface-hub, llama-cpp,
outlines, segment-anything-model, dspy, trl-fine-tuning
Productivity: airtable, google-workspace, linear, maps, nano-pdf,
notion, ocr-and-documents, powerpoint
Red-teaming / research: godmode, arxiv, blogwatcher, llm-wiki,
polymarket
Software-dev: debugging-hermes-tui-commands, hermes-agent-skill-authoring,
node-inspect-debugger, plan, requesting-code-review, spike,
subagent-driven-development, systematic-debugging,
test-driven-development, writing-plans
Misc: yuanbao
5 skills gated from Windows (platforms: [linux, macos]):
mlops/inference/vllm (serving-llms-vllm)
vLLM is officially Linux-only; Windows requires WSL.
mlops/training/axolotl
Axolotl's flash-attn + deepspeed + bitsandbytes stack is Linux-first.
mlops/training/unsloth
Requires Triton + xformers + flash-attn — Linux only in practice.
mlops/models/audiocraft (audiocraft-audio-generation)
torchaudio ffmpeg backend + encodec dependencies are Linux-first.
mlops/inference/obliteratus
Research abliteration workflow; relies on Linux-focused pytorch
kernels and MLX — no first-class Windows path.
Same strict-over-lenient policy as the optional-skills sweep: when the
underlying tool's Windows support is rough, missing, or WSL-only, gate the
skill. Easier to un-gate after verified Windows support lands than to leak
partial support that manifests as mid-task failures.
Combined with prior commits in this branch, every bundled SKILL.md
(skills/ + optional-skills/) now has a platforms: declaration.
204 lines
6.7 KiB
Markdown
204 lines
6.7 KiB
Markdown
---
|
|
name: webhook-subscriptions
|
|
description: "Webhook subscriptions: event-driven agent runs."
|
|
version: 1.1.0
|
|
platforms: [linux, macos, windows]
|
|
metadata:
|
|
hermes:
|
|
tags: [webhook, events, automation, integrations, notifications, push]
|
|
---
|
|
|
|
# Webhook Subscriptions
|
|
|
|
Create dynamic webhook subscriptions so external services (GitHub, GitLab, Stripe, CI/CD, IoT sensors, monitoring tools) can trigger Hermes agent runs by POSTing events to a URL.
|
|
|
|
## Setup (Required First)
|
|
|
|
The webhook platform must be enabled before subscriptions can be created. Check with:
|
|
```bash
|
|
hermes webhook list
|
|
```
|
|
|
|
If it says "Webhook platform is not enabled", set it up:
|
|
|
|
### Option 1: Setup wizard
|
|
```bash
|
|
hermes gateway setup
|
|
```
|
|
Follow the prompts to enable webhooks, set the port, and set a global HMAC secret.
|
|
|
|
### Option 2: Manual config
|
|
Add to `~/.hermes/config.yaml`:
|
|
```yaml
|
|
platforms:
|
|
webhook:
|
|
enabled: true
|
|
extra:
|
|
host: "0.0.0.0"
|
|
port: 8644
|
|
secret: "generate-a-strong-secret-here"
|
|
```
|
|
|
|
### Option 3: Environment variables
|
|
Add to `~/.hermes/.env`:
|
|
```bash
|
|
WEBHOOK_ENABLED=true
|
|
WEBHOOK_PORT=8644
|
|
WEBHOOK_SECRET=generate-a-strong-secret-here
|
|
```
|
|
|
|
After configuration, start (or restart) the gateway:
|
|
```bash
|
|
hermes gateway run
|
|
# Or if using systemd:
|
|
systemctl --user restart hermes-gateway
|
|
```
|
|
|
|
Verify it's running:
|
|
```bash
|
|
curl http://localhost:8644/health
|
|
```
|
|
|
|
## Commands
|
|
|
|
All management is via the `hermes webhook` CLI command:
|
|
|
|
### Create a subscription
|
|
```bash
|
|
hermes webhook subscribe <name> \
|
|
--prompt "Prompt template with {payload.fields}" \
|
|
--events "event1,event2" \
|
|
--description "What this does" \
|
|
--skills "skill1,skill2" \
|
|
--deliver telegram \
|
|
--deliver-chat-id "12345" \
|
|
--secret "optional-custom-secret"
|
|
```
|
|
|
|
Returns the webhook URL and HMAC secret. The user configures their service to POST to that URL.
|
|
|
|
### List subscriptions
|
|
```bash
|
|
hermes webhook list
|
|
```
|
|
|
|
### Remove a subscription
|
|
```bash
|
|
hermes webhook remove <name>
|
|
```
|
|
|
|
### Test a subscription
|
|
```bash
|
|
hermes webhook test <name>
|
|
hermes webhook test <name> --payload '{"key": "value"}'
|
|
```
|
|
|
|
## Prompt Templates
|
|
|
|
Prompts support `{dot.notation}` for accessing nested payload fields:
|
|
|
|
- `{issue.title}` — GitHub issue title
|
|
- `{pull_request.user.login}` — PR author
|
|
- `{data.object.amount}` — Stripe payment amount
|
|
- `{sensor.temperature}` — IoT sensor reading
|
|
|
|
If no prompt is specified, the full JSON payload is dumped into the agent prompt.
|
|
|
|
## Common Patterns
|
|
|
|
### GitHub: new issues
|
|
```bash
|
|
hermes webhook subscribe github-issues \
|
|
--events "issues" \
|
|
--prompt "New GitHub issue #{issue.number}: {issue.title}\n\nAction: {action}\nAuthor: {issue.user.login}\nBody:\n{issue.body}\n\nPlease triage this issue." \
|
|
--deliver telegram \
|
|
--deliver-chat-id "-100123456789"
|
|
```
|
|
|
|
Then in GitHub repo Settings → Webhooks → Add webhook:
|
|
- Payload URL: the returned webhook_url
|
|
- Content type: application/json
|
|
- Secret: the returned secret
|
|
- Events: "Issues"
|
|
|
|
### GitHub: PR reviews
|
|
```bash
|
|
hermes webhook subscribe github-prs \
|
|
--events "pull_request" \
|
|
--prompt "PR #{pull_request.number} {action}: {pull_request.title}\nBy: {pull_request.user.login}\nBranch: {pull_request.head.ref}\n\n{pull_request.body}" \
|
|
--skills "github-code-review" \
|
|
--deliver github_comment
|
|
```
|
|
|
|
### Stripe: payment events
|
|
```bash
|
|
hermes webhook subscribe stripe-payments \
|
|
--events "payment_intent.succeeded,payment_intent.payment_failed" \
|
|
--prompt "Payment {data.object.status}: {data.object.amount} cents from {data.object.receipt_email}" \
|
|
--deliver telegram \
|
|
--deliver-chat-id "-100123456789"
|
|
```
|
|
|
|
### CI/CD: build notifications
|
|
```bash
|
|
hermes webhook subscribe ci-builds \
|
|
--events "pipeline" \
|
|
--prompt "Build {object_attributes.status} on {project.name} branch {object_attributes.ref}\nCommit: {commit.message}" \
|
|
--deliver discord \
|
|
--deliver-chat-id "1234567890"
|
|
```
|
|
|
|
### Generic monitoring alert
|
|
```bash
|
|
hermes webhook subscribe alerts \
|
|
--prompt "Alert: {alert.name}\nSeverity: {alert.severity}\nMessage: {alert.message}\n\nPlease investigate and suggest remediation." \
|
|
--deliver origin
|
|
```
|
|
|
|
### Direct delivery (no agent, zero LLM cost)
|
|
|
|
For use cases where you just want to push a notification through to a user's chat — no reasoning, no agent loop — add `--deliver-only`. The rendered `--prompt` template becomes the literal message body and is dispatched directly to the target adapter.
|
|
|
|
Use this for:
|
|
- External service push notifications (Supabase/Firebase webhooks → Telegram)
|
|
- Monitoring alerts that should forward verbatim
|
|
- Inter-agent pings where one agent is telling another agent's user something
|
|
- Any webhook where an LLM round trip would be wasted effort
|
|
|
|
```bash
|
|
hermes webhook subscribe antenna-matches \
|
|
--deliver telegram \
|
|
--deliver-chat-id "123456789" \
|
|
--deliver-only \
|
|
--prompt "🎉 New match: {match.user_name} matched with you!" \
|
|
--description "Antenna match notifications"
|
|
```
|
|
|
|
The POST returns `200 OK` on successful delivery, `502` on target failure — so upstream services can retry intelligently. HMAC auth, rate limits, and idempotency still apply.
|
|
|
|
Requires `--deliver` to be a real target (telegram, discord, slack, github_comment, etc.) — `--deliver log` is rejected because log-only direct delivery is pointless.
|
|
|
|
## Security
|
|
|
|
- Each subscription gets an auto-generated HMAC-SHA256 secret (or provide your own with `--secret`)
|
|
- The webhook adapter validates signatures on every incoming POST
|
|
- Static routes from config.yaml cannot be overwritten by dynamic subscriptions
|
|
- Subscriptions persist to `~/.hermes/webhook_subscriptions.json`
|
|
|
|
## How It Works
|
|
|
|
1. `hermes webhook subscribe` writes to `~/.hermes/webhook_subscriptions.json`
|
|
2. The webhook adapter hot-reloads this file on each incoming request (mtime-gated, negligible overhead)
|
|
3. When a POST arrives matching a route, the adapter formats the prompt and triggers an agent run
|
|
4. The agent's response is delivered to the configured target (Telegram, Discord, GitHub comment, etc.)
|
|
|
|
## Troubleshooting
|
|
|
|
If webhooks aren't working:
|
|
|
|
1. **Is the gateway running?** Check with `systemctl --user status hermes-gateway` or `ps aux | grep gateway`
|
|
2. **Is the webhook server listening?** `curl http://localhost:8644/health` should return `{"status": "ok"}`
|
|
3. **Check gateway logs:** `grep webhook ~/.hermes/logs/gateway.log | tail -20`
|
|
4. **Signature mismatch?** Verify the secret in your service matches the one from `hermes webhook list`. GitHub sends `X-Hub-Signature-256`, GitLab sends `X-Gitlab-Token`.
|
|
5. **Firewall/NAT?** The webhook URL must be reachable from the service. For local development, use a tunnel (ngrok, cloudflared).
|
|
6. **Wrong event type?** Check `--events` filter matches what the service sends. Use `hermes webhook test <name>` to verify the route works.
|