# RelayRL Framework Version Comparison
## v0.4.52 → v0.5.0-alpha
This document provides a comprehensive comparison between `relayrl_framework` v0.4.52 (prototype) and v0.5.0-alpha (rewrite), analyzing architecture changes, API differences, dependency updates, and breaking changes.
---
## Executive Summary
Version 0.5.0-alpha represents a **complete rewrite** of the RelayRL framework, transforming it from a Python-centric prototype into a Rust-first, multi-actor native reinforcement learning framework.
| **Design Philosophy** | Python-first with Rust backend | Rust-first, language-agnostic |
| **Agent Model** | Single-agent focused | Multi-actor native |
| **Tensor Backend** | TorchScript (`tch`) only | Backend-agnostic (`burn-tensor`) |
| **Transport** | gRPC + ZMQ | ZMQ only (gRPC removed) |
| **Python Bindings** | Embedded (PyO3) | Separated crate (`relayrl_python`) |
| **Type System** | Internal modules | External crate (`relayrl_types`) |
| **Configuration** | Single unified config | Separated client/server configs |
| **Error Handling** | Panics & unwraps | Proper error types with propagation |
---
## 1. Package Metadata Changes
### Cargo.toml Comparison
| **Version** | `0.4.52` | `0.5.0-alpha` |
| **Description** | "A system-oriented, distributed reinforcement learning framework using a Rust backend with Python interfaces" | "A distributed, system-oriented multi-agent reinforcement learning framework" |
| **Keywords** | `reinforcement`, `learning`, `rl`, `distributed`, `system-integration` | `machine-learning`, `multi-agent`, `framework`, `client-server`, `system-integration` |
| **Crate Type** | `["rlib", "cdylib"]` | `["rlib"]` |
| **Repository** | Included | Removed |
| **Documentation** | `docs.rs` link | Removed |
### Key Changes:
- Removed `cdylib` crate type (no longer building Python extension module)
- Updated description to emphasize "multi-agent" over "Python interfaces"
- Simplified metadata by removing repository and documentation links
---
## 2. Dependency Changes
### Removed Dependencies
| `tch` | 0.18.1 | PyTorch/TorchScript tensor operations |
| `tonic` | 0.12.3 | gRPC client/server |
| `tonic-build` | 0.12.3 | Protobuf compilation |
| `prost` | 0.13.5 | Protobuf serialization |
| `pyo3` | 0.24.2 | Python bindings |
| `pyo3-build-config` | 0.24.2 | Python build configuration |
| `safetensors` | 0.5.3 | Tensor serialization |
### Added Dependencies
| `relayrl_types` | 0.3.21 | External type definitions |
| `active-uuid-registry` | 0.3.0 | UUID pool management |
| `burn-tensor` | 0.18.0 | Backend-agnostic tensor operations |
| `arrow` | 57.1.0 | Trajectory data serialization |
| `arrow-schema` | 57.1.0 | Arrow schema definitions |
| `arrow-array` | 57.1.0 | Arrow array types |
| `dashmap` | 6.1.0 | Concurrent hash maps |
| `thiserror` | 2.0.17 | Error derive macros |
| `async-trait` | 0.1.89 | Async trait support |
| `uuid` | 1.18.1 | UUID generation |
| `log` | 0.4.28 | Logging facade |
| `bincode` | 2.0.1 | Binary serialization |
### Updated Dependencies
| `tokio` | 1.44.2 | 1.48.0 |
| `serde` | 1.0.215 | 1.0.195 |
| `rand` | 0.8.5 | 0.9.2 |
| `once_cell` | 1.20.2 | 1.19.0 |
| `tempfile` | 3.17.1 | 3.9.0 |
| `serde_json` | 1.0.133 | 1.0.111 |
| `serde-pickle` | 1.2.0 | 1.1.1 |
| `bytemuck` | 1.20.0 | 1.14.1 |
### Optional Dependencies (New)
| `postgres` | `postgres_db` | PostgreSQL database support |
| `sqlite` | `sqlite_db` | SQLite database support |
| `prometheus` | `metrics` | Prometheus metrics export |
| `opentelemetry` | `metrics` | OpenTelemetry integration |
| `opentelemetry_sdk` | `metrics` | OpenTelemetry SDK |
| `opentelemetry-otlp` | `metrics` | OTLP exporter |
| `log4rs` | `logging` | Logging implementation |
---
## 3. Feature Flag Reorganization
### v0.4.52 Feature Flags
```toml
[features]
default = ["full"]
full = ["networks", "data_types", "python_bindings"]
networks = ["grpc_network", "zmq_network"]
grpc_network = ["tonic", "prost", "tonic-build", "pyo3", "data_types"]
zmq_network = ["zmq", "pyo3", "data_types"]
data_types = []
python_ipc_channel = ["pyo3"]
python_bindings = ["networks"]
profile = ["flamegraph", "console-subscriber"]
```
### v0.5.0-alpha Feature Flags
```toml
[features]
default = ["client"]
network = ["client", "inference_server", "training_server"]
client = []
inference_server = ["transport_layer"]
training_server = ["transport_layer"]
transport_layer = ["async_transport", "sync_transport"]
async_transport = []
sync_transport = ["zmq_transport"]
zmq_transport = ["zmq"]
database_layer = ["postgres_db", "sqlite_db"]
postgres_db = ["postgres"]
sqlite_db = ["sqlite"]
logging = ["log4rs"]
metrics = ["prometheus", "opentelemetry", "opentelemetry_sdk", "opentelemetry-otlp"]
profile = ["flamegraph", "console-subscriber"]
```
### Key Feature Changes:
1. **Default changed**: `full` → `client`
2. **gRPC removed**: No more `grpc_network` feature
3. **Python removed**: No more `python_bindings`, `python_ipc_channel`
4. **New server features**: `inference_server`, `training_server`
5. **New data layers**: `database_layer` with PostgreSQL/SQLite
6. **New observability**: `logging`, `metrics` features
---
## 4. Architecture Changes
### v0.4.52 Architecture
```
┌─────────────────────────────────────────────────┐
│ Python Bindings (PyO3) │
│ - PyRelayRLAgent, PyTrainingServer │
│ - PyConfigLoader, PyRelayRLAction │
└─────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────┐
│ Network Layer │
│ - agent_wrapper.rs (unified agent interface) │
│ - agent_grpc.rs / agent_zmq.rs │
│ - training_server_wrapper.rs │
│ - training_grpc.rs / training_zmq.rs │
└─────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────┐
│ Core Types & Utilities │
│ - types/action.rs, types/trajectory.rs │
│ - sys_utils/config_loader.rs │
│ - Python subprocess management │
└─────────────────────────────────────────────────┘
```
### v0.5.0-alpha Architecture
```
┌─────────────────────────────────────────────────┐
│ Public API (RelayRLAgent, AgentBuilder) │
│ - network/client/agent.rs │
└─────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────┐
│ Runtime Coordination Layer │
│ - ClientCoordinator │
│ - ScaleManager (router scaling) │
│ - StateManager (actor state) │
│ - LifecycleManager (shutdown coordination) │
└─────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────┐
│ Message Routing Layer │
│ - RouterDispatcher │
│ - Router instances (scalable workers) │
│ - TrajectoryBuffer (priority scheduling) │
└─────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────┐
│ Actor Execution Layer │
│ - Concurrent Actor instances │
│ - Local model inference │
│ - Trajectory building │
└─────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────┐
│ Data Collection Layer │
│ - Arrow File Sink (available) │
│ - Transport Sink (under development) │
│ - Database Sink (under development) │
└─────────────────────────────────────────────────┘
```
---
## 5. Module Structure Comparison
### v0.4.52 Directory Structure
```
src/
├── lib.rs # PyO3 module definition
├── default_config.json
├── bindings/
│ └── python/
│ ├── network/
│ │ ├── client/o3_agent.rs
│ │ └── server/o3_training_server.rs
│ ├── o3_action.rs
│ ├── o3_config_loader.rs
│ └── o3_trajectory.rs
├── native/
│ └── python/ # Python algorithm implementations
│ ├── algorithms/
│ │ └── REINFORCE/
│ └── _common/_algorithms/
├── network/
│ ├── mod.rs
│ ├── client/
│ │ ├── agent_wrapper.rs
│ │ ├── agent_grpc.rs
│ │ └── agent_zmq.rs
│ └── server/
│ ├── training_server_wrapper.rs
│ ├── training_grpc.rs
│ ├── training_zmq.rs
│ └── python_subprocesses/
├── sys_utils/
│ ├── config_loader.rs
│ ├── grpc_utils.rs
│ ├── misc_utils.rs
│ ├── resolve_server_config.rs
│ └── tokio_utils.rs
└── types/
├── action.rs
└── trajectory.rs
```
### v0.5.0-alpha Directory Structure
```
src/
├── lib.rs # Prelude and module exports
├── network/
│ ├── mod.rs # TransportType, HyperparameterArgs
│ ├── client/
│ │ ├── mod.rs
│ │ ├── agent.rs # Public API: RelayRLAgent, AgentBuilder
│ │ └── runtime/
│ │ ├── actor.rs
│ │ ├── router_dispatcher.rs
│ │ ├── coordination/
│ │ │ ├── coordinator.rs
│ │ │ ├── lifecycle_manager.rs
│ │ │ ├── scale_manager.rs
│ │ │ └── state_manager.rs
│ │ ├── router/
│ │ │ ├── buffer.rs
│ │ │ ├── filter.rs
│ │ │ └── receiver.rs
│ │ └── data/
│ │ ├── database/
│ │ │ ├── postgres.rs
│ │ │ └── sqlite.rs
│ │ └── transport/
│ │ └── zmq.rs
│ └── server/
│ ├── mod.rs
│ ├── inference_server.rs # Skeleton
│ ├── training_server.rs # Skeleton
│ └── runtime/coordination/
├── templates/
│ └── mod.rs # Environment traits
└── utilities/
├── configuration.rs # Client/Server config loaders
├── observability/
│ ├── logging/
│ │ ├── builder.rs
│ │ ├── filters.rs
│ │ └── sinks/
│ └── metrics/
│ ├── manager.rs
│ └── export/
│ ├── prometheus.rs
│ └── open_telemetry.rs
└── tokio/
```
---
## 6. API Changes
### Agent Construction
**v0.4.52:**
```rust
use relayrl_framework::network::client::agent_wrapper::RelayRLAgent;
use tch::CModule;
let agent = RelayRLAgent::new(
model: Option<CModule>,
config_path: Option<PathBuf>,
server_type: Option<String>, // "grpc" or "zmq"
training_prefix: Option<String>,
training_port: Option<String>,
training_host: Option<String>,
).await;
```
**v0.5.0-alpha:**
```rust
use relayrl_framework::prelude::network::*;
use burn_ndarray::NdArray;
use burn_tensor::Float;
let (agent, params) = AgentBuilder::<NdArray, D_IN, D_OUT, Float, Float>::builder()
.actor_count(4)
.router_scale(2)
.default_device(DeviceType::Cpu)
.default_model(model)
.config_path(PathBuf::from("client_config.json"))
.trajectory_persistence_mode(TrajectoryPersistenceMode::Local(Some(params)))
.build()
.await?;
agent.start(
params.actor_count,
params.router_scale,
params.default_device,
params.default_model,
params.config_path,
).await?;
```
### Agent Interaction
**v0.4.52:**
```rust
// Single action request via internal ZMQ/gRPC transport
let action = agent.request_for_action(obs_tensor, mask_tensor, reward).await;
```
**v0.5.0-alpha:**
```rust
// Multi-actor action request
let actor_ids = agent.get_actor_ids()?;
let actions: Vec<(Uuid, Arc<RelayRLAction>)> = agent
.request_action(actor_ids, observation, mask, reward)
.await?;
// Flag last action as terminal
agent.flag_last_action(actor_ids, Some(final_reward)).await?;
// Get model versions per actor
let versions = agent.get_model_version(actor_ids).await?;
```
### Actor Management (New in v0.5.0-alpha)
```rust
// Create new actors
agent.new_actor(DeviceType::Cpu, Some(model)).await?;
agent.new_actors(10, DeviceType::Mps, None).await?;
// Remove actors
agent.remove_actor(actor_id).await?;
// Modify actor IDs
agent.set_actor_id(current_id, new_id).await?;
// Scale throughput (router workers)
agent.scale_throughput(2).await?; // Add 2 routers
agent.scale_throughput(-1).await?; // Remove 1 router
```
### Lifecycle Management
**v0.4.52:**
```rust
agent.restart_agent(training_server_address).await;
agent.enable_agent(training_server_address).await;
agent.disable_agent().await;
```
**v0.5.0-alpha:**
```rust
agent.restart(/* params */).await?;
agent.shutdown().await?;
```
---
## 7. Configuration System Changes
### v0.4.52 Configuration
Single `ConfigLoader` class with unified `relayrl_config.json`:
```rust
pub struct ConfigLoader {
pub algorithm_params: Option<LoadedAlgorithmParams>,
pub train_server: ServerParams,
pub traj_server: ServerParams,
pub agent_listener: ServerParams,
pub tb_params: TensorboardParams,
pub client_model_path: PathBuf,
pub server_model_path: PathBuf,
pub max_traj_length: u32,
pub grpc_idle_timeout: u32,
}
```
### v0.5.0-alpha Configuration
Separated configuration with builders:
```rust
// Client Configuration
pub struct ClientConfigLoader {
pub client_config: ClientConfigParams,
pub transport_config: TransportConfigParams,
}
pub struct ClientConfigParams {
pub algorithm_name: String,
pub config_path: PathBuf,
pub config_update_polling_seconds: f32,
pub init_hyperparameters: HyperparameterConfig,
pub trajectory_file_output: TrajectoryFileParams,
}
// Server Configuration
pub struct ServerConfigLoader {
pub server_config: ServerConfigParams,
pub transport_config: TransportConfigParams,
}
// Transport Configuration
pub struct TransportConfigParams {
pub inference_server_address: NetworkParams,
pub agent_listener_address: NetworkParams,
pub model_server_address: NetworkParams,
pub trajectory_server_address: NetworkParams,
pub scaling_server_address: NetworkParams,
pub max_traj_length: u128,
pub local_model_module: LocalModelModuleParams,
}
```
### Configuration File Format
**v0.4.52 (`relayrl_config.json`):**
```json
{
"algorithms": {
"REINFORCE": { /* params */ }
},
"grpc_idle_timeout": 30,
"max_traj_length": 1000,
"model_paths": {
"client_model": "client_model.pt",
"server_model": "server_model.pt"
},
"server": {
"training_server": { "prefix": "tcp://", "host": "127.0.0.1", "port": "50051" },
"trajectory_server": { /* ... */ },
"agent_listener": { /* ... */ }
},
"tensorboard": { /* ... */ }
}
```
**v0.5.0-alpha (`client_config.json`):**
```json
{
"client_config": {
"algorithm_name": "REINFORCE",
"config_update_polling_seconds": 10.0,
"init_hyperparameters": {
"DDPG": { /* params */ },
"PPO": { /* params */ },
"REINFORCE": { /* params */ },
"TD3": { /* params */ }
},
"trajectory_file_output": {
"enabled": true,
"encode": true,
"output": { "directory": "data", "file_name": "action_data", "format": "json" }
}
},
"transport_config": {
"addresses": {
"model_server": { /* ... */ },
"trajectory_server": { /* ... */ },
"agent_listener": { /* ... */ },
"scaling_server": { /* ... */ },
"inference_server": { /* ... */ }
},
"local_model_module": { /* ... */ },
"max_traj_length": 1000
}
}
```
### Algorithm Support Expansion
| REINFORCE | ✓ | ✓ |
| PPO | - | ✓ |
| DDPG | - | ✓ |
| TD3 | - | ✓ |
| CUSTOM | - | ✓ |
---
## 8. Type System Changes
### Relocation to External Crate
The following types moved from internal `types/` module to `relayrl_types` crate:
| `RelayRLAction` | `types/action.rs` | `relayrl_types::types::data::action` |
| `TensorData` | `types/action.rs` | `relayrl_types::types::data::tensor` |
| `RelayRLData` | `types/action.rs` | `relayrl_types::types::data::action` |
| `RelayRLTrajectory` | `types/trajectory.rs` | `relayrl_types::types::data::trajectory` |
### New Types in v0.5.0-alpha
```rust
// Backend-agnostic tensor types
pub enum AnyBurnTensor<B: Backend, const D: usize> {
Float(FloatBurnTensor<B, D>),
Int(IntBurnTensor<B, D>),
Bool(BoolBurnTensor<B, D>),
}
// Model module wrapper
pub struct ModelModule<B: Backend> {
pub model: /* backend-specific model */,
pub metadata: ModelMetadata,
}
// Device type enum
pub enum DeviceType {
Cpu,
Cuda(usize),
Mps,
}
// Codec configuration
pub struct CodecConfig {
pub compression: CompressionType,
pub format: SerializationFormat,
}
```
---
## 9. Error Handling Improvements
### v0.4.52 Error Handling
Heavy reliance on panics and unwraps:
```rust
// Example from agent_wrapper.rs
let input_dim: IValue = model
.method_is::<IValue>("get_input_dim", &[])
.expect("Failed to get input dimension");
// Example from config_loader.rs
config_path.expect("[ConfigLoader - new] Invalid config path")
```
### v0.5.0-alpha Error Handling
Comprehensive error types with `thiserror`:
```rust
#[derive(Debug, Error)]
pub enum ClientError {
#[error(transparent)]
UuidPoolError(#[from] UuidPoolError),
#[error("Inference server mode disabled: {0}")]
InferenceServerModeDisabled(String),
#[error(transparent)]
CoordinatorError(#[from] CoordinatorError),
#[error("Backend mismatch: {0}")]
BackendMismatchError(String),
// ... more variants
}
#[derive(Debug, Error)]
pub enum CoordinatorError {
#[error("Client modes are invalid: {0}")]
InvalidClientModesError(String),
#[error(transparent)]
TransportError(#[from] TransportError),
#[error(transparent)]
ScaleManagerError(#[from] ScaleManagerError),
#[error(transparent)]
StateManagerError(#[from] StateManagerError),
#[error(transparent)]
LifeCycleManagerError(#[from] LifeCycleManagerError),
// ... more variants
}
```
---
## 10. Observability (New in v0.5.0-alpha)
### Logging System
```rust
// New logging infrastructure
pub struct LoggingBuilder {
// Configurable logging with multiple sinks
}
// Sinks available:
// - Console sink (utilities/observability/logging/sinks/console.rs)
// - File sink (utilities/observability/logging/sinks/file.rs)
// Filters available:
// - Level filters
// - Module filters
```
### Metrics System
```rust
// New metrics infrastructure
pub struct MetricsManager {
// Unified metrics collection and export
}
// Export options:
// - Prometheus (utilities/observability/metrics/export/prometheus.rs)
// - OpenTelemetry (utilities/observability/metrics/export/open_telemetry.rs)
// Usage in coordinator:
#[cfg(feature = "metrics")]
params.metrics.record_counter("actors_created", 1, &[]);
#[cfg(feature = "metrics")]
params.metrics.record_histogram("action_request_latency", duration, &[]);
```
---
## 11. Breaking Changes Summary
### Removed Functionality
1. **Python Bindings**: All PyO3 code removed from core framework
- `PyRelayRLAgent`, `PyTrainingServer`, `PyConfigLoader`, etc.
- Moved to separate `relayrl_python` crate (not yet implemented)
2. **gRPC Transport**: All Tonic/Protobuf code removed
- `agent_grpc.rs`, `training_grpc.rs`
- `grpc_utils.rs`
- `proto/relayrl_grpc.proto`
3. **Python Algorithm Runtime**: Python subprocess management removed
- `python_subprocesses/` directory
- `native/python/` algorithm implementations
4. **TorchScript Direct Support**: `tch` crate dependency removed
- Direct `CModule` usage no longer supported
- Replaced with `ModelModule<B>` abstraction
### API Breaking Changes
1. **Agent Construction**: `RelayRLAgent::new()` → `AgentBuilder::builder().build()`
2. **Type Parameters**: Agent now requires generic type parameters
```rust
RelayRLAgent
RelayRLAgent<B, D_IN, D_OUT, KindIn, KindOut>
```
3. **Action Request**: Returns `Vec<(Uuid, Arc<RelayRLAction>)>` instead of single action
4. **Configuration**: `ConfigLoader` → `ClientConfigLoader` / `ServerConfigLoader`
5. **Config File**: `relayrl_config.json` → `client_config.json` / `server_config.json`
### Migration Requirements
| Update imports | Change from `tch` to `burn_tensor` types |
| Rewrite agent init | Use `AgentBuilder` pattern |
| Update config files | Migrate to new JSON structure |
| Handle multi-actor | Update code to handle multiple actor IDs |
| Error handling | Handle `Result` returns instead of expecting success |
---
## 12. Files Comparison Table
| **Package Config** | `Cargo.toml` | `Cargo.toml` | Restructured |
| **Library Root** | `src/lib.rs` | `src/lib.rs` | Completely rewritten |
| **Agent API** | `network/client/agent_wrapper.rs` | `network/client/agent.rs` | Completely rewritten |
| **gRPC Agent** | `network/client/agent_grpc.rs` | - | Removed |
| **ZMQ Agent** | `network/client/agent_zmq.rs` | `network/client/runtime/data/transport/zmq.rs` | Redesigned |
| **Training Server** | `network/server/training_server_wrapper.rs` | `network/server/training_server.rs` | Skeleton only |
| **gRPC Server** | `network/server/training_grpc.rs` | - | Removed |
| **ZMQ Server** | `network/server/training_zmq.rs` | `network/server/runtime/transport/zmq.rs` | Skeleton only |
| **Configuration** | `sys_utils/config_loader.rs` | `utilities/configuration.rs` | Expanded (3x larger) |
| **Action Types** | `types/action.rs` | `relayrl_types` crate | Moved externally |
| **Trajectory Types** | `types/trajectory.rs` | `relayrl_types` crate | Moved externally |
| **gRPC Utils** | `sys_utils/grpc_utils.rs` | - | Removed |
| **Protobuf** | `proto/relayrl_grpc.proto` | - | Removed |
| **Python Bindings** | `bindings/python/*` | `relayrl_python` crate | Moved externally |
| **Python Algorithms** | `native/python/*` | `relayrl_algorithms` crate | Moved externally |
| **Coordinator** | - | `network/client/runtime/coordination/coordinator.rs` | New |
| **Scale Manager** | - | `network/client/runtime/coordination/scale_manager.rs` | New |
| **State Manager** | - | `network/client/runtime/coordination/state_manager.rs` | New |
| **Lifecycle Manager** | - | `network/client/runtime/coordination/lifecycle_manager.rs` | New |
| **Router** | - | `network/client/runtime/router/*.rs` | New |
| **Actor** | - | `network/client/runtime/actor.rs` | New |
| **Logging** | - | `utilities/observability/logging/*` | New |
| **Metrics** | - | `utilities/observability/metrics/*` | New |
| **Templates** | - | `templates/mod.rs` | New |
---
## 13. Development Status
### v0.5.0-alpha Completion Status
| **Client Runtime** | ✓ Available | Multi-actor native, fully functional |
| **Agent API** | ✓ Available | Builder pattern, comprehensive |
| **Local File Sink** | ✓ Available | Arrow format trajectory storage |
| **Configuration** | ✓ Available | Separated client/server configs |
| **Observability** | ✓ Available | Logging + metrics infrastructure |
| **ZMQ Transport** | ⚠ Under Development | Client-side partially implemented |
| **Database Layer** | ⚠ Under Development | PostgreSQL/SQLite interfaces |
| **Training Server** | ⚠ Skeleton Only | Runtime not implemented |
| **Inference Server** | ⚠ Skeleton Only | Runtime not implemented |
| **Python Bindings** | ✗ Not Available | Moved to separate crate |
| **Algorithms** | ✗ Not Available | Moved to separate crate |
### Roadmap to v1.0.0
- **v0.5.0**: Complete ZMQ transport and database interfaces
- **v0.6.0**: Training server implementation
- **v0.7.0**: Inference server implementation
- **v0.8.0**: Full integration and optimization
- **v0.9.0/v1.0.0**: API stabilization
---
## 14. Recommendations for Migration
### For Rust Users
1. **Update Dependencies**: Add `relayrl_types` to your `Cargo.toml`
2. **Choose Backend**: Select `NdArray` (CPU) or `Tch` (CPU/CUDA/MPS)
3. **Use Builder Pattern**: Migrate agent creation to `AgentBuilder`
4. **Handle Multi-Actor**: Update loops to iterate over actor IDs
5. **Migrate Config**: Create new `client_config.json` file
### For Python Users
The v0.5.0-alpha release does not include Python bindings. Options:
1. **Wait for `relayrl_python`**: Future crate will provide bindings
2. **Use v0.4.52**: Continue with prototype for Python workflows
3. **Use CLI (Future)**: `relayrl_cli` will enable language-agnostic usage
---
*Document generated for RelayRL Framework comparison between v0.4.52 and v0.5.0-alpha*