mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-15 14:22:43 +00:00
docs(webhook): complete filters + route-scripts coverage across doc surfaces (#60983)
Follow-up to #60944 (webhook payload filters and route scripts): - reference/cli-commands.md (en+zh): document the new --script option on 'hermes webhook subscribe' - zh-Hans user-guide webhooks.md: mirror the Payload Filters and Script Filters/Transforms sections plus the filters/script route properties (the salvage shipped English-only docs) - hermes-agent skill webhooks reference: teach the agent the filters/ script surface so agent-driven subscriptions can use them
This commit is contained in:
parent
76381e2a8e
commit
aabfedcac0
4 changed files with 86 additions and 0 deletions
|
|
@ -67,6 +67,22 @@ hermes webhook subscribe <name> \
|
|||
|
||||
Returns the webhook URL and HMAC secret. The user configures their service to POST to that URL.
|
||||
|
||||
### Filter or transform payloads before the agent runs
|
||||
|
||||
Two mechanisms narrow broad event streams (e.g. Todoist/GitHub fire on every update) so only relevant payloads wake the agent:
|
||||
|
||||
- **Declarative `filters`** (config.yaml routes only): list of conditions on payload fields, event type, or headers — operators `equals`, `not_equals`, `contains`, `exists`, `missing`, `in`, `in_file`, `regex`, with `all`/`any`/`not` grouping. Non-matching events are ignored with HTTP 200.
|
||||
- **Route scripts** (`--script` on subscribe, or `script:` on a config route): a script under `~/.hermes/scripts/` receives the payload as JSON on stdin. JSON stdout replaces the payload before prompt templating; empty stdout, `[SILENT]`, or a nonzero exit ignores the webhook. `.sh`/`.bash` run with bash, everything else with Python. Scripts cannot live outside `~/.hermes/scripts/` (path traversal is blocked).
|
||||
|
||||
```bash
|
||||
hermes webhook subscribe todoist-hermes \
|
||||
--prompt "Task changed: {payload.content}" \
|
||||
--script "todoist-hermes-label.py" \
|
||||
--deliver telegram --deliver-chat-id "12345"
|
||||
```
|
||||
|
||||
Full filter syntax: https://hermes-agent.nousresearch.com/docs/user-guide/messaging/webhooks#payload-filters
|
||||
|
||||
### List subscriptions
|
||||
```bash
|
||||
hermes webhook list
|
||||
|
|
|
|||
|
|
@ -671,6 +671,7 @@ hermes webhook subscribe <name> [options]
|
|||
| `--deliver-chat-id` | Target chat/channel ID for cross-platform delivery. |
|
||||
| `--secret` | Custom HMAC secret. Auto-generated if omitted. |
|
||||
| `--deliver-only` | Skip the agent — deliver the rendered `--prompt` as the literal message. Zero LLM cost, sub-second delivery. Requires `--deliver` to be a real target (not `log`). |
|
||||
| `--script` | Filter/transform script under `~/.hermes/scripts/`. The webhook payload is passed as JSON on stdin; JSON stdout replaces the payload, and empty stdout, `[SILENT]`, or a nonzero exit code ignores the webhook. See [Script Filters and Transforms](../user-guide/messaging/webhooks.md#script-filters-and-transforms). |
|
||||
|
||||
Subscriptions persist to `~/.hermes/webhook_subscriptions.json` and are hot-reloaded by the webhook adapter without a gateway restart.
|
||||
|
||||
|
|
|
|||
|
|
@ -477,6 +477,7 @@ hermes webhook subscribe <name> [options]
|
|||
| `--deliver-chat-id` | 跨平台投递的目标聊天/频道 ID。 |
|
||||
| `--secret` | 自定义 HMAC 密钥。省略时自动生成。 |
|
||||
| `--deliver-only` | 跳过 agent——将渲染后的 `--prompt` 作为字面消息投递。零 LLM 成本,亚秒级投递。要求 `--deliver` 为真实目标(非 `log`)。 |
|
||||
| `--script` | 位于 `~/.hermes/scripts/` 下的过滤/转换脚本。webhook payload 以 JSON 形式通过 stdin 传入;JSON stdout 会替换 payload,空 stdout、`[SILENT]` 或非零退出码会忽略该 webhook。参见[脚本过滤与转换](../user-guide/messaging/webhooks.md#script-filters-and-transforms)。 |
|
||||
|
||||
订阅持久化到 `~/.hermes/webhook_subscriptions.json`,webhook 适配器无需重启 gateway 即可热重载。
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ curl http://localhost:8644/health
|
|||
| `events` | 否 | 要接受的事件类型列表(例如 `["pull_request"]`)。若为空,则接受所有事件。事件类型从 `X-GitHub-Event`、`X-GitLab-Event` 或 payload 中的 `event_type` 读取。 |
|
||||
| `secret` | **是** | 用于签名验证的 HMAC secret。若路由未设置,则回退到全局 `secret`。仅用于测试时可设为 `"INSECURE_NO_AUTH"`(跳过验证)。 |
|
||||
| `prompt` | 否 | 使用点号表示法访问 payload 字段的模板字符串(例如 `{pull_request.title}`)。若省略,则将完整 JSON payload 转储到 prompt 中。 |
|
||||
| `filters` | 否 | 声明式 payload 过滤器,在认证/请求体/事件过滤之后、agent 或直接投递之前求值。不匹配时返回 `{"status":"ignored","reason":"filter"}`(HTTP 200)。 |
|
||||
| `script` | 否 | 位于 `~/.hermes/scripts/` 下的过滤/转换脚本。webhook payload 以 JSON 形式通过 stdin 传入。stdout 为 JSON 对象时会在模板渲染前替换 payload;文本 stdout 以 `script_output` 形式暴露;空 stdout、`[SILENT]` 或非零退出码会忽略该 webhook。 |
|
||||
| `skills` | 否 | agent 运行时加载的 skill 名称列表。 |
|
||||
| `deliver` | 否 | 响应发送目标:`github_comment`、`telegram`、`discord`、`slack`、`signal`、`sms`、`whatsapp`、`matrix`、`mattermost`、`homeassistant`、`email`、`dingtalk`、`feishu`、`wecom`、`weixin`、`bluebubbles`、`qqbot`,或 `log`(默认)。 |
|
||||
| `deliver_extra` | 否 | 额外的投递配置——键取决于 `deliver` 类型(例如 `repo`、`pr_number`、`chat_id`)。值支持与 `prompt` 相同的 `{dot.notation}` 模板语法。 |
|
||||
|
|
@ -116,9 +118,75 @@ platforms:
|
|||
events: ["push"]
|
||||
secret: "deploy-secret"
|
||||
prompt: "New push to {repository.full_name} branch {ref}: {head_commit.message}"
|
||||
filters:
|
||||
- field: "ref"
|
||||
equals: "refs/heads/main"
|
||||
deliver: "telegram"
|
||||
```
|
||||
|
||||
### Payload 过滤器 {#payload-filters}
|
||||
|
||||
当服务商发送宽泛的事件流、但只有部分 payload 应唤醒 agent 或触发 `deliver_only` 投递时,使用 `filters`。过滤器在签名验证、请求体解析和 `events` 之后运行,但在 prompt 渲染、幂等去重、agent 调度或直接投递之前运行。
|
||||
|
||||
```yaml
|
||||
platforms:
|
||||
webhook:
|
||||
extra:
|
||||
routes:
|
||||
todoist:
|
||||
events: ["item:updated"]
|
||||
secret: "todoist-secret"
|
||||
filters:
|
||||
- field: "payload.labels"
|
||||
contains: "hermes"
|
||||
- any:
|
||||
- field: "payload.priority"
|
||||
equals: 4
|
||||
- field: "payload.project_id"
|
||||
in_file: "~/.hermes/data/todoist/watchlist.json"
|
||||
prompt: "Todoist task changed: {payload.content}"
|
||||
```
|
||||
|
||||
支持的操作符:
|
||||
|
||||
- `exists: true|false`
|
||||
- `missing: true`
|
||||
- `equals` / `not_equals`
|
||||
- `contains` — 适用于字符串、列表和 dict 键
|
||||
- `in` — 内联列表
|
||||
- `in_file` — JSON 数组、JSON 对象(使用其键)或按行分隔的文本文件
|
||||
- `regex`
|
||||
- `all`、`any` 和 `not` 分组
|
||||
|
||||
字段路径使用点号表示法。当存在顶层 `payload` 对象时,`payload.foo` 从中读取;对扁平 payload 则从 webhook 请求体根部读取。`event` / `event_type` 匹配解析出的事件类型,`headers.<Name>` 读取请求头。
|
||||
|
||||
### 脚本过滤与转换 {#script-filters-and-transforms}
|
||||
|
||||
当声明式过滤器不够用时,使用 `script`。脚本必须位于当前 profile 的 `~/.hermes/scripts/` 目录下;相对路径在该目录内解析,且禁止路径穿越到目录之外。`.sh` 和 `.bash` 脚本用 bash 运行,其他扩展名用当前 Python 解释器运行。
|
||||
|
||||
路由 payload 以 JSON 形式发送到 stdin:
|
||||
|
||||
```python
|
||||
# ~/.hermes/scripts/todoist-hermes-label.py
|
||||
import json
|
||||
import sys
|
||||
|
||||
payload = json.load(sys.stdin)
|
||||
labels = payload.get("payload", {}).get("labels", [])
|
||||
if "hermes" not in labels:
|
||||
print("[SILENT]")
|
||||
raise SystemExit(0)
|
||||
|
||||
payload["body"] = payload["payload"]["content"]
|
||||
print(json.dumps(payload))
|
||||
```
|
||||
|
||||
脚本结果:
|
||||
|
||||
- stdout 为 JSON 对象时,替换 `prompt` 和 `deliver_extra` 使用的 payload。
|
||||
- 非 JSON 文本 stdout 会以 `script_output` 字段加入 payload。
|
||||
- 空 stdout、精确的 `[SILENT]`、`{"__hermes_ignore__": true}`、超时、脚本缺失或非零退出码,均返回 HTTP 200 及 `{"status":"ignored","reason":"script"}`。
|
||||
|
||||
### Prompt 模板
|
||||
|
||||
Prompt 使用点号表示法访问 webhook payload 中的嵌套字段:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue