use anyhow::Result;
use serde_json::Value;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
use crate::config::types::CapabilityLevel;
use crate::llm::provider::ToolDefinition;
use crate::llm::providers::gemini::wire::FunctionDeclaration;
use crate::tool_policy::ToolPolicy;
use crate::tools::handlers::{SessionSurface, SessionToolsConfig, ToolCallError, ToolSchemaEntry};
use super::{ToolExecutionRecord, ToolPermissionDecision, ToolRegistration};
#[async_trait::async_trait]
pub trait ToolSecurity: Send + Sync {
async fn evaluate_tool_policy(&self, tool_name: &str) -> Result<ToolPermissionDecision>;
async fn get_tool_policy(&self, tool_name: &str) -> ToolPolicy;
async fn set_tool_policy(&self, tool_name: &str, policy: ToolPolicy) -> Result<()>;
async fn mark_tool_preapproved(&self, tool_name: &str);
async fn enable_full_auto_permission(&self, allowed_tools: &[String]);
async fn disable_full_auto_permission(&self);
async fn is_allowed_in_full_auto(&self, tool_name: &str) -> bool;
async fn apply_config_policies(&self, tools_config: &crate::config::ToolsConfig) -> Result<()>;
fn sandbox_config(&self) -> vtcode_config::SandboxConfig;
fn apply_sandbox_config(&self, config: &vtcode_config::SandboxConfig);
async fn persist_approval_cache_key(&self, key: &str) -> Result<()>;
async fn has_persisted_approval(&self, key: &str) -> bool;
}
#[async_trait::async_trait]
pub trait PtySessionControl: Send + Sync {
fn can_start_session(&self) -> bool;
fn active_session_count(&self) -> usize;
async fn terminate_all_sessions(&self) -> Result<()>;
fn exec_session_manager(&self) -> crate::tools::exec_session::ExecSessionManager;
}
#[async_trait::async_trait]
pub trait McpBridge: Send + Sync {
async fn set_mcp_client(&self, client: Arc<crate::mcp::McpClient>);
async fn clear_mcp_client(&self);
fn mcp_client(&self) -> Option<Arc<crate::mcp::McpClient>>;
async fn list_mcp_tools(&self) -> Result<Vec<crate::mcp::McpToolInfo>>;
async fn has_mcp_tool(&self, tool_name: &str) -> bool;
async fn execute_mcp_tool(&self, tool_name: &str, args: Value) -> Result<Value>;
async fn refresh_mcp_tools(&self) -> Result<()>;
}
pub trait ToolResilience: Send + Sync {
fn effective_timeout(&self, category: super::ToolTimeoutCategory) -> Option<Duration>;
fn record_failure(&self, category: super::ToolTimeoutCategory) -> bool;
fn reset_failure(&self, category: super::ToolTimeoutCategory);
fn record_latency(&self, category: super::ToolTimeoutCategory, duration: Duration);
fn should_circuit_break(&self, category: super::ToolTimeoutCategory) -> Option<Duration>;
fn decay_adaptive_timeout(&self, category: super::ToolTimeoutCategory);
}
#[async_trait::async_trait]
pub trait ToolCatalog: Send + Sync {
async fn register_tool(&self, registration: ToolRegistration) -> Result<()>;
async fn unregister_tool(&self, name: &str) -> Result<bool>;
fn get_tool(&self, name: &str) -> Option<Arc<dyn crate::tools::traits::Tool>>;
fn workspace_root(&self) -> PathBuf;
async fn public_tool_names(&self, surface: SessionSurface, capability_level: CapabilityLevel) -> Vec<String>;
async fn schema_entries(&self, config: SessionToolsConfig) -> Vec<ToolSchemaEntry>;
async fn function_declarations(&self, config: SessionToolsConfig) -> Vec<FunctionDeclaration>;
async fn model_tools(&self, config: SessionToolsConfig) -> Vec<ToolDefinition>;
fn resolve_tool_name(&self, name: &str) -> Result<String, ToolCallError>;
}
pub trait ToolMetrics: Send + Sync {
fn record_execution(&self, record: ToolExecutionRecord);
fn call_count(&self) -> u64;
fn pty_poll_count(&self) -> u64;
fn metrics_collector(&self) -> Arc<crate::metrics::MetricsCollector>;
}
pub trait ToolRegistryApi:
ToolSecurity + PtySessionControl + McpBridge + ToolResilience + ToolCatalog + ToolMetrics + Send + Sync + 'static
{
}
impl<T> ToolRegistryApi for T where
T: ToolSecurity
+ PtySessionControl
+ McpBridge
+ ToolResilience
+ ToolCatalog
+ ToolMetrics
+ Send
+ Sync
+ 'static
{
}
pub type SharedRegistry = Arc<dyn ToolRegistryApi>;