Просмотр исходного кода

框架:为工具注册增加安全能力标签

新增 read、write、agent_spawn、external_send、task_control 等 ToolCapability。ToolRegistry 支持在注册和装饰器中声明能力,并提供统一查询接口,为角色权限的 fail-closed 判定建立基础。
SamLee 4 дней назад
Родитель
Сommit
30a5f9579e

+ 2 - 1
agent/agent/__init__.py

@@ -25,7 +25,7 @@ from agent.skill.models import Skill
 
 # 工具系统
 from agent.tools import tool, ToolRegistry, get_tool_registry
-from agent.tools.models import ToolResult, ToolContext
+from agent.tools.models import ToolCapability, ToolResult, ToolContext
 
 # 显式任务执行与独立验证
 from agent.orchestration import (
@@ -75,6 +75,7 @@ __all__ = [
     "tool",
     "ToolRegistry",
     "get_tool_registry",
+    "ToolCapability",
     "ToolResult",
     "ToolContext",
     # Orchestration

+ 2 - 1
agent/agent/tools/__init__.py

@@ -4,7 +4,7 @@ Tools 包 - 工具注册和 Schema 生成
 
 from agent.tools.registry import ToolRegistry, tool, get_tool_registry
 from agent.tools.schema import SchemaGenerator
-from agent.tools.models import ToolResult, ToolContext, ToolContextImpl
+from agent.tools.models import ToolCapability, ToolResult, ToolContext, ToolContextImpl
 
 # 导入 builtin 工具以触发 @tool 装饰器注册
 # noqa: F401 表示这是故意的副作用导入
@@ -15,6 +15,7 @@ __all__ = [
 	"tool",
 	"get_tool_registry",
 	"SchemaGenerator",
+	"ToolCapability",
 	"ToolResult",
 	"ToolContext",
 	"ToolContextImpl",

+ 16 - 0
agent/agent/tools/models.py

@@ -7,9 +7,25 @@ Tool Models - 工具系统核心数据模型
 """
 
 from dataclasses import dataclass, field
+from enum import Enum
 from typing import Any, Dict, List, Optional, Protocol
 
 
+class ToolCapability(str, Enum):
+	"""Security-relevant effects declared by every explicit-mode tool."""
+
+	READ = "read"
+	WRITE = "write"
+	AGENT_SPAWN = "agent_spawn"
+	EXTERNAL_SEND = "external_send"
+	TASK_CONTROL = "task_control"
+	ATTEMPT_SUBMIT = "attempt_submit"
+	VALIDATION_SUBMIT = "validation_submit"
+
+	def __str__(self) -> str:
+		return self.value
+
+
 @dataclass
 class ToolResult:
 	"""

+ 16 - 1
agent/agent/tools/registry.py

@@ -14,7 +14,9 @@ import json
 import inspect
 import logging
 import time
-from typing import Any, Callable, Dict, List, Optional
+from typing import Any, Callable, Dict, List, Optional, Sequence
+
+from agent.tools.models import ToolCapability
 
 from agent.tools.url_matcher import filter_by_url
 
@@ -70,6 +72,7 @@ class ToolRegistry:
 		hidden_params: Optional[List[str]] = None,
 		inject_params: Optional[Dict[str, Any]] = None,
 		groups: Optional[List[str]] = None,
+		capabilities: Optional[Sequence[ToolCapability | str]] = None,
 	):
 		"""
 		注册工具
@@ -84,6 +87,7 @@ class ToolRegistry:
 			hidden_params: 隐藏参数列表(不生成 schema,LLM 看不到)
 			inject_params: 注入参数规则 {param_name: injector_func}
 			groups: 工具分组标签(如 ["core"]、["browser"]),用于 RunConfig.tool_groups 过滤
+			capabilities: 安全副作用标签;explicit_validation 工具必须显式声明
 		"""
 		func_name = func.__name__
 
@@ -103,6 +107,7 @@ class ToolRegistry:
 			"hidden_params": hidden_params or [],
 			"inject_params": inject_params or {},
 			"groups": groups or [],
+			"capabilities": frozenset(ToolCapability(item) for item in capabilities or []),
 			"ui_metadata": {
 				"requires_confirmation": requires_confirmation,
 				"editable_params": editable_params or [],
@@ -208,6 +213,13 @@ class ToolRegistry:
 			groups.update(tool.get("groups", []))
 		return sorted(groups)
 
+	def get_capabilities(self, tool_name: str) -> frozenset[ToolCapability]:
+		"""Return declared effects; an empty set means unclassified."""
+		tool = self._tools.get(tool_name)
+		if not tool:
+			return frozenset()
+		return frozenset(tool.get("capabilities", ()))
+
 	def get_schemas_for_url(self, current_url: Optional[str] = None) -> List[Dict]:
 		"""
 		根据当前 URL 获取匹配的工具 Schema
@@ -516,6 +528,7 @@ def tool(
 	hidden_params: Optional[List[str]] = None,
 	inject_params: Optional[Dict[str, Any]] = None,
 	groups: Optional[List[str]] = None,
+	capabilities: Optional[Sequence[ToolCapability | str]] = None,
 ):
 	"""
 	工具装饰器 - 自动注册工具并生成 Schema
@@ -530,6 +543,7 @@ def tool(
 		hidden_params: 隐藏参数列表(不生成 schema,LLM 看不到)
 		inject_params: 注入参数规则 {param_name: injector_func}
 		groups: 工具分组标签(如 ["core"]、["browser"]),用于 RunConfig.tool_groups 过滤
+		capabilities: 安全副作用标签(read/write/agent_spawn/external_send 等)
 
 	Example:
 		@tool(
@@ -565,6 +579,7 @@ def tool(
 			hidden_params=hidden_params,
 			inject_params=inject_params,
 			groups=groups,
+			capabilities=capabilities,
 		)
 		return func