hermes-bsd/tools
Teknium 4d7fc0f37c feat(gateway,cli): confirm /reload-mcp to warn about prompt cache invalidation
Reloading MCP servers rebuilds the tool set for the active session, which
invalidates the provider prompt cache (tool schemas are baked into the
system prompt). The next message re-sends full input tokens — can be
expensive on long-context or high-reasoning models.

To surface that cost, /reload-mcp now routes through a new slash-confirm
primitive with three options: Approve Once / Always Approve / Cancel.
'Always Approve' persists approvals.mcp_reload_confirm: false so future
reloads run silently.

Coverage:

* Classic CLI (cli.py) — interactive numbered prompt.
* TUI (tui_gateway + Ink ops.ts) — text warning on first call; `now` /
  `always` args skip the gate; `always` also persists the opt-out.
* Messenger gateway — button UI on Telegram (inline keyboard), Discord
  (discord.ui.View), Slack (Block Kit actions); text fallback on every
  other platform via /approve /always /cancel replies intercepted in
  gateway/run.py _handle_message.
* Config key: approvals.mcp_reload_confirm (default true).
* Auto-reload paths (CLI file watcher, TUI config-sync mtime poll) pass
  confirm=true so they do NOT prompt.

Implementation:

* tools/slash_confirm.py — module-level pending-state store used by all
  adapters and by the CLI prompt. Thread-safe register/resolve/clear.
