tiny_agent/sandbox/
mod.rs1mod host;
2
3pub use async_trait::async_trait;
4pub use host::HostSandbox;
5use std::{fmt, sync::Arc};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum OutStream {
10 Stdout,
11 Stderr,
12}
13
14pub type OutputCallback = Arc<dyn Fn(OutStream, &str) + Send + Sync>;
17
18#[derive(Debug, Clone)]
20pub struct ExecOutput {
21 pub stdout: String,
22 pub stderr: String,
23 pub exit_code: Option<i32>,
24}
25
26impl ExecOutput {
27 pub fn is_success(&self) -> bool {
29 self.exit_code == Some(0)
30 }
31}
32
33#[derive(Debug)]
35pub enum SandboxError {
36 Io(String),
38 Unsupported,
40 Other(String),
42}
43
44impl fmt::Display for SandboxError {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 match self {
47 SandboxError::Io(e) => write!(f, "sandbox io error: {e}"),
48 SandboxError::Unsupported => {
49 write!(f, "operation not supported by this sandbox")
50 }
51 SandboxError::Other(e) => write!(f, "sandbox error: {e}"),
52 }
53 }
54}
55
56impl std::error::Error for SandboxError {}
57
58impl From<std::io::Error> for SandboxError {
59 fn from(e: std::io::Error) -> Self {
60 SandboxError::Io(e.to_string())
61 }
62}
63
64#[async_trait]
82pub trait Sandbox: Send + Sync {
83 async fn open(self: Arc<Self>, session_id: &str) -> Result<Arc<dyn Sandbox>, SandboxError>;
86
87 async fn execute(
94 &self,
95 command: &str,
96 on_output: Option<OutputCallback>,
97 ) -> Result<ExecOutput, SandboxError>;
98
99 async fn save(&self) -> Result<(), SandboxError> {
102 Ok(())
103 }
104
105 async fn fork(&self, _to_session: &str) -> Result<(), SandboxError> {
107 Err(SandboxError::Unsupported)
108 }
109}