feat: 子代理继承主代理的 MCP 工具
- 为 McpToolWrapper 添加 Clone trait,支持工具实例复用 - 修改 build_subagent_tools 方法,支持传入 MCP 工具列表 - 调整 runtime 构建顺序:先等待 MCP 连接,再将 MCP 工具传递给子代理 子代理现在可以自动使用主代理配置的 MCP 工具(如 filesystem、fetch 等)。
This commit is contained in:
parent
861aa04690
commit
644f5f9132
@ -124,10 +124,51 @@ pub(crate) fn build_session_manager_with_sender(
|
|||||||
factory
|
factory
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Wait for MCP connections and collect MCP tools for subagents
|
||||||
|
// This needs to happen before building subagent tools
|
||||||
|
let mut mcp_tools_for_subagents: Vec<crate::mcp::tool_adapter::McpToolWrapper> = Vec::new();
|
||||||
|
if mcp_initializer.is_enabled() {
|
||||||
|
tokio::task::block_in_place(|| {
|
||||||
|
tokio::runtime::Handle::current().block_on(async {
|
||||||
|
// Wait for connections to complete
|
||||||
|
if let Err(e) = mcp_initializer.wait_for_connections().await {
|
||||||
|
tracing::error!(error = %e, "Failed to wait for MCP connections");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect MCP tools for subagents
|
||||||
|
if let Some(manager) = mcp_initializer.manager() {
|
||||||
|
let all_tools = manager.all_tools().await;
|
||||||
|
for (server_key, tool_info) in all_tools {
|
||||||
|
let wrapper = crate::mcp::tool_adapter::McpToolWrapper::new(
|
||||||
|
manager.clone(),
|
||||||
|
server_key.clone(),
|
||||||
|
tool_info,
|
||||||
|
);
|
||||||
|
mcp_tools_for_subagents.push(wrapper);
|
||||||
|
}
|
||||||
|
tracing::info!(
|
||||||
|
tool_count = mcp_tools_for_subagents.len(),
|
||||||
|
"Collected MCP tools for subagents"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Create SubAgentRuntime (if task tool is enabled)
|
// Create SubAgentRuntime (if task tool is enabled)
|
||||||
let (factory, task_repository): (_, Arc<dyn TaskRepository>) = if task_config.enabled {
|
let (factory, task_repository): (_, Arc<dyn TaskRepository>) = if task_config.enabled {
|
||||||
let task_repository = Arc::new(InMemoryTaskRepository::new());
|
let task_repository = Arc::new(InMemoryTaskRepository::new());
|
||||||
let subagent_tools = Arc::new(factory.build_subagent_tools());
|
// Build subagent tools with MCP tools
|
||||||
|
let subagent_tools = Arc::new(
|
||||||
|
factory.build_subagent_tools(
|
||||||
|
if mcp_tools_for_subagents.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(mcp_tools_for_subagents.clone())
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Create subagent catalog with discovery
|
// Create subagent catalog with discovery
|
||||||
let catalog = Arc::new(SubagentCatalog::discover(&subagents_config));
|
let catalog = Arc::new(SubagentCatalog::discover(&subagents_config));
|
||||||
@ -157,14 +198,16 @@ pub(crate) fn build_session_manager_with_sender(
|
|||||||
// Build base tools
|
// Build base tools
|
||||||
let mut tools = factory.build();
|
let mut tools = factory.build();
|
||||||
|
|
||||||
// Register MCP tools (async)
|
// Register MCP tools to main agent (async)
|
||||||
// This waits briefly for connections, then registers available tools
|
// Note: MCP tools for subagents are already collected above
|
||||||
if mcp_initializer.is_enabled() {
|
if mcp_initializer.is_enabled() {
|
||||||
tokio::task::block_in_place(|| {
|
tokio::task::block_in_place(|| {
|
||||||
tokio::runtime::Handle::current().block_on(async {
|
tokio::runtime::Handle::current().block_on(async {
|
||||||
if let Err(e) = mcp_initializer.register_tools(&mut tools).await {
|
// Register pre-collected MCP tools
|
||||||
tracing::error!(error = %e, "Failed to register MCP tools");
|
for tool in mcp_tools_for_subagents {
|
||||||
|
tools.register(tool);
|
||||||
}
|
}
|
||||||
|
tracing::info!("Registered MCP tools to main agent");
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -142,7 +142,11 @@ impl ToolRegistryFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 构建子代理专用工具集(不包含 task 工具防止递归)
|
/// 构建子代理专用工具集(不包含 task 工具防止递归)
|
||||||
pub(crate) fn build_subagent_tools(&self) -> ToolRegistry {
|
/// 可选地包含 MCP 工具(通过 mcp_tools 参数传递)
|
||||||
|
pub(crate) fn build_subagent_tools(
|
||||||
|
&self,
|
||||||
|
mcp_tools: Option<Vec<crate::mcp::tool_adapter::McpToolWrapper>>,
|
||||||
|
) -> ToolRegistry {
|
||||||
let mut registry = ToolRegistry::new();
|
let mut registry = ToolRegistry::new();
|
||||||
|
|
||||||
// 基础工具
|
// 基础工具
|
||||||
@ -194,6 +198,13 @@ impl ToolRegistryFactory {
|
|||||||
registry.register(SessionSendTool::new(self.session_message_sender.clone()));
|
registry.register(SessionSendTool::new(self.session_message_sender.clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 注册 MCP 工具(如果提供)
|
||||||
|
if let Some(mcp_tools) = mcp_tools {
|
||||||
|
for tool in mcp_tools {
|
||||||
|
registry.register(tool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 注意:不注册 task 工具,防止递归创建子代理
|
// 注意:不注册 task 工具,防止递归创建子代理
|
||||||
|
|
||||||
registry
|
registry
|
||||||
|
|||||||
@ -9,6 +9,7 @@ use crate::mcp::client::McpClientManager;
|
|||||||
use crate::tools::traits::{Tool as PicoBotTool, ToolResult};
|
use crate::tools::traits::{Tool as PicoBotTool, ToolResult};
|
||||||
|
|
||||||
/// Wrapper that adapts an MCP tool to PicoBot's Tool trait
|
/// Wrapper that adapts an MCP tool to PicoBot's Tool trait
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct McpToolWrapper {
|
pub struct McpToolWrapper {
|
||||||
/// The MCP client manager
|
/// The MCP client manager
|
||||||
manager: Arc<McpClientManager>,
|
manager: Arc<McpClientManager>,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user