Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
09ab3e1
feat: add download acceleration infrastructure
deanq Aug 16, 2025
795c9e5
feat: integrate download acceleration with dependency installer
deanq Aug 16, 2025
046eb58
feat: add workspace acceleration support
deanq Aug 16, 2025
45a65fe
test: add download acceleration test coverage
deanq Aug 16, 2025
ce51390
chore: moved test-handler files to src/
deanq Aug 16, 2025
6c04de1
feat: runtime uses aria2 for accelerated parallel downloads
deanq Aug 16, 2025
66eb286
chore: update project structure and dependencies
deanq Aug 16, 2025
1930b4b
chore: updated tetra-rp
deanq Aug 19, 2025
731fd56
build: local-execution-test use make test-handler
deanq Aug 19, 2025
e829140
chore: update CLAUDE.md
deanq Aug 19, 2025
104b2da
chore: move these values to constants.py for maintainability
deanq Aug 19, 2025
f8aa89a
feat: add system package acceleration with nala
deanq Aug 19, 2025
cd56185
refactor: disable Python package download acceleration
deanq Aug 20, 2025
d7c996d
test: uv is no longer part of download accelerator
deanq Aug 20, 2025
2ab93e3
feat: implement accelerate_downloads parameter logic in RemoteExecutor
deanq Aug 21, 2025
b50a7bf
feat: add pip fallback for Python dependencies when acceleration disa…
deanq Aug 21, 2025
440d00d
feat: enhance HF model caching with hf_transfer/hf_xet strategy
deanq Aug 21, 2025
0320e4d
test: add comprehensive coverage for accelerate_downloads parameter
deanq Aug 21, 2025
034f770
test: update integration tests for new acceleration parameter
deanq Aug 21, 2025
9531079
chore: update dependencies and constants for download acceleration
deanq Aug 21, 2025
d75d320
refactor: remove pip installation method from dependency installer
deanq Aug 21, 2025
227b33e
test: update unit tests to expect UV instead of pip
deanq Aug 21, 2025
338a165
test: rename test file from pip to UV naming convention
deanq Aug 21, 2025
f88745d
feat: implement parallel execution for accelerated downloads
deanq Aug 21, 2025
f22e74d
feat: add async wrapper for HuggingFace model download acceleration
deanq Aug 21, 2025
816fc75
test: update tests for parallel execution and async dependencies
deanq Aug 21, 2025
c9ad0d3
test: comprehensive test coverage expansion and cleanup
deanq Aug 21, 2025
e31137a
refactor: optimize HF acceleration to use native Hub features
deanq Aug 21, 2025
e1db417
chore: memory correction
deanq Aug 21, 2025
76ab9c0
feat: implement HuggingFace download acceleration strategies
deanq Aug 21, 2025
c269bcd
feat: implement centralized log streaming system
deanq Aug 21, 2025
04e5b54
chore: these logs are for debug level
deanq Aug 21, 2025
f1db33a
chore: specs for Endpoint Persistence using Network Volume and CDR
deanq Aug 22, 2025
bb27ae3
chore: local setup
deanq Aug 22, 2025
f232a9c
Merge branch 'main' into deanq/ae-962-log-streaming
deanq Aug 29, 2025
83b3293
fix: merge conflicts
deanq Aug 29, 2025
f9a068c
chore: make update
deanq Aug 29, 2025
692d8fc
chore: these are debug lines
deanq Aug 29, 2025
ce2deae
chore: nala logs were too noisy
deanq Aug 29, 2025
90e3b9a
chore: updated tetra-rp
deanq Aug 29, 2025
a2f67d3
Merge branch 'deanq/ae-962-log-streaming' into deanq/ae-1092-tetra-vo…
deanq Aug 29, 2025
e578007
fix: duplicated lines due to bad merge conflict resolution
deanq Aug 29, 2025
7e7201e
Merge branch 'main' into deanq/ae-962-log-streaming
deanq Sep 14, 2025
8091476
chore: update uv.lock
deanq Sep 14, 2025
8c8f902
fix: test-handler was not exactly testing properly
deanq Sep 15, 2025
47699d2
Merge branch 'deanq/ae-962-log-streaming' into deanq/ae-1165-bug-pyto…
deanq Sep 17, 2025
c6ac06d
chore: use GPU build for smoke tests
deanq Sep 17, 2025
cc92323
fix: multi-stage build loses crucial built-in system Python
deanq Sep 17, 2025
83787e7
chore: updated to latest submodule state
deanq Sep 17, 2025
b99af9d
fix: local/macos testing fails due to lack of apt-get or nala
deanq Sep 17, 2025
736c2eb
test: tests to confirm system Python access
deanq Sep 17, 2025
0785310
refactor: install_dependencies relies on uv and pip provisions
deanq Sep 17, 2025
16f7a1b
chore: better debug logs for dependency_installer
deanq Sep 17, 2025
ee6595e
feat: implement universal subprocess utility with automatic logging
deanq Sep 17, 2025
8c259c2
fix: use Docker detection for dependency installation method
deanq Sep 18, 2025
fcd51bd
docs: update CLAUDE.md with universal subprocess utility documentation
deanq Sep 18, 2025
b980e51
chore: vscode config to point to src
deanq Sep 18, 2025
0bda8a1
chore: no need for a NALA_CHECK_CMD constant
deanq Sep 18, 2025
177c3d2
build: update submodule
deanq Sep 18, 2025
d365f2a
chore: logs namespace is now just `tetra`
deanq Sep 18, 2025
8b2cf5f
Merge branch 'deanq/ae-962-log-streaming' into deanq/ae-1165-bug-pyto…
deanq Sep 18, 2025
b95451d
docs: System Python Runtime Architecture
deanq Sep 18, 2025
011890a
docs: Centralized Log Streaming System
deanq Sep 18, 2025
d1a6fa2
Merge branch 'main' into deanq/ae-1092-tetra-volume-warm-cache
deanq Sep 18, 2025
22d80cf
chore: update submodule
deanq Sep 18, 2025
55eac77
Merge branch 'deanq/ae-962-log-streaming' into deanq/ae-1092-tetra-vo…
deanq Sep 18, 2025
a277bc0
Merge branch 'deanq/ae-1165-bug-pytorchs-not-found' into deanq/ae-109…
deanq Sep 18, 2025
f11b4dc
chore: update and cleanup
deanq Sep 22, 2025
e2fe764
fix: docker uses system's conda python; local uses uv
deanq Sep 22, 2025
c1c95c8
refactor: configurable `NAMESPACE` for logs; default: tetra
deanq Sep 22, 2025
df70047
refactor: no longer need to setup python paths in workspace
deanq Sep 22, 2025
d1a832c
Merge branch 'deanq/ae-1165-bug-pytorchs-not-found' into deanq/ae-109…
deanq Sep 22, 2025
9ddb6d8
refactor: reorganize test_*.json files into src/tests/ directory
deanq Sep 23, 2025
d4e1366
Merge branch 'main' into deanq/ae-1092-tetra-volume-warm-cache
deanq Sep 26, 2025
0a61a98
fix: incorrect merge
deanq Sep 26, 2025
90ebc63
chore: update version from release
deanq Sep 26, 2025
91d621b
chore: these tests were moved to src/tests/
deanq Sep 26, 2025
1c4b046
Merge branch 'deanq/ae-1092-tetra-volume-warm-cache' of https://githu…
deanq Sep 27, 2025
19498ff
build: consolidated local-execution-test and docker-pr into docker-test
deanq Sep 28, 2025
b0b3ec7
build: make sure all of src/ is copied
deanq Sep 28, 2025
168e4ef
refactor: removed the use of network volume as runtime workspaces
deanq Sep 30, 2025
54fe320
refactor: remove workspace_manager dependency from all modules
deanq Sep 30, 2025
a01ae7e
refactor: huggingface_accelerator -> huggingface_cache
deanq Oct 1, 2025
e95afb5
refactor: completely removed workspace manager
deanq Oct 1, 2025
7a4093d
docs: updated docs with the latest refactors
deanq Oct 1, 2025
7880b2b
fix: set non-error debug log when cached for the first time
deanq Oct 1, 2025
4132da8
fix: catch CacheNotFound instead
deanq Oct 1, 2025
7d9e82a
refactor: remove log acceleration summary
deanq Oct 1, 2025
6a5d87d
fix: deleted duplicate code block
deanq Oct 6, 2025
c191b02
chore: simplified happy path return
deanq Oct 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 20 additions & 63 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,26 @@ jobs:
- name: Check code style with ruff
run: make lint

