pub mod messages; pub mod tools; use serde::{Deserialize, Serialize}; /// 角色能力策略:工具、技能、子代理的白/黑名单。全为空表示沿用默认(不过滤)。 /// /// 生效顺序:先白名单取交集,再黑名单扣除。专家与子代理共用此结构, /// 确保语义一致。MCP 工具注册在 `ToolRegistry` 中(名 `mcp_*`),与内置 /// 工具同源,因此 `allowed_tools`/`denied_tools` 覆盖内置 + MCP 工具; /// `allowed_skills`/`denied_skills` 仅覆盖 SKILL.md 技能; /// `allowed_subagents`/`denied_subagents` 覆盖子代理加载(通过 ToolContext /// 传递给 TaskTool,在 spawn/resume 时强制校验)。 #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct CapabilityPolicy { /// 技能白名单:`None` = 不限;`Some(vec)` = 仅这些 SKILL.md 技能可见。 /// `Some(vec![])` 表示全禁(与 `ToolRegistry::only` 的空交集语义对齐)。 #[serde(default, skip_serializing_if = "Option::is_none")] pub allowed_skills: Option>, /// 技能黑名单:禁用这些 SKILL.md 技能。空表示不禁。 #[serde(default, skip_serializing_if = "Vec::is_empty")] pub denied_skills: Vec, /// 工具白名单(含 `mcp_*` 工具):`None` = 不限。 #[serde(default, skip_serializing_if = "Option::is_none")] pub allowed_tools: Option>, /// 工具黑名单(含 `mcp_*` 工具)。 #[serde(default, skip_serializing_if = "Vec::is_empty")] pub denied_tools: Vec, /// 子代理白名单:`None` = 不限;`Some(vec)` = 仅这些子代理可被加载。 /// 通过 ToolContext 传递给 TaskTool,在 spawn/resume 时强制校验。 #[serde(default, skip_serializing_if = "Option::is_none")] pub allowed_subagents: Option>, /// 子代理黑名单:禁止加载这些子代理。空表示不禁。 #[serde(default, skip_serializing_if = "Vec::is_empty")] pub denied_subagents: Vec, } impl CapabilityPolicy { /// 所有策略字段均为空 → 沿用主智能体默认配置(不过滤)。 pub fn is_empty(&self) -> bool { self.allowed_skills.is_none() && self.denied_skills.is_empty() && self.allowed_tools.is_none() && self.denied_tools.is_empty() && self.allowed_subagents.is_none() && self.denied_subagents.is_empty() } /// 是否声明了任何技能策略。 pub fn has_skill_policy(&self) -> bool { self.allowed_skills.is_some() || !self.denied_skills.is_empty() } /// 是否声明了任何工具策略。 pub fn has_tool_policy(&self) -> bool { self.allowed_tools.is_some() || !self.denied_tools.is_empty() } /// 是否声明了任何子代理策略。 pub fn has_subagent_policy(&self) -> bool { self.allowed_subagents.is_some() || !self.denied_subagents.is_empty() } /// 校验指定子代理是否被允许。返回 Err 时附带拒绝原因。 pub fn check_subagent_allowed(&self, name: &str) -> Result<(), String> { if let Some(list) = &self.allowed_subagents { if !list.iter().any(|s| s == name) { return Err(format!( "subagent '{}' is not in the allowed_subagents whitelist", name )); } } if self.denied_subagents.iter().any(|s| s == name) { return Err(format!( "subagent '{}' is in the denied_subagents blacklist", name )); } Ok(()) } }