Capsule: Secure AI Agent Runtime
Detailed Description of Capsule: A Secure, Durable Runtime for AI Agents
Introduction to Capsule
Capsule is a cutting-edge runtime designed specifically for executing AI agent tasks in isolated environments. It ensures secure and efficient execution by leveraging WebAssembly (Wasm) technology, providing a sandboxed environment where untrusted code can run without compromising system stability or security. Whether you are processing large datasets, managing long-running workflows, or orchestrating multi-agent systems, Capsule offers robust isolation, resource management, automatic retries, and lifecycle tracking to streamline execution.
The platform is designed to handle complex tasks such as data analysis, machine learning model inference, and distributed computing while maintaining strict control over system resources. By encapsulating each task in its own WebAssembly sandbox, Capsule prevents unintended side effects, enforces CPU and memory limits, and ensures that failures do not propagate across the entire workflow.
Core Features of Capsule
1. Isolated Execution
Each task runs independently within a dedicated WebAssembly sandbox, ensuring that one task’s failure does not disrupt others. This isolation is achieved through Wasm’s inherent security model, which restricts access to system resources and prevents malicious code from affecting the host environment.
2. Resource Limits
Capsule allows fine-grained control over computational resources by defining CPU allocation levels (LOW, MEDIUM, HIGH) and memory constraints (512MB, 2GB). These limits prevent resource exhaustion attacks and ensure that tasks do not consume excessive system resources unnecessarily.
3. Automatic Retries
When a task fails, Capsule automatically retries it up to the specified number of times (max_retries), reducing manual intervention required for error handling. This feature is particularly useful in environments where tasks may encounter transient failures due to network issues or temporary resource unavailability.
4. Lifecycle Tracking
Capsule provides detailed monitoring of task execution, including:
- Running status (active, completed, failed)
- Execution duration (in milliseconds)
- CPU fuel consumption (via Wasm’s metering system)
- Retry attempts
This transparency allows developers to debug issues efficiently and optimize workflows.
How Capsule Works: A Step-by-Step Overview
1. Task Annotation with Decorators
Capsule supports two primary programming languages: Python and TypeScript/JavaScript. Tasks are annotated using decorators or function wrappers, defining metadata such as resource allocation, timeouts, and retry policies.
Python Example:
from capsule import task
@task(
name="analyze_data",
compute="MEDIUM",
ram="512MB",
timeout="30s",
max_retries=1
)
def analyze_data(dataset: list) -> dict:
"""Process data in an isolated, resource-controlled environment."""
return {"processed": len(dataset), "status": "complete"}
@taskdecorator marks the function as a Capsule task.- Metadata parameters (
name,compute,ram, etc.) define execution constraints.
TypeScript/JavaScript Example:
import { task } from "@capsule-run/sdk";
export const analyzeData = task(
{
name: "analyze_data",
compute: "MEDIUM",
ram: "512MB",
timeout: "30s",
maxRetries: 1,
},
(dataset: number[]) => {
return { processed: dataset.length, status: "complete" };
}
);
export const main = task(
{ name: "main", compute: "HIGH" },
() => analyzeData([1, 2, 3, 4, 5])
);
task()wrapper encapsulates the function with configurable settings.- The
maintask serves as the entry point for execution.
2. Compilation to WebAssembly
When a task is executed via the Capsule CLI (capsule run), your Python or TypeScript code is compiled into a WebAssembly module. This compilation happens in an isolated environment, ensuring security and efficiency.
Compilation Process:
- The host system processes the annotated function.
- The code is converted into a
.wasmfile using Capsule’s internal compiler (leveraging tools likecomponentize-pyfor Python). - The compiled Wasm module runs in a sandboxed runtime, enforcing resource limits and isolation.
3. Execution in Sandboxes
Each task executes within its own WebAssembly sandbox, where:
- CPU fuel is metered based on the
computelevel. - Memory usage is strictly limited by
ram. - Timeouts prevent indefinite execution.
- Retries handle transient failures gracefully.
The host system monitors execution and enforces these constraints dynamically.
Getting Started with Capsule
1. Installation
Python Setup:
pip install capsule-run
TypeScript/JavaScript Setup:
npm install -g @capsule-run/cli
npm install @capsule-run/sdk
2. Running a Simple Task
Python Example (hello.py):
from capsule import task
@task(name="main", compute="LOW", ram="64MB")
def main() -> str:
return "Hello from Capsule!"
# Execute the task
capsule run hello.py
- The script outputs:
{"success": true, "result": "Hello from Capsule!", ...}
TypeScript Example (hello.ts):
import { task } from "@capsule-run/sdk";
export const main = task(
{ name: "main", compute: "LOW", ram: "64MB" },
(): string => {
return "Hello from Capsule!";
}
);
# Execute the task
capsule run hello.ts
3. Running Tasks Programmatically
Instead of using the CLI, you can execute tasks directly in your code:
Python Example:
from capsule import run
async def main():
result = await run(file="./sandbox.py", args=["code to execute"])
print(result)
# Execute sandbox.py (see below)
TypeScript/JavaScript Example:
import { run } from '@capsule-run/sdk/runner';
const result = await run({
file: './sandbox.ts',
args: ['code to execute']
});
console.log(result);
Task Configuration Options
Capsule provides a rich set of configuration parameters to customize task behavior:
| Parameter | Description | Type | Default Value |
|--------------------|-------------------------------------------------------------------------------------------------|------------|---------------------|
| name | Task identifier (required in TypeScript). | str | Function name (Python) / Required (TS) |
| compute | CPU allocation level (LOW, MEDIUM, HIGH). | str | "MEDIUM" |
| ram | Memory limit for the task (512MB, 2GB). | str | Unlimited |
| timeout | Maximum execution time (30s, 5m, 1h). | str | Unlimited |
| max_retries | Number of retry attempts on failure. | int | 0 |
| allowed_files | Directories accessible in the sandbox (Python). | list[str]| [] |
| allowed_hosts | Domains allowed for HTTP requests (TypeScript/Python). | list[str]| ["*"] |
| env_variables | Environment variables exposed to the task. | list[str]| [] |
Compute Levels
Capsule uses WebAssembly’s fuel mechanism to allocate CPU resources dynamically:
- LOW: Minimal allocation for lightweight tasks.
- MEDIUM: Balanced resources for typical workloads.
- HIGH: Maximum fuel for compute-intensive operations.
- CUSTOM: Specify an exact fuel value (e.g.,
compute="1000000").
Response Format
Each task returns a structured JSON envelope containing:
{
"success": true,
"result": "Hello from Capsule!",
"error": null,
"execution": {
"task_name": "data_processor",
"duration_ms": 1523,
"retries": 0,
"fuel_consumed": 45000
}
}
success: Boolean indicating task completion.result: The actual return value (e.g., JSON, string).error: Error details if the task failed.execution: Performance metrics:task_name: Name of the executed task.duration_ms: Execution time in milliseconds.retries: Number of retry attempts.fuel_consumed: CPU resources used.
HTTP Client API
Python (Custom HTTP Client)
Since standard libraries like requests are incompatible with Wasm’s sandboxed I/O, Capsule provides its own HTTP client:
from capsule import task
from capsule.http import get, post
@task(name="http_example", compute="MEDIUM", timeout="30s")
def main() -> dict:
response = get("https://api.example.com/data")
return {
"status": response.status_code,
"success": response.ok(),
"data": response.json()
}
TypeScript/JavaScript (Standard fetch)
No custom client is needed since fetch works seamlessly in Wasm:
import { task } from "@capsule-run/sdk";
export const main = task(
{ name: "main", compute: "MEDIUM" },
async () => {
const response = await fetch("https://api.example.com/data");
return response.json();
}
);
Network Access and Security
Tasks can make HTTP requests only to domains specified in allowed_hosts. By default, all outbound requests are allowed (["*"]), but you can restrict access:
from capsule import task
from capsule.http import get
@task(name="main", allowed_hosts=["api.openai.com", "*.anthropic.com"])
def main() -> dict:
response = get("https://api.openai.com/v1/models")
return response.json()
File Access
Tasks can read/write files only within directories listed in allowed_files. Python’s standard file operations work normally, while TypeScript uses Node.js’s fs module.
Python Example:
from capsule import task
@task(name="restricted_writer", allowed_files=["./output"])
def restricted_writer() -> None:
with open("./output/result.txt", "w") as f:
f.write("result")
@task(name="main")
def main() -> str:
restricted_writer()
TypeScript Example:
import { task } from "@capsule-run/sdk";
import fs from "fs/promises";
export const restrictedWriter = task(
{ name: "restricted_writer", allowedFiles: ["./output"] },
async () => {
await fs.writeFile("./output/result.txt", "result");
}
);
export const main = task(
{ name: "main", allowedFiles: ["./data"] },
async () => {
await restrictedWriter();
return await fs.readFile("./data/input.txt", "utf8");
}
);
Environment Variables
Tasks can access environment variables to read configuration or API keys.
Python Example:
from capsule import task
import os
@task(name="main", env_variables=["API_KEY"])
def main() -> dict:
api_key = os.environ.get("API_KEY")
return {"api_key": api_key}
TypeScript Example:
import { task } from "@capsule-run/sdk";
export const main = task(
{ name: "main", envVariables: ["API_KEY"] },
() => {
const apiKey = process.env.API_KEY;
return { apiKeySet: apiKey !== undefined };
}
);
Project Configuration (Optional)
You can define default settings for all tasks using a capsule.toml file:
[workflow]
name = "My AI Workflow"
version = "1.0.0"
entrypoint = "src/main.py"
[tasks]
default_compute = "MEDIUM"
default_ram = "256MB"
default_timeout = "30s"
default_max_retries = 2
- Entry point (
entrypoint) specifies the default file when runningcapsule run. - Task-level settings override these defaults.
Cache Management
Capsule generates a .capsule folder in your project root, containing:
- Compiled WebAssembly modules (
.wasm,.cwasm) - Interface definitions (
wit/) - Execution logs (
trace.db)
This cache speeds up subsequent runs by avoiding recompilation.
Precompiling Tasks:
capsule build main.ts # Precompile ahead of time
Production Execution
Running source code directly (e.g., .py, .ts) compiles at runtime, adding latency. For sub-second performance, precompile tasks into .wasm files:
Compiling and Executing:
capsule build hello.py --export # Generates optimized hello.wasm
capsule exec hello.wasm # Runs compiled artifact
Compatibility
Python Support
- Only pure Python is supported in sandboxes (no C extensions like
numpyorpandas). - Host code using
run()has full access to the Python ecosystem.
TypeScript/JavaScript Support
- npm packages and ES modules work seamlessly.
- Common Node.js built-ins are available.
Contributing to Capsule
Capsule is an open-source project, and contributions are welcome! Here’s how you can get involved:
Prerequisites:
- Rust (latest stable)
- Python 3.13+
- Node.js 22+
Installation:
git clone https://github.com/mavdol/capsule.git
cd capsule
# Build and install CLI
cargo install --path crates/capsule-cli
# Python SDK (editable install)
pip install -e crates/capsule-sdk/python
# TypeScript SDK (link for local dev)
cd crates/capsule-sdk/javascript
npm install && npm run build && npm link
Running Tests:
cargo test # For CLI/core components
Credits
Capsule builds on several open-source projects:
- componentize-py – Python to WebAssembly Component compilation.
- jco – JavaScript toolchain for WebAssembly Components.
- wasmtime – WebAssembly runtime.
- WASI – WebAssembly System Interface.
License
Capsule is licensed under the Apache License 2.0. Check the LICENSE file for details.
Conclusion
Capsule provides a robust, secure, and efficient runtime for executing AI agent tasks in isolated environments. By leveraging WebAssembly’s sandboxing capabilities, it ensures safe execution of untrusted code while offering fine-grained control over resources, automatic retries, and detailed monitoring. Whether you are developing complex workflows or deploying multi-agent systems, Capsule simplifies task management with its intuitive decorators, CLI tools, and structured response format.
For further exploration, refer to the official documentation and explore integrations like the TypeScript adapter for pre-built solutions.
Enjoying this project?
Discover more amazing open-source projects on TechLogHub. We curate the best developer tools and projects.
Repository:https://github.com/mavdol/capsule
GitHub - mavdol/capsule: Capsule: Secure AI Agent Runtime
Capsule is a cutting‑edge runtime designed specifically for executing AI agent tasks in isolated environments. It ensures secure and efficient execution by leve...
github - mavdol/capsule