brainwires-code-interpreters
Sandboxed code execution for multiple languages (Rhai, Lua, JavaScript, Python).
Overview
brainwires-code-interpreters provides a unified Executor that dispatches code to language-specific interpreters, all running in-process with configurable safety limits. Each interpreter captures stdout/stderr, accepts JSON context injection, and returns structured results — making it suitable for AI agent tool use, REPL environments, and WASM targets.
Design principles:
- Unified API — one
Executor::execute()method for all languages - Sandboxed — configurable limits on time, memory, operations, output size, call depth, and data structure sizes
- Context injection — pass JSON values into the execution scope as native variables
- WASM-ready — full
wasm-bindgenbindings with thewasmfeature
┌────────────────────────────────────────┐
│ Executor │
│ │
ExecutionRequest│ language ──► dispatch │
────────────────► │ │
│ ┌───────────┼───────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────┐ ┌──────┐ ┌──────────┐ │
│ │ Rhai │ │ Lua │ │JavaScript│ ... │
│ │ │ │ 5.4 │ │ (Boa) │ │
│ └──┬───┘ └──┬───┘ └────┬─────┘ │
│ │ │ │ │
│ └─────────┼───────────┘ │
│ ▼ │
│ ExecutionResult │
◄───────────────│ { success, stdout, stderr, │
│ result, timing_ms, ... } │
│ │
│ ┌──────────────────────────┐ │
│ │ ExecutionLimits │ │
│ │ timeout · memory · ops │ │
│ │ output · depth · sizes │ │
│ └──────────────────────────┘ │
└────────────────────────────────────────┘
Quick Start
Add to your Cargo.toml:
[]
= "0.1"
Execute code:
use ;
let executor = new;
let result = executor.execute;
assert!;
assert!;
Or use the convenience method:
let result = executor.execute_str;
assert!;
Features
| Feature | Default | Description |
|---|---|---|
native |
Yes | Native target support (marker feature) |
rhai |
Yes | Rhai scripting language |
lua |
Yes | Lua 5.4 via mlua (vendored) |
javascript |
No | JavaScript ES2022+ via Boa engine |
python |
No | Python 3.12 compatible via RustPython |
all-languages |
No | Enables all four language interpreters |
wasm |
No | WASM target with wasm-bindgen exports |
Enable features in Cargo.toml:
# Default (Rhai + Lua)
= "0.1"
# All languages
= { = "0.3", = ["all-languages"] }
# WASM target
= { = "0.3", = false, = ["wasm", "rhai", "lua"] }
Architecture
Executor
The central dispatch point. Routes ExecutionRequest to the correct language interpreter and enforces limits.
Language Trait
All interpreters implement LanguageExecutor:
Built-in implementations:
| Struct | Feature | Language | Version |
|---|---|---|---|
RhaiExecutor |
rhai |
Rhai | 1.20 |
LuaExecutor |
lua |
Lua | 5.4 |
JavaScriptExecutor |
javascript |
JavaScript | ES2022+ (Boa 0.20) |
PythonExecutor |
python |
Python | 3.12 (RustPython 0.4) |
Language Enum
| Method | Description |
|---|---|
as_str() |
"rhai", "lua", "javascript", "python" |
from_str(s) |
Case-insensitive, accepts "js" and "py" aliases |
extension() |
File extension: "rhai", "lua", "js", "py" |
Execution Request & Result
ExecutionRequest:
| Field | Type | Default | Description |
|---|---|---|---|
language |
Language |
Rhai |
Target language |
code |
String |
"" |
Source code to execute |
stdin |
Option<String> |
None |
Standard input |
timeout_ms |
u64 |
30,000 | Execution timeout |
memory_limit_mb |
u32 |
256 | Memory ceiling |
context |
Option<Value> |
None |
JSON values injected as native variables |
limits |
Option<ExecutionLimits> |
None |
Override executor-level limits |
ExecutionResult:
| Field | Type | Description |
|---|---|---|
success |
bool |
Whether execution completed without error |
stdout |
String |
Captured standard output |
stderr |
String |
Captured standard error |
result |
Option<Value> |
Return value as JSON |
error |
Option<String> |
Error message on failure |
timing_ms |
u64 |
Wall-clock execution time |
memory_used_bytes |
Option<u64> |
Memory consumed (when available) |
operations_count |
Option<u64> |
Operations executed (when tracked) |
Constructors: ExecutionResult::success(stdout, result, timing_ms), ExecutionResult::error(msg, timing_ms), ExecutionResult::error_with_output(msg, stdout, stderr, timing_ms).
Execution Limits
Configurable safety boundaries applied to every execution.
| Field | Default | Strict | Relaxed |
|---|---|---|---|
max_timeout_ms |
30,000 | 5,000 | 120,000 |
max_memory_mb |
256 | 64 | 512 |
max_output_bytes |
1 MB | 64 KB | 10 MB |
max_operations |
1,000,000 | 100,000 | 10,000,000 |
max_call_depth |
64 | 32 | 128 |
max_string_length |
10 MB | 1 MB | 100 MB |
max_array_length |
100,000 | 10,000 | 1,000,000 |
max_map_size |
10,000 | 1,000 | 100,000 |
Presets: ExecutionLimits::default(), ExecutionLimits::strict(), ExecutionLimits::relaxed().
Sandbox Profiles
Higher-level categorization of what standard library modules are available:
| Profile | Allowed Modules |
|---|---|
Minimal |
math |
Standard |
math, json, string, array, print |
Extended |
math, json, string, array, print, datetime, regex, base64 |
Error Types
ExecutionError variants:
| Variant | Description |
|---|---|
UnsupportedLanguage(String) |
Language not enabled or not recognized |
Timeout(u64) |
Execution exceeded timeout (ms) |
MemoryLimitExceeded(u32) |
Memory ceiling reached (MB) |
OperationLimitExceeded(u64) |
Operation count ceiling reached |
OutputTooLarge(usize) |
Output exceeded max bytes |
SyntaxError(String) |
Code failed to parse |
RuntimeError(String) |
Error during execution |
InternalError(String) |
Internal interpreter error |
All variants convert to ExecutionResult via error.to_result(timing_ms).
WASM Bindings
When the wasm feature is enabled, WasmExecutor is exported via wasm-bindgen:
Global functions are also exported: execute_code(language, code) and get_supported_languages().
Usage Examples
Basic Execution
use ;
let executor = new;
let result = executor.execute;
assert!;
assert!;
Context Injection
use ;
let executor = new;
let result = executor.execute;
assert!;
Strict Limits for Untrusted Code
use ;
let executor = with_limits;
let result = executor.execute;
assert!;
JavaScript with Console Output
use ;
let executor = new;
let result = executor.execute;
assert!;
assert!;
Python Execution
use ;
let executor = new;
let result = executor.execute;
assert!;
assert!;
Language-Specific Executor
use ;
use LanguageExecutor;
let rhai = new;
println!;
let result = rhai.execute;
assert!;
Check Supported Languages
use ;
let languages = supported_languages;
for lang in &languages
assert!;
Custom Execution Limits
use ;
let limits = ExecutionLimits ;
let executor = with_limits;
let result = executor.execute_str;
assert!;
Configuration
ExecutionLimits Presets
| Preset | Use Case | Timeout | Memory | Operations |
|---|---|---|---|---|
default() |
General use | 30s | 256 MB | 1M |
strict() |
Untrusted code | 5s | 64 MB | 100K |
relaxed() |
Trusted / long-running | 120s | 512 MB | 10M |
SandboxProfile
use SandboxProfile;
let modules = Extended.allowed_modules;
// ["math", "json", "string", "array", "print", "datetime", "regex", "base64"]
Integration with Brainwires
Use via the brainwires facade crate:
[]
= { = "0.3", = ["interpreter-all"] }
Or use standalone — brainwires-code-interpreters has no dependency on any other Brainwires crate.
License
Licensed under the MIT License.