agent_base/engine/
approval.rs1use async_trait::async_trait;
2
3use crate::types::{AgentResult, ApprovalDecision, ApprovalRequest};
4
5#[async_trait]
31pub trait ApprovalHandler: Send + Sync {
32 async fn approve(
33 &self,
34 request: ApprovalRequest,
35 cancel_token: tokio_util::sync::CancellationToken,
36 ) -> AgentResult<ApprovalDecision>;
37}
38
39#[derive(Clone, Debug, Default)]
40pub struct DenyAllApprovalHandler;
41
42#[async_trait]
43impl ApprovalHandler for DenyAllApprovalHandler {
44 async fn approve(
45 &self,
46 _request: ApprovalRequest,
47 _cancel_token: tokio_util::sync::CancellationToken,
48 ) -> AgentResult<ApprovalDecision> {
49 Ok(ApprovalDecision::Deny)
50 }
51}
52
53#[derive(Clone, Debug, Default)]
54pub struct AllowAllApprovalHandler;
55
56#[async_trait]
57impl ApprovalHandler for AllowAllApprovalHandler {
58 async fn approve(
59 &self,
60 _request: ApprovalRequest,
61 _cancel_token: tokio_util::sync::CancellationToken,
62 ) -> AgentResult<ApprovalDecision> {
63 Ok(ApprovalDecision::AllowAlways)
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70 use crate::types::RiskLevel;
71 use tokio_util::sync::CancellationToken;
72
73 fn request() -> ApprovalRequest {
74 ApprovalRequest {
75 title: "Delete file".to_string(),
76 message: "Really delete?".to_string(),
77 action_key: Some("delete".to_string()),
78 risk_level: RiskLevel::Destructive,
79 raw: None,
80 source: None,
81 }
82 }
83
84 #[tokio::test]
85 async fn deny_all_returns_deny() {
86 let decision = DenyAllApprovalHandler
87 .approve(request(), CancellationToken::new())
88 .await
89 .unwrap();
90 assert_eq!(decision, ApprovalDecision::Deny);
91 }
92
93 #[tokio::test]
94 async fn allow_all_returns_allow_always() {
95 let decision = AllowAllApprovalHandler
96 .approve(request(), CancellationToken::new())
97 .await
98 .unwrap();
99 assert_eq!(decision, ApprovalDecision::AllowAlways);
100 }
101}