a3s_code_core/agent_api/
governance_facade.rs1use super::*;
2
3impl AgentSession {
4 pub fn set_budget_guard(
14 &self,
15 guard: Option<Arc<dyn crate::budget::BudgetGuard>>,
16 ) -> crate::error::Result<()> {
17 self.close_handle.mutate_immediate(|| {
18 let mut slot = self
19 .runtime_budget_guard
20 .lock()
21 .unwrap_or_else(|p| p.into_inner());
22 *slot = guard;
23 drop(slot);
24 self.refresh_task_delegation_tools();
29 self.refresh_skill_tools();
30 })
31 }
32
33 pub fn budget_guard(&self) -> Option<Arc<dyn crate::budget::BudgetGuard>> {
36 self.runtime_budget_guard
37 .lock()
38 .unwrap_or_else(|p| p.into_inner())
39 .clone()
40 }
41
42 pub async fn pending_confirmations(&self) -> Vec<PendingConfirmationInfo> {
44 HitlControl::from_session(self)
45 .pending_confirmations()
46 .await
47 }
48
49 pub async fn confirm_tool_use(
54 &self,
55 tool_id: &str,
56 approved: bool,
57 reason: Option<String>,
58 ) -> Result<bool> {
59 HitlControl::from_session(self)
60 .confirm_tool_use(tool_id, approved, reason)
61 .await
62 }
63
64 pub async fn cancel_confirmations(&self) -> usize {
66 HitlControl::from_session(self).cancel_confirmations().await
67 }
68
69 pub fn verification_reports(&self) -> Vec<crate::verification::VerificationReport> {
71 VerificationRuntime::from_session(self).reports()
72 }
73
74 pub fn verification_summary(&self) -> crate::verification::VerificationSummary {
76 VerificationRuntime::from_session(self).summary()
77 }
78
79 pub fn verification_summary_text(&self) -> String {
81 VerificationRuntime::from_session(self).summary_text()
82 }
83
84 pub fn record_verification_reports(
86 &self,
87 reports: impl IntoIterator<Item = crate::verification::VerificationReport>,
88 ) {
89 VerificationRuntime::from_session(self).record(reports);
90 }
91
92 pub fn register_hook(&self, hook: crate::hooks::Hook) -> crate::error::Result<()> {
94 self.close_handle.mutate_immediate(|| {
95 self.ensure_compatibility_name_available(
96 crate::capability::CapabilityKind::Hook,
97 &hook.id,
98 )?;
99 HookControl::from_session(self).register_hook(hook);
100 Ok(())
101 })?
102 }
103
104 pub fn unregister_hook(
106 &self,
107 hook_id: &str,
108 ) -> crate::error::Result<Option<crate::hooks::Hook>> {
109 self.close_handle.mutate_immediate(|| {
110 self.ensure_compatibility_name_available(
111 crate::capability::CapabilityKind::Hook,
112 hook_id,
113 )?;
114 Ok(HookControl::from_session(self).unregister_hook(hook_id))
115 })?
116 }
117
118 pub fn register_hook_handler(
120 &self,
121 hook_id: &str,
122 handler: Arc<dyn crate::hooks::HookHandler>,
123 ) -> crate::error::Result<()> {
124 let mut pending_handler = Some(handler);
125 let retired = self.close_handle.mutate_immediate(|| {
126 self.ensure_compatibility_name_available(
127 crate::capability::CapabilityKind::Hook,
128 hook_id,
129 )?;
130 let handler = pending_handler.take().ok_or_else(|| {
131 crate::error::CodeError::Capability(
132 crate::capability::CapabilityRuntimeError::RuntimeValueInvalid {
133 kind: crate::capability::CapabilityKind::Hook,
134 public_name: hook_id.to_owned(),
135 message: "Hook handler mutation was already consumed".to_owned(),
136 },
137 )
138 })?;
139 Ok::<_, crate::error::CodeError>(
140 HookControl::from_session(self).register_hook_handler(hook_id, handler),
141 )
142 })??;
143 drop(retired);
144 Ok(())
145 }
146
147 pub fn unregister_hook_handler(&self, hook_id: &str) -> crate::error::Result<()> {
149 let retired = self.close_handle.mutate_immediate(|| {
150 self.ensure_compatibility_name_available(
151 crate::capability::CapabilityKind::Hook,
152 hook_id,
153 )?;
154 Ok::<_, crate::error::CodeError>(
155 HookControl::from_session(self).unregister_hook_handler(hook_id),
156 )
157 })??;
158 drop(retired);
159 Ok(())
160 }
161
162 pub fn register_hook_registration(
168 &self,
169 hook: crate::hooks::Hook,
170 handler: Option<Arc<dyn crate::hooks::HookHandler>>,
171 ) -> crate::error::Result<()> {
172 let mut pending_handler = Some(handler);
173 let retired = self.close_handle.mutate_immediate(|| {
174 self.ensure_compatibility_name_available(
175 crate::capability::CapabilityKind::Hook,
176 &hook.id,
177 )?;
178 let handler = pending_handler.take().ok_or_else(|| {
179 crate::error::CodeError::Capability(
180 crate::capability::CapabilityRuntimeError::RuntimeValueInvalid {
181 kind: crate::capability::CapabilityKind::Hook,
182 public_name: hook.id.clone(),
183 message: "Hook registration was already consumed".to_owned(),
184 },
185 )
186 })?;
187 Ok::<_, crate::error::CodeError>(
188 HookControl::from_session(self).register_hook_registration(hook, handler),
189 )
190 })??;
191 drop(retired);
192 Ok(())
193 }
194
195 pub fn unregister_hook_registration(
197 &self,
198 hook_id: &str,
199 ) -> crate::error::Result<Option<crate::hooks::Hook>> {
200 let (retired_hook, retired_handler) = self.close_handle.mutate_immediate(|| {
201 self.ensure_compatibility_name_available(
202 crate::capability::CapabilityKind::Hook,
203 hook_id,
204 )?;
205 Ok::<_, crate::error::CodeError>(
206 HookControl::from_session(self).unregister_hook_registration(hook_id),
207 )
208 })??;
209 let removed = retired_hook.as_deref().cloned();
210 drop((retired_hook, retired_handler));
211 Ok(removed)
212 }
213
214 pub fn hook_count(&self) -> usize {
216 HookControl::from_session(self).hook_count()
217 }
218
219 pub async fn verify_commands(
221 &self,
222 subject: &str,
223 commands: &[crate::verification::VerificationCommand],
224 ) -> Result<crate::verification::VerificationReport> {
225 VerificationRuntime::from_session(self)
226 .verify_commands(subject, commands)
227 .await
228 }
229
230 pub fn verification_presets(&self) -> Vec<crate::verification::VerificationPreset> {
232 VerificationRuntime::from_session(self).presets()
233 }
234}