Skip to main content

oxicode_sdk/
tool_factory.rs

1//! Tool factories for common tool sets
2
3use std::path::Path;
4use std::sync::Arc;
5
6use oxicode_agent::{
7    ToolRegistry,
8    tools::{EditTool, LsTool, ReadTool, WriteTool},
9};
10
11/// Create the standard coding tools: read, write, edit, ls
12pub fn coding_tools(cwd: &Path) -> Arc<ToolRegistry> {
13    let registry = ToolRegistry::new();
14    registry.register(ReadTool::with_cwd(cwd.to_path_buf()));
15    registry.register(WriteTool::with_cwd(cwd.to_path_buf()));
16    registry.register(EditTool::with_cwd(cwd.to_path_buf()));
17    registry.register(LsTool::with_cwd(cwd.to_path_buf()));
18    Arc::new(registry)
19}
20
21/// Create read-only tools: read, ls
22pub fn readonly_tools(cwd: &Path) -> Arc<ToolRegistry> {
23    let registry = ToolRegistry::new();
24    registry.register(ReadTool::with_cwd(cwd.to_path_buf()));
25    registry.register(LsTool::with_cwd(cwd.to_path_buf()));
26    Arc::new(registry)
27}
28
29// ── MCP tool factory (Phase SDK) ─────────────────────────────────────
30
31/// Create a `ToolRegistry` containing the MCP proxy tool plus any
32/// direct tools registered via `directTools` in the cache.
33///
34/// The MCP manager is spawned with the supplied config, or auto-discovers
35/// from `~/.config/oxicode/mcp.json` / `.mcp.json` if `config` is `None`.
36///
37/// The `cwd` parameter is used to resolve `.mcp.json` lookup paths.
38pub fn mcp_tools(
39    cwd: &std::path::Path,
40    config: Option<oxicode_agent::mcp::McpConfig>,
41) -> std::sync::Arc<ToolRegistry> {
42    use oxicode_agent::mcp::{McpDirectTool, McpManager, McpTool};
43
44    let manager = match config {
45        Some(cfg) => McpManager::spawn_with_config(cfg),
46        None => {
47            // Auto-discover from the standard paths relative to `cwd`.
48            // For now, fall back to the default loader (which uses CWD).
49            let _ = cwd; // silence unused
50            McpManager::spawn()
51        }
52    };
53
54    let registry = ToolRegistry::new();
55
56    // Direct tools (Phase 3) — read from cache.
57    for def in manager.direct_tools_from_cache() {
58        registry.register(McpDirectTool::new(manager.clone(), def));
59    }
60
61    // Proxy tool (unless explicitly disabled).
62    if !manager.should_disable_proxy() {
63        registry.register(McpTool::new(manager.clone()));
64    }
65
66    // Stash the manager so the TUI / other consumers can reach it.
67    registry.set_mcp_manager(manager);
68
69    std::sync::Arc::new(registry)
70}