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}