Skip to main content
Mirage picks a runtime for every command line. Most Python an agent writes runs on Monty, in-process and at no infrastructure cost. A line that needs a GPU has to run on one, and a GPU is billed while it runs. A route policy makes that choice per line. This example sends GPU work to a Daytona GPU sandbox and keeps everything else on Monty: first with a fixed script, then with one that asks an LLM. The LLM step builds on the LLM routing example in Python and TypeScript, which routes between Monty and the host’s Python.

The GPU sandbox

Create a GPU sandbox in Daytona from a snapshot with PyTorch and CUDA, and note its id. Daytona sets the GPU type on the snapshot, and a GPU sandbox is ephemeral. Mirage runs programs in it and leaves its lifecycle to Daytona.

The workspace

Two runtimes capture python3: monty first, then daytona. The route policy is a script that runs on Monty, read from route.py:
workspace.yaml

Route by a fixed script

A policy script reads the line as JSON and prints where it runs. This one sends any line that names PyTorch or CUDA to the GPU:
route.py
A line the script stays silent on runs on the first runtime that captures it, so python3 -c "print(sum(range(1, 101)))" runs on Monty. The script costs microseconds, and it misses what it does not name: a script file that imports torch, or a GPU library under another name.

Route by an LLM

An LLM reads the line the way an engineer would. This route.py describes each runtime and asks which one the line needs. A program on Monty has no network, so the LLM call is a host function, parse_runtime, that the workspace hands it:
route.py
A line with no python3 gets no answer, and runs where its commands’ captures put it. parse_runtime asks the LLM for a runtime and a one-sentence reason. Both explain and the run ask the policy, so it keeps each line’s answer and the preview and the run agree:

Run it

ws.explain(line) shows where a line will run and why, before it runs, so no GPU starts for a line that does not need one:
The sum stays on Monty and prints 5050 in-process; only the torch line reaches the GPU.

Notes

  • Daytona GPU sandboxes cannot mount FUSE, so a Mirage inside one cannot serve the workspace’s files. Lines routed there should carry their code (python3 -c, or a script piped on stdin) and fetch their data, such as model weights from Hugging Face, themselves.
  • The script has 10 seconds, the LLM call included. A script that fails or runs past them fails the line with a routing error rather than guessing.
  • Hybrid Terminal routes with a fixed rule written as a function in code instead of a script.