feat(approvals): add profile-local per-tool policies

This commit is contained in:
Teknium 2026-07-12 20:50:20 -07:00
parent e589b739ca
commit 5bff2c28ee
No known key found for this signature in database
13 changed files with 1307 additions and 39 deletions

View file

@ -1906,6 +1906,8 @@ def init_agent(
# would still leak lcm_* tools into the tool surface and incur the
# same local-model latency penalty.
agent._context_engine_tool_names: set = set()
if not hasattr(agent, "_dynamic_tool_entries"):
agent._dynamic_tool_entries = {}
if (
hasattr(agent, "context_compressor")
and agent.context_compressor
@ -1940,6 +1942,10 @@ def init_agent(
agent.tools.append(_wrapped)
agent.valid_tool_names.add(_tname)
agent._context_engine_tool_names.add(_tname)
from tools.registry import DynamicToolEntry as _DynamicToolEntry
agent._dynamic_tool_entries[_tname] = _DynamicToolEntry(
_tname, "context_engine"
)
_existing_tool_names.add(_tname)
# Notify context engine of session start

View file

@ -2304,6 +2304,15 @@ def invoke_tool(agent, function_name: str, function_args: dict, effective_task_i
),
)
return _finish_agent_tool(result, next_args)
elif (
getattr(agent, "_context_engine_tool_names", None)
and function_name in agent._context_engine_tool_names
):
def _execute(next_args: dict) -> Any:
return _finish_agent_tool(
agent.context_compressor.handle_tool_call(function_name, next_args),
next_args,
)
elif agent._memory_manager and agent._memory_manager.has_tool(function_name):
def _execute(next_args: dict) -> Any:
return _finish_agent_tool(agent._memory_manager.handle_tool_call(function_name, next_args), next_args)
@ -2333,6 +2342,8 @@ def invoke_tool(agent, function_name: str, function_args: dict, effective_task_i
def _execute(next_args: dict) -> Any:
return _finish_agent_tool(agent._dispatch_delegate_task(next_args), next_args)
else:
from model_tools import registry
def _execute(next_args: dict) -> Any:
return _ra().handle_function_call(
function_name, next_args, effective_task_id,
@ -2346,9 +2357,15 @@ def invoke_tool(agent, function_name: str, function_args: dict, effective_task_i
enabled_toolsets=getattr(agent, "enabled_toolsets", None),
disabled_toolsets=getattr(agent, "disabled_toolsets", None),
tool_request_middleware_trace=list(_tool_middleware_trace),
dispatch_registry=registry,
)
from hermes_cli.middleware import run_tool_execution_middleware
from model_tools import registry
registry_entry = registry.get_entry(function_name)
if registry_entry is None:
registry_entry = getattr(agent, "_dynamic_tool_entries", {}).get(function_name)
return run_tool_execution_middleware(
function_name,
@ -2360,6 +2377,8 @@ def invoke_tool(agent, function_name: str, function_args: dict, effective_task_i
tool_call_id=tool_call_id or "",
turn_id=getattr(agent, "_current_turn_id", "") or "",
api_request_id=getattr(agent, "_current_api_request_id", "") or "",
registry_entry=registry_entry,
dispatch_registry=registry if registry_entry is registry.get_entry(function_name) else None,
)

View file

@ -35,7 +35,7 @@ from typing import Any, Callable, Dict, List, Optional
from agent.memory_provider import MemoryProvider
from agent.skill_commands import extract_user_instruction_from_skill_message
from tools.registry import tool_error
from tools.registry import DynamicToolEntry, tool_error
logger = logging.getLogger(__name__)
@ -123,6 +123,10 @@ def inject_memory_provider_tools(agent: Any) -> int:
if valid_tool_names is None:
valid_tool_names = set()
agent.valid_tool_names = valid_tool_names
dynamic_entries = getattr(agent, "_dynamic_tool_entries", None)
if dynamic_entries is None:
dynamic_entries = {}
agent._dynamic_tool_entries = dynamic_entries
added = 0
for raw_schema in get_schemas():
@ -139,6 +143,7 @@ def inject_memory_provider_tools(agent: Any) -> int:
continue
tools.append({"type": "function", "function": schema})
valid_tool_names.add(tool_name)
dynamic_entries[tool_name] = DynamicToolEntry(tool_name, "memory")
existing_tool_names.add(tool_name)
added += 1

View file

@ -307,6 +307,11 @@ def _run_agent_tool_execution_middleware(
return execute(observed_args)
from hermes_cli.middleware import run_tool_execution_middleware
from model_tools import registry
registry_entry = registry.get_entry(function_name)
if registry_entry is None:
registry_entry = getattr(agent, "_dynamic_tool_entries", {}).get(function_name)
result = run_tool_execution_middleware(
function_name,
@ -318,6 +323,7 @@ def _run_agent_tool_execution_middleware(
tool_call_id=tool_call_id or "",
turn_id=getattr(agent, "_current_turn_id", "") or "",
api_request_id=getattr(agent, "_current_api_request_id", "") or "",
registry_entry=registry_entry,
)
return result, observed_args