merge: resolve conflict with main (i18n refactor)

Main moved StatusPage constants/functions inside the component and added
i18n support. Resolved by keeping the i18n structure and adding the
runningRemote key to en.ts, zh.ts, and types.ts for remote gateway
display.
This commit is contained in:
Hermes Agent 2026-04-14 22:30:50 +00:00
commit 5ad28a2dbe
158 changed files with 10933 additions and 1378 deletions

View file

@ -120,7 +120,7 @@ hermes-agent/
│ └── platforms/ # 18 adapters: telegram, discord, slack, whatsapp,
│ # signal, matrix, mattermost, email, sms,
│ # dingtalk, feishu, wecom, wecom_callback, weixin,
│ # bluebubbles, homeassistant, webhook, api_server
│ # bluebubbles, qqbot, homeassistant, webhook, api_server
├── acp_adapter/ # ACP server (VS Code / Zed / JetBrains)
├── cron/ # Scheduler (jobs.py, scheduler.py)

View file

@ -180,6 +180,7 @@ Cron job results can be delivered to any supported platform:
| WeCom | `wecom` | Deliver to WeCom |
| Weixin | `weixin` | Deliver to Weixin (WeChat) |
| BlueBubbles | `bluebubbles` | Deliver to iMessage via BlueBubbles |
| QQ Bot | `qqbot` | Deliver to QQ (Tencent) via Official API v2 |
For Telegram topics, use the format `telegram:<chat_id>:<thread_id>` (e.g., `telegram:-1001234567890:17585`).

View file

@ -162,6 +162,7 @@ gateway/platforms/
├── wecom.py # WeCom (WeChat Work) callback
├── weixin.py # Weixin (personal WeChat) via iLink Bot API
├── bluebubbles.py # Apple iMessage via BlueBubbles macOS server
├── qqbot.py # QQ Bot (Tencent QQ) via Official API v2
├── webhook.py # Inbound/outbound webhook adapter
├── api_server.py # REST API server adapter
└── homeassistant.py # Home Assistant conversation integration

View file

@ -0,0 +1,593 @@
---
sidebar_position: 15
title: "Automation Templates"
description: "Ready-to-use automation recipes — scheduled tasks, GitHub event triggers, API webhooks, and multi-skill workflows"
---
# Automation Templates
Copy-paste recipes for common automation patterns. Each template uses Hermes's built-in [cron scheduler](/docs/user-guide/features/cron) for time-based triggers and [webhook platform](/docs/user-guide/messaging/webhooks) for event-driven triggers.
Every template works with **any model** — not locked to a single provider.
:::tip Three Trigger Types
| Trigger | How | Tool |
|---------|-----|------|
| **Schedule** | Runs on a cadence (hourly, nightly, weekly) | `cronjob` tool or `/cron` slash command |
| **GitHub Event** | Fires on PR opens, pushes, issues, CI results | Webhook platform (`hermes webhook subscribe`) |
| **API Call** | External service POSTs JSON to your endpoint | Webhook platform (config.yaml routes or `hermes webhook subscribe`) |
All three support delivery to Telegram, Discord, Slack, SMS, email, GitHub comments, or local files.
:::
---
## Development Workflow
### Nightly Backlog Triage
Label, prioritize, and summarize new issues every night. Delivers a digest to your team channel.
**Trigger:** Schedule (nightly)
```bash
hermes cron create "0 2 * * *" \
"You are a project manager triaging the NousResearch/hermes-agent GitHub repo.
1. Run: gh issue list --repo NousResearch/hermes-agent --state open --json number,title,labels,author,createdAt --limit 30
2. Identify issues opened in the last 24 hours
3. For each new issue:
- Suggest a priority label (P0-critical, P1-high, P2-medium, P3-low)
- Suggest a category label (bug, feature, docs, security)
- Write a one-line triage note
4. Summarize: total open issues, new today, breakdown by priority
Format as a clean digest. If no new issues, respond with [SILENT]." \
--name "Nightly backlog triage" \
--deliver telegram
```
### Automatic PR Code Review
Review every pull request automatically when it's opened. Posts a review comment directly on the PR.
**Trigger:** GitHub webhook
**Option A — Dynamic subscription (CLI):**
```bash
hermes webhook subscribe github-pr-review \
--events "pull_request" \
--prompt "Review this pull request:
Repository: {repository.full_name}
PR #{pull_request.number}: {pull_request.title}
Author: {pull_request.user.login}
Action: {action}
Diff URL: {pull_request.diff_url}
Fetch the diff with: curl -sL {pull_request.diff_url}
Review for:
- Security issues (injection, auth bypass, secrets in code)
- Performance concerns (N+1 queries, unbounded loops, memory leaks)
- Code quality (naming, duplication, error handling)
- Missing tests for new behavior
Post a concise review. If the PR is a trivial docs/typo change, say so briefly." \
--skills "github-code-review" \
--deliver github_comment
```
**Option B — Static route (config.yaml):**
```yaml
platforms:
webhook:
enabled: true
extra:
port: 8644
secret: "your-global-secret"
routes:
github-pr-review:
events: ["pull_request"]
secret: "github-webhook-secret"
prompt: |
Review PR #{pull_request.number}: {pull_request.title}
Repository: {repository.full_name}
Author: {pull_request.user.login}
Diff URL: {pull_request.diff_url}
Review for security, performance, and code quality.
skills: ["github-code-review"]
deliver: "github_comment"
deliver_extra:
repo: "{repository.full_name}"
pr_number: "{pull_request.number}"
```
Then in GitHub: **Settings → Webhooks → Add webhook** → Payload URL: `http://your-server:8644/webhooks/github-pr-review`, Content type: `application/json`, Secret: `github-webhook-secret`, Events: **Pull requests**.
### Docs Drift Detection
Weekly scan of merged PRs to find API changes that need documentation updates.
**Trigger:** Schedule (weekly)
```bash
hermes cron create "0 9 * * 1" \
"Scan the NousResearch/hermes-agent repo for documentation drift.
1. Run: gh pr list --repo NousResearch/hermes-agent --state merged --json number,title,files,mergedAt --limit 30
2. Filter to PRs merged in the last 7 days
3. For each merged PR, check if it modified:
- Tool schemas (tools/*.py) — may need docs/reference/tools-reference.md update
- CLI commands (hermes_cli/commands.py, hermes_cli/main.py) — may need docs/reference/cli-commands.md update
- Config options (hermes_cli/config.py) — may need docs/user-guide/configuration.md update
- Environment variables — may need docs/reference/environment-variables.md update
4. Cross-reference: for each code change, check if the corresponding docs page was also updated in the same PR
Report any gaps where code changed but docs didn't. If everything is in sync, respond with [SILENT]." \
--name "Docs drift detection" \
--deliver telegram
```
### Dependency Security Audit
Daily scan for known vulnerabilities in project dependencies.
**Trigger:** Schedule (daily)
```bash
hermes cron create "0 6 * * *" \
"Run a dependency security audit on the hermes-agent project.
1. cd ~/.hermes/hermes-agent && source .venv/bin/activate
2. Run: pip audit --format json 2>/dev/null || pip audit 2>&1
3. Run: npm audit --json 2>/dev/null (in website/ directory if it exists)
4. Check for any CVEs with CVSS score >= 7.0
If vulnerabilities found:
- List each one with package name, version, CVE ID, severity
- Check if an upgrade is available
- Note if it's a direct dependency or transitive
If no vulnerabilities, respond with [SILENT]." \
--name "Dependency audit" \
--deliver telegram
```
---
## DevOps & Monitoring
### Deploy Verification
Trigger smoke tests after every deployment. Your CI/CD pipeline POSTs to the webhook when a deploy completes.
**Trigger:** API call (webhook)
```bash
hermes webhook subscribe deploy-verify \
--events "deployment" \
--prompt "A deployment just completed:
Service: {service}
Environment: {environment}
Version: {version}
Deployed by: {deployer}
Run these verification steps:
1. Check if the service is responding: curl -s -o /dev/null -w '%{http_code}' {health_url}
2. Search recent logs for errors: check the deployment payload for any error indicators
3. Verify the version matches: curl -s {health_url}/version
Report: deployment status (healthy/degraded/failed), response time, any errors found.
If healthy, keep it brief. If degraded or failed, provide detailed diagnostics." \
--deliver telegram
```
Your CI/CD pipeline triggers it:
```bash
curl -X POST http://your-server:8644/webhooks/deploy-verify \
-H "Content-Type: application/json" \
-H "X-Hub-Signature-256: sha256=$(echo -n '{"service":"api","environment":"prod","version":"2.1.0","deployer":"ci","health_url":"https://api.example.com/health"}' | openssl dgst -sha256 -hmac 'your-secret' | cut -d' ' -f2)" \
-d '{"service":"api","environment":"prod","version":"2.1.0","deployer":"ci","health_url":"https://api.example.com/health"}'
```
### Alert Triage
Correlate monitoring alerts with recent changes to draft a response. Works with Datadog, PagerDuty, Grafana, or any alerting system that can POST JSON.
**Trigger:** API call (webhook)
```bash
hermes webhook subscribe alert-triage \
--prompt "Monitoring alert received:
Alert: {alert.name}
Severity: {alert.severity}
Service: {alert.service}
Message: {alert.message}
Timestamp: {alert.timestamp}
Investigate:
1. Search the web for known issues with this error pattern
2. Check if this correlates with any recent deployments or config changes
3. Draft a triage summary with:
- Likely root cause
- Suggested first response steps
- Escalation recommendation (P1-P4)
Be concise. This goes to the on-call channel." \
--deliver slack
```
### Uptime Monitor
Check endpoints every 30 minutes. Only notify when something is down.
**Trigger:** Schedule (every 30 min)
```python title="~/.hermes/scripts/check-uptime.py"
import urllib.request, json, time
ENDPOINTS = [
{"name": "API", "url": "https://api.example.com/health"},
{"name": "Web", "url": "https://www.example.com"},
{"name": "Docs", "url": "https://docs.example.com"},
]
results = []
for ep in ENDPOINTS:
try:
start = time.time()
req = urllib.request.Request(ep["url"], headers={"User-Agent": "Hermes-Monitor/1.0"})
resp = urllib.request.urlopen(req, timeout=10)
elapsed = round((time.time() - start) * 1000)
results.append({"name": ep["name"], "status": resp.getcode(), "ms": elapsed})
except Exception as e:
results.append({"name": ep["name"], "status": "DOWN", "error": str(e)})
down = [r for r in results if r.get("status") == "DOWN" or (isinstance(r.get("status"), int) and r["status"] >= 500)]
if down:
print("OUTAGE DETECTED")
for r in down:
print(f" {r['name']}: {r.get('error', f'HTTP {r[\"status\"]}')} ")
print(f"\nAll results: {json.dumps(results, indent=2)}")
else:
print("NO_ISSUES")
```
```bash
hermes cron create "every 30m" \
"If the script reports OUTAGE DETECTED, summarize which services are down and suggest likely causes. If NO_ISSUES, respond with [SILENT]." \
--script ~/.hermes/scripts/check-uptime.py \
--name "Uptime monitor" \
--deliver telegram
```
---
## Research & Intelligence
### Competitive Repository Scout
Monitor competitor repos for interesting PRs, features, and architectural decisions.
**Trigger:** Schedule (daily)
```bash
hermes cron create "0 8 * * *" \
"Scout these AI agent repositories for notable activity in the last 24 hours:
Repos to check:
- anthropics/claude-code
- openai/codex
- All-Hands-AI/OpenHands
- Aider-AI/aider
For each repo:
1. gh pr list --repo <repo> --state all --json number,title,author,createdAt,mergedAt --limit 15
2. gh issue list --repo <repo> --state open --json number,title,labels,createdAt --limit 10
Focus on:
- New features being developed
- Architectural changes
- Integration patterns we could learn from
- Security fixes that might affect us too
Skip routine dependency bumps and CI fixes. If nothing notable, respond with [SILENT].
If there are findings, organize by repo with brief analysis of each item." \
--skills "competitive-pr-scout" \
--name "Competitor scout" \
--deliver telegram
```
### AI News Digest
Weekly roundup of AI/ML developments.
**Trigger:** Schedule (weekly)
```bash
hermes cron create "0 9 * * 1" \
"Generate a weekly AI news digest covering the past 7 days:
1. Search the web for major AI announcements, model releases, and research breakthroughs
2. Search for trending ML repositories on GitHub
3. Check arXiv for highly-cited papers on language models and agents
Structure:
## Headlines (3-5 major stories)
## Notable Papers (2-3 papers with one-sentence summaries)
## Open Source (interesting new repos or major releases)
## Industry Moves (funding, acquisitions, launches)
Keep each item to 1-2 sentences. Include links. Total under 600 words." \
--name "Weekly AI digest" \
--deliver telegram
```
### Paper Digest with Notes
Daily arXiv scan that saves summaries to your note-taking system.
**Trigger:** Schedule (daily)
```bash
hermes cron create "0 8 * * *" \
"Search arXiv for the 3 most interesting papers on 'language model reasoning' OR 'tool-use agents' from the past day. For each paper, create an Obsidian note with the title, authors, abstract summary, key contribution, and potential relevance to Hermes Agent development." \
--skills "arxiv,obsidian" \
--name "Paper digest" \
--deliver local
```
---
## GitHub Event Automations
### Issue Auto-Labeling
Automatically label and respond to new issues.
**Trigger:** GitHub webhook
```bash
hermes webhook subscribe github-issues \
--events "issues" \
--prompt "New GitHub issue received:
Repository: {repository.full_name}
Issue #{issue.number}: {issue.title}
Author: {issue.user.login}
Action: {action}
Body: {issue.body}
Labels: {issue.labels}
If this is a new issue (action=opened):
1. Read the issue title and body carefully
2. Suggest appropriate labels (bug, feature, docs, security, question)
3. If it's a bug report, check if you can identify the affected component from the description
4. Post a helpful initial response acknowledging the issue
If this is a label or assignment change, respond with [SILENT]." \
--deliver github_comment
```
### CI Failure Analysis
Analyze CI failures and post diagnostics on the PR.
**Trigger:** GitHub webhook
```yaml
# config.yaml route
platforms:
webhook:
enabled: true
extra:
routes:
ci-failure:
events: ["check_run"]
secret: "ci-secret"
prompt: |
CI check failed:
Repository: {repository.full_name}
Check: {check_run.name}
Status: {check_run.conclusion}
PR: #{check_run.pull_requests.0.number}
Details URL: {check_run.details_url}
If conclusion is "failure":
1. Fetch the log from the details URL if accessible
2. Identify the likely cause of failure
3. Suggest a fix
If conclusion is "success", respond with [SILENT].
deliver: "github_comment"
deliver_extra:
repo: "{repository.full_name}"
pr_number: "{check_run.pull_requests.0.number}"
```
### Auto-Port Changes Across Repos
When a PR merges in one repo, automatically port the equivalent change to another.
**Trigger:** GitHub webhook
```bash
hermes webhook subscribe auto-port \
--events "pull_request" \
--prompt "PR merged in the source repository:
Repository: {repository.full_name}
PR #{pull_request.number}: {pull_request.title}
Author: {pull_request.user.login}
Action: {action}
Merge commit: {pull_request.merge_commit_sha}
If action is 'closed' and pull_request.merged is true:
1. Fetch the diff: curl -sL {pull_request.diff_url}
2. Analyze what changed
3. Determine if this change needs to be ported to the Go SDK equivalent
4. If yes, create a branch, apply the equivalent changes, and open a PR on the target repo
5. Reference the original PR in the new PR description
If action is not 'closed' or not merged, respond with [SILENT]." \
--skills "github-pr-workflow" \
--deliver log
```
---
## Business Operations
### Stripe Payment Monitoring
Track payment events and get summaries of failures.
**Trigger:** API call (webhook)
```bash
hermes webhook subscribe stripe-payments \
--events "payment_intent.succeeded,payment_intent.payment_failed,charge.dispute.created" \
--prompt "Stripe event received:
Event type: {type}
Amount: {data.object.amount} cents ({data.object.currency})
Customer: {data.object.customer}
Status: {data.object.status}
For payment_intent.payment_failed:
- Identify the failure reason from {data.object.last_payment_error}
- Suggest whether this is a transient issue (retry) or permanent (contact customer)
For charge.dispute.created:
- Flag as urgent
- Summarize the dispute details
For payment_intent.succeeded:
- Brief confirmation only
Keep responses concise for the ops channel." \
--deliver slack
```
### Daily Revenue Summary
Compile key business metrics every morning.
**Trigger:** Schedule (daily)
```bash
hermes cron create "0 8 * * *" \
"Generate a morning business metrics summary.
Search the web for:
1. Current Bitcoin and Ethereum prices
2. S&P 500 status (pre-market or previous close)
3. Any major tech/AI industry news from the last 12 hours
Format as a brief morning briefing, 3-4 bullet points max.
Deliver as a clean, scannable message." \
--name "Morning briefing" \
--deliver telegram
```
---
## Multi-Skill Workflows
### Security Audit Pipeline
Combine multiple skills for a comprehensive weekly security review.
**Trigger:** Schedule (weekly)
```bash
hermes cron create "0 3 * * 0" \
"Run a comprehensive security audit of the hermes-agent codebase.
1. Check for dependency vulnerabilities (pip audit, npm audit)
2. Search the codebase for common security anti-patterns:
- Hardcoded secrets or API keys
- SQL injection vectors (string formatting in queries)
- Path traversal risks (user input in file paths without validation)
- Unsafe deserialization (pickle.loads, yaml.load without SafeLoader)
3. Review recent commits (last 7 days) for security-relevant changes
4. Check if any new environment variables were added without being documented
Write a security report with findings categorized by severity (Critical, High, Medium, Low).
If nothing found, report a clean bill of health." \
--skills "codebase-security-audit" \
--name "Weekly security audit" \
--deliver telegram
```
### Content Pipeline
Research, draft, and prepare content on a schedule.
**Trigger:** Schedule (weekly)
```bash
hermes cron create "0 10 * * 3" \
"Research and draft a technical blog post outline about a trending topic in AI agents.
1. Search the web for the most discussed AI agent topics this week
2. Pick the most interesting one that's relevant to open-source AI agents
3. Create an outline with:
- Hook/intro angle
- 3-4 key sections
- Technical depth appropriate for developers
- Conclusion with actionable takeaway
4. Save the outline to ~/drafts/blog-$(date +%Y%m%d).md
Keep the outline to ~300 words. This is a starting point, not a finished post." \
--name "Blog outline" \
--deliver local
```
---
## Quick Reference
### Cron Schedule Syntax
| Expression | Meaning |
|-----------|---------|
| `every 30m` | Every 30 minutes |
| `every 2h` | Every 2 hours |
| `0 2 * * *` | Daily at 2:00 AM |
| `0 9 * * 1` | Every Monday at 9:00 AM |
| `0 9 * * 1-5` | Weekdays at 9:00 AM |
| `0 3 * * 0` | Every Sunday at 3:00 AM |
| `0 */6 * * *` | Every 6 hours |
### Delivery Targets
| Target | Flag | Notes |
|--------|------|-------|
| Same chat | `--deliver origin` | Default — delivers to where the job was created |
| Local file | `--deliver local` | Saves output, no notification |
| Telegram | `--deliver telegram` | Home channel, or `telegram:CHAT_ID` for specific |
| Discord | `--deliver discord` | Home channel, or `discord:CHANNEL_ID` |
| Slack | `--deliver slack` | Home channel |
| SMS | `--deliver sms:+15551234567` | Direct to phone number |
| Specific thread | `--deliver telegram:-100123:456` | Telegram forum topic |
### Webhook Template Variables
| Variable | Description |
|----------|-------------|
| `{pull_request.title}` | PR title |
| `{issue.number}` | Issue number |
| `{repository.full_name}` | `owner/repo` |
| `{action}` | Event action (opened, closed, etc.) |
| `{__raw__}` | Full JSON payload (truncated at 4000 chars) |
| `{sender.login}` | GitHub user who triggered the event |
### The [SILENT] Pattern
When a cron job's response contains `[SILENT]`, delivery is suppressed. Use this to avoid notification spam on quiet runs:
```
If nothing noteworthy happened, respond with [SILENT].
```
This means you only get notified when the agent has something to report.

