rightkit_agent_engine_protocol/
protocol.rs1use serde::{Deserialize, Serialize};
17
18#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
20#[serde(rename_all = "kebab-case")]
21pub enum AskForApproval {
22 #[serde(rename = "untrusted")]
24 UnlessTrusted,
25 #[default]
27 OnRequest,
28 Granular(GranularApprovalConfig),
30 Never,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
35pub struct GranularApprovalConfig {
36 pub sandbox_approval: bool,
37 pub rules: bool,
38 #[serde(default)]
39 pub skill_approval: bool,
40 #[serde(default)]
41 pub request_permissions: bool,
42 pub mcp_elicitations: bool,
43}
44
45impl GranularApprovalConfig {
46 pub const fn allows_sandbox_approval(self) -> bool {
47 self.sandbox_approval
48 }
49 pub const fn allows_rules_approval(self) -> bool {
50 self.rules
51 }
52 pub const fn allows_skill_approval(self) -> bool {
53 self.skill_approval
54 }
55 pub const fn allows_request_permissions(self) -> bool {
56 self.request_permissions
57 }
58 pub const fn allows_mcp_elicitations(self) -> bool {
59 self.mcp_elicitations
60 }
61}
62
63#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
64#[serde(rename_all = "kebab-case")]
65pub enum NetworkAccess {
66 #[default]
67 Restricted,
68 Enabled,
69}
70
71impl NetworkAccess {
72 pub const fn is_enabled(self) -> bool {
73 matches!(self, Self::Enabled)
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
86 fn ask_for_approval_keeps_codex_wire_tags() {
87 assert_eq!(
88 serde_json::to_value(AskForApproval::UnlessTrusted).unwrap(),
89 serde_json::json!("untrusted")
90 );
91 assert_eq!(
92 serde_json::to_value(AskForApproval::OnRequest).unwrap(),
93 serde_json::json!("on-request")
94 );
95 assert_eq!(
96 serde_json::to_value(AskForApproval::Never).unwrap(),
97 serde_json::json!("never")
98 );
99 assert_eq!(
100 serde_json::from_value::<AskForApproval>(serde_json::json!("untrusted")).unwrap(),
101 AskForApproval::UnlessTrusted
102 );
103 }
104
105 #[test]
106 fn ask_for_approval_defaults_to_on_request() {
107 assert_eq!(AskForApproval::default(), AskForApproval::OnRequest);
108 }
109
110 #[test]
111 fn granular_approval_config_round_trips() {
112 let config = GranularApprovalConfig {
113 sandbox_approval: true,
114 rules: false,
115 skill_approval: true,
116 request_permissions: false,
117 mcp_elicitations: true,
118 };
119 let ask = AskForApproval::Granular(config);
120 let value = serde_json::to_value(ask).unwrap();
121 let back: AskForApproval = serde_json::from_value(value).unwrap();
122 assert_eq!(back, ask);
123 assert!(config.allows_sandbox_approval());
124 assert!(!config.allows_rules_approval());
125 assert!(config.allows_skill_approval());
126 assert!(!config.allows_request_permissions());
127 assert!(config.allows_mcp_elicitations());
128 }
129
130 #[test]
131 fn network_access_keeps_kebab_case_wire_tags() {
132 assert_eq!(
133 serde_json::to_value(NetworkAccess::Restricted).unwrap(),
134 serde_json::json!("restricted")
135 );
136 assert_eq!(
137 serde_json::to_value(NetworkAccess::Enabled).unwrap(),
138 serde_json::json!("enabled")
139 );
140 assert!(!NetworkAccess::Restricted.is_enabled());
141 assert!(NetworkAccess::Enabled.is_enabled());
142 assert_eq!(NetworkAccess::default(), NetworkAccess::Restricted);
143 }
144}