oxios_kernel/kernel_handle/
infra_api.rs1use crate::ToolMeta;
4use crate::config::OxiosConfig;
5use crate::cron::{CronJob, CronJobUpdate, CronScheduler};
6use crate::event_bus::{EventBus, KernelEvent};
7use crate::git_layer::{GitLayer, LogEntry};
8use crate::resource_monitor::{ResourceMonitor, ResourceSnapshot};
9use crate::tools::{PendingAskUser, PendingToolApprovals, known_tools};
10use std::sync::Arc;
11use std::time::{Duration, Instant};
12
13pub struct InfraApi {
15 pub(crate) git_layer: Arc<GitLayer>,
16 pub(crate) cron_scheduler: Arc<CronScheduler>,
17 pub(crate) resource_monitor: Arc<ResourceMonitor>,
18 pub(crate) event_bus: EventBus,
19 pub(crate) config: OxiosConfig,
20 pub(crate) start_time: Instant,
21 pub(crate) orchestrator_config: parking_lot::RwLock<crate::config::OrchestratorConfig>,
23 pub(crate) approval_config: Arc<parking_lot::RwLock<crate::approval::ApprovalConfig>>,
24 pub(crate) pending_tool_approvals: Arc<PendingToolApprovals>,
26 pub(crate) pending_ask_user: Arc<PendingAskUser>,
28}
29
30impl InfraApi {
31 #[allow(clippy::too_many_arguments)]
34 pub fn new(
35 git_layer: Arc<GitLayer>,
36 cron_scheduler: Arc<CronScheduler>,
37 resource_monitor: Arc<ResourceMonitor>,
38 event_bus: EventBus,
39 config: OxiosConfig,
40 start_time: Instant,
41 pending_tool_approvals: Arc<PendingToolApprovals>,
42 pending_ask_user: Arc<PendingAskUser>,
43 ) -> Self {
44 let approval_config = config.security.approval.clone();
45 Self {
46 git_layer,
47 cron_scheduler,
48 resource_monitor,
49 event_bus,
50 config,
51 start_time,
52 orchestrator_config: parking_lot::RwLock::new(
53 crate::config::OrchestratorConfig::default(),
54 ),
55 approval_config: Arc::new(parking_lot::RwLock::new(approval_config)),
56 pending_tool_approvals,
57 pending_ask_user,
58 }
59 }
60 pub fn git(&self) -> &GitLayer {
62 &self.git_layer
63 }
64
65 pub fn approval_config_handle(
66 &self,
67 ) -> Arc<parking_lot::RwLock<crate::approval::ApprovalConfig>> {
68 Arc::clone(&self.approval_config)
69 }
70 pub fn approval_config(&self) -> crate::approval::ApprovalConfig {
71 self.approval_config.read().clone()
72 }
73
74 pub async fn set_approval_config(
75 &self,
76 config: crate::approval::ApprovalConfig,
77 ) -> anyhow::Result<crate::approval::ApprovalConfig> {
78 *self.approval_config.write() = config.clone();
79 Ok(config)
80 }
81
82 pub async fn add_grant(&self, key: String) -> anyhow::Result<crate::approval::ApprovalConfig> {
83 let mut config = self.approval_config();
84 if !config.allow_list.contains(&key) {
85 config.allow_list.push(key);
86 }
87 self.set_approval_config(config.clone()).await
88 }
89
90 pub async fn remove_grant(&self, key: &str) -> anyhow::Result<crate::approval::ApprovalConfig> {
91 let mut config = self.approval_config();
92 config.allow_list.retain(|item| item != key);
93 self.set_approval_config(config.clone()).await
94 }
95
96 pub fn git_log(&self, max: usize) -> anyhow::Result<Vec<LogEntry>> {
98 self.git_layer.log(max)
99 }
100
101 pub fn git_tag(&self, name: &str, message: &str) -> anyhow::Result<()> {
103 self.git_layer.tag(name, message)
104 }
105
106 pub fn git_restore(&self, path: &str, hash: &str) -> anyhow::Result<()> {
108 self.git_layer.restore_file(path, hash)
109 }
110
111 pub fn git_verify(&self) -> anyhow::Result<bool> {
113 self.git_layer.verify()
114 }
115
116 pub fn git_tags(&self) -> anyhow::Result<Vec<String>> {
118 self.git_layer.list_tags()
119 }
120
121 pub fn git_delete_tag(&self, name: &str) -> anyhow::Result<()> {
123 self.git_layer.delete_tag(name)
124 }
125
126 pub async fn add_cron(&self, job: CronJob) -> anyhow::Result<uuid::Uuid> {
128 self.cron_scheduler.add_job(job).await
129 }
130
131 pub fn get_cron(&self, id: uuid::Uuid) -> Option<CronJob> {
133 self.cron_scheduler.get_job(id)
134 }
135
136 pub async fn update_cron(&self, id: uuid::Uuid, update: CronJobUpdate) -> anyhow::Result<()> {
138 self.cron_scheduler.update_job(id, update).await
139 }
140
141 pub async fn remove_cron(&self, id: uuid::Uuid) -> anyhow::Result<()> {
143 self.cron_scheduler.remove_job(id).await
144 }
145
146 pub fn trigger_cron(&self, id: uuid::Uuid) -> anyhow::Result<CronJob> {
148 self.cron_scheduler.trigger_job(id)
149 }
150
151 pub async fn complete_cron(&self, id: uuid::Uuid, success: bool, summary: String) {
153 self.cron_scheduler
154 .mark_job_completed(id, success, summary)
155 .await
156 }
157
158 pub fn list_crons(&self) -> Vec<CronJob> {
160 self.cron_scheduler.list_jobs()
161 }
162
163 pub fn resource_snapshot(&self) -> ResourceSnapshot {
165 self.resource_monitor.snapshot()
166 }
167
168 pub fn resource_history(&self, last_n: usize) -> Vec<ResourceSnapshot> {
170 self.resource_monitor.history(last_n)
171 }
172
173 pub fn is_overloaded(&self) -> bool {
175 self.resource_monitor.is_overloaded()
176 }
177
178 pub fn subscribe(&self) -> tokio::sync::broadcast::Receiver<KernelEvent> {
180 self.event_bus.subscribe()
181 }
182
183 pub fn publish(&self, event: KernelEvent) -> anyhow::Result<()> {
185 self.event_bus
186 .publish(event)
187 .map_err(|e| anyhow::anyhow!("broadcast error: {e}"))
188 }
189
190 pub fn config(&self) -> &OxiosConfig {
192 &self.config
193 }
194
195 pub fn resource_monitor(&self) -> &Arc<ResourceMonitor> {
197 &self.resource_monitor
198 }
199
200 pub fn update_orchestrator_config(&self, config: crate::config::OrchestratorConfig) {
202 *self.orchestrator_config.write() = config;
203 }
204
205 pub fn uptime(&self) -> Duration {
207 self.start_time.elapsed()
208 }
209
210 pub fn pending_tool_approvals(&self) -> Arc<PendingToolApprovals> {
212 self.pending_tool_approvals.clone()
213 }
214
215 pub fn pending_ask_user(&self) -> Arc<PendingAskUser> {
217 Arc::clone(&self.pending_ask_user)
218 }
219
220 pub fn event_bus_clone(&self) -> EventBus {
223 self.event_bus.clone()
224 }
225
226 pub fn list_available_tools(&self) -> &'static [ToolMeta] {
228 known_tools()
229 }
230}