Skip to main content

oxios_kernel/tools/
kernel_bridge.rs

1//! KernelToolProvider bridge — plugs oxios kernel tools into oxi-sdk agent builder.
2//!
3//! Implements [`oxi_sdk::KernelToolProvider`] so that oxios kernel tools
4//! (exec, memory, browser, etc.) can be registered into the SDK's
5//! `AgentBuilder` via `.kernel_tools()`.
6
7use std::sync::Arc;
8
9use oxi_sdk::SearchCache;
10use oxi_sdk::ToolRegistry;
11use oxi_sdk::{
12    KernelToolContext as SdkKernelToolContext, KernelToolProvider as SdkKernelToolProvider,
13};
14
15use crate::tools::registration::register_always_on;
16use crate::KernelHandle;
17
18/// Bridges all oxios kernel tools into the oxi-sdk agent builder.
19pub struct OxiosKernelBridge {
20    kernel_handle: Arc<KernelHandle>,
21    search_cache: Arc<SearchCache>,
22}
23
24impl OxiosKernelBridge {
25    /// Create a new bridge with the given kernel handle.
26    pub fn new(kernel_handle: Arc<KernelHandle>) -> Self {
27        Self {
28            kernel_handle,
29            search_cache: Arc::new(SearchCache::new()),
30        }
31    }
32
33    /// Create a new bridge with a pre-built search cache.
34    pub fn with_cache(kernel_handle: Arc<KernelHandle>, search_cache: Arc<SearchCache>) -> Self {
35        Self {
36            kernel_handle,
37            search_cache,
38        }
39    }
40}
41
42impl SdkKernelToolProvider for OxiosKernelBridge {
43    fn tool_names(&self) -> Vec<&str> {
44        vec![
45            // Always-on file tools
46            "read",
47            "write",
48            "edit",
49            "grep",
50            "find",
51            "ls",
52            // Kernel domain
53            "exec",
54            "memory_read",
55            "memory_write",
56            "memory_search",
57            "space",
58            "agent",
59            "a2a_delegate",
60            "a2a_send",
61            "a2a_query",
62            "persona",
63            "program",
64            "cron",
65            "security",
66            "budget",
67            "resource",
68            "mcp",
69            "browser",
70        ]
71    }
72
73    fn register_tools(&self, registry: &ToolRegistry, context: &SdkKernelToolContext) {
74        // 1. Always-on file tools + web search
75        register_always_on(registry, Arc::clone(&self.search_cache));
76
77        // 2. Kernel domain tools via KernelHandle
78        crate::tools::kernel::register_all_kernel_tools(
79            registry,
80            &self.kernel_handle,
81            &context.agent_id,
82        );
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    /// Verify that `tool_names()` returns the expected number of tool names.
91    #[test]
92    fn test_tool_names_length() {
93        // Build a minimal KernelHandle for testing
94        let state_store = Arc::new(
95            oxios_kernel::state_store::StateStore::new(std::path::PathBuf::from(
96                "/tmp/oxios-test-workspace",
97            ))
98            .unwrap(),
99        );
100
101        let kernel = Arc::new(oxios_kernel::KernelHandle::new(
102            oxios_kernel::StateApi::new(state_store.clone()),
103            oxios_kernel::AgentApi::new(
104                Arc::new(oxios_kernel::supervisor::NoOpSupervisor),
105                Arc::new(oxios_kernel::budget::BudgetManager::new()),
106                Arc::new(oxios_kernel::memory::MemoryManager::new(
107                    state_store.clone(),
108                )),
109            ),
110            oxios_kernel::SecurityApi::new(
111                Arc::new(parking_lot::Mutex::new(
112                    oxios_kernel::auth::AuthManager::new(),
113                )),
114                Arc::new(oxios_kernel::audit_trail::AuditTrail::new(100)),
115                Arc::new(parking_lot::Mutex::new(
116                    oxios_kernel::access_manager::AccessManager::new(),
117                )),
118                state_store.clone(),
119            ),
120            oxios_kernel::PersonaApi::new(Arc::new(
121                oxios_kernel::persona_manager::PersonaManager::new(),
122            )),
123            oxios_kernel::ExtensionApi::new(
124                Arc::new(oxios_kernel::program::ProgramManager::new(
125                    std::path::PathBuf::from("/tmp/oxios-test/programs"),
126                )),
127                Arc::new(
128                    oxios_kernel::skill::SkillStore::new(std::path::PathBuf::from(
129                        "/tmp/oxios-test/skills",
130                    ))
131                    .unwrap(),
132                ),
133                Arc::new(oxios_kernel::host_tools::HostToolValidator::new(
134                    vec![],
135                    vec![],
136                )),
137            ),
138            oxios_kernel::McpApi::new(Arc::new(oxios_kernel::mcp::McpBridge::new())),
139            oxios_kernel::InfraApi::new(
140                Arc::new(
141                    oxios_kernel::git_layer::GitLayer::new(
142                        std::path::PathBuf::from("/tmp/oxios-test"),
143                        false,
144                    )
145                    .unwrap(),
146                ),
147                Arc::new(oxios_kernel::scheduler::AgentScheduler::new(5, 60, 300)),
148                Arc::new(oxios_kernel::cron::CronScheduler::new(
149                    state_store.clone(),
150                    60,
151                )),
152                Arc::new(oxios_kernel::resource_monitor::ResourceMonitor::new(60, 60)),
153                Arc::new(oxios_kernel::event_bus::EventBus::new(256)),
154                oxios_kernel::OxiosConfig::default(),
155                std::time::Instant::now(),
156            ),
157            oxios_kernel::SpaceApi::new(
158                Arc::new(
159                    oxios_kernel::space::SpaceManager::new(
160                        state_store.clone(),
161                        Arc::new(oxios_kernel::event_bus::EventBus::new(256)),
162                    )
163                    .unwrap(),
164                ),
165                Arc::new(oxios_kernel::event_bus::EventBus::new(256)),
166            ),
167            oxios_kernel::ExecApi::new(
168                Arc::new(oxios_kernel::config::ExecConfig::default()),
169                Arc::new(parking_lot::Mutex::new(
170                    oxios_kernel::access_manager::AccessManager::new(),
171                )),
172            ),
173            oxios_kernel::BrowserApi::default(),
174            oxios_kernel::A2aApi::new(Arc::new(oxios_kernel::a2a::A2AProtocol::new(Arc::new(
175                oxios_kernel::event_bus::EventBus::new(256),
176            )))),
177        ));
178
179        let bridge = OxiosKernelBridge::new(kernel);
180
181        let names = bridge.tool_names();
182        // 6 always-on + 12 kernel domain = 18 tools
183        assert_eq!(names.len(), 18, "expected 18 tools, got {:?}", names);
184    }
185}