agentmux_srv\server/
tool_handlers.rs

1// Copyright 2025-2026, AgentMux Corp.
2// SPDX-License-Identifier: Apache-2.0
3
4//! HTTP/WebSocket RPC handlers for the tool store.
5//! Registers `gettoolstatus` and `installtool` commands with the WshRpcEngine.
6
7use std::sync::Arc;
8
9use crate::backend::rpc::engine::WshRpcEngine;
10use crate::backend::rpc_types::{
11    CommandInstallToolData, GetToolStatusResult, InstallFailure, InstallToolResult,
12    COMMAND_GET_TOOL_STATUS, COMMAND_INSTALL_TOOL,
13};
14use crate::backend::tool_store;
15
16use super::AppState;
17
18pub fn register_tool_handlers(engine: &Arc<WshRpcEngine>, state: &AppState) {
19    let http_client = state.http_client.clone();
20
21    // gettoolstatus → return current install status of all catalog tools
22    engine.register_handler(
23        COMMAND_GET_TOOL_STATUS,
24        Box::new(move |_data, _ctx| {
25            Box::pin(async move {
26                let tools = tool_store::get_tool_statuses();
27                Ok(Some(
28                    serde_json::to_value(GetToolStatusResult { tools })
29                        .map_err(|e| format!("serialize: {e}"))?,
30                ))
31            })
32        }),
33    );
34
35    // installtool → download + verify + install requested tools
36    engine.register_handler(
37        COMMAND_INSTALL_TOOL,
38        Box::new(move |data, _ctx| {
39            let client = http_client.clone();
40            Box::pin(async move {
41                let cmd: CommandInstallToolData = serde_json::from_value(data)
42                    .map_err(|e| format!("installtool: {e}"))?;
43
44                let mut installed = Vec::new();
45                let mut failed = Vec::new();
46
47                for id in &cmd.tool_ids {
48                    match tool_store::install_tool(id, &client).await {
49                        Ok(path) => {
50                            tracing::info!(tool = %id, path = %path, "tool installed");
51                            installed.push(id.clone());
52                        }
53                        Err(e) => {
54                            tracing::warn!(tool = %id, error = %e, "tool install failed");
55                            failed.push(InstallFailure {
56                                id: id.clone(),
57                                error: e,
58                            });
59                        }
60                    }
61                }
62
63                Ok(Some(
64                    serde_json::to_value(InstallToolResult { installed, failed })
65                        .map_err(|e| format!("serialize: {e}"))?,
66                ))
67            })
68        }),
69    );
70}