Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
1. Anthropic Driver ToolResult 格式修复 — ContentBlock 添加 ToolResult 变体, tool_call_id 不再被丢弃, 按 Anthropic API 规范发送 tool_result 格式 2. 前端 callMcpTool 参数名对齐 — serviceName/toolName/args 改为 service_name/tool_name/arguments, 后端支持 service_name 精确路由 3. MCP 工具桥接到 ToolRegistry — McpToolAdapter 添加 service_name/clone, 新建 McpToolWrapper 实现 Tool trait, Kernel 添加 mcp_adapters 共享状态, McpManagerState 与 Kernel 共享同一 Arc<RwLock<Vec>>, MCP 服务启停时 自动同步工具列表到 LLM 可见的 ToolRegistry
49 lines
1.3 KiB
Rust
49 lines
1.3 KiB
Rust
//! MCP Tool Wrapper — bridges MCP server tools into the ToolRegistry
|
|
//!
|
|
//! Wraps `McpToolAdapter` (from zclaw-protocols) as a `Tool` trait object
|
|
//! so the LLM can discover and call MCP tools during conversations.
|
|
|
|
use async_trait::async_trait;
|
|
use serde_json::Value;
|
|
use std::sync::Arc;
|
|
use zclaw_types::Result;
|
|
|
|
use crate::tool::{Tool, ToolContext};
|
|
|
|
/// Wraps an MCP tool adapter into the `Tool` trait.
|
|
///
|
|
/// The wrapper holds an `Arc<McpToolAdapter>` and delegates execution
|
|
/// to the adapter, ignoring the `ToolContext` (MCP tools don't need
|
|
/// agent_id, workspace, etc.).
|
|
pub struct McpToolWrapper {
|
|
adapter: Arc<zclaw_protocols::McpToolAdapter>,
|
|
/// Cached qualified name (service.tool) for Tool::name()
|
|
qualified_name: String,
|
|
}
|
|
|
|
impl McpToolWrapper {
|
|
pub fn new(adapter: Arc<zclaw_protocols::McpToolAdapter>) -> Self {
|
|
let qualified_name = adapter.qualified_name();
|
|
Self { adapter, qualified_name }
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl Tool for McpToolWrapper {
|
|
fn name(&self) -> &str {
|
|
&self.qualified_name
|
|
}
|
|
|
|
fn description(&self) -> &str {
|
|
self.adapter.description()
|
|
}
|
|
|
|
fn input_schema(&self) -> Value {
|
|
self.adapter.input_schema().clone()
|
|
}
|
|
|
|
async fn execute(&self, input: Value, _context: &ToolContext) -> Result<Value> {
|
|
self.adapter.execute(input).await
|
|
}
|
|
}
|