┌─────────────────────────────────────────────────────────────────────────┐
│ Phase 1: SELECTION │
│ ───────────────── │
│ SelectorAgent analyzes your code and chooses the best strategy │
│ (skipped if you specify a strategy explicitly) │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Phase 2: ADAPTATION │
│ ─────────────────── │
│ AdapterAgent transforms your code for the target platform: │
│ - Creates deployment files (Dockerfile, modal_app.py, etc.) │
│ - Adds entry point (main.py with predict() function) │
│ - Runs the deployment command │
│ - Reports the endpoint URL │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Phase 3: RUNNER CREATION │
│ ──────────────────────── │
│ Factory creates the appropriate Runner for the strategy: │
│ - LocalRunner: imports and calls Python functions │
│ - ModalRunner: calls Modal remote functions │
│ - DockerRunner: makes HTTP requests to container │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Phase 4: SOFTWARE WRAPPER │
│ ───────────────────────── │
│ DeployedSoftware wraps the runner with unified interface: │
│ - Normalizes all responses to {"status": "...", "output": ...} │
│ - Provides run(), stop(), logs(), is_healthy() │
│ - Hides all infrastructure complexity from users │
└─────────────────────────────────────────────────────────────────────────┘