Skip to main content

agentic_sandbox/
traits.rs

1//! Sandbox traits and types.
2
3use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5
6use crate::error::SandboxError;
7
8/// An artifact produced during execution.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct SandboxArtifact {
11    /// Path to the artifact
12    pub path: String,
13    /// Content of the artifact
14    pub content: String,
15}
16
17/// Result of code execution.
18#[derive(Debug, Clone)]
19pub struct ExecutionResult {
20    /// Exit code (0 = success)
21    pub exit_code: i32,
22    /// Standard output
23    pub stdout: String,
24    /// Standard error
25    pub stderr: String,
26    /// Execution time in milliseconds
27    pub execution_time_ms: u64,
28    /// Generated artifacts (files)
29    pub artifacts: Vec<SandboxArtifact>,
30}
31
32impl ExecutionResult {
33    /// Check if execution was successful.
34    #[must_use]
35    pub const fn is_success(&self) -> bool {
36        self.exit_code == 0
37    }
38}
39
40/// Trait for sandbox implementations.
41///
42/// A sandbox provides isolated code execution with resource limits.
43#[async_trait]
44pub trait Sandbox: Send + Sync {
45    /// Execute code in the sandbox.
46    ///
47    /// # Arguments
48    ///
49    /// * `code` - The code/command to execute
50    ///
51    /// # Errors
52    ///
53    /// Returns an error if execution fails.
54    async fn execute(&self, code: &str) -> Result<ExecutionResult, SandboxError>;
55
56    /// Check if the sandbox is ready.
57    ///
58    /// # Errors
59    ///
60    /// Returns an error if the sandbox is not accessible.
61    async fn is_ready(&self) -> Result<bool, SandboxError>;
62
63    /// Stop and cleanup the sandbox.
64    ///
65    /// # Errors
66    ///
67    /// Returns an error if cleanup fails.
68    async fn stop(&self) -> Result<(), SandboxError>;
69}
70
71/// Implementation of Sandbox for `Box<dyn Sandbox>`.
72/// This allows using trait objects with generic sandbox validators.
73#[async_trait]
74impl Sandbox for Box<dyn Sandbox> {
75    async fn execute(&self, code: &str) -> Result<ExecutionResult, SandboxError> {
76        (**self).execute(code).await
77    }
78
79    async fn is_ready(&self) -> Result<bool, SandboxError> {
80        (**self).is_ready().await
81    }
82
83    async fn stop(&self) -> Result<(), SandboxError> {
84        (**self).stop().await
85    }
86}