Secure code execution for multi-agent AI systems
Project description
Codemode
Secure code execution for multi-agent AI systems
Codemode enables AI agents to dynamically generate and execute code to orchestrate complex workflows while maintaining production-grade security through isolated execution environments.
Key Features
- Secure Execution: Code runs in isolated Docker containers with security hardening
- RPC Bridge: Tools execute in main app with full access, code runs in isolation
- TLS/mTLS Encryption: End-to-end encryption for all gRPC communications
- Retry Logic: Automatic retries with exponential backoff for transient failures
- Correlation IDs: End-to-end request tracing across the distributed system
- Framework Support: Native CrewAI integration, LangChain and LangGraph coming soon
Quick Start
Installation
pip install opencodemode[crewai]
Basic Usage
from codemode import Codemode
from codemode.config import ClientConfig
# Configure the client
config = ClientConfig(
executor_url="http://localhost:8001",
executor_api_key="your-api-key",
)
# Create Codemode instance
codemode = Codemode.from_client_config(config)
# Execute code
result = codemode.execute("result = 2 + 2")
print(result) # "4"
Environment Variables
Configure via environment variables for production:
export CODEMODE_EXECUTOR_URL="http://executor:8001"
export CODEMODE_EXECUTOR_API_KEY="your-api-key"
from codemode import Codemode
codemode = Codemode.from_env()
result = codemode.execute("result = 2 + 2")
With CrewAI
from crewai import Agent, Task, Crew
from codemode import Codemode
codemode = Codemode.from_env()
code_tool = codemode.as_crewai_tool()
developer = Agent(
role="Python Developer",
goal="Write and execute Python code",
tools=[code_tool],
backstory="You are an expert Python developer",
)
task = Task(
description="Calculate the first 10 Fibonacci numbers",
agent=developer,
expected_output="List of first 10 Fibonacci numbers",
)
crew = Crew(agents=[developer], tasks=[task])
result = crew.kickoff()
Registering Tools
Register tools that AI-generated code can call back into your main application:
from codemode import Codemode, ComponentRegistry
registry = ComponentRegistry()
# Register a tool instance
registry.register_tool(
name="weather",
tool=weather_tool,
description="Get current weather for a location",
)
codemode = Codemode.from_env(registry=registry)
result = codemode.execute("weather = tools['weather'].run(location='London')")
@tool Decorator
Use the @tool decorator for a concise registration workflow:
from codemode import tool
@tool(name="add", description="Add two numbers")
def add(a: int, b: int) -> int:
return a + b
@tool(name="weather", description="Get weather")
def get_weather(location: str) -> dict:
return {"temp": 72, "location": location}
# Register individually
registry.register(add)
# Or auto-discover all decorated tools from a module
import my_tools
registered = registry.discover_tools(my_tools)
Schemas can be attached via the decorator:
from pydantic import BaseModel, Field
class WeatherInput(BaseModel):
location: str = Field(..., description="City name")
@tool(name="weather", input_schema=WeatherInput)
def get_weather(location: str) -> dict:
"""Get current weather for a location."""
return {"temp": 72}
Tool Access Filtering
Control which tools each agent can access during execution:
# At execution time, restrict available tools
result = codemode.execute(
code="data = tools['database'].run(query='SELECT 1')",
tool_filter=["database", "cache"],
)
# Or create a scoped registry for fine-grained control
scoped = registry.scoped(["weather", "database"])
# scoped.get_tool("weather") -> works
# scoped.get_tool("admin") -> raises ComponentNotFoundError
Meta-tools (__list__, __schema__, __search__) are always accessible regardless of filtering.
Meta-Tools
Built-in meta-tools allow executed code to discover available tools at runtime:
| Tool | Description |
|---|---|
__list__ |
List all available tools with descriptions, async status, and schema availability |
__schema__ |
Get input/output schema for a specific tool by name |
__search__ |
Search for tools by keyword across names and descriptions |
Meta-tools are auto-registered when you create a ComponentRegistry. Inside executed code:
# List all tools
all_tools = tools['__list__'].run()
# Get schema for a specific tool
schema = tools['__schema__'].run(name="weather")
# Search for tools by keyword
matches = tools['__search__'].run(query="database")
Architecture
+------------------+ gRPC/HTTP +------------------+
| | -----------------------> | |
| Main App | Execute Code | Executor |
| (Client) | <----------------------- | Sidecar |
| | Tool Callbacks | (Docker) |
+------------------+ +------------------+
- AI agent generates Python code
- Code executes in isolated executor (no network, read-only FS)
- When code calls
tools['database'].run(), gRPC callback to main app - Main app executes real tool with full access
- Result returned to executor, code continues
Documentation
Full documentation is available in the docs/ directory:
- Getting Started - Installation and quickstart
- Configuration - Client and sidecar configuration
- Architecture - System design and components
- Features - Tools, schemas, and integrations
- Deployment - Docker and production deployment
- API Reference - Complete API documentation
- Development - Contributing and testing
- Migration - Version migration guides
Docker Setup
# Initialize project
codemode init
# Build executor image
codemode docker build
# Start executor container
codemode docker start
# Verify status
codemode docker status
Additional Docker Commands
# Generate .env file from codemode.yaml (for docker-compose)
codemode docker env --config codemode.yaml --output .env
# Export Docker assets for custom deployment
codemode docker assets --dest ./deploy
# Start with custom configuration
codemode docker start --config custom.yaml --port 8001
# Remove executor container
codemode docker remove
Docker Compose
For multi-container setups:
# Generate .env from your config
codemode docker env --output .env
# Start with docker-compose
docker-compose --env-file .env -f docker_sidecar/docker-compose.yml up -d
See Deployment Guide for detailed Docker instructions.
Security
Codemode implements defense-in-depth security:
- Container Isolation: Separate container with no external network access
- Import Blocking: Dangerous modules blocked before execution
- TLS Encryption: Optional end-to-end encryption with mTLS support
- Filesystem Protection: Read-only root filesystem
- Resource Limits: CPU, memory, and process limits
- Code Validation: Pattern matching for dangerous code
See Security Model for details.
Contributing
We welcome contributions! Here's the workflow:
- Fork the repository
- Create a feature branch from
develop(git checkout -b feature/amazing-feature develop) - Make your changes and commit (
git commit -m 'Add amazing feature') - Push to your fork (
git push origin feature/amazing-feature) - Open a Pull Request against
develop
Branch Strategy
develop- Active development branch (submit PRs here)main- Stable releasesrelease-test- Triggers Test PyPI publishrelease- Triggers PyPI publish
PRs are merged: feature branch -> develop -> main -> release-test -> release
Development Setup
# Clone and setup
git clone https://github.com/mldlwizard/code_mode.git
cd code_mode
git checkout develop
uv sync --extra dev
# Run tests
make test
# Run linting
make lint
# Run E2E tests (requires Docker)
make e2e
See Development Guide for details.
License
MIT License - see LICENSE for details.
Support
- GitHub Issues: Report bugs
- Documentation: Full docs
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file opencodemode-0.2.3b11.tar.gz.
File metadata
- Download URL: opencodemode-0.2.3b11.tar.gz
- Upload date:
- Size: 492.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4660af98f91dd9aa639313745b3487fd34c5c1f240b4309a01735f5a3006cfe1
|
|
| MD5 |
ec1cdb55bb41eb322cee762f4ce0f479
|
|
| BLAKE2b-256 |
5d72a0ff7da471db61c5c1c9a7157dab15f1a9321e42f653a6f335b4b3e5c412
|
File details
Details for the file opencodemode-0.2.3b11-py3-none-any.whl.
File metadata
- Download URL: opencodemode-0.2.3b11-py3-none-any.whl
- Upload date:
- Size: 111.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
05e44c9b2033589dcd6f57686346589396d9fd578fac163e35597f0617d2927c
|
|
| MD5 |
62b2cfa9a0ba5c2cf9f47f97933d4b51
|
|
| BLAKE2b-256 |
7576ac9e9db6b138d80a5654af38d6ef39fc93c4113bbb5a786ce252ae21532c
|