diff --git a/src/gateway/agent_factory.rs b/src/gateway/agent_factory.rs index 3a4fb2c..cabd8ef 100644 --- a/src/gateway/agent_factory.rs +++ b/src/gateway/agent_factory.rs @@ -80,6 +80,7 @@ impl AgentFactory { message_seq: None, subagent_description: None, nesting_depth: 0, + task_id: None, parent_task_id: None, }); // 如果有取消信号接收端,注入 Agent diff --git a/src/gateway/runtime.rs b/src/gateway/runtime.rs index 5be8404..a7ca2be 100644 --- a/src/gateway/runtime.rs +++ b/src/gateway/runtime.rs @@ -209,9 +209,9 @@ pub(crate) fn build_session_manager_with_sender( // 注册 task 工具到子代理工具集(需在 runtime 创建之后,打破循环依赖) if factory.is_enabled("task") { - subagent_tools.register(TaskTool::new_with_depth( + subagent_tools.register(TaskTool::new( subagent_runtime.clone(), - task_config.max_nesting_depth, + Some(task_config.max_nesting_depth), )); } diff --git a/src/gateway/tool_registry_factory.rs b/src/gateway/tool_registry_factory.rs index 182dc8e..cffaccc 100644 --- a/src/gateway/tool_registry_factory.rs +++ b/src/gateway/tool_registry_factory.rs @@ -164,7 +164,7 @@ impl ToolRegistryFactory { // 注册 Task 工具(如果启用且有 subagent_runtime) if self.is_enabled("task") && self.task_config.enabled { if let Some(runtime) = &self.subagent_runtime { - registry.register(TaskTool::new(runtime.clone())); + registry.register(TaskTool::new(runtime.clone(), None)); } } diff --git a/src/tools/task/runtime.rs b/src/tools/task/runtime.rs index bdf1dda..f1085b6 100644 --- a/src/tools/task/runtime.rs +++ b/src/tools/task/runtime.rs @@ -262,14 +262,6 @@ impl SystemPromptProvider for StaticSystemPromptProvider { } } -/// 从 session_id 中提取 task_id 部分 -/// session_id 格式: "sub:{...}:task:{uuid}",提取 "task:{uuid}" 部分 -fn extract_task_id_from_session_id(session_id: &str) -> Option { - session_id - .rfind(":task:") - .map(|pos| session_id[pos + 1..].to_string()) -} - /// 默认子代理运行时实现 pub struct DefaultSubAgentRuntime { config: SubAgentRuntimeConfig, @@ -335,6 +327,7 @@ impl DefaultSubAgentRuntime { session: &TaskSession, system_prompt: String, parent_nesting_depth: u32, + parent_task_id: Option, ) -> Result { let prompt_provider = Arc::new(StaticSystemPromptProvider::new(system_prompt)); @@ -345,15 +338,6 @@ impl DefaultSubAgentRuntime { None, // 子代理不需要 skill provider ) .map(|agent| { - // 确定 parent_task_id: - // - 主 agent (depth=0) 创建子 agent → parent_task_id = None - // - 子 agent (depth>0) 创建孙 agent → parent_task_id = 父 agent 自身的 task_id - let parent_task_id = if parent_nesting_depth > 0 { - extract_task_id_from_session_id(&session.parent_session_id) - } else { - None - }; - let agent = agent.with_tool_context(ToolContext { channel_name: Some(session.parent_channel_name.clone()), sender_id: None, @@ -364,6 +348,7 @@ impl DefaultSubAgentRuntime { message_seq: None, subagent_description: Some(session.description.clone()), nesting_depth: parent_nesting_depth + 1, + task_id: Some(session.id.clone()), parent_task_id, }); @@ -553,14 +538,8 @@ impl SubAgentRuntime for DefaultSubAgentRuntime { metadata.insert("topic_id".to_string(), session.parent_topic_id.clone().unwrap_or_default()); // 如果是子智能体创建的孙智能体,传递父 task_id - if parent_context.nesting_depth > 0 { - if let Some(ref ptid) = parent_context.parent_task_id { - metadata.insert("parent_task_id".to_string(), ptid.clone()); - } else if let Some(ptid) = extract_task_id_from_session_id( - parent_context.session_id.as_deref().unwrap_or(""), - ) { - metadata.insert("parent_task_id".to_string(), ptid); - } + if let Some(ref ptid) = parent_context.task_id { + metadata.insert("parent_task_id".to_string(), ptid.clone()); } let event = OutboundMessage { @@ -595,7 +574,7 @@ impl SubAgentRuntime for DefaultSubAgentRuntime { ); // 7. 创建子代理 - let agent = self.create_subagent(&session, system_prompt, parent_context.nesting_depth)?; + let agent = self.create_subagent(&session, system_prompt, parent_context.nesting_depth, parent_context.task_id.clone())?; // 8. 执行任务 let result = self @@ -676,7 +655,7 @@ impl SubAgentRuntime for DefaultSubAgentRuntime { ); // 5. 创建子代理 - let agent = self.create_subagent(&session, system_prompt, parent_context.nesting_depth)?; + let agent = self.create_subagent(&session, system_prompt, parent_context.nesting_depth, parent_context.task_id.clone())?; // 6. 使用历史继续执行 let result = self diff --git a/src/tools/task/tool.rs b/src/tools/task/tool.rs index 3b9be66..07385c0 100644 --- a/src/tools/task/tool.rs +++ b/src/tools/task/tool.rs @@ -10,20 +10,15 @@ use super::types::{TaskDefinition, TaskToolArgs}; /// Task 工具 - 创建和管理子代理 pub struct TaskTool { runtime: Arc, - /// 最大嵌套深度(0 = 无限制用于主 agent,>0 = 限制子代理最大嵌套层级) - max_nesting_depth: u32, + /// 最大嵌套深度(None = 无限制用于主 agent,Some(N) = 允许最多 N 层嵌套) + max_nesting_depth: Option, } impl TaskTool { - pub fn new(runtime: Arc) -> Self { - Self { - runtime, - max_nesting_depth: 0, // 主 agent 无深度限制 - } - } - - /// 创建带嵌套深度限制的 TaskTool(用于子代理) - pub fn new_with_depth(runtime: Arc, max_nesting_depth: u32) -> Self { + /// 创建 TaskTool + /// - `max_nesting_depth = None`:无深度限制(主 agent) + /// - `max_nesting_depth = Some(N)`:允许最多 N 层嵌套(子 agent) + pub fn new(runtime: Arc, max_nesting_depth: Option) -> Self { Self { runtime, max_nesting_depth, @@ -139,16 +134,19 @@ impl Tool for TaskTool { }); } - // 4. 深度校验(仅对嵌套场景生效,主 agent 的 max_nesting_depth = 0 不限制) - if self.max_nesting_depth > 0 && context.nesting_depth >= self.max_nesting_depth { - return Ok(ToolResult { - success: false, - output: String::new(), - error: Some(format!( - "Cannot create nested subagent: max nesting depth ({}) reached", - self.max_nesting_depth - )), - }); + // 4. 深度校验(仅对嵌套场景生效,None = 不限制) + // Some(N) 表示允许最多 N 层嵌套:depth=1 的 agent 可创建 depth=2,但 depth=2 不能再创建 + if let Some(max_depth) = self.max_nesting_depth { + if context.nesting_depth > max_depth { + return Ok(ToolResult { + success: false, + output: String::new(), + error: Some(format!( + "Cannot create nested subagent: max nesting depth ({}) reached", + max_depth + )), + }); + } } // 5. 执行任务 diff --git a/src/tools/todo_read.rs b/src/tools/todo_read.rs index d0e8d8d..1219568 100644 --- a/src/tools/todo_read.rs +++ b/src/tools/todo_read.rs @@ -183,6 +183,7 @@ mod tests { message_seq: Some(1), subagent_description: None, nesting_depth: 0, + task_id: None, parent_task_id: None, } } diff --git a/src/tools/todo_write.rs b/src/tools/todo_write.rs index 17c4616..af04bdb 100644 --- a/src/tools/todo_write.rs +++ b/src/tools/todo_write.rs @@ -409,6 +409,7 @@ mod tests { message_seq: Some(1), subagent_description: None, nesting_depth: 0, + task_id: None, parent_task_id: None, } } diff --git a/src/tools/traits.rs b/src/tools/traits.rs index 52d6f2b..3483050 100644 --- a/src/tools/traits.rs +++ b/src/tools/traits.rs @@ -20,6 +20,8 @@ pub struct ToolContext { pub subagent_description: Option, /// 当前嵌套深度(0 = 主 agent,1 = 子 agent,2 = 孙 agent...) pub nesting_depth: u32, + /// 当前智能体自身的任务 ID(主 agent 为 None,子/孙 agent 为 Some(uuid)) + pub task_id: Option, /// 父任务 ID(仅子/孙智能体有值,用于构建任务层级) pub parent_task_id: Option, }