View file

@ -306,35 +306,49 @@ with open(_DATA_FILE) as f:
_DATA = yaml.safe_load(f)
```
### Bundle a skill
### Bundle skills
Include a `skill.md` file and install it during registration:
Plugins can ship skill files that the agent loads via `skill_view("plugin:skill")`. Register them in your `__init__.py`:
```
~/.hermes/plugins/my-plugin/
├── __init__.py
├── plugin.yaml
└── skills/
├── my-workflow/
│ └── SKILL.md
└── my-checklist/
└── SKILL.md
```
```python
import shutil
from pathlib import Path
def _install_skill():
"""Copy our skill to ~/.hermes/skills/ on first load."""
try:
from hermes_cli.config import get_hermes_home
dest = get_hermes_home() / "skills" / "my-plugin" / "SKILL.md"
except Exception:
dest = Path.home() / ".hermes" / "skills" / "my-plugin" / "SKILL.md"
if dest.exists():
return # don't overwrite user edits
source = Path(__file__).parent / "skill.md"
if source.exists():
dest.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(source, dest)
def register(ctx):
ctx.register_tool(...)
_install_skill()
skills_dir = Path(__file__).parent / "skills"
for child in sorted(skills_dir.iterdir()):
skill_md = child / "SKILL.md"
if child.is_dir() and skill_md.exists():
ctx.register_skill(child.name, skill_md)
```
The agent can now load your skills with their namespaced name:
```python
skill_view("my-plugin:my-workflow") # → plugin's version
skill_view("my-workflow") # → built-in version (unchanged)
```
**Key properties:**
- Plugin skills are **read-only** — they don't enter `~/.hermes/skills/` and can't be edited via `skill_manage`.
- Plugin skills are **not** listed in the system prompt's `<available_skills>` index — they're opt-in explicit loads.
- Bare skill names are unaffected — the namespace prevents collisions with built-in skills.
- When the agent loads a plugin skill, a bundle context banner is prepended listing sibling skills from the same plugin.
:::tip Legacy pattern
The old `shutil.copy2` pattern (copying a skill into `~/.hermes/skills/`) still works but creates name collision risk with built-in skills. Prefer `ctx.register_skill()` for new plugins.
:::
### Gate on environment variables
If your plugin needs an API key:

View file

@ -70,7 +70,7 @@ Delivery targets are case-sensitive and require the correct platform to be confi
| `local` | Write access to `~/.hermes/cron/output/` |
| `origin` | Delivers to the chat where the job was created |
Other supported platforms include `mattermost`, `homeassistant`, `dingtalk`, `feishu`, `wecom`, `weixin`, `bluebubbles`, and `webhook`. You can also target a specific chat with `platform:chat_id` syntax (e.g., `telegram:-1001234567890`).
Other supported platforms include `mattermost`, `homeassistant`, `dingtalk`, `feishu`, `wecom`, `weixin`, `bluebubbles`, `qqbot`, and `webhook`. You can also target a specific chat with `platform:chat_id` syntax (e.g., `telegram:-1001234567890`).
If delivery fails, the job still runs — it just won't send anywhere. Check `hermes cron list` for updated `last_error` field (if available).

View file

@ -117,6 +117,24 @@ hermes skills list | grep arxiv
---
## Plugin-Provided Skills
Plugins can bundle their own skills using namespaced names (`plugin:skill`). This prevents name collisions with built-in skills.
```bash
# Load a plugin skill by its qualified name
skill_view("superpowers:writing-plans")
# Built-in skill with the same base name is unaffected
skill_view("writing-plans")
```
Plugin skills are **not** listed in the system prompt and don't appear in `skills_list`. They're opt-in — load them explicitly when you know a plugin provides one. When loaded, the agent sees a banner listing sibling skills from the same plugin.
For how to ship skills in your own plugin, see [Build a Hermes Plugin → Bundle skills](/docs/guides/build-a-hermes-plugin#bundle-skills).
---
## Configuring Skill Settings
Some skills declare configuration they need in their frontmatter:

View file

@ -82,7 +82,7 @@ Speech-to-text supports three providers: local Whisper (free, runs on-device), G
Hermes runs as a gateway bot on 15+ messaging platforms, all configured through the same `gateway` subsystem:
- **[Telegram](/docs/user-guide/messaging/telegram)**, **[Discord](/docs/user-guide/messaging/discord)**, **[Slack](/docs/user-guide/messaging/slack)**, **[WhatsApp](/docs/user-guide/messaging/whatsapp)**, **[Signal](/docs/user-guide/messaging/signal)**, **[Matrix](/docs/user-guide/messaging/matrix)**, **[Mattermost](/docs/user-guide/messaging/mattermost)**, **[Email](/docs/user-guide/messaging/email)**, **[SMS](/docs/user-guide/messaging/sms)**, **[DingTalk](/docs/user-guide/messaging/dingtalk)**, **[Feishu/Lark](/docs/user-guide/messaging/feishu)**, **[WeCom](/docs/user-guide/messaging/wecom)**, **[WeCom Callback](/docs/user-guide/messaging/wecom-callback)**, **[Weixin](/docs/user-guide/messaging/weixin)**, **[BlueBubbles](/docs/user-guide/messaging/bluebubbles)**, **[Home Assistant](/docs/user-guide/messaging/homeassistant)**, **[Webhooks](/docs/user-guide/messaging/webhooks)**
- **[Telegram](/docs/user-guide/messaging/telegram)**, **[Discord](/docs/user-guide/messaging/discord)**, **[Slack](/docs/user-guide/messaging/slack)**, **[WhatsApp](/docs/user-guide/messaging/whatsapp)**, **[Signal](/docs/user-guide/messaging/signal)**, **[Matrix](/docs/user-guide/messaging/matrix)**, **[Mattermost](/docs/user-guide/messaging/mattermost)**, **[Email](/docs/user-guide/messaging/email)**, **[SMS](/docs/user-guide/messaging/sms)**, **[DingTalk](/docs/user-guide/messaging/dingtalk)**, **[Feishu/Lark](/docs/user-guide/messaging/feishu)**, **[WeCom](/docs/user-guide/messaging/wecom)**, **[WeCom Callback](/docs/user-guide/messaging/wecom-callback)**, **[Weixin](/docs/user-guide/messaging/weixin)**, **[BlueBubbles](/docs/user-guide/messaging/bluebubbles)**, **[QQ Bot](/docs/user-guide/messaging/qqbot)**, **[Home Assistant](/docs/user-guide/messaging/homeassistant)**, **[Webhooks](/docs/user-guide/messaging/webhooks)**
See the [Messaging Gateway overview](/docs/user-guide/messaging) for the platform comparison table and setup guide.

View file

@ -262,6 +262,15 @@ For cloud sandbox backends, persistence is filesystem-oriented. `TERMINAL_LIFETI
| `BLUEBUBBLES_HOME_CHANNEL` | Phone/email for cron/notification delivery |
| `BLUEBUBBLES_ALLOWED_USERS` | Comma-separated authorized users |
| `BLUEBUBBLES_ALLOW_ALL_USERS` | Allow all users (`true`/`false`) |
| `QQ_APP_ID` | QQ Bot App ID from [q.qq.com](https://q.qq.com) |
| `QQ_CLIENT_SECRET` | QQ Bot App Secret from [q.qq.com](https://q.qq.com) |
| `QQ_STT_API_KEY` | API key for external STT fallback provider (optional, used when QQ built-in ASR returns no text) |
| `QQ_STT_BASE_URL` | Base URL for external STT provider (optional) |
| `QQ_STT_MODEL` | Model name for external STT provider (optional) |
| `QQ_ALLOWED_USERS` | Comma-separated QQ user openIDs allowed to message the bot |
| `QQ_GROUP_ALLOWED_USERS` | Comma-separated QQ group IDs for group @-message access |
| `QQ_ALLOW_ALL_USERS` | Allow all users (`true`/`false`, overrides `QQ_ALLOWED_USERS`) |
| `QQ_HOME_CHANNEL` | QQ user/group openID for cron delivery and notifications |
| `MATTERMOST_URL` | Mattermost server URL (e.g. `https://mm.example.com`) |
| `MATTERMOST_TOKEN` | Bot token or personal access token for Mattermost |
| `MATTERMOST_ALLOWED_USERS` | Comma-separated Mattermost user IDs allowed to message the bot |
@ -292,6 +301,8 @@ For cloud sandbox backends, persistence is filesystem-oriented. `TERMINAL_LIFETI
| `API_SERVER_PORT` | Port for the API server (default: `8642`) |
| `API_SERVER_HOST` | Host/bind address for the API server (default: `127.0.0.1`). Use `0.0.0.0` for network access — requires `API_SERVER_KEY` and a narrow `API_SERVER_CORS_ORIGINS` allowlist. |
| `API_SERVER_MODEL_NAME` | Model name advertised on `/v1/models`. Defaults to the profile name (or `hermes-agent` for the default profile). Useful for multi-user setups where frontends like Open WebUI need distinct model names per connection. |
| `GATEWAY_PROXY_URL` | URL of a remote Hermes API server to forward messages to ([proxy mode](/docs/user-guide/messaging/matrix#proxy-mode-e2ee-on-macos)). When set, the gateway handles platform I/O only — all agent work is delegated to the remote server. Also configurable via `gateway.proxy_url` in `config.yaml`. |
| `GATEWAY_PROXY_KEY` | Bearer token for authenticating with the remote API server in proxy mode. Must match `API_SERVER_KEY` on the remote host. |
| `MESSAGING_CWD` | Working directory for terminal commands in messaging mode (default: `~`) |
| `GATEWAY_ALLOWED_USERS` | Comma-separated user IDs allowed across all platforms |
| `GATEWAY_ALLOW_ALL_USERS` | Allow all users without allowlists (`true`/`false`, default: `false`) |

View file

@ -106,6 +106,7 @@ Platform toolsets define the complete tool configuration for a deployment target
| `hermes-wecom-callback` | WeCom callback toolset — enterprise self-built app messaging (full access). |
| `hermes-weixin` | Same as `hermes-cli`. |
| `hermes-bluebubbles` | Same as `hermes-cli`. |
| `hermes-qqbot` | Same as `hermes-cli`. |
| `hermes-homeassistant` | Same as `hermes-cli`. |
| `hermes-webhook` | Same as `hermes-cli`. |
| `hermes-gateway` | Union of all messaging platform toolsets. Used internally when the gateway needs the broadest possible tool set. |

View file

@ -919,7 +919,7 @@ display:
slack: 'off' # quiet in shared Slack workspace
```
Platforms without an override fall back to the global `tool_progress` value. Valid platform keys: `telegram`, `discord`, `slack`, `signal`, `whatsapp`, `matrix`, `mattermost`, `email`, `sms`, `homeassistant`, `dingtalk`, `feishu`, `wecom`, `weixin`, `bluebubbles`.
Platforms without an override fall back to the global `tool_progress` value. Valid platform keys: `telegram`, `discord`, `slack`, `signal`, `whatsapp`, `matrix`, `mattermost`, `email`, `sms`, `homeassistant`, `dingtalk`, `feishu`, `wecom`, `weixin`, `bluebubbles`, `qqbot`.
`interim_assistant_messages` is gateway-only. When enabled, Hermes sends completed mid-turn assistant updates as separate chat messages. This is independent from `tool_progress` and does not require gateway streaming.

View file

@ -277,6 +277,6 @@ docker restart hermes
```sh
docker logs --tail 50 hermes # Recent logs
docker exec hermes hermes version # Verify version
docker run -it --rm nousresearch/hermes-agent:latest version # Verify version
docker stats hermes # Resource usage
```

View file

@ -278,3 +278,9 @@ In Open WebUI, add each as a separate connection. The model dropdown shows `alic
- **Response storage** — stored responses (for `previous_response_id`) are persisted in SQLite and survive gateway restarts. Max 100 stored responses (LRU eviction).
- **No file upload** — vision/document analysis via uploaded files is not yet supported through the API.
- **Model field is cosmetic** — the `model` field in requests is accepted but the actual LLM model used is configured server-side in config.yaml.
## Proxy Mode
The API server also serves as the backend for **gateway proxy mode**. When another Hermes gateway instance is configured with `GATEWAY_PROXY_URL` pointing at this API server, it forwards all messages here instead of running its own agent. This enables split deployments — for example, a Docker container handling Matrix E2EE that relays to a host-side agent.
See [Matrix Proxy Mode](/docs/user-guide/messaging/matrix#proxy-mode-e2ee-on-macos) for the full setup guide.

View file

@ -204,6 +204,7 @@ When scheduling jobs, you specify where the output goes:
| `"wecom"` | WeCom | |
| `"weixin"` | Weixin (WeChat) | |
| `"bluebubbles"` | BlueBubbles (iMessage) | |
| `"qqbot"` | QQ Bot (Tencent QQ) | |
The agent's final response is automatically delivered. You do not need to call `send_message` in the cron prompt.

View file

@ -86,7 +86,7 @@ Project-local plugins under `./.hermes/plugins/` are disabled by default. Enable
| Add CLI commands | `ctx.register_cli_command(name, help, setup_fn, handler_fn)` — adds `hermes <plugin> <subcommand>` |
| Inject messages | `ctx.inject_message(content, role="user")` — see [Injecting Messages](#injecting-messages) |
| Ship data files | `Path(__file__).parent / "data" / "file.yaml"` |
| Bundle skills | Copy `skill.md` to `~/.hermes/skills/` at load time |
| Bundle skills | `ctx.register_skill(name, path)` — namespaced as `plugin:skill`, loaded via `skill_view("plugin:skill")` |
| Gate on env vars | `requires_env: [API_KEY]` in plugin.yaml — prompted during `hermes plugins install` |
| Distribute via pip | `[project.entry-points."hermes_agent.plugins"]` |

View file

@ -36,6 +36,8 @@ display:
| `ares` | War-god theme — crimson and bronze | `Ares Agent` | Deep crimson borders with bronze accents. Aggressive spinner verbs ("forging", "marching", "tempering steel"). Custom sword-and-shield ASCII art banner. |
| `mono` | Monochrome — clean grayscale | `Hermes Agent` | All grays — no color. Borders are `#555555`, text is `#c9d1d9`. Ideal for minimal terminal setups or screen recordings. |
| `slate` | Cool blue — developer-focused | `Hermes Agent` | Royal blue borders (`#4169e1`), soft blue text. Calm and professional. No custom spinner — uses default faces. |
| `daylight` | Light theme for bright terminals with dark text and cool blue accents | `Hermes Agent` | Designed for white or bright terminals. Dark slate text with blue borders, pale status surfaces, and a light completion menu that stays readable in light terminal profiles. |
| `warm-lightmode` | Warm brown/gold text for light terminal backgrounds | `Hermes Agent` | Warm parchment tones for light terminals. Dark brown text with saddle-brown accents, cream-colored status surfaces. An earthy alternative to the cooler daylight theme. |
| `poseidon` | Ocean-god theme — deep blue and seafoam | `Poseidon Agent` | Deep blue to seafoam gradient. Ocean-themed spinners ("charting currents", "sounding the depth"). Trident ASCII art banner. |
| `sisyphus` | Sisyphean theme — austere grayscale with persistence | `Sisyphus Agent` | Light grays with stark contrast. Boulder-themed spinners ("pushing uphill", "resetting the boulder", "enduring the loop"). Boulder-and-hill ASCII art banner. |
| `charizard` | Volcanic theme — burnt orange and ember | `Charizard Agent` | Warm burnt orange to ember gradient. Fire-themed spinners ("banking into the draft", "measuring burn"). Dragon-silhouette ASCII art banner. |
@ -63,6 +65,12 @@ Controls all color values throughout the CLI. Values are hex color strings.
| `response_border` | Border around the agent's response box (ANSI escape) | `#FFD700` |
| `session_label` | Session label color | `#DAA520` |
| `session_border` | Session ID dim border color | `#8B8682` |
| `status_bar_bg` | Background color for the TUI status / usage bar | `#1a1a2e` |
| `voice_status_bg` | Background color for the voice-mode status badge | `#1a1a2e` |
| `completion_menu_bg` | Background color for the completion menu list | `#1a1a2e` |
| `completion_menu_current_bg` | Background color for the active completion row | `#333355` |
| `completion_menu_meta_bg` | Background color for the completion meta column | `#1a1a2e` |
| `completion_menu_meta_current_bg` | Background color for the active completion meta column | `#333355` |
### Spinner (`spinner:`)
@ -129,6 +137,12 @@ colors:
response_border: "#FFD700"
session_label: "#DAA520"
session_border: "#8B8682"
status_bar_bg: "#1a1a2e"
voice_status_bg: "#1a1a2e"
completion_menu_bg: "#1a1a2e"
completion_menu_current_bg: "#333355"
completion_menu_meta_bg: "#1a1a2e"
completion_menu_meta_current_bg: "#333355"
spinner:
waiting_faces:

View file

@ -6,7 +6,7 @@ description: "Chat with Hermes from Telegram, Discord, Slack, WhatsApp, Signal,
# Messaging Gateway
Chat with Hermes from Telegram, Discord, Slack, WhatsApp, Signal, SMS, Email, Home Assistant, Mattermost, Matrix, DingTalk, Feishu/Lark, WeCom, Weixin, BlueBubbles (iMessage), or your browser. The gateway is a single background process that connects to all your configured platforms, handles sessions, runs cron jobs, and delivers voice messages.
Chat with Hermes from Telegram, Discord, Slack, WhatsApp, Signal, SMS, Email, Home Assistant, Mattermost, Matrix, DingTalk, Feishu/Lark, WeCom, Weixin, BlueBubbles (iMessage), QQ, or your browser. The gateway is a single background process that connects to all your configured platforms, handles sessions, runs cron jobs, and delivers voice messages.
For the full voice feature set — including CLI microphone mode, spoken replies in messaging, and Discord voice-channel conversations — see [Voice Mode](/docs/user-guide/features/voice-mode) and [Use Voice Mode with Hermes](/docs/guides/use-voice-mode-with-hermes).
@ -30,6 +30,7 @@ For the full voice feature set — including CLI microphone mode, spoken replies
| WeCom Callback | — | — | — | — | — | — | — |
| Weixin | ✅ | ✅ | ✅ | — | — | ✅ | ✅ |
| BlueBubbles | — | ✅ | ✅ | — | ✅ | ✅ | — |
| QQ | ✅ | ✅ | ✅ | — | — | ✅ | — |
**Voice** = TTS audio replies and/or voice message transcription. **Images** = send/receive images. **Files** = send/receive file attachments. **Threads** = threaded conversations. **Reactions** = emoji reactions on messages. **Typing** = typing indicator while processing. **Streaming** = progressive message updates via editing.
@ -55,6 +56,7 @@ flowchart TB
wcb[WeCom Callback]
wx[Weixin]
bb[BlueBubbles]
qq[QQ]
api["API Server<br/>(OpenAI-compatible)"]
wh[Webhooks]
end
@ -80,6 +82,7 @@ flowchart TB
wcb --> store
wx --> store
bb --> store
qq --> store
api --> store
wh --> store
store --> agent
@ -369,6 +372,7 @@ Each platform has its own toolset:
| WeCom Callback | `hermes-wecom-callback` | Full tools including terminal |
| Weixin | `hermes-weixin` | Full tools including terminal |
| BlueBubbles | `hermes-bluebubbles` | Full tools including terminal |
| QQBot | `hermes-qqbot` | Full tools including terminal |
| API Server | `hermes` (default) | Full tools including terminal |
| Webhooks | `hermes-webhook` | Full tools including terminal |
@ -390,5 +394,6 @@ Each platform has its own toolset:
- [WeCom Callback Setup](wecom-callback.md)
- [Weixin Setup (WeChat)](weixin.md)
- [BlueBubbles Setup (iMessage)](bluebubbles.md)
- [QQBot Setup](qqbot.md)
- [Open WebUI + API Server](open-webui.md)
- [Webhooks](webhooks.md)

View file

@ -439,6 +439,141 @@ security breach). A new access token gets a new device ID with no stale key
history, so other clients trust it immediately.
:::
## Proxy Mode (E2EE on macOS)
Matrix E2EE requires `libolm`, which doesn't compile on macOS ARM64 (Apple Silicon). The `hermes-agent[matrix]` extra is gated to Linux only. If you're on macOS, proxy mode lets you run E2EE in a Docker container on a Linux VM while the actual agent runs natively on macOS with full access to your local files, memory, and skills.
### How It Works
```
macOS (Host):
└─ hermes gateway
├─ api_server adapter ← listens on 0.0.0.0:8642
├─ AIAgent ← single source of truth
├─ Sessions, memory, skills
└─ Local file access (Obsidian, projects, etc.)
Linux VM (Docker):
└─ hermes gateway (proxy mode)
├─ Matrix adapter ← E2EE decryption/encryption
└─ HTTP forward → macOS:8642/v1/chat/completions
(no LLM API keys, no agent, no inference)
```
The Docker container only handles Matrix protocol + E2EE. When a message arrives, it decrypts it and forwards the text to the host via a standard HTTP request. The host runs the agent, calls tools, generates a response, and streams it back. The container encrypts and sends the response to Matrix. All sessions are unified — CLI, Matrix, Telegram, and any other platform share the same memory and conversation history.
### Step 1: Configure the Host (macOS)
Enable the API server so the host accepts incoming requests from the Docker container.
Add to `~/.hermes/.env`:
```bash
API_SERVER_ENABLED=true
API_SERVER_KEY=your-secret-key-here
API_SERVER_HOST=0.0.0.0
```
- `API_SERVER_HOST=0.0.0.0` binds to all interfaces so the Docker container can reach it.
- `API_SERVER_KEY` is required for non-loopback binding. Pick a strong random string.
- The API server runs on port 8642 by default (change with `API_SERVER_PORT` if needed).
Start the gateway:
```bash
hermes gateway
```
You should see the API server start alongside any other platforms you have configured. Verify it's reachable from the VM:
```bash
# From the Linux VM
curl http://<mac-ip>:8642/health
```
### Step 2: Configure the Docker Container (Linux VM)
The container needs Matrix credentials and the proxy URL. It does NOT need LLM API keys.
**`docker-compose.yml`:**
```yaml
services:
hermes-matrix:
build: .
environment:
# Matrix credentials
MATRIX_HOMESERVER: "https://matrix.example.org"
MATRIX_ACCESS_TOKEN: "syt_..."
MATRIX_ALLOWED_USERS: "@you:matrix.example.org"
MATRIX_ENCRYPTION: "true"
MATRIX_DEVICE_ID: "HERMES_BOT"
# Proxy mode — forward to host agent
GATEWAY_PROXY_URL: "http://192.168.1.100:8642"
GATEWAY_PROXY_KEY: "your-secret-key-here"
volumes:
- ./matrix-store:/root/.hermes/platforms/matrix/store
```
**`Dockerfile`:**
```dockerfile
FROM python:3.11-slim
RUN apt-get update && apt-get install -y libolm-dev && rm -rf /var/lib/apt/lists/*
RUN pip install 'hermes-agent[matrix]'
CMD ["hermes", "gateway"]
```
That's the entire container. No API keys for OpenRouter, Anthropic, or any inference provider.
### Step 3: Start Both
1. Start the host gateway first:
```bash
hermes gateway
```
2. Start the Docker container:
```bash
docker compose up -d
```
3. Send a message in an encrypted Matrix room. The container decrypts it, forwards it to the host, and streams the response back.
### Configuration Reference
Proxy mode is configured on the **container side** (the thin gateway):
| Setting | Description |
|---------|-------------|
| `GATEWAY_PROXY_URL` | URL of the remote Hermes API server (e.g., `http://192.168.1.100:8642`) |
| `GATEWAY_PROXY_KEY` | Bearer token for authentication (must match `API_SERVER_KEY` on the host) |
| `gateway.proxy_url` | Same as `GATEWAY_PROXY_URL` but in `config.yaml` |
The host side needs:
| Setting | Description |
|---------|-------------|
| `API_SERVER_ENABLED` | Set to `true` |
| `API_SERVER_KEY` | Bearer token (shared with the container) |
| `API_SERVER_HOST` | Set to `0.0.0.0` for network access |
| `API_SERVER_PORT` | Port number (default: `8642`) |
### Works for Any Platform
Proxy mode is not limited to Matrix. Any platform adapter can use it — set `GATEWAY_PROXY_URL` on any gateway instance and it will forward to the remote agent instead of running one locally. This is useful for any deployment where the platform adapter needs to run in a different environment from the agent (network isolation, E2EE requirements, resource constraints).
:::tip
Session continuity is maintained via the `X-Hermes-Session-Id` header. The host's API server tracks sessions by this ID, so conversations persist across messages just like they would with a local agent.
:::
:::note
**Limitations (v1):** Tool progress messages from the remote agent are not relayed back — the user sees the streamed final response only, not individual tool calls. Dangerous command approval prompts are handled on the host side, not relayed to the Matrix user. These can be addressed in future updates.
:::
### Sync issues / bot falls behind
**Cause**: Long-running tool executions can delay the sync loop, or the homeserver is slow.

View file

@ -0,0 +1,122 @@
# QQ Bot
Connect Hermes to QQ via the **Official QQ Bot API (v2)** — supporting private (C2C), group @-mentions, guild, and direct messages with voice transcription.
## Overview
The QQ Bot adapter uses the [Official QQ Bot API](https://bot.q.qq.com/wiki/develop/api-v2/) to:
- Receive messages via a persistent **WebSocket** connection to the QQ Gateway
- Send text and markdown replies via the **REST API**
- Download and process images, voice messages, and file attachments
- Transcribe voice messages using Tencent's built-in ASR or a configurable STT provider
## Prerequisites
1. **QQ Bot Application** — Register at [q.qq.com](https://q.qq.com):
- Create a new application and note your **App ID** and **App Secret**
- Enable the required intents: C2C messages, Group @-messages, Guild messages
- Configure your bot in sandbox mode for testing, or publish for production
2. **Dependencies** — The adapter requires `aiohttp` and `httpx`:
```bash
pip install aiohttp httpx
```
## Configuration
### Interactive setup
```bash
hermes setup gateway
```
Select **QQ Bot** from the platform list and follow the prompts.
### Manual configuration
Set the required environment variables in `~/.hermes/.env`:
```bash
QQ_APP_ID=your-app-id
QQ_CLIENT_SECRET=your-app-secret
```
## Environment Variables
| Variable | Description | Default |
|---|---|---|
| `QQ_APP_ID` | QQ Bot App ID (required) | — |
| `QQ_CLIENT_SECRET` | QQ Bot App Secret (required) | — |
| `QQ_HOME_CHANNEL` | OpenID for cron/notification delivery | — |
| `QQ_HOME_CHANNEL_NAME` | Display name for home channel | `Home` |
| `QQ_ALLOWED_USERS` | Comma-separated user OpenIDs for DM access | open (all users) |
| `QQ_ALLOW_ALL_USERS` | Set to `true` to allow all DMs | `false` |
| `QQ_MARKDOWN_SUPPORT` | Enable QQ markdown (msg_type 2) | `true` |
| `QQ_STT_API_KEY` | API key for voice-to-text provider | — |
| `QQ_STT_BASE_URL` | Base URL for STT provider | `https://open.bigmodel.cn/api/coding/paas/v4` |
| `QQ_STT_MODEL` | STT model name | `glm-asr` |
## Advanced Configuration
For fine-grained control, add platform settings to `~/.hermes/config.yaml`:
```yaml
platforms:
qq:
enabled: true
extra:
app_id: "your-app-id"
client_secret: "your-secret"
markdown_support: true
dm_policy: "open" # open | allowlist | disabled
allow_from:
- "user_openid_1"
group_policy: "open" # open | allowlist | disabled
group_allow_from:
- "group_openid_1"
stt:
provider: "zai" # zai (GLM-ASR), openai (Whisper), etc.
baseUrl: "https://open.bigmodel.cn/api/coding/paas/v4"
apiKey: "your-stt-key"
model: "glm-asr"
```
## Voice Messages (STT)
Voice transcription works in two stages:
1. **QQ built-in ASR** (free, always tried first) — QQ provides `asr_refer_text` in voice message attachments, which uses Tencent's own speech recognition
2. **Configured STT provider** (fallback) — If QQ's ASR doesn't return text, the adapter calls an OpenAI-compatible STT API:
- **Zhipu/GLM (zai)**: Default provider, uses `glm-asr` model
- **OpenAI Whisper**: Set `QQ_STT_BASE_URL` and `QQ_STT_MODEL`
- Any OpenAI-compatible STT endpoint
## Troubleshooting
### Bot disconnects immediately (quick disconnect)
This usually means:
- **Invalid App ID / Secret** — Double-check your credentials at q.qq.com
- **Missing permissions** — Ensure the bot has the required intents enabled
- **Sandbox-only bot** — If the bot is in sandbox mode, it can only receive messages from QQ's sandbox test channel
### Voice messages not transcribed
1. Check if QQ's built-in `asr_refer_text` is present in the attachment data
2. If using a custom STT provider, verify `QQ_STT_API_KEY` is set correctly
3. Check gateway logs for STT error messages
### Messages not delivered
- Verify the bot's **intents** are enabled at q.qq.com
- Check `QQ_ALLOWED_USERS` if DM access is restricted
- For group messages, ensure the bot is **@mentioned** (group policy may require allowlisting)
- Check `QQ_HOME_CHANNEL` for cron/notification delivery
### Connection errors
- Ensure `aiohttp` and `httpx` are installed: `pip install aiohttp httpx`
- Check network connectivity to `api.sgroup.qq.com` and the WebSocket gateway
- Review gateway logs for detailed error messages and reconnect behavior

View file

@ -70,7 +70,7 @@ Routes define how different webhook sources are handled. Each route is a named e
| `secret` | **Yes** | HMAC secret for signature validation. Falls back to the global `secret` if not set on the route. Set to `"INSECURE_NO_AUTH"` for testing only (skips validation). |
| `prompt` | No | Template string with dot-notation payload access (e.g. `{pull_request.title}`). If omitted, the full JSON payload is dumped into the prompt. |
| `skills` | No | List of skill names to load for the agent run. |
| `deliver` | No | Where to send the response: `github_comment`, `telegram`, `discord`, `slack`, `signal`, `sms`, `whatsapp`, `matrix`, `mattermost`, `homeassistant`, `email`, `dingtalk`, `feishu`, `wecom`, `weixin`, `bluebubbles`, or `log` (default). |
| `deliver` | No | Where to send the response: `github_comment`, `telegram`, `discord`, `slack`, `signal`, `sms`, `whatsapp`, `matrix`, `mattermost`, `homeassistant`, `email`, `dingtalk`, `feishu`, `wecom`, `weixin`, `bluebubbles`, `qqbot`, or `log` (default). |
| `deliver_extra` | No | Additional delivery config — keys depend on `deliver` type (e.g. `repo`, `pr_number`, `chat_id`). Values support the same `{dot.notation}` templates as `prompt`. |
### Full example

View file

@ -46,6 +46,7 @@ Each session is tagged with its source platform:
| `wecom` | WeCom (WeChat Work) |
| `weixin` | Weixin (personal WeChat) |
| `bluebubbles` | Apple iMessage via BlueBubbles macOS server |
| `qqbot` | QQ Bot (Tencent QQ) via Official API v2 |
| `homeassistant` | Home Assistant conversation |
| `webhook` | Incoming webhooks |
| `api-server` | API server requests |