* gateway/platforms/base.py — send_slash_confirm hook (default 'Not
  supported' → text fallback).
* gateway/run.py — _request_slash_confirm helper + text intercept in
  _handle_message (yields to in-progress tool-exec approvals so
  dangerous-command /approve still unblocks the tool thread first).

Tests:

* tests/tools/test_slash_confirm.py — primitive lifecycle + async
  resolution + double-click atomicity (16 tests).
* tests/hermes_cli/test_mcp_reload_confirm_gate.py — default-config
  shape + deep-merge preserves user opt-out (5 tests).

Targeted runs (hermetic): 89 passed (slash-confirm, config gate,
existing agent cache, existing telegram approval buttons).
2026-04-29 21:56:47 -07:00
..
browser_providers
environments fix: address self-review findings for Vercel Sandbox salvage 2026-04-29 07:22:33 -07:00
neutts_samples
__init__.py
ansi_strip.py
approval.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
binary_extensions.py
browser_camofox.py refactor(config): add cfg_get() helper; migrate 20 nested-get call sites (#17304) 2026-04-28 23:17:39 -07:00
browser_camofox_state.py
browser_cdp_tool.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
browser_dialog_tool.py feat(browser): CDP supervisor — dialog detection + response + cross-origin iframe eval (#14540) 2026-04-23 22:23:37 -07:00
browser_supervisor.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
browser_tool.py refactor(config): add cfg_get() helper; migrate 20 nested-get call sites (#17304) 2026-04-28 23:17:39 -07:00
budget_config.py
checkpoint_manager.py feat(checkpoints): auto-prune orphan and stale shadow repos at startup (#16303) 2026-04-26 19:05:52 -07:00
clarify_tool.py
code_execution_tool.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
credential_files.py refactor(config): add cfg_get() helper; migrate 20 nested-get call sites (#17304) 2026-04-28 23:17:39 -07:00
cronjob_tools.py fix(cron): accept list-form deliver values so deliver=['telegram'] works (#17456) 2026-04-29 06:35:34 -07:00
debug_helpers.py
delegate_tool.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
discord_tool.py fix(discord_tool): coerce limit parameter to int before min() call 2026-04-26 20:48:38 -07:00
env_passthrough.py refactor(config): add cfg_get() helper; migrate 20 nested-get call sites (#17304) 2026-04-28 23:17:39 -07:00
feishu_doc_tool.py
feishu_drive_tool.py
file_operations.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00
file_state.py
file_tools.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
fuzzy_match.py
homeassistant_tool.py
image_generation_tool.py
interrupt.py
managed_tool_gateway.py
mcp_oauth.py fix(mcp-oauth): preserve server_url path for protected-resource validation (#16031) 2026-04-26 05:43:54 -07:00
mcp_oauth_manager.py fix(mcp-oauth): preserve server_url path for protected-resource validation (#16031) 2026-04-26 05:43:54 -07:00
mcp_tool.py refactor(schema): consolidate nullable-union stripping in schema_sanitizer 2026-04-28 04:58:03 -07:00
memory_tool.py refactor: consolidate symlink-safe atomic replace into shared helper 2026-04-28 04:58:22 -07:00
mixture_of_agents_tool.py Fix (mixture_of_agents): replace deprecated Gemini model and forward max_tokens to OpenRouter (#6621) 2026-04-23 15:14:11 -07:00
neutts_synth.py
openrouter_client.py
osv_check.py
patch_parser.py
path_security.py
process_registry.py fix(process): reconcile session.exited against real child exit in poll/wait (#17430) 2026-04-29 04:59:21 -07:00
registry.py perf(tools): memoize get_tool_definitions + TTL-cache check_fn results (#17098) 2026-04-28 18:20:17 -07:00
rl_training_tool.py
schema_sanitizer.py refactor(schema): consolidate nullable-union stripping in schema_sanitizer 2026-04-28 04:58:03 -07:00
send_message_tool.py feat(yuanbao): wire native text + media delivery into send_message 2026-04-29 04:56:18 -07:00
session_search_tool.py fix(session-search): exclude current lineage root deterministically in recent mode 2026-04-26 19:03:17 -07:00
skill_manager_tool.py feat(skills): refuse skill_manage writes on pinned skills (#17562) 2026-04-29 10:28:25 -07:00
skill_usage.py fix(curator): defense-in-depth gates against bundled/hub skills 2026-04-28 22:33:33 -07:00
skills_guard.py feat(skills-guard): gate agent-created scanner on config.skills.guard_agent_created (default off) 2026-04-23 06:20:47 -07:00
skills_hub.py feat(skills): install skills from a direct HTTP(S) URL (#16323) 2026-04-26 20:57:10 -07:00
skills_sync.py refactor: consolidate symlink-safe atomic replace into shared helper 2026-04-28 04:58:22 -07:00
skills_tool.py refactor(reload-skills): queue note for next turn, drop cache invalidation + agent tool 2026-04-29 21:07:47 -07:00
slash_confirm.py feat(gateway,cli): confirm /reload-mcp to warn about prompt cache invalidation 2026-04-29 21:56:47 -07:00
terminal_tool.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
tirith_security.py
todo_tool.py
tool_backend_helpers.py fix(cli): coerce use_gateway config flags in tool routing 2026-04-26 19:02:55 -07:00
tool_output_limits.py feat(skills): add design-md skill for Google's DESIGN.md spec (#14876) 2026-04-23 21:51:19 -07:00
tool_result_storage.py
transcription_tools.py fix(stt): resolve API keys from ~/.hermes/.env via get_env_value (#17140) 2026-04-29 06:25:20 -07:00
tts_tool.py fix(tts): tolerate missing hermes_cli.config in tts_tool import 2026-04-29 06:25:20 -07:00
url_safety.py fix(security): treat quoted false as false in browser SSRF guards 2026-04-26 18:27:13 -07:00
vision_tools.py fix(vision): use HERMES_HOME-based cache dir instead of cwd (#17719) 2026-04-29 20:14:02 -07:00
voice_mode.py
web_tools.py perf(tools): memoize get_tool_definitions + TTL-cache check_fn results (#17098) 2026-04-28 18:20:17 -07:00
website_policy.py
xai_http.py
yuanbao_tools.py chore: remove unused imports and dead locals (ruff F401, F841) (#17010) 2026-04-28 06:46:45 -07:00