Metadata-Version: 2.4
Name: mosaic-sandbox
Version: 0.14.3
Summary: Python SDK for Mosaic Sandbox (MAR)
Author: Mosaic
License-Expression: Apache-2.0
Project-URL: Homepage, https://sandbox.mosaicos.com
Project-URL: Documentation, https://sandbox.mosaicos.com/docs/
Project-URL: Support, https://sandbox.mosaicos.com/start/
Project-URL: Changelog, https://sandbox.mosaicos.com/roadmap/
Keywords: sandbox,firecracker,microvm,agent,cli,mcp,ssh
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Distributed Computing
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: tomli>=2.0.1; python_version < "3.11"
Provides-Extra: harbor
Requires-Dist: harbor>=0.22.0; extra == "harbor"
Requires-Dist: dockerfile-parse>=2.0.1; extra == "harbor"
Dynamic: license-file

# Mosaic Sandbox Python SDK

`mosaic-sandbox` is the Python SDK and CLI for Mosaic Sandbox, a Firecracker-based
runtime for coding agents.

Install (Python 3.9 or newer):

```bash
python3 --version   # 3.9 or newer
python3 -m pip install mosaic-sandbox
```

Authenticate once with the CLI:

```bash
mos auth --token msk_live_...
mos whoami
```

Run the CLI smoke test:

```bash
mos doctor
mos run --template node-20 node -v
mos create --template node-20 --ssh
mos ssh <sandbox-id> --print-command
```

Or run the one-command first-run check:

```bash
mos smoke
```

Python example:

```python
from mosaic_sandbox import Sandbox

sbx = Sandbox.create(
    template="node-20",
    endpoint="https://sandbox.mosaicos.com",
    api_token="msk_live_...",
    enable_ssh=False,
)

try:
    result = sbx.run_command("node -v")
    print(result.stdout)
    print(result.tti_ms)
finally:
    sbx.destroy()
```

## Functions

A function is a name you keep for a one-shot run: a specification — template,
command, secrets, network policy, resources, timeout — that lives in your code.
Defining one makes no request and creates nothing to deploy or delete. Each
invocation creates one isolated microVM, runs the command, and destroys it, so
an idle function costs nothing.

```python
from mosaic_sandbox import Function

thumbnail = Function(
    ["python", "-m", "thumbnail"],
    template="python-3.11",
    secrets=["OBJECT_STORE_TOKEN"],
    network={"allow": ["objects.mosaicos.com:443"]},
    timeout_ms=60_000,
)

result = thumbnail.invoke(env={"OBJECT_KEY": "images/input.jpg"})
print(result.stdout, result.sandbox_destroyed)
```

What the sandbox is stays fixed for every invocation. Only `cwd`, `env`,
`stdin`, `timeout_ms` and `idempotency_key` may be passed per call; anything
else raises rather than being silently ignored, so one call cannot widen
another's secrets or egress. Retrying with the same `idempotency_key` replays
the first invocation instead of running a second one.

Work that must outlive one synchronous call belongs in a process or job, and
work that needs a URL belongs behind a preview.

## Long-running attempts

Synchronous exec is capped at 900,000 ms (15 minutes). A durable process is
owned by the sandbox rather than by the request that starts it, so persist the
sandbox and process IDs and reconnect after a client restart. Its lifetime is
bounded by its own timeout, when supplied, and by the sandbox TTL.

```python
sbx = Sandbox.create(template="base", ttl_seconds=86_400)
try:
    started = sbx.process.start(["python", "-m", "train"])
    sandbox_id, process_id = sbx.id, started.id

    sbx = Sandbox.connect(sandbox_id)
    handle = next(p for p in sbx.process.list() if p.id == process_id)
    for chunk in handle.iter_logs():
        print(chunk["stdout"], end="")
    result = handle.wait()
finally:
    sbx.destroy()
```

A running process prevents hibernation; after it finishes, pause/resume works
normally. Call `handle.kill()` to cancel it. The full Python, TypeScript, Go,
CLI, and raw-HTTP recovery patterns are in the public documentation.

## LangChain and LlamaIndex tools

Give an agent a sandbox without writing tools for it. Neither framework is a
dependency of this SDK; the one you use is imported when you ask for it.

```python
from langchain.agents import create_react_agent
from mosaic_sandbox.integrations.langchain import mosaic_sandbox_tools

agent = create_react_agent(model, mosaic_sandbox_tools(template="python-3.11"))
```

```python
from llama_index.core.agent import ReActAgent
from mosaic_sandbox.integrations.llamaindex import mosaic_sandbox_tools

agent = ReActAgent.from_tools(mosaic_sandbox_tools(), llm=llm)
```

The tools — `mosaic_run_command`, `mosaic_run_python`, `mosaic_run_javascript`,
`mosaic_read_file`, `mosaic_write_file`, `mosaic_list_files` and
`mosaic_start_server` — share one sandbox, created on the first call rather
than when the agent is built. `mosaic_start_server` returns a public HTTPS
preview URL, so "run the dev server and show me" is a single tool call.

Keyword arguments are `Sandbox.create`'s, so `snapshot_id=` starts the agent in
an environment you built earlier. Hold the `SandboxToolset` yourself if you
want to `close()` it explicitly; `close()` destroys the sandbox it created but
leaves a sandbox you passed in alone, and the toolset is spent either way — a
later tool call raises rather than quietly starting a second machine.

## Harbor environment provider

Harbor 0.22 and newer can run its trials in Mosaic Sandbox through the
first-party provider. Install the optional dependency on Python 3.12 or newer:

```bash
python -m pip install 'mosaic-sandbox[harbor]'
```

Point Harbor at the provider in the trial environment configuration:

```toml
[environment]
import_path = "mosaic_sandbox.integrations.harbor:MosaicEnvironment"
```

Authenticate first with `mos login`. The provider builds each Docker image or
Dockerfile environment once, keyed by its content hash, and starts one Mosaic
snapshot replica builds per requested `MOSAIC_HARBOR_REPLICAS` (default `1`) and
starts one Mosaic sandbox per trial. Set that variable to an integer from `1`
through `16` to spread named snapshot restores across hosts. The optional
`MOSAIC_HARBOR_TTL_SECONDS` variable controls abandoned-trial cleanup and
defaults to `3600`. Mosaic currently supports Linux single-VM tasks, including
no-network and public-IPv4/hostname allowlists; Docker Compose and Windows
tasks are out of scope for this provider. A Firecracker guest can run Docker
natively, so DinD-style tasks are a plausible follow-up.

Docs: <https://sandbox.mosaicos.com/docs/>
