use async_trait::async_trait;
use serde_json::Value;
use crate::error::{ToolError, codes};
use crate::metadata::ToolMetadata;
use crate::tool::DynTool;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum ApprovalDecision {
Allow,
Deny,
}
#[async_trait]
pub trait ApprovalGate: Send + Sync {
async fn approve(
&self,
tool: &dyn DynTool,
metadata: &ToolMetadata,
arguments: &Value,
) -> Result<ApprovalDecision, ToolError>;
}
#[derive(Debug, Default, Clone, Copy)]
pub struct AutoApprove;
#[async_trait]
impl ApprovalGate for AutoApprove {
async fn approve(
&self,
_tool: &dyn DynTool,
_metadata: &ToolMetadata,
_arguments: &Value,
) -> Result<ApprovalDecision, ToolError> {
Ok(ApprovalDecision::Allow)
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct AlwaysDeny;
#[async_trait]
impl ApprovalGate for AlwaysDeny {
async fn approve(
&self,
tool: &dyn DynTool,
_metadata: &ToolMetadata,
_arguments: &Value,
) -> Result<ApprovalDecision, ToolError> {
Err(codes::approval_denied(format!(
"approval denied for tool {}",
tool.name()
)))
}
}
#[must_use]
pub fn denied_error(tool_name: &str) -> ToolError {
codes::approval_denied(format!("approval denied for tool {tool_name}"))
}