refactor(task): 优化任务工具和子代理深度管理
- 在 AgentContext 中新增 task_id 字段,用于标识当前智能体任务 ID - 统一 TaskTool 构造函数,使用 Option<u32> 表示最大嵌套深度限制 - 调整子代理工具注册,适配新的 TaskTool 构造函数 - 修改子代理运行时创建逻辑,传递并设置 task_id 和 parent_task_id - 删除重复的 task_id 提取函数,改用传递参数进行关联 - 深度校验改为判断 Option,支持无深度限制和有限层数 - 增强子代理间的任务层级关联,正确传递 parent_task_id 元数据
This commit is contained in:
parent
e506ffd539
commit
2607ca4aa4
@ -80,6 +80,7 @@ impl AgentFactory {
|
|||||||
message_seq: None,
|
message_seq: None,
|
||||||
subagent_description: None,
|
subagent_description: None,
|
||||||
nesting_depth: 0,
|
nesting_depth: 0,
|
||||||
|
task_id: None,
|
||||||
parent_task_id: None,
|
parent_task_id: None,
|
||||||
});
|
});
|
||||||
// 如果有取消信号接收端,注入 Agent
|
// 如果有取消信号接收端,注入 Agent
|
||||||
|
|||||||
@ -209,9 +209,9 @@ pub(crate) fn build_session_manager_with_sender(
|
|||||||
|
|
||||||
// 注册 task 工具到子代理工具集(需在 runtime 创建之后,打破循环依赖)
|
// 注册 task 工具到子代理工具集(需在 runtime 创建之后,打破循环依赖)
|
||||||
if factory.is_enabled("task") {
|
if factory.is_enabled("task") {
|
||||||
subagent_tools.register(TaskTool::new_with_depth(
|
subagent_tools.register(TaskTool::new(
|
||||||
subagent_runtime.clone(),
|
subagent_runtime.clone(),
|
||||||
task_config.max_nesting_depth,
|
Some(task_config.max_nesting_depth),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -164,7 +164,7 @@ impl ToolRegistryFactory {
|
|||||||
// 注册 Task 工具(如果启用且有 subagent_runtime)
|
// 注册 Task 工具(如果启用且有 subagent_runtime)
|
||||||
if self.is_enabled("task") && self.task_config.enabled {
|
if self.is_enabled("task") && self.task_config.enabled {
|
||||||
if let Some(runtime) = &self.subagent_runtime {
|
if let Some(runtime) = &self.subagent_runtime {
|
||||||
registry.register(TaskTool::new(runtime.clone()));
|
registry.register(TaskTool::new(runtime.clone(), None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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<String> {
|
|
||||||
session_id
|
|
||||||
.rfind(":task:")
|
|
||||||
.map(|pos| session_id[pos + 1..].to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 默认子代理运行时实现
|
/// 默认子代理运行时实现
|
||||||
pub struct DefaultSubAgentRuntime {
|
pub struct DefaultSubAgentRuntime {
|
||||||
config: SubAgentRuntimeConfig,
|
config: SubAgentRuntimeConfig,
|
||||||
@ -335,6 +327,7 @@ impl DefaultSubAgentRuntime {
|
|||||||
session: &TaskSession,
|
session: &TaskSession,
|
||||||
system_prompt: String,
|
system_prompt: String,
|
||||||
parent_nesting_depth: u32,
|
parent_nesting_depth: u32,
|
||||||
|
parent_task_id: Option<String>,
|
||||||
) -> Result<AgentLoop, TaskError> {
|
) -> Result<AgentLoop, TaskError> {
|
||||||
let prompt_provider = Arc::new(StaticSystemPromptProvider::new(system_prompt));
|
let prompt_provider = Arc::new(StaticSystemPromptProvider::new(system_prompt));
|
||||||
|
|
||||||
@ -345,15 +338,6 @@ impl DefaultSubAgentRuntime {
|
|||||||
None, // 子代理不需要 skill provider
|
None, // 子代理不需要 skill provider
|
||||||
)
|
)
|
||||||
.map(|agent| {
|
.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 {
|
let agent = agent.with_tool_context(ToolContext {
|
||||||
channel_name: Some(session.parent_channel_name.clone()),
|
channel_name: Some(session.parent_channel_name.clone()),
|
||||||
sender_id: None,
|
sender_id: None,
|
||||||
@ -364,6 +348,7 @@ impl DefaultSubAgentRuntime {
|
|||||||
message_seq: None,
|
message_seq: None,
|
||||||
subagent_description: Some(session.description.clone()),
|
subagent_description: Some(session.description.clone()),
|
||||||
nesting_depth: parent_nesting_depth + 1,
|
nesting_depth: parent_nesting_depth + 1,
|
||||||
|
task_id: Some(session.id.clone()),
|
||||||
parent_task_id,
|
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());
|
metadata.insert("topic_id".to_string(), session.parent_topic_id.clone().unwrap_or_default());
|
||||||
|
|
||||||
// 如果是子智能体创建的孙智能体,传递父 task_id
|
// 如果是子智能体创建的孙智能体,传递父 task_id
|
||||||
if parent_context.nesting_depth > 0 {
|
if let Some(ref ptid) = parent_context.task_id {
|
||||||
if let Some(ref ptid) = parent_context.parent_task_id {
|
|
||||||
metadata.insert("parent_task_id".to_string(), ptid.clone());
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let event = OutboundMessage {
|
let event = OutboundMessage {
|
||||||
@ -595,7 +574,7 @@ impl SubAgentRuntime for DefaultSubAgentRuntime {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 7. 创建子代理
|
// 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. 执行任务
|
// 8. 执行任务
|
||||||
let result = self
|
let result = self
|
||||||
@ -676,7 +655,7 @@ impl SubAgentRuntime for DefaultSubAgentRuntime {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 5. 创建子代理
|
// 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. 使用历史继续执行
|
// 6. 使用历史继续执行
|
||||||
let result = self
|
let result = self
|
||||||
|
|||||||
@ -10,20 +10,15 @@ use super::types::{TaskDefinition, TaskToolArgs};
|
|||||||
/// Task 工具 - 创建和管理子代理
|
/// Task 工具 - 创建和管理子代理
|
||||||
pub struct TaskTool {
|
pub struct TaskTool {
|
||||||
runtime: Arc<dyn SubAgentRuntime>,
|
runtime: Arc<dyn SubAgentRuntime>,
|
||||||
/// 最大嵌套深度(0 = 无限制用于主 agent,>0 = 限制子代理最大嵌套层级)
|
/// 最大嵌套深度(None = 无限制用于主 agent,Some(N) = 允许最多 N 层嵌套)
|
||||||
max_nesting_depth: u32,
|
max_nesting_depth: Option<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TaskTool {
|
impl TaskTool {
|
||||||
pub fn new(runtime: Arc<dyn SubAgentRuntime>) -> Self {
|
/// 创建 TaskTool
|
||||||
Self {
|
/// - `max_nesting_depth = None`:无深度限制(主 agent)
|
||||||
runtime,
|
/// - `max_nesting_depth = Some(N)`:允许最多 N 层嵌套(子 agent)
|
||||||
max_nesting_depth: 0, // 主 agent 无深度限制
|
pub fn new(runtime: Arc<dyn SubAgentRuntime>, max_nesting_depth: Option<u32>) -> Self {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 创建带嵌套深度限制的 TaskTool(用于子代理)
|
|
||||||
pub fn new_with_depth(runtime: Arc<dyn SubAgentRuntime>, max_nesting_depth: u32) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
runtime,
|
runtime,
|
||||||
max_nesting_depth,
|
max_nesting_depth,
|
||||||
@ -139,17 +134,20 @@ impl Tool for TaskTool {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 深度校验(仅对嵌套场景生效,主 agent 的 max_nesting_depth = 0 不限制)
|
// 4. 深度校验(仅对嵌套场景生效,None = 不限制)
|
||||||
if self.max_nesting_depth > 0 && context.nesting_depth >= self.max_nesting_depth {
|
// 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 {
|
return Ok(ToolResult {
|
||||||
success: false,
|
success: false,
|
||||||
output: String::new(),
|
output: String::new(),
|
||||||
error: Some(format!(
|
error: Some(format!(
|
||||||
"Cannot create nested subagent: max nesting depth ({}) reached",
|
"Cannot create nested subagent: max nesting depth ({}) reached",
|
||||||
self.max_nesting_depth
|
max_depth
|
||||||
)),
|
)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 5. 执行任务
|
// 5. 执行任务
|
||||||
let result = if let Some(task_id) = task_args.task_id {
|
let result = if let Some(task_id) = task_args.task_id {
|
||||||
|
|||||||
@ -183,6 +183,7 @@ mod tests {
|
|||||||
message_seq: Some(1),
|
message_seq: Some(1),
|
||||||
subagent_description: None,
|
subagent_description: None,
|
||||||
nesting_depth: 0,
|
nesting_depth: 0,
|
||||||
|
task_id: None,
|
||||||
parent_task_id: None,
|
parent_task_id: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -409,6 +409,7 @@ mod tests {
|
|||||||
message_seq: Some(1),
|
message_seq: Some(1),
|
||||||
subagent_description: None,
|
subagent_description: None,
|
||||||
nesting_depth: 0,
|
nesting_depth: 0,
|
||||||
|
task_id: None,
|
||||||
parent_task_id: None,
|
parent_task_id: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,8 @@ pub struct ToolContext {
|
|||||||
pub subagent_description: Option<String>,
|
pub subagent_description: Option<String>,
|
||||||
/// 当前嵌套深度(0 = 主 agent,1 = 子 agent,2 = 孙 agent...)
|
/// 当前嵌套深度(0 = 主 agent,1 = 子 agent,2 = 孙 agent...)
|
||||||
pub nesting_depth: u32,
|
pub nesting_depth: u32,
|
||||||
|
/// 当前智能体自身的任务 ID(主 agent 为 None,子/孙 agent 为 Some(uuid))
|
||||||
|
pub task_id: Option<String>,
|
||||||
/// 父任务 ID(仅子/孙智能体有值,用于构建任务层级)
|
/// 父任务 ID(仅子/孙智能体有值,用于构建任务层级)
|
||||||
pub parent_task_id: Option<String>,
|
pub parent_task_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user