feat(phase5): implement mode consolidation and tool availability system
Implements Phase 5 from the roadmap with complete mode-based tool filtering: - Add Mode enum (Chat/Code) with FromStr trait implementation - Extend Config with ModeConfig for per-mode tool availability - Update ToolRegistry to enforce mode-based filtering - Add --code/-c CLI argument to start in code mode - Implement TUI commands: :mode, :code, :chat, :tools - Add operating mode indicator to status line (💬/💻 badges) - Create comprehensive documentation in docs/phase5-mode-system.md Default configuration: - Chat mode: only web_search allowed - Code mode: all tools allowed (wildcard *) All code compiles cleanly with cargo clippy passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use crate::mode::Mode;
|
||||
use crate::tools::registry::ToolRegistry;
|
||||
use crate::validation::SchemaValidator;
|
||||
use crate::Result;
|
||||
@@ -46,6 +47,7 @@ pub struct McpToolResponse {
|
||||
pub struct McpServer {
|
||||
registry: Arc<ToolRegistry>,
|
||||
validator: Arc<SchemaValidator>,
|
||||
mode: Arc<tokio::sync::RwLock<Mode>>,
|
||||
}
|
||||
|
||||
impl McpServer {
|
||||
@@ -53,14 +55,29 @@ impl McpServer {
|
||||
Self {
|
||||
registry,
|
||||
validator,
|
||||
mode: Arc::new(tokio::sync::RwLock::new(Mode::default())),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the current operating mode
|
||||
pub async fn set_mode(&self, mode: Mode) {
|
||||
*self.mode.write().await = mode;
|
||||
}
|
||||
|
||||
/// Get the current operating mode
|
||||
pub async fn get_mode(&self) -> Mode {
|
||||
*self.mode.read().await
|
||||
}
|
||||
|
||||
/// Enumerate the registered tools as MCP descriptors
|
||||
pub fn list_tools(&self) -> Vec<McpToolDescriptor> {
|
||||
pub async fn list_tools(&self) -> Vec<McpToolDescriptor> {
|
||||
let mode = self.get_mode().await;
|
||||
let available_tools = self.registry.available_tools(mode).await;
|
||||
|
||||
self.registry
|
||||
.all()
|
||||
.into_iter()
|
||||
.filter(|tool| available_tools.contains(&tool.name().to_string()))
|
||||
.map(|tool| McpToolDescriptor {
|
||||
name: tool.name().to_string(),
|
||||
description: tool.description().to_string(),
|
||||
@@ -74,7 +91,11 @@ impl McpServer {
|
||||
/// Execute a tool call after validating inputs against the registered schema
|
||||
pub async fn call_tool(&self, call: McpToolCall) -> Result<McpToolResponse> {
|
||||
self.validator.validate(&call.name, &call.arguments)?;
|
||||
let result = self.registry.execute(&call.name, call.arguments).await?;
|
||||
let mode = self.get_mode().await;
|
||||
let result = self
|
||||
.registry
|
||||
.execute(&call.name, call.arguments, mode)
|
||||
.await?;
|
||||
Ok(McpToolResponse {
|
||||
name: call.name,
|
||||
success: result.success,
|
||||
@@ -99,12 +120,22 @@ impl LocalMcpClient {
|
||||
server: McpServer::new(registry, validator),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the current operating mode
|
||||
pub async fn set_mode(&self, mode: Mode) {
|
||||
self.server.set_mode(mode).await;
|
||||
}
|
||||
|
||||
/// Get the current operating mode
|
||||
pub async fn get_mode(&self) -> Mode {
|
||||
self.server.get_mode().await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl McpClient for LocalMcpClient {
|
||||
async fn list_tools(&self) -> Result<Vec<McpToolDescriptor>> {
|
||||
Ok(self.server.list_tools())
|
||||
Ok(self.server.list_tools().await)
|
||||
}
|
||||
|
||||
async fn call_tool(&self, call: McpToolCall) -> Result<McpToolResponse> {
|
||||
|
||||
Reference in New Issue
Block a user