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