Skip to main content

do_memory_mcp/server/tools/
code.rs

1// Code execution tool handlers
2//!
3//! This module contains the execute_agent_code tool handler.
4
5use crate::types::{ErrorType, ExecutionContext, ExecutionResult};
6use anyhow::Result;
7use tracing::{debug, info, warn};
8
9impl crate::server::MemoryMCPServer {
10    /// Execute the execute_agent_code tool
11    ///
12    /// # Arguments
13    ///
14    /// * `code` - TypeScript/JavaScript code to execute
15    /// * `context` - Execution context
16    ///
17    /// # Returns
18    ///
19    /// Returns execution result from the sandbox
20    ///
21    /// # Security
22    ///
23    /// This method executes code in a secure sandbox with:
24    /// - Timeout enforcement
25    /// - Resource limits
26    /// - No network access (by default)
27    /// - No filesystem access (by default)
28    /// - Malicious code detection
29    pub async fn execute_agent_code(
30        &self,
31        code: String,
32        context: ExecutionContext,
33    ) -> Result<ExecutionResult> {
34        self.track_tool_usage("execute_agent_code").await;
35
36        // Start monitoring request
37        let request_id = format!(
38            "execute_agent_code_{}",
39            std::time::SystemTime::now()
40                .duration_since(std::time::UNIX_EPOCH)
41                .unwrap_or_default()
42                .as_nanos()
43        );
44        self.monitoring
45            .start_request(request_id.clone(), "execute_agent_code".to_string())
46            .await;
47
48        info!(
49            "Executing agent code: task='{}', code_length={}",
50            context.task,
51            code.len()
52        );
53
54        let start = std::time::Instant::now();
55
56        // Execute in sandbox
57        let result = match self.sandbox.execute(&code, context).await {
58            Ok(r) => r,
59            Err(e) => {
60                // Even on error, we should track the execution attempt
61                let duration_ms = start.elapsed().as_millis() as u64;
62                let mut stats = self.stats.write();
63                stats.record_execution(
64                    &ExecutionResult::Error {
65                        message: e.to_string(),
66                        error_type: ErrorType::Runtime,
67                        stdout: "".to_string(),
68                        stderr: "".to_string(),
69                    },
70                    duration_ms,
71                );
72                return Err(e);
73            }
74        };
75
76        let duration_ms = start.elapsed().as_millis() as u64;
77
78        // Update statistics
79        {
80            let mut stats = self.stats.write();
81            stats.record_execution(&result, duration_ms);
82        }
83
84        // End monitoring request
85        let success = matches!(result, ExecutionResult::Success { .. });
86        let error_message = match &result {
87            ExecutionResult::Error { message, .. } => Some(message.clone()),
88            ExecutionResult::SecurityViolation { reason, .. } => Some(reason.clone()),
89            _ => None,
90        };
91        self.monitoring
92            .end_request(&request_id, success, error_message)
93            .await;
94
95        // Log result
96        match &result {
97            ExecutionResult::Success { .. } => {
98                debug!("Code execution succeeded in {}ms", duration_ms);
99            }
100            ExecutionResult::Error { error_type, .. } => {
101                warn!(
102                    "Code execution failed: {:?} in {}ms",
103                    error_type, duration_ms
104                );
105            }
106            ExecutionResult::Timeout { elapsed_ms, .. } => {
107                warn!("Code execution timed out after {}ms", elapsed_ms);
108            }
109            ExecutionResult::SecurityViolation { violation_type, .. } => {
110                warn!("Security violation detected: {:?}", violation_type);
111            }
112        }
113
114        Ok(result)
115    }
116}