Skip to content

Latest commit

 

History

History
166 lines (126 loc) · 4.75 KB

File metadata and controls

166 lines (126 loc) · 4.75 KB

CUA Snapshot System

Overview

The CUA Snapshot System enables creating, managing, and restoring filesystem snapshots of Docker containers during agent execution by extending the Docker provider.

Architecture Diagram

flowchart TD
    A[Agent / ComputerAgent] --> B[SnapshotManagerCallback]

    B --> C{Trigger}
    C -->|manual| D[create_manual_snapshot]
    C -->|run_start / run_end / every_action| E[auto snapshot]

    D --> F[SnapshotCreator]
    E --> F
    F --> G[ProviderAdapter]
    G --> H{{Docker}}
    H --> I[docker commit to image]
    I --> J[Write metadata: labels and files]
    J --> K[RetentionEnforcer]
    K -->|count/age| L[delete old snapshots]

    B --> M[restore snapshot by id]
    M --> G
    G --> N[restore via provider]
    N --> O[Container filesystem replaced]
    O --> P[Container restarted]
    P --> Q[Agent continues from restored state]

    classDef comp fill:#eaf7ff,stroke:#2b90d9,color:#0b3d62;
    class A,B,D,E,F,G,M comp;
Loading

Core Functionality

Snapshot Operations

  • Create: Capture current container state as a Docker image
  • Restore: Roll back container to a previous snapshot state
  • List: View all available snapshots with metadata
  • Delete: Remove snapshots to free storage space

Scheduling Options

  • manual: Create snapshots only when explicitly requested
  • every_action: Snapshot after each computer action (debugging)
  • run_start: Snapshot at the beginning of each agent run
  • run_end: Snapshot at the end of each agent run
  • run_boundaries: Snapshot at both start and end (recommended)

Retention Management

  • Count-based: Keep only the N most recent snapshots
  • Age-based: Delete snapshots older than specified days
  • Automatic cleanup: Configurable background cleanup

Basic Usage

from computer import Computer
from agent import ComputerAgent
from libs.python.agent.agent.callbacks.snapshot_manager import SnapshotManagerCallback  # TODO This will eventually be a part of the pip package

# Setup computer with Docker provider
computer = Computer(
    os_type="linux",
    provider_type="docker", 
    image="trycua/cua-ubuntu:latest",
    name='my-container'
)

# Configure snapshot callback
snapshot_callback = SnapshotManagerCallback(
    computer=computer,
    snapshot_interval="run_boundaries",  # When to create snapshots
    max_snapshots=10,                    # Keep latest 10 snapshots
    retention_days=7,                    # Delete snapshots older than 7 days
    auto_cleanup=True                    # Enable automatic cleanup
)

# Create agent with snapshot support
agent = ComputerAgent(
    model="claude-3-5-sonnet-20241022",
    callbacks=[snapshot_callback]
)

Manual Operations

# Create manual snapshot
result = await snapshot_callback.create_manual_snapshot("before-risky-operation")

# List all snapshots  
snapshots = await snapshot_callback.list_snapshots()

# Restore to specific snapshot
restore_result = await snapshot_callback.restore_snapshot(snapshot_id)

# Delete snapshot
delete_result = await snapshot_callback.delete_snapshot(snapshot_id)

Configuration

Parameter Default Description
snapshot_interval "manual" When to create snapshots automatically
max_snapshots 10 Maximum snapshots to retain
retention_days 7 Delete snapshots older than N days
auto_cleanup True Enable automatic cleanup
metadata_dir "/tmp/cua_snapshots" Metadata storage location

Implementation Details

Docker Integration

Snapshots are implemented using Docker's native docker commit functionality:

  • Container state is captured as a Docker image
  • Metadata stored as image labels (prefixed with cua.snapshot.)
  • Container configuration (memory, CPU, ports) preserved during restore
  • Unique snapshot IDs generated with timestamps

Provider Interface

VM providers must implement these methods:

async def create_snapshot(name: str, snapshot_name: str = None, metadata: dict = None) -> dict
async def restore_snapshot(name: str, snapshot_id: str) -> dict  
async def list_snapshots(name: str) -> List[dict]
async def delete_snapshot(snapshot_id: str) -> dict

Error Handling

All operations return status information:

# Success response
{
    "id": "uuid-v4-string",
    "status": "created", 
    "timestamp": "2024-01-01T12:00:00",
    "size": "150MB"
}

# Error response  
{
    "status": "error",
    "error": "Detailed error message"
}

Best Practices

  1. Use run_boundaries interval for most cases
  2. Set reasonable retention limits to manage storage
  3. Include descriptive metadata for easier identification
  4. Test restore procedures regularly
  5. Monitor disk space usage
  6. Handle operation errors gracefully