local-execution-test:
docker-test:
runs-on: ubuntu-latest
needs: [test, lint]
strategy:
matrix:
image-type: [cpu]
steps:
- name: Clear Space
if: github.event_name == 'pull_request'
run: |
rm -rf /usr/share/dotnet
rm -rf /opt/ghc
rm -rf "/usr/local/share/boost"
rm -rf "$AGENT_TOOLSDIRECTORY"

- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
Expand All @@ -102,28 +111,27 @@ jobs:
git submodule update --remote --rebase
cp tetra-rp/src/tetra_rp/protos/remote_execution.py src/

- name: Build CPU Docker image for handler testing
if: matrix.image-type == 'cpu'
- name: Build CPU Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile-cpu
platforms: linux/amd64
push: false
tags: tetra-rp-cpu:local-test
tags: tetra-rp-cpu:test
cache-from: type=gha
cache-to: type=gha,mode=max
load: true

- name: Test CPU handler execution in Docker environment
if: matrix.image-type == 'cpu'
run: |
echo "Testing CPU handler in Docker environment..."
docker run --rm tetra-rp-cpu:local-test ./test-handler.sh
docker run --rm tetra-rp-cpu:test ./test-handler.sh


release:
runs-on: ubuntu-latest
needs: [test, lint, local-execution-test]
needs: [test, lint, docker-test]
if: github.ref == 'refs/heads/main'
outputs:
release_created: ${{ steps.release.outputs.release_created }}
Expand All @@ -135,61 +143,10 @@ jobs:
release-type: python
token: ${{ secrets.GITHUB_TOKEN }}

