oxios_kernel/kernel_handle/
mod.rs1pub mod a2a_api;
4pub mod agent_api;
5pub mod browser_api;
6pub mod exec_api;
7pub mod extension_api;
8pub mod infra_api;
9pub mod mcp_api;
10pub mod persona_api;
11pub mod security_api;
12pub mod space_api;
13pub mod state_api;
14
15pub use a2a_api::A2aApi;
16pub use agent_api::AgentApi;
17pub use browser_api::BrowserApi;
18pub use exec_api::ExecApi;
19pub use extension_api::ExtensionApi;
20pub use infra_api::InfraApi;
21pub use mcp_api::McpApi;
22pub use persona_api::PersonaApi;
23pub use security_api::SecurityApi;
24pub use space_api::SpaceApi;
25pub use state_api::StateApi;
26
27
28use crate::a2a::A2AProtocol;
29use crate::access_manager::AccessManager;
30use crate::audit_trail::AuditTrail;
31use crate::auth::AuthManager;
32use crate::budget::BudgetManager;
33use crate::config::OxiosConfig;
34use crate::cron::CronScheduler;
35use crate::event_bus::EventBus;
36use crate::git_layer::CommitInfo;
37use crate::git_layer::GitLayer;
38use crate::host_tools::HostToolValidator;
39use crate::mcp::McpBridge;
40use crate::memory::MemoryManager;
41use crate::persona_manager::PersonaManager;
42use crate::program::ProgramManager;
43use crate::resource_monitor::ResourceMonitor;
44use crate::scheduler::AgentScheduler;
45use crate::skill::SkillStore;
46use crate::space::SpaceManager;
47use crate::state_store::StateStore;
48use crate::supervisor::Supervisor;
49use serde::Serialize;
50use std::sync::Arc;
51use std::time::Instant;
52
53pub struct KernelHandle {
67 pub state: StateApi,
69 pub agents: AgentApi,
71 pub security: SecurityApi,
73 pub persona: PersonaApi,
75 pub extensions: ExtensionApi,
77 pub mcp: McpApi,
79 pub infra: InfraApi,
81 pub spaces: SpaceApi,
83 pub exec: ExecApi,
85 pub browser: BrowserApi,
87 pub a2a: A2aApi,
89}
90
91impl KernelHandle {
92 #[allow(clippy::too_many_arguments)]
97 pub fn new(
98 state: StateApi,
99 agents: AgentApi,
100 security: SecurityApi,
101 persona: PersonaApi,
102 extensions: ExtensionApi,
103 mcp: McpApi,
104 infra: InfraApi,
105 spaces: SpaceApi,
106 exec: ExecApi,
107 browser: BrowserApi,
108 a2a: A2aApi,
109 ) -> Self {
110 Self {
111 state,
112 agents,
113 security,
114 persona,
115 extensions,
116 mcp,
117 infra,
118 spaces,
119 exec,
120 browser,
121 a2a,
122 }
123 }
124
125 #[deprecated(note = "Use KernelHandle::new() with pre-built Facades instead")]
129 #[allow(clippy::too_many_arguments)]
130 pub fn from_subsystems(
131 state_store: Arc<StateStore>,
132 event_bus: EventBus,
133 supervisor: Arc<dyn Supervisor>,
134 scheduler: Arc<AgentScheduler>,
135 memory_manager: Arc<MemoryManager>,
136 git_layer: Arc<GitLayer>,
137 audit_trail: Arc<AuditTrail>,
138 budget_manager: Arc<BudgetManager>,
139 resource_monitor: Arc<ResourceMonitor>,
140 cron_scheduler: Arc<CronScheduler>,
141 program_manager: Arc<ProgramManager>,
142 skill_store: Arc<SkillStore>,
143 persona_manager: Arc<PersonaManager>,
144 mcp_bridge: Arc<McpBridge>,
145 auth_manager: Arc<parking_lot::Mutex<AuthManager>>,
146 access_manager: Arc<parking_lot::Mutex<AccessManager>>,
147 host_tool_validator: Arc<HostToolValidator>,
148 config: OxiosConfig,
149 start_time: Instant,
150 space_manager: Arc<SpaceManager>,
151 ) -> Self {
152 Self {
153 security: SecurityApi::new(
154 auth_manager.clone(),
155 audit_trail,
156 access_manager.clone(),
157 state_store.clone(),
158 ),
159 state: StateApi::new(state_store),
160 agents: AgentApi::new(supervisor, budget_manager, memory_manager, Some(event_bus.clone())),
161 persona: PersonaApi::new(persona_manager),
162 extensions: ExtensionApi::new(program_manager, skill_store, host_tool_validator),
163 mcp: McpApi::new(mcp_bridge),
164 infra: InfraApi::new(
165 git_layer,
166 scheduler,
167 cron_scheduler,
168 resource_monitor,
169 event_bus.clone(),
170 config.clone(),
171 start_time,
172 ),
173 spaces: SpaceApi::new(space_manager, event_bus),
174 exec: ExecApi::new(Arc::new(config.exec.clone()), access_manager),
175 browser: BrowserApi::default(),
176 a2a: A2aApi::new(Arc::new(A2AProtocol::new(crate::EventBus::new(0)))),
177 }
178 }
179
180 pub async fn save_and_commit<T: Serialize>(
186 &self,
187 category: &str,
188 name: &str,
189 data: &T,
190 ) -> anyhow::Result<()> {
191 self.state.save(category, name, data).await?;
192 let git = self.infra.git();
193 if git.is_enabled() {
194 let rel_path = format!("{}/{}.json", category, name);
195 let _ = git.commit_file(&rel_path, &format!("save {}/{}", category, name));
196 }
197 Ok(())
198 }
199
200 pub async fn save_markdown_and_commit(
202 &self,
203 category: &str,
204 name: &str,
205 content: &str,
206 ) -> anyhow::Result<()> {
207 self.state.save_markdown(category, name, content).await?;
208 let git = self.infra.git();
209 if git.is_enabled() {
210 let rel_path = format!("{}/{}.md", category, name);
211 let _ = git.commit_file(&rel_path, &format!("save {}/{}", category, name));
212 }
213 Ok(())
214 }
215
216 pub async fn delete_and_commit(&self, category: &str, name: &str) -> anyhow::Result<bool> {
218 let deleted = self.state.delete(category, name).await?;
219 if deleted {
220 let git = self.infra.git();
221 if git.is_enabled() {
222 let rel_path = format!("{}/{}.json", category, name);
223 let _ = git.remove_file(&rel_path, &format!("delete {}/{}", category, name));
224 }
225 }
226 Ok(deleted)
227 }
228
229 pub fn commit_all(&self, message: &str) -> anyhow::Result<Option<CommitInfo>> {
231 self.state.commit_all(self.infra.git(), message)
232 }
233
234 pub fn flush_audit(&self) -> anyhow::Result<()> {
236 self.security.flush(self.infra.git())
237 }
238
239 pub async fn schedule(
241 &self,
242 cron_expr: &str,
243 task: &str,
244 persona: Option<&str>,
245 ) -> anyhow::Result<String> {
246 let _persona = persona.unwrap_or("default");
247 let job = crate::cron::CronJob::new(
248 format!("job_{}", uuid::Uuid::new_v4()),
249 cron_expr.to_string(),
250 task.to_string(),
251 );
252 let job_id = self.infra.add_cron(job).await?;
253 Ok(job_id.to_string())
254 }
255
256 pub async fn unschedule(&self, job_id: &str) -> anyhow::Result<bool> {
258 let uuid =
259 uuid::Uuid::parse_str(job_id).map_err(|e| anyhow::anyhow!("invalid job id: {e}"))?;
260 match self.infra.remove_cron(uuid).await {
261 Ok(()) => Ok(true),
262 Err(_) => Ok(false),
263 }
264 }
265
266 pub fn list_schedules(&self) -> Vec<crate::cron::CronJob> {
268 self.infra.list_crons()
269 }
270
271 pub async fn load_json<T: serde::de::DeserializeOwned>(
273 &self,
274 category: &str,
275 name: &str,
276 ) -> anyhow::Result<Option<T>> {
277 self.state.load(category, name).await
278 }
279
280 pub fn start_time(&self) -> std::time::Instant {
282 self.infra.start_time
283 }
284}