remove: BOOT.md built-in hook (#17093)

BOOT.md was merged in PR #3733 before the feature was ready — the
built-in hook spawned a bare AIAgent() with no model/runtime kwargs,
which immediately 401s on any provider with a custom endpoint. Three
separate community PRs (#5240, #12514, #14992) tried to paper over it.

Remove the BOOT.md hook entirely and its user-facing docs/tips. Keep
the gateway/builtin_hooks/ package and the HookRegistry._register_builtin_hooks()
hook-point intact as the extension surface for future always-on
gateway hooks.

Closes #5239.

Co-authored-by: teknium1 <teknium@users.noreply.github.com>
This commit is contained in:
Teknium 2026-04-28 09:50:27 -07:00 committed by GitHub
parent b5128a751b
commit b53a091b97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 9 additions and 121 deletions

View File

@ -38,7 +38,7 @@ hermes-agent/
│ │ # homeassistant, signal, matrix, mattermost, email, sms, │ │ # homeassistant, signal, matrix, mattermost, email, sms,
│ │ # dingtalk, wecom, weixin, feishu, qqbot, bluebubbles, │ │ # dingtalk, wecom, weixin, feishu, qqbot, bluebubbles,
│ │ # webhook, api_server, ...). See ADDING_A_PLATFORM.md. │ │ # webhook, api_server, ...). See ADDING_A_PLATFORM.md.
│ └── builtin_hooks/ # Always-registered gateway hooks (boot-md, ...) │ └── builtin_hooks/ # Extension point for always-registered gateway hooks (none shipped)
├── plugins/ # Plugin system (see "Plugins" section below) ├── plugins/ # Plugin system (see "Plugins" section below)
│ ├── memory/ # Memory-provider plugins (honcho, mem0, supermemory, ...) │ ├── memory/ # Memory-provider plugins (honcho, mem0, supermemory, ...)
│ ├── context_engine/ # Context-engine plugins │ ├── context_engine/ # Context-engine plugins

View File

@ -1,85 +0,0 @@
"""Built-in boot-md hook — run ~/.hermes/BOOT.md on gateway startup.
This hook is always registered. It silently skips if no BOOT.md exists.
To activate, create ``~/.hermes/BOOT.md`` with instructions for the
agent to execute on every gateway restart.
Example BOOT.md::
# Startup Checklist
1. Check if any cron jobs failed overnight
2. Send a status update to Discord #general
3. If there are errors in /opt/app/deploy.log, summarize them
The agent runs in a background thread so it doesn't block gateway
startup. If nothing needs attention, it replies with [SILENT] to
suppress delivery.
"""
import logging
import threading
logger = logging.getLogger("hooks.boot-md")
from hermes_constants import get_hermes_home
HERMES_HOME = get_hermes_home()
BOOT_FILE = HERMES_HOME / "BOOT.md"
def _build_boot_prompt(content: str) -> str:
"""Wrap BOOT.md content in a system-level instruction."""
return (
"You are running a startup boot checklist. Follow the BOOT.md "
"instructions below exactly.\n\n"
"---\n"
f"{content}\n"
"---\n\n"
"Execute each instruction. If you need to send a message to a "
"platform, use the send_message tool.\n"
"If nothing needs attention and there is nothing to report, "
"reply with ONLY: [SILENT]"
)
def _run_boot_agent(content: str) -> None:
"""Spawn a one-shot agent session to execute the boot instructions."""
try:
from run_agent import AIAgent
prompt = _build_boot_prompt(content)
agent = AIAgent(
quiet_mode=True,
skip_context_files=True,
skip_memory=True,
max_iterations=20,
)
result = agent.run_conversation(prompt)
response = result.get("final_response", "")
if response and "[SILENT]" not in response:
logger.info("boot-md completed: %s", response[:200])
else:
logger.info("boot-md completed (nothing to report)")
except Exception as e:
logger.error("boot-md agent failed: %s", e)
async def handle(event_type: str, context: dict) -> None:
"""Gateway startup handler — run BOOT.md if it exists."""
if not BOOT_FILE.exists():
return
content = BOOT_FILE.read_text(encoding="utf-8").strip()
if not content:
return
logger.info("Running BOOT.md (%d chars)", len(content))
# Run in a background thread so we don't block gateway startup.
thread = threading.Thread(
target=_run_boot_agent,
args=(content,),
name="boot-md",
daemon=True,
)
thread.start()

View File

@ -52,19 +52,13 @@ class HookRegistry:
return list(self._loaded_hooks) return list(self._loaded_hooks)
def _register_builtin_hooks(self) -> None: def _register_builtin_hooks(self) -> None:
"""Register built-in hooks that are always active.""" """Register built-in hooks that are always active.
try:
from gateway.builtin_hooks.boot_md import handle as boot_md_handle
self._handlers.setdefault("gateway:startup", []).append(boot_md_handle) Currently empty no shipped built-in hooks. Kept as the extension
self._loaded_hooks.append({ point for future always-on gateway hooks so they drop in without
"name": "boot-md", re-plumbing discover_and_load().
"description": "Run ~/.hermes/BOOT.md on gateway startup", """
"events": ["gateway:startup"], return
"path": "(builtin)",
})
except Exception as e:
print(f"[hooks] Could not load built-in boot-md hook: {e}", flush=True)
def discover_and_load(self) -> None: def discover_and_load(self) -> None:
""" """