docker-pr:
runs-on: ubuntu-latest
needs: [test, lint, local-execution-test]
if: github.event_name == 'pull_request'
steps:
- name: Clear Space
run: |
rm -rf /usr/share/dotnet
rm -rf /opt/ghc
rm -rf "/usr/local/share/boost"
rm -rf "$AGENT_TOOLSDIRECTORY"

- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Set up uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true

- name: Setup dependencies
run: |
uv sync
git submodule update --remote --rebase
cp tetra-rp/src/tetra_rp/protos/remote_execution.py src/

- name: Build and test CPU Docker image (PR)
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile-cpu
platforms: linux/amd64
push: false
tags: tetra-rp-cpu:pr-test
cache-from: type=gha
cache-to: type=gha,mode=max
load: true

- name: Test CPU Docker image with handler test suite
run: |
echo "Testing CPU image with handler test suite..."
docker run --rm tetra-rp-cpu:pr-test ./test-handler.sh

docker-main-gpu:
runs-on: ubuntu-latest
needs: [test, lint, local-execution-test, release]
needs: [test, lint, docker-test, release]
if: github.ref == 'refs/heads/main' && github.event_name == 'push' && !needs.release.outputs.release_created
steps:
- name: Clear Space
Expand Down Expand Up @@ -242,7 +199,7 @@ jobs:

docker-main-cpu:
runs-on: ubuntu-latest
needs: [test, lint, local-execution-test, release]
needs: [test, lint, docker-test, release]
if: github.ref == 'refs/heads/main' && github.event_name == 'push' && !needs.release.outputs.release_created
steps:
- name: Clear Space
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ celerybeat.pid
*.sage.py

# Environments
.envrc
.env
.venv
env/
Expand Down
57 changes: 26 additions & 31 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ This is `worker-tetra`, a RunPod Serverless worker template that provides dynami
- **Function Executor** (`src/function_executor.py:12`): Handles individual function execution with full output capture (stdout, stderr, logs)
- **Class Executor** (`src/class_executor.py:14`): Manages class instantiation and method execution with instance persistence and metadata tracking

### 2. Workspace & Environment Management (`src/workspace_manager.py:12`)
- Local workspace configuration and directory management
- Environment variable setup for execution contexts
- Integration with HuggingFace accelerator for model downloads
- Python path configuration for execution isolation
- Change directory management for execution context
### 2. HuggingFace Model Cache-Ahead (`src/huggingface_cache.py`)
- **Model Pre-Caching**: Downloads HuggingFace models before user code execution
- **Cache Validation**: Checks if models are already cached to avoid redundant downloads
- **Authentication**: Supports HF_TOKEN for private/gated model access
- **Transfer Acceleration**: Uses hf_transfer when HF_HUB_ENABLE_HF_TRANSFER=1 is set
- **Transparent Caching**: User code references models without knowing they're pre-cached

### 3. Dependency Management System (`src/dependency_installer.py:14`)
- **Python Package Installation**: UV-based package management with environment-aware configuration (Docker vs local)
Expand All @@ -32,48 +32,41 @@ This is `worker-tetra`, a RunPod Serverless worker template that provides dynami
- **System Package Filtering**: Intelligent detection of system-available packages to avoid redundant installation
- **Universal Subprocess Integration**: All subprocess operations use centralized logging utility

### 4. Download Acceleration Infrastructure
- **Download Accelerator** (`src/download_accelerator.py:166`): HuggingFace transfer optimization using hf_transfer
- **HuggingFace Integration** (`src/huggingface_accelerator.py`): Model caching and acceleration strategies
- **Strategy Pattern**: Multiple download strategies (native HF, hf_transfer, factory-based selection)
- **Performance Metrics**: Download speed tracking and optimization reporting

### 5. Universal Subprocess Utility (`src/subprocess_utils.py`)
### 4. Universal Subprocess Utility (`src/subprocess_utils.py`)
- **Centralized Subprocess Operations**: All subprocess calls use `run_logged_subprocess` for consistency
- **Automatic Logging Integration**: All subprocess output flows through log streamer at DEBUG level
- **Environment-Aware Execution**: Handles Docker vs local environment differences automatically
- **Standardized Error Handling**: Consistent FunctionResponse pattern for all subprocess operations
- **Timeout Management**: Configurable timeouts with proper cleanup on timeout/cancellation

### 6. Serialization & Protocol Management
### 5. Serialization & Protocol Management
- **Protocol Definitions** (`src/remote_execution.py:13`): Pydantic models for request/response with validation
- **Serialization Utils** (`src/serialization_utils.py`): CloudPickle-based data serialization for function arguments and results
- **Base Executor** (`src/base_executor.py`): Common execution interface and environment setup

### 7. Tetra SDK Integration (`tetra-rp/` submodule)
### 6. Tetra SDK Integration (`tetra-rp/` submodule)
- **Client Interface**: `@remote` decorator for marking functions for remote execution
- **Resource Management**: GPU/CPU configuration and provisioning through LiveServerless objects
- **Live Serverless**: Dynamic infrastructure provisioning with auto-scaling
- **Protocol Buffers**: Communication protocol definitions for distributed execution

### 8. Testing Infrastructure (`tests/`)
### 7. Testing Infrastructure (`tests/`)
- **Unit Tests** (`tests/unit/`): Component-level testing for individual modules with mocking
- **Integration Tests** (`tests/integration/`): End-to-end workflow testing with real execution
- **Test Fixtures** (`tests/conftest.py:1`): Shared test data, mock objects, and utility functions
- **Handler Testing**: Local execution validation with JSON test files (`src/test_*.json`)
- **Full Coverage**: All 14 handler tests pass with environment-aware dependency installation
- **Handler Testing**: Local execution validation with JSON test files (`src/tests/`)
- **Full Coverage**: All handler tests pass with environment-aware dependency installation
- **Cross-Platform**: Works correctly in both Docker containers and local macOS/Linux environments

### 9. Build & Deployment Pipeline
### 8. Build & Deployment Pipeline
- **Docker Containerization**: GPU (`Dockerfile`) and CPU (`Dockerfile-cpu`) image builds
- **CI/CD Pipeline**: Automated testing, linting, and releases (`.github/workflows/`)
- **Quality Gates** (`Makefile:104`): Format checking, type checking, test coverage requirements
- **Release Management**: Automated semantic versioning and Docker Hub deployment

### 10. Configuration & Constants
- **Constants** (`src/constants.py`): System-wide configuration values and thresholds
- **Environment Configuration**: RunPod API integration and workspace paths
- **Performance Tuning**: Download acceleration thresholds and caching strategies
### 9. Configuration & Constants
- **Constants** (`src/constants.py`): System-wide configuration values (NAMESPACE, LARGE_SYSTEM_PACKAGES)
- **Environment Configuration**: RunPod API integration and HuggingFace cache settings

## Architecture

Expand All @@ -97,12 +90,13 @@ This is `worker-tetra`, a RunPod Serverless worker template that provides dynami
### Key Patterns

1. **Remote Function Execution**: Functions decorated with `@remote` are automatically executed on RunPod GPU workers
2. **Composition Pattern**: RemoteExecutor uses specialized components (WorkspaceManager, DependencyInstaller, Executors)
2. **Composition Pattern**: RemoteExecutor uses specialized components (DependencyInstaller, HuggingFaceCacheAhead, Executors)
3. **Dynamic Dependency Management**: Dependencies specified in decorators are installed at runtime with differential updates
4. **Universal Subprocess Operations**: All subprocess calls use centralized `run_logged_subprocess` for consistent logging and error handling
5. **Environment-Aware Configuration**: Automatic Docker vs local environment detection for appropriate installation methods
6. **Serialization**: Uses cloudpickle + base64 encoding for function arguments and results
7. **Resource Configuration**: `LiveServerless` objects define GPU requirements, scaling, and worker configuration
4. **HuggingFace Cache-Ahead**: Models specified in `hf_models_to_cache` are pre-downloaded before execution
5. **Universal Subprocess Operations**: All subprocess calls use centralized `run_logged_subprocess` for consistent logging and error handling
6. **Environment-Aware Configuration**: Automatic Docker vs local environment detection for appropriate installation methods
7. **Serialization**: Uses cloudpickle + base64 encoding for function arguments and results
8. **Resource Configuration**: `LiveServerless` objects define GPU requirements, scaling, and worker configuration

## Development Commands

Expand Down Expand Up @@ -150,6 +144,8 @@ git submodule update --remote --rebase # Update tetra-rp to latest
### Environment Variables
- `RUNPOD_API_KEY`: Required for RunPod Serverless integration
- `RUNPOD_ENDPOINT_ID`: Used for workspace isolation (automatically set by RunPod)
- `HF_HUB_ENABLE_HF_TRANSFER`: Set to "1" in Dockerfile to enable accelerated HuggingFace downloads
- `HF_TOKEN`: Optional authentication token for private/gated HuggingFace models
- `DEBIAN_FRONTEND=noninteractive`: Set during system package installation
- `UV_CACHE_DIR`: Package cache configuration
- `VIRTUAL_ENV`: Virtual environment path configuration
Expand Down Expand Up @@ -207,13 +203,12 @@ gpu_config = LiveServerless(
│ ├── remote_execution.py # Protocol definitions
│ ├── function_executor.py # Function execution with output capture
│ ├── class_executor.py # Class execution with persistence
│ ├── workspace_manager.py # Workspace and environment management
│ ├── dependency_installer.py # Python and system dependency management
│ ├── download_accelerator.py # HuggingFace download optimization
│ ├── huggingface_cache.py # HuggingFace model cache-ahead system
│ ├── serialization_utils.py # CloudPickle serialization utilities
│ ├── base_executor.py # Common execution interface
│ ├── constants.py # System-wide configuration constants
│ └── test_*.json # Local handler test files
│ └── tests/ # Handler test JSON files
├── tests/ # Comprehensive test suite
│ ├── conftest.py # Shared test fixtures
│ ├── unit/ # Unit tests for individual components
Expand Down
6 changes: 5 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ FROM pytorch/pytorch:2.8.0-cuda12.8-cudnn9-runtime

WORKDIR /app

# Enable HuggingFace transfer acceleration
ENV HF_HUB_ENABLE_HF_TRANSFER=1

# Install system dependencies and uv
RUN apt-get update && apt-get install -y --no-install-recommends \
curl ca-certificates nala \
Expand All @@ -12,7 +15,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& rm -rf /var/lib/apt/lists/*

# Copy app code and install dependencies
COPY README.md src/* pyproject.toml uv.lock ./
COPY README.md pyproject.toml uv.lock ./
COPY src/ ./
RUN uv export --format requirements-txt --no-dev --no-hashes > requirements.txt \
&& uv pip install --system -r requirements.txt

Expand Down
3 changes: 2 additions & 1 deletion Dockerfile-cpu
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& rm -rf /var/lib/apt/lists/*

# Copy app code and install dependencies
COPY README.md src/* pyproject.toml uv.lock ./
COPY README.md pyproject.toml uv.lock ./
COPY src/ ./
RUN uv export --format requirements-txt --no-dev --no-hashes > requirements.txt \
&& uv pip install --system -r requirements.txt

Expand Down
3 changes: 0 additions & 3 deletions docs/Centralized_Log_Streaming_System.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,11 @@ sequenceDiagram
participant RE as RemoteExecutor
participant LS as LogStreamer
participant DI as DependencyInstaller
participant WM as WorkspaceManager

C->>RE: Execute Function
RE->>LS: Start Log Streaming
RE->>DI: Install Dependencies
DI-->>LS: Log installation progress
RE->>WM: Setup Workspace
WM-->>LS: Log workspace operations
RE->>RE: Execute Function
RE-->>LS: Capture execution logs
LS->>RE: Streamed logs
Expand Down
70 changes: 70 additions & 0 deletions docs/Endpoint Persistence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Endpoint Persistence using Network Volume and CDR

## Definitions

- Worker: docker container that relies on their local sandbox environment `/app` for all of its operations.

- Volume: network volume attached to a Worker as provisioned by its parent Endpoint.

- Workspace: designated environment residing in the network volume `/runpod-volume/runtimes/{endpoint_id}`. Serves as an Endpoint persistence disk.

- CDR: continuous data replication daemon that ensures data is replicated to the network volume workspace with an optional "hydrate" function (data transfers from volume to container)

## Logic

- First container boots, and checks for volume presence and endpoint workspace. Create if not found.

1. Container will proceed to download any system, python or HF pre-cache instructed from the remote decorator.

2. Container runs its job.

3. Container launches its own CDR daemon to monitor `/app` for changes and replicates `/app` to `/runpod-volume/runtimes/{endpoint_id}` as files are downloaded or changed.

- Subsequent container boots, and checks for volume presence and endpoint workspace. Found.

1. Container launches its own CDR daemon to hydrate its `/app` from the workspace and then watch `/app` for changes.

2. Container completely skips downloading from the internet.

3. Container runs its job.

### Logic Flow
```mermaid
graph TD
A[Container Boot] --> B{Volume Present?}
B -->|No| C[Use Local /app Only]
B -->|Yes| D{Workspace Exists?}

D -->|No| E["Create Workspace<br/>/runpod-volume/runtimes/{endpoint_id}"]
D -->|Yes| F[Workspace Found]

E --> G[Launch CDR Daemon<br/>Monitor /app → Workspace]
F --> H{First Container?}

H -->|Yes| I[Launch CDR Daemon<br/>Monitor /app → Workspace]
H -->|No| J[Launch CDR Daemon<br/>Hydrate /app ← Workspace<br/>Then Monitor /app →
Workspace]

G --> K[Download Dependencies<br/>System + Python + HF]
I --> K
J --> L[Skip Downloads<br/>Use Cached Data]

K --> M[CDR: Replicate Downloads<br/>/app → Workspace]
L --> N[Execute Job]
M --> O[Execute Job]

O --> P[CDR: Continue Monitoring<br/>/app → Workspace]
N --> Q[CDR: Continue Monitoring<br/>/app → Workspace]

C --> R[Execute Job<br/>No Persistence]

style A fill:#e1f5fe,color:#000000
style G fill:#f3e5f5,color:#000000
style I fill:#f3e5f5,color:#000000
style J fill:#fff3e0,color:#000000
style K fill:#e8f5e8,color:#000000
style L fill:#fff9c4,color:#000000
style M fill:#fce4ec,color:#000000
style P fill:#fce4ec,color:#000000
style Q fill:#fce4ec,color:#000000
```
Loading
Loading