oxios_kernel/kernel_handle/
mod.rs1pub mod a2a_api;
4pub mod agent_api;
5pub mod calendar_api;
6pub mod email_api;
7pub mod engine_api;
8pub mod exec_api;
9pub mod extension_api;
10pub mod infra_api;
11pub mod knowledge_lens;
12pub mod marketplace_api;
13pub mod mcp_api;
14pub mod memory_api;
15pub mod mount_api;
16pub mod persona_api;
17pub mod project_api;
18pub mod security_api;
19pub mod state_api;
20
21pub use a2a_api::A2aApi;
22pub use agent_api::AgentApi;
23pub use calendar_api::CalendarApi;
24pub use email_api::EmailApi;
25pub use engine_api::{
26 EngineApi, EngineConfigResponse, FallbackEvent, InputModality, ModelInfo, ProviderCategory,
27 ProviderInfo, RoutingConfigSnapshot, RoutingStats, RoutingStatsSnapshot, RoutingUpdate,
28 ValidateKeyResult,
29};
30pub use exec_api::ExecApi;
31pub use exec_api::SharedExecConfig;
32pub use extension_api::ExtensionApi;
33pub use infra_api::InfraApi;
34pub use knowledge_lens::{
35 CopilotResponse, KnowledgeContext, KnowledgeLens, KnowledgeNote, MemoryNote,
36};
37pub use marketplace_api::MarketplaceApi;
38pub use mcp_api::McpApi;
39pub use memory_api::MemoryApi;
40pub use mount_api::{MountApi, MountInfo};
41pub use persona_api::PersonaApi;
42pub use project_api::{ProjectApi, ProjectInfo};
43pub use security_api::SecurityApi;
44pub use state_api::StateApi;
45
46use crate::git_layer::CommitInfo;
47use crate::readiness::ReadinessGate;
48use serde::Serialize;
49use std::sync::Arc;
50
51pub 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 projects: Option<ProjectApi>,
83 pub mounts: Option<MountApi>,
85 pub exec: ExecApi,
87 pub a2a: A2aApi,
89 pub engine: EngineApi,
91 pub knowledge: Arc<oxios_markdown::KnowledgeBase>,
93 pub knowledge_lens: Arc<KnowledgeLens>,
95 pub marketplace_api: MarketplaceApi,
97 pub calendar: Option<CalendarApi>,
99 pub email: Option<EmailApi>,
101 pub readiness: Arc<ReadinessGate>,
103}
104
105impl KernelHandle {
106 #[allow(clippy::too_many_arguments)]
111 pub fn new(
112 state: StateApi,
113 agents: AgentApi,
114 security: SecurityApi,
115 persona: PersonaApi,
116 extensions: ExtensionApi,
117 mcp: McpApi,
118 infra: InfraApi,
119 projects: Option<ProjectApi>,
120 exec: ExecApi,
121 a2a: A2aApi,
122 engine: EngineApi,
123 knowledge: Arc<oxios_markdown::KnowledgeBase>,
124 knowledge_lens: Arc<KnowledgeLens>,
125 marketplace_api: MarketplaceApi,
126 calendar: Option<CalendarApi>,
127 email: Option<EmailApi>,
128 ) -> Self {
129 Self {
130 state,
131 agents,
132 security,
133 persona,
134 extensions,
135 mcp,
136 infra,
137 projects,
138 mounts: None,
139 exec,
140 a2a,
141 engine,
142 knowledge,
143 knowledge_lens,
144 marketplace_api,
145 calendar,
146 email,
147 readiness: Arc::new(ReadinessGate::new(0)),
151 }
152 }
153
154 pub fn with_mounts(mut self, mounts: MountApi) -> Self {
160 self.mounts = Some(mounts);
161 self
162 }
163
164 pub fn set_mounts(&mut self, mounts: MountApi) {
166 self.mounts = Some(mounts);
167 }
168
169 pub async fn save_and_commit<T: Serialize>(
175 &self,
176 category: &str,
177 name: &str,
178 data: &T,
179 ) -> anyhow::Result<()> {
180 self.state.save(category, name, data).await?;
181 let git = self.infra.git();
182 if git.is_enabled() {
183 let rel_path = format!("{category}/{name}.json");
184 let _ = git.commit_file(&rel_path, &format!("save {category}/{name}"));
185 }
186 Ok(())
187 }
188
189 pub async fn save_markdown_and_commit(
191 &self,
192 category: &str,
193 name: &str,
194 content: &str,
195 ) -> anyhow::Result<()> {
196 self.state.save_markdown(category, name, content).await?;
197 let git = self.infra.git();
198 if git.is_enabled() {
199 let rel_path = format!("{category}/{name}.md");
200 let _ = git.commit_file(&rel_path, &format!("save {category}/{name}"));
201 }
202 Ok(())
203 }
204
205 pub async fn delete_and_commit(&self, category: &str, name: &str) -> anyhow::Result<bool> {
207 let deleted = self.state.delete(category, name).await?;
208 if deleted {
209 let git = self.infra.git();
210 if git.is_enabled() {
211 let rel_path = format!("{category}/{name}.json");
212 let _ = git.remove_file(&rel_path, &format!("delete {category}/{name}"));
213 }
214 }
215 Ok(deleted)
216 }
217
218 pub fn commit_all(&self, message: &str) -> anyhow::Result<Option<CommitInfo>> {
220 self.state.commit_all(self.infra.git(), message)
221 }
222
223 pub fn flush_audit(&self) -> anyhow::Result<()> {
225 self.security.flush(self.infra.git())
226 }
227
228 pub async fn schedule(
230 &self,
231 cron_expr: &str,
232 task: &str,
233 persona: Option<&str>,
234 ) -> anyhow::Result<String> {
235 let _persona = persona.unwrap_or("default");
236 let job = crate::cron::CronJob::new(
237 format!("job_{}", uuid::Uuid::new_v4()),
238 cron_expr.to_string(),
239 task.to_string(),
240 );
241 let job_id = self.infra.add_cron(job).await?;
242 Ok(job_id.to_string())
243 }
244
245 pub async fn unschedule(&self, job_id: &str) -> anyhow::Result<bool> {
247 let uuid =
248 uuid::Uuid::parse_str(job_id).map_err(|e| anyhow::anyhow!("invalid job id: {e}"))?;
249 match self.infra.remove_cron(uuid).await {
250 Ok(()) => Ok(true),
251 Err(_) => Ok(false),
252 }
253 }
254
255 pub fn list_schedules(&self) -> Vec<crate::cron::CronJob> {
257 self.infra.list_crons()
258 }
259
260 pub async fn load_json<T: serde::de::DeserializeOwned>(
262 &self,
263 category: &str,
264 name: &str,
265 ) -> anyhow::Result<Option<T>> {
266 self.state.load(category, name).await
267 }
268
269 pub fn start_time(&self) -> std::time::Instant {
271 self.infra.start_time
272 }
273
274 pub fn marketplace_api(&self) -> &MarketplaceApi {
276 &self.marketplace_api
277 }
278
279 pub fn memory(&self) -> MemoryApi {
287 let mm = self.agents.memory_manager().clone();
291 MemoryApi::new(mm)
292 }
293}