diff --git a/agent/prompt_builder.py b/agent/prompt_builder.py index aaef51192f..6d35cdde3d 100644 --- a/agent/prompt_builder.py +++ b/agent/prompt_builder.py @@ -848,6 +848,11 @@ def build_skills_system_prompt( "Skills also encode the user's preferred approach, conventions, and quality standards " "for tasks like code review, planning, and testing — load them even for tasks you " "already know how to do, because the skill defines how it should be done here.\n" + "Whenever the user asks you to configure, set up, install, enable, disable, modify, " + "or troubleshoot Hermes Agent itself — its CLI, config, models, providers, tools, " + "skills, voice, gateway, plugins, or any feature — load the `hermes-agent` skill " + "first. It has the actual commands (e.g. `hermes config set …`, `hermes tools`, " + "`hermes setup`) so you don't have to guess or invent workarounds.\n" "If a skill has issues, fix it with skill_manage(action='patch').\n" "After difficult/iterative tasks, offer to save as a skill. " "If a skill you loaded was missing steps, had wrong commands, or needed " diff --git a/skills/autonomous-ai-agents/hermes-agent/SKILL.md b/skills/autonomous-ai-agents/hermes-agent/SKILL.md index 76a0e51b6c..4603a37e2d 100644 --- a/skills/autonomous-ai-agents/hermes-agent/SKILL.md +++ b/skills/autonomous-ai-agents/hermes-agent/SKILL.md @@ -402,6 +402,63 @@ Tool changes take effect on `/reset` (new session). They do NOT apply mid-conver --- +## Security & Privacy Toggles + +Common "why is Hermes doing X to my output / tool calls / commands?" toggles — and the exact commands to change them. Most of these need a fresh session (`/reset` in chat, or start a new `hermes` invocation) because they're read once at startup. + +### Secret redaction in tool output + +Hermes auto-redacts strings that look like API keys, tokens, and secrets in all tool output (terminal stdout, `read_file`, web content, subagent summaries, etc.) so the model never sees raw credentials. If the user is intentionally working with mock tokens, share-management tokens, or their own secrets and the redaction is getting in the way: + +```bash +hermes config set security.redact_secrets false # disable globally +``` + +**Restart required.** `security.redact_secrets` is snapshotted at import time — setting it mid-session (e.g. via `export HERMES_REDACT_SECRETS=false` from a tool call) will NOT take effect for the running process. Tell the user to run `hermes config set security.redact_secrets false` in a terminal, then start a new session. This is deliberate — it prevents an LLM from turning off redaction on itself mid-task. + +Re-enable with: +```bash +hermes config set security.redact_secrets true +``` + +### PII redaction in gateway messages + +Separate from secret redaction. When enabled, the gateway hashes user IDs and strips phone numbers from the session context before it reaches the model: + +```bash +hermes config set privacy.redact_pii true # enable +hermes config set privacy.redact_pii false # disable (default) +``` + +### Command approval prompts + +By default (`approvals.mode: manual`), Hermes prompts the user before running shell commands flagged as destructive (`rm -rf`, `git reset --hard`, etc.). The modes are: + +- `manual` — always prompt (default) +- `smart` — use an auxiliary LLM to auto-approve low-risk commands, prompt on high-risk +- `off` — skip all approval prompts (equivalent to `--yolo`) + +```bash +hermes config set approvals.mode smart # recommended middle ground +hermes config set approvals.mode off # bypass everything (not recommended) +``` + +Per-invocation bypass without changing config: +- `hermes --yolo …` +- `export HERMES_YOLO_MODE=1` + +Note: YOLO / `approvals.mode: off` does NOT turn off secret redaction. They are independent. + +### Shell hooks allowlist + +Some shell-hook integrations require explicit allowlisting before they fire. Managed via `~/.hermes/shell-hooks-allowlist.json` — prompted interactively the first time a hook wants to run. + +### Disabling the web/browser/image-gen tools + +To keep the model away from network or media tools entirely, open `hermes tools` and toggle per-platform. Takes effect on next session (`/reset`). See the Tools & Skills section above. + +--- + ## Voice & Transcription ### STT (Voice → Text) diff --git a/tools/browser_tool.py b/tools/browser_tool.py index 3fde1dd9c6..87ed56b270 100644 --- a/tools/browser_tool.py +++ b/tools/browser_tool.py @@ -995,7 +995,7 @@ atexit.register(_stop_browser_cleanup_thread) BROWSER_TOOL_SCHEMAS = [ { "name": "browser_navigate", - "description": "Navigate to a URL in the browser. Initializes the session and loads the page. Must be called before other browser tools. For simple information retrieval, prefer web_search or web_extract (faster, cheaper). Use browser tools when you need to interact with a page (click, fill forms, dynamic content). Returns a compact page snapshot with interactive elements and ref IDs — no need to call browser_snapshot separately after navigating.", + "description": "Navigate to a URL in the browser. Initializes the session and loads the page. Must be called before other browser tools. For simple information retrieval, prefer web_search or web_extract (faster, cheaper). For plain-text endpoints — URLs ending in .md, .txt, .json, .yaml, .yml, .csv, .xml, raw.githubusercontent.com, or any documented API endpoint — prefer curl via the terminal tool or web_extract; the browser stack is overkill and much slower for these. Use browser tools when you need to interact with a page (click, fill forms, dynamic content). Returns a compact page snapshot with interactive elements and ref IDs — no need to call browser_snapshot separately after navigating.", "parameters": { "type": "object", "properties": { diff --git a/tools/delegate_tool.py b/tools/delegate_tool.py index abdec4717f..397b7c958b 100644 --- a/tools/delegate_tool.py +++ b/tools/delegate_tool.py @@ -2316,6 +2316,18 @@ DELEGATE_TASK_SCHEMA = { "IMPORTANT:\n" "- Subagents have NO memory of your conversation. Pass all relevant " "info (file paths, error messages, constraints) via the 'context' field.\n" + "- If the user is writing in a non-English language, or asked for " + "output in a specific language / tone / style, say so in 'context' " + "(e.g. \"respond in Chinese\", \"return output in Japanese\"). " + "Otherwise subagents default to English and their summaries will " + "contaminate your final reply with the wrong language.\n" + "- Subagent summaries are SELF-REPORTS, not verified facts. A subagent " + "that claims \"uploaded successfully\" or \"file written\" may be wrong. " + "For operations with external side-effects (HTTP POST/PUT, remote " + "writes, file creation at shared paths, publishing), require the " + "subagent to return a verifiable handle (URL, ID, absolute path, HTTP " + "status) and verify it yourself — fetch the URL, stat the file, read " + "back the content — before telling the user the operation succeeded.\n" "- Leaf subagents (role='leaf', the default) CANNOT call: " "delegate_task, clarify, memory, send_message, execute_code.\n" "- Orchestrator subagents (role='orchestrator') retain "