Files
2026-08-21 16:00:13 +08:00

88 lines
4.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""安全 / 工具策略 API schema(api-spec §15 / §16)。
`tool_policies` 表同时服务两组 API:
- `/tools`(§15):返回 `ToolPolicyResponse`(完整元数据 + executable 派生位)。
- `/safety/policies`(§16):返回 `SafetyPolicyItem`(策略子集)。
"""
from pydantic import BaseModel, ConfigDict, Field
class ToolPolicyResponse(BaseModel):
"""工具策略完整元数据(GET /tools 元素、POST/PATCH /tools 响应)。"""
model_config = ConfigDict(from_attributes=True)
name: str = Field(description="工具名(主键)。")
description: str = Field(default="", description="工具描述。")
risk_level: str = Field(description="风险等级 L0–L4。")
permission_policy: str = Field(description="权限策略 allow/ask/always_ask/forbidden。")
side_effect: bool = Field(description="是否有副作用。")
audit_required: bool = Field(description="是否强制记审计。")
source: str = Field(description="来源:builtin / custom。")
enabled: bool = Field(description="是否启用(禁用的工具不进入司命策略)。")
executable: bool = Field(
default=False,
description="是否具备执行实现(builtin 或已注册 ToolSpec);纯治理声明为 false。",
)
created_at: str = Field(description="创建时间,UTC ISO 8601。")
updated_at: str = Field(description="更新时间,UTC ISO 8601。")
class SafetyPolicyItem(BaseModel):
"""策略子集(GET /safety/policies 元素)。"""
model_config = ConfigDict(from_attributes=True)
tool: str = Field(description="工具名。")
risk_level: str = Field(description="风险等级 L0–L4。")
permission_policy: str = Field(description="权限策略。")
side_effect: bool = Field(description="是否有副作用。")
audit_required: bool = Field(description="是否强制记审计。")
class CreateToolPolicyRequest(BaseModel):
"""注册工具 / 新增策略请求(POST /tools、POST /safety/policies 共用)。"""
name: str = Field(description="工具名(唯一)。")
description: str = Field(default="", description="工具描述。")
risk_level: str = Field(default="L2", description="风险等级 L0–L4。")
permission_policy: str = Field(default="ask", description="权限策略。")
side_effect: bool = Field(default=True, description="是否有副作用。")
audit_required: bool = Field(default=True, description="是否强制记审计。")
enabled: bool = Field(default=True, description="是否启用。")
class UpdateToolPolicyRequest(BaseModel):
"""编辑工具 / 策略请求(PATCH /tools/{name}、PATCH /safety/policies/{tool} 共用)。
所有字段可选;spec §15 要求 risk_level、§16 要求 permission_policy / risk_level,
此处统一放开为完整元数据编辑(至少传一个)。
"""
description: str | None = None
risk_level: str | None = None
permission_policy: str | None = None
side_effect: bool | None = None
audit_required: bool | None = None
enabled: bool | None = None
class ToolCallDetail(BaseModel):
"""单次工具调用事件详情(GET /tools/calls/{tool_call_id})。
`tool_call_id` 对应一炁事件存储中 tool.* 事件的主键;一次调用会产生 started /
completed / failed 多个事件,每个均可单独查询。
"""
model_config = ConfigDict(from_attributes=True)
event_id: str = Field(description="事件 ID(即路径 tool_call_id)。")
type: str = Field(description="事件类型:tool.started / tool.completed / tool.failed 等。")
tool: str | None = Field(default=None, description="工具名(payload 解出)。")
run_id: str | None = Field(default=None)
character_id: str | None = Field(default=None)
trace_id: str | None = Field(default=None)
payload: dict = Field(default_factory=dict, description="事件原始负载。")
created_at: str = Field(description="事件时间,UTC ISO 8601。")