View File

@ -263,7 +263,6 @@ TIPS = [
"hermes status --deep runs deeper diagnostic checks across all components.", "hermes status --deep runs deeper diagnostic checks across all components.",
# --- Hidden Gems & Power-User Tricks --- # --- Hidden Gems & Power-User Tricks ---
"BOOT.md at ~/.hermes/BOOT.md runs automatically on every gateway start — use it for startup checks.",
"Cron jobs can attach a Python script (--script) whose stdout is injected into the prompt as context.", "Cron jobs can attach a Python script (--script) whose stdout is injected into the prompt as context.",
"Cron scripts live in ~/.hermes/scripts/ and run before the agent — perfect for data collection pipelines.", "Cron scripts live in ~/.hermes/scripts/ and run before the agent — perfect for data collection pipelines.",
"prefill_messages_file in config.yaml injects few-shot examples into every API call, never saved to history.", "prefill_messages_file in config.yaml injects few-shot examples into every API call, never saved to history.",

View File

@ -116,7 +116,7 @@ hermes-agent/
│ ├── hooks.py # Hook discovery and lifecycle events │ ├── hooks.py # Hook discovery and lifecycle events
│ ├── mirror.py # Cross-session message mirroring │ ├── mirror.py # Cross-session message mirroring
│ ├── status.py # Token locks, profile-scoped process tracking │ ├── status.py # Token locks, profile-scoped process tracking
│ ├── builtin_hooks/ # Always-registered hooks │ ├── builtin_hooks/ # Extension point for always-registered hooks (none shipped)
│ └── platforms/ # 18 adapters: telegram, discord, slack, whatsapp, │ └── platforms/ # 18 adapters: telegram, discord, slack, whatsapp,
│ # signal, matrix, mattermost, email, sms, │ # signal, matrix, mattermost, email, sms,
│ # dingtalk, feishu, wecom, wecom_callback, weixin, │ # dingtalk, feishu, wecom, wecom_callback, weixin,

View File

@ -20,7 +20,7 @@ The messaging gateway is the long-running process that connects Hermes to 14+ ex
| `gateway/hooks.py` | Hook discovery, loading, and lifecycle event dispatch | | `gateway/hooks.py` | Hook discovery, loading, and lifecycle event dispatch |
| `gateway/mirror.py` | Cross-session message mirroring for `send_message` | | `gateway/mirror.py` | Cross-session message mirroring for `send_message` |
| `gateway/status.py` | Token lock management for profile-scoped gateway instances | | `gateway/status.py` | Token lock management for profile-scoped gateway instances |
| `gateway/builtin_hooks/` | Always-registered hooks (e.g., BOOT.md system prompt hook) | | `gateway/builtin_hooks/` | Extension point for always-registered hooks (none shipped) |
| `gateway/platforms/` | Platform adapters (one per messaging platform) | | `gateway/platforms/` | Platform adapters (one per messaging platform) |
## Architecture Overview ## Architecture Overview

View File

@ -89,26 +89,6 @@ Handlers registered for `command:*` fire for any `command:` event (`command:mode
### Examples ### Examples
#### Boot Checklist (BOOT.md) — Built-in
The gateway ships with a built-in `boot-md` hook that looks for `~/.hermes/BOOT.md` on every startup. If the file exists, the agent runs its instructions in a background session. No installation needed — just create the file.
**Create `~/.hermes/BOOT.md`:**
```markdown
# Startup Checklist
1. Check if any cron jobs failed overnight — run `hermes cron list`
2. Send a message to Discord #general saying "Gateway restarted, all systems go"
3. Check if /opt/app/deploy.log has any errors from the last 24 hours
```
The agent runs these instructions in a background thread so it doesn't block gateway startup. If nothing needs attention, the agent replies with `[SILENT]` and no message is delivered.
:::tip
No BOOT.md? The hook silently skips — zero overhead. Create the file whenever you need startup automation, delete it when you don't.
:::
#### Telegram Alert on Long Tasks #### Telegram Alert on Long Tasks
Send yourself a message when the agent takes more than 10 steps: Send yourself a message when the agent takes more than 10 steps: