Skip to main content

oxios_kernel/kernel_handle/
infra_api.rs

1//! Infra API — Git, cron, resources, events, system.
2
3use 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
13/// Infrastructure system calls.
14pub 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    /// Hot-reloadable orchestrator config (evolution iterations, score threshold).
22    pub(crate) orchestrator_config: parking_lot::RwLock<crate::config::OrchestratorConfig>,
23    /// Pending tool approval requests (HitL escalation).
24    pub(crate) pending_tool_approvals: Arc<PendingToolApprovals>,
25    /// Pending `ask_user` requests (RFC-027 agent-driven clarification).
26    pub(crate) pending_ask_user: Arc<PendingAskUser>,
27}
28
29impl InfraApi {
30    /// Create a new InfraApi.
31    // Facade construction gathers the independent infrastructure services.
32    #[allow(clippy::too_many_arguments)]
33    pub fn new(
34        git_layer: Arc<GitLayer>,
35        cron_scheduler: Arc<CronScheduler>,
36        resource_monitor: Arc<ResourceMonitor>,
37        event_bus: EventBus,
38        config: OxiosConfig,
39        start_time: Instant,
40        pending_tool_approvals: Arc<PendingToolApprovals>,
41        pending_ask_user: Arc<PendingAskUser>,
42    ) -> Self {
43        Self {
44            git_layer,
45            cron_scheduler,
46            resource_monitor,
47            event_bus,
48            config,
49            start_time,
50            orchestrator_config: parking_lot::RwLock::new(
51                crate::config::OrchestratorConfig::default(),
52            ),
53            pending_tool_approvals,
54            pending_ask_user,
55        }
56    }
57    /// Get a reference to the GitLayer.
58    pub fn git(&self) -> &GitLayer {
59        &self.git_layer
60    }
61
62    /// Get commit log.
63    pub fn git_log(&self, max: usize) -> anyhow::Result<Vec<LogEntry>> {
64        self.git_layer.log(max)
65    }
66
67    /// Tag current state.
68    pub fn git_tag(&self, name: &str, message: &str) -> anyhow::Result<()> {
69        self.git_layer.tag(name, message)
70    }
71
72    /// Restore file from commit.
73    pub fn git_restore(&self, path: &str, hash: &str) -> anyhow::Result<()> {
74        self.git_layer.restore_file(path, hash)
75    }
76
77    /// Verify git repository integrity.
78    pub fn git_verify(&self) -> anyhow::Result<bool> {
79        self.git_layer.verify()
80    }
81
82    /// List git tags.
83    pub fn git_tags(&self) -> anyhow::Result<Vec<String>> {
84        self.git_layer.list_tags()
85    }
86
87    /// Delete a tag by name.
88    pub fn git_delete_tag(&self, name: &str) -> anyhow::Result<()> {
89        self.git_layer.delete_tag(name)
90    }
91
92    /// Add a cron job.
93    pub async fn add_cron(&self, job: CronJob) -> anyhow::Result<uuid::Uuid> {
94        self.cron_scheduler.add_job(job).await
95    }
96
97    /// Get a cron job by ID.
98    pub fn get_cron(&self, id: uuid::Uuid) -> Option<CronJob> {
99        self.cron_scheduler.get_job(id)
100    }
101
102    /// Update a cron job.
103    pub async fn update_cron(&self, id: uuid::Uuid, update: CronJobUpdate) -> anyhow::Result<()> {
104        self.cron_scheduler.update_job(id, update).await
105    }
106
107    /// Remove a cron job by ID.
108    pub async fn remove_cron(&self, id: uuid::Uuid) -> anyhow::Result<()> {
109        self.cron_scheduler.remove_job(id).await
110    }
111
112    /// Trigger a cron job manually.
113    pub fn trigger_cron(&self, id: uuid::Uuid) -> anyhow::Result<CronJob> {
114        self.cron_scheduler.trigger_job(id)
115    }
116
117    /// Mark cron job completed.
118    pub async fn complete_cron(&self, id: uuid::Uuid, success: bool, summary: String) {
119        self.cron_scheduler
120            .mark_job_completed(id, success, summary)
121            .await
122    }
123
124    /// List all cron jobs.
125    pub fn list_crons(&self) -> Vec<CronJob> {
126        self.cron_scheduler.list_jobs()
127    }
128
129    /// Get resource snapshot.
130    pub fn resource_snapshot(&self) -> ResourceSnapshot {
131        self.resource_monitor.snapshot()
132    }
133
134    /// Get resource history snapshots.
135    pub fn resource_history(&self, last_n: usize) -> Vec<ResourceSnapshot> {
136        self.resource_monitor.history(last_n)
137    }
138
139    /// Check if system is overloaded.
140    pub fn is_overloaded(&self) -> bool {
141        self.resource_monitor.is_overloaded()
142    }
143
144    /// Subscribe to kernel events.
145    pub fn subscribe(&self) -> tokio::sync::broadcast::Receiver<KernelEvent> {
146        self.event_bus.subscribe()
147    }
148
149    /// Publish a kernel event.
150    pub fn publish(&self, event: KernelEvent) -> anyhow::Result<()> {
151        self.event_bus
152            .publish(event)
153            .map_err(|e| anyhow::anyhow!("broadcast error: {e}"))
154    }
155
156    /// Get config reference.
157    pub fn config(&self) -> &OxiosConfig {
158        &self.config
159    }
160
161    /// Resource monitor reference — for hot-reload config propagation.
162    pub fn resource_monitor(&self) -> &Arc<ResourceMonitor> {
163        &self.resource_monitor
164    }
165
166    /// Hot-reload orchestrator config (stored in InfraApi for propagation).
167    pub fn update_orchestrator_config(&self, config: crate::config::OrchestratorConfig) {
168        *self.orchestrator_config.write() = config;
169    }
170
171    /// Get system uptime.
172    pub fn uptime(&self) -> Duration {
173        self.start_time.elapsed()
174    }
175
176    /// Access the pending tool approvals registry.
177    pub fn pending_tool_approvals(&self) -> Arc<PendingToolApprovals> {
178        self.pending_tool_approvals.clone()
179    }
180
181    /// Access the pending `ask_user` registry (RFC-027 agent-driven clarification).
182    pub fn pending_ask_user(&self) -> Arc<PendingAskUser> {
183        Arc::clone(&self.pending_ask_user)
184    }
185
186    /// Clone the underlying event bus so tools can publish `KernelEvent`s
187    /// without routing through the wrapping `publish` helper.
188    pub fn event_bus_clone(&self) -> EventBus {
189        self.event_bus.clone()
190    }
191
192    /// List all known tool metadata (static catalog).
193    pub fn list_available_tools(&self) -> &'static [ToolMeta] {
194        known_tools()
195    }
196}