adk_sandbox/types.rs
1//! Core types for sandbox execution: [`Language`], [`ExecRequest`], and [`ExecResult`].
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use std::fmt;
6use std::time::Duration;
7
8/// Supported execution languages.
9///
10/// Each variant maps to a specific interpreter or compiler used by the backend.
11///
12/// # Example
13///
14/// ```rust
15/// use adk_sandbox::Language;
16///
17/// let lang = Language::Rust;
18/// assert_eq!(lang.to_string(), "rust");
19/// ```
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
21#[serde(rename_all = "lowercase")]
22pub enum Language {
23 /// Rust source compiled with `rustc`.
24 Rust,
25 /// Python source executed with `python3`.
26 Python,
27 /// JavaScript source executed with `node`.
28 JavaScript,
29 /// TypeScript source (requires a compatible runtime).
30 TypeScript,
31 /// Pre-compiled WebAssembly module bytes.
32 Wasm,
33 /// Raw shell command executed via `sh -c`.
34 Command,
35}
36
37impl fmt::Display for Language {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 match self {
40 Language::Rust => write!(f, "rust"),
41 Language::Python => write!(f, "python"),
42 Language::JavaScript => write!(f, "javascript"),
43 Language::TypeScript => write!(f, "typescript"),
44 Language::Wasm => write!(f, "wasm"),
45 Language::Command => write!(f, "command"),
46 }
47 }
48}
49
50/// A request to execute code in a sandbox.
51///
52/// `ExecRequest` intentionally has no `Default` implementation — callers must
53/// explicitly set the `timeout` to avoid unbounded execution.
54///
55/// # Example
56///
57/// ```rust
58/// use adk_sandbox::{ExecRequest, Language};
59/// use std::time::Duration;
60/// use std::collections::HashMap;
61///
62/// let request = ExecRequest {
63/// language: Language::Python,
64/// code: "print('hello')".to_string(),
65/// stdin: None,
66/// timeout: Duration::from_secs(30),
67/// memory_limit_mb: None,
68/// env: HashMap::new(),
69/// };
70/// ```
71#[derive(Debug, Clone)]
72pub struct ExecRequest {
73 /// The language of the code to execute.
74 pub language: Language,
75 /// The source code or command to execute.
76 pub code: String,
77 /// Optional standard input to feed to the process.
78 pub stdin: Option<String>,
79 /// Maximum wall-clock time allowed for execution. No default — must be set explicitly.
80 pub timeout: Duration,
81 /// Optional memory limit in megabytes. Only enforced by `WasmBackend`.
82 pub memory_limit_mb: Option<u32>,
83 /// Environment variables passed to the child process. The backend clears
84 /// the inherited environment and sets only these variables.
85 pub env: HashMap<String, String>,
86}
87
88/// The result of a sandbox execution.
89///
90/// Non-zero `exit_code` is a valid result, not an error. The caller decides
91/// how to interpret the exit code.
92///
93/// # Example
94///
95/// ```rust
96/// use adk_sandbox::ExecResult;
97/// use std::time::Duration;
98///
99/// let result = ExecResult {
100/// stdout: "hello\n".to_string(),
101/// stderr: String::new(),
102/// exit_code: 0,
103/// duration: Duration::from_millis(42),
104/// };
105/// assert_eq!(result.exit_code, 0);
106/// ```
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct ExecResult {
109 /// Captured standard output (UTF-8, truncated to 1 MB by backends).
110 pub stdout: String,
111 /// Captured standard error (UTF-8, truncated to 1 MB by backends).
112 pub stderr: String,
113 /// Process exit code. 0 typically means success.
114 pub exit_code: i32,
115 /// Wall-clock duration of the execution.
116 pub duration: Duration,
117}