mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-18 04:41:56 +00:00
feat(plugins): add thread-local tool whitelist to pre_tool_call gate
Adds set_thread_tool_whitelist / clear_thread_tool_whitelist to hermes_cli/plugins.py. When set on the current thread, restricts which tools can pass through get_pre_tool_call_block_message; non-whitelisted tools are blocked with a configurable deny message. Mirrors the per-thread approval-callback pattern already used by set_approval_callback (tools/terminal_tool.py:190). Used by _spawn_background_review to deny non-memory/non-skill tools at runtime while inheriting the parent agent's full tools schema for prefix-cache parity (see follow-up commit). Tests cover allow / deny / clear / cross-thread isolation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d898e0eb7f
commit
3a30c605b3
2 changed files with 109 additions and 0 deletions
|
|
@ -1339,6 +1339,21 @@ def invoke_hook(hook_name: str, **kwargs: Any) -> List[Any]:
|
|||
|
||||
|
||||
|
||||
_thread_tool_whitelist = threading.local()
|
||||
|
||||
|
||||
def set_thread_tool_whitelist(
|
||||
allowed: Optional[Set[str]],
|
||||
deny_msg_fmt: str = "Tool '{tool_name}' denied: not in this thread's tool whitelist",
|
||||
) -> None:
|
||||
_thread_tool_whitelist.allowed = allowed
|
||||
_thread_tool_whitelist.fmt = deny_msg_fmt
|
||||
|
||||
|
||||
def clear_thread_tool_whitelist() -> None:
|
||||
_thread_tool_whitelist.allowed = None
|
||||
|
||||
|
||||
def get_pre_tool_call_block_message(
|
||||
tool_name: str,
|
||||
args: Optional[Dict[str, Any]],
|
||||
|
|
@ -1357,6 +1372,11 @@ def get_pre_tool_call_block_message(
|
|||
directive wins. Invalid or irrelevant hook return values are
|
||||
silently ignored so existing observer-only hooks are unaffected.
|
||||
"""
|
||||
allowed = getattr(_thread_tool_whitelist, "allowed", None)
|
||||
if allowed is not None and tool_name not in allowed:
|
||||
fmt = getattr(_thread_tool_whitelist, "fmt", "Tool '{tool_name}' denied")
|
||||
return fmt.format(tool_name=tool_name)
|
||||
|
||||
hook_results = invoke_hook(
|
||||
"pre_tool_call",
|
||||
tool_name=tool_name,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue