Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.worldflux.ai/llms.txt

Use this file to discover all available pages before exploring further.

Module path

The runtime package is worldflux.runtime (singular). Sources:
src/worldflux/runtime/
├── base.py              # Protocol + RuntimeContext + RuntimeResult
├── dispatcher.py        # registry: get_runtime, list_runtimes, doctor_all
├── local_plugin.py      # local subprocess
├── modal_plugin.py      # Modal sandbox
├── aws_ec2_plugin.py    # AWS EC2 (with cost guard, Spot, custom AMI)
├── replicate_plugin.py  # Replicate vendor runtime
├── cpu_smoke.py         # `worldflux run` entrypoint (calls run_project)
├── dreamer_style_light.py
├── mujoco_smoke.py
└── mujoco_policy_eval.py

The Protocol

# src/worldflux/runtime/base.py
from typing import Protocol, runtime_checkable

@runtime_checkable
class RuntimePlugin(Protocol):
    name: str

    def doctor(self) -> list[str]: ...

    def build_env(self, adapter, install_dir: Path) -> None: ...

    def run(self, ctx: RuntimeContext, command: tuple[str, ...]) -> RuntimeResult: ...

    def teardown(self, ctx: RuntimeContext) -> None: ...
Four methods. doctor returns a list of human-readable diagnostic lines. build_env materialises the venv (or vendor equivalent) for an adapter. run actually launches the command. teardown cleans up.

Context and result

@dataclass(frozen=True)
class RuntimeContext:
    adapter_id: str
    task: str                  # e.g. "generate", "rollout", "eval"
    output_dir: Path
    install_dir: Path
    source_dir: Path
    venv_python: Path | None
    timeout: int | None
    env_vars: dict[str, str]
    extra_args: tuple[str, ...] = ()
    run_id: str = ""

@dataclass(frozen=True)
class RuntimeResult:
    exit_code: int
    duration_seconds: float
    log_path: Path
    artifacts: dict[str, Path] = field(default_factory=dict)
    cost_estimate_usd: float | None = None
    metadata: dict[str, str] = field(default_factory=dict)
cost_estimate_usd is filled by the AWS plugin when the run uses paid instances. metadata carries free-form key/value pairs that end up in the manifest.

Built-in plugins

nameModuleWhen
locallocal_plugin.LocalPluginAnything you can run on the local box.
modalmodal_plugin.ModalPluginModal sandbox. Requires modal and a Modal token.
aws-ec2aws_ec2_plugin.AwsEc2PluginSpin up an EC2 host, run, collect artifacts, terminate.
replicatereplicate_plugin.ReplicatePluginReplicate-hosted models. Requires REPLICATE_API_TOKEN.
The dispatcher registers them at import time:
# src/worldflux/runtime/dispatcher.py
_register(LocalPlugin())
_register(ModalPlugin())
_register(AwsEc2Plugin())
_register(ReplicatePlugin())
get_runtime("aws-ec2") returns the singleton. list_runtimes() returns the sorted name list. doctor_all() runs every plugin’s doctor() and returns a dict[str, list[str]].

Runtime CLI

The runtime sub-tree exposes the dispatcher to the CLI:
worldflux runtime list
worldflux runtime doctor
worldflux runtime list prints registered plugin names. worldflux runtime doctor runs every plugin’s doctor() and prints the result. The same diagnostics also surface in worldflux doctor.

Writing a plugin

1

Drop the file

Create src/worldflux/runtime/<name>_plugin.py. Define a class with the four Protocol methods and a name: str class attribute.
2

Register it

In src/worldflux/runtime/dispatcher.py, import the class and call _register(MyPlugin()) at module bottom.
3

Add a doctor probe

doctor() returns one line per check. Lines starting with error: block runs; everything else is informational. Common checks: binary on $PATH, env vars set, GPU visible, vendor SDK importable.
4

Implement run()

Use RuntimeContext.venv_python (or the equivalent runtime entrypoint) to launch the command. Capture stdout/stderr to RuntimeContext.output_dir / "logs" / f"{run_id}.log" and pass that path back as RuntimeResult.log_path.
5

Tests

Add tests/runtime/test_<name>_plugin.py. The fakes under tests/runtime/fakes/ cover the Modal SDK, the AWS API, and the Replicate API surface; reuse them rather than mocking ad hoc.

What lands in the manifest

Anything the plugin writes via RuntimeResult.metadata becomes a leaf under manifest.runtime. The recipe-level metrics live under manifest.metrics. Logs are referenced by path (the manifest carries the path, the bytes ride the artifact channel).