AI-Q sandbox provider for Fly.io Sprites
aiq-sandbox-sprites runs NVIDIA AI-Q generated code in one isolated
Fly.io Sprite per AI-Q job. It implements AI-Q's official
third-party aiq.sandbox_providers entry point and LangChain Deep Agents'
BaseSandbox contract.
This package is an alpha proof of concept. It deliberately reports resource limits as unsupported, so AI-Q fails closed if a workflow requests CPU or memory limits that Sprites cannot currently enforce through its public API.
Installation
Install AI-Q from NVIDIA's source distribution, then install the provider into that same Python environment:
pip install aiq-sandbox-sprites
AI-Q is installed from NVIDIA's source distribution. The provider declares the shared Deep Agents protocol rather than coupling its package metadata to the host application's distribution channel.
The provider requires AI-Q 2.2's aiq.sandbox_providers extension point. AI-Q
2.1 does not expose that interface and is not supported. The tested compatibility
range currently covers AI-Q v2.2.1 with Deep Agents 0.6.8 and AI-Q's
develop branch with Deep Agents 0.7.x.
Set a restricted Sprites token on the AI-Q host:
export SPRITE_TOKEN="..."
The token is used by the host-side SDK. It is never copied into a Sprite or passed to generated code.
AI-Q configuration
Select sprites in the normal AI-Q sandbox block:
functions:
deep_research_sandbox:
_type: deep_research_sandbox
provider: sprites
workdir: /workspace
network: blocked
timeout: 1200
idle_timeout: 1800
artifact_capture:
enabled: true
max_file_bytes: 50000000
allow_extensions: [.png, .jpg, .jpeg, .webp, .csv, .json, .md, .ipynb, .pdf]
AI-Q 2.2 does not yet expose third-party provider-specific fields in its YAML model. Configure the temporary Sprites-specific surface through environment variables:
| Variable | Default | Purpose |
|---|---|---|
SPRITE_TOKEN |
required | Host-side Sprites API token |
AIQ_SPRITES_API_URL |
https://api.sprites.dev |
Sprites API endpoint |
AIQ_SPRITES_RUNTIME |
dev |
Sprite runtime; empty means the API default |
AIQ_SPRITES_PYTHON_PACKAGES |
unset | JSON array of locked package requirements installed before network policy |
AIQ_SPRITES_MAX_OUTPUT_BYTES |
1000000 |
Maximum combined command output returned to AI-Q |
AIQ_SPRITES_MAX_DOWNLOAD_BYTES |
50000000 |
Independent upper bound on one downloaded file |
AIQ_SPRITES_VERIFY_NETWORK |
true |
Require live pre/post-policy connectivity probes |
AIQ_SPRITES_NETWORK_VERIFY_TIMEOUT_SECONDS |
10 |
Time allowed for policy enforcement |
AIQ_SPRITES_DENY_PROBE_HOST |
1.1.1.1 |
Known-reachable direct-IP egress probe |
AIQ_SPRITES_DENY_PROBE_PORT |
443 |
Probe TCP port |
For the AI-Q analytics profile:
export AIQ_SPRITES_PYTHON_PACKAGES='["matplotlib", "numpy", "pandas", "pillow", "tabulate"]'
Lifecycle and security behavior
- Job IDs are hashed into deterministic
aiq-<digest>Sprite names and matching ownership labels. - Creation is attempted first. A name collision is attachable only when both the provider and exact job ownership labels match.
- Trusted package bootstrap runs only for a newly created Sprite, before generated code and before the final network restriction is installed.
blockedmaps to a wildcard deny policy;allowlistmaps to explicit allow rules with default deny;openmaps to an empty policy.- Restricted policies are checked through the policy API and a live direct-IP connectivity probe before the session is returned to AI-Q.
- Command output is drained inside the Sprite while only a bounded head/tail is returned, preventing unbounded SDK buffers.
- File downloads are streamed with a byte cap. Oversized files return the
per-file
file_too_largeerror instead of being loaded into host memory. - Close and terminate re-check the job ownership label before destroying the Sprite. Missing Sprites are treated as already cleaned up.
Provider cleanup cannot run if the complete AI-Q worker is lost. A production
deployment still requires an external reaper scoped to the aiq-sandbox label
and an authoritative job/expiry record.
Development
Tests use the current AI-Q sandbox source through PYTHONPATH and never create
cloud resources:
PYTHONPATH=/path/to/aiq/src .venv/bin/pytest
.venv/bin/ruff check .
.venv/bin/python -m build
.venv/bin/python -m twine check dist/*
The opt-in smoke test creates one disposable Sprite, runs commands and file transfer, verifies blocked egress, terminates the provider, and confirms the Sprite no longer exists:
AIQ_SOURCE_DIR=/path/to/aiq/src .venv/bin/python scripts/smoke_test.py
The broader live release matrix covers blocked, open, and allowlisted networking; binary transfer and size bounds; bounded output; command timeout recovery; package bootstrap; collision ownership; interrupted execution; and cleanup:
AIQ_SOURCE_DIR=/path/to/aiq/src \
AIQ_SPRITES_LIVE_TEST=1 \
.venv/bin/pytest -vv tests/test_live.py
After installing the built wheel into a complete AI-Q environment, exercise the real AI-Q runtime, artifact store, lifecycle events, and normal/interrupted cleanup:
python scripts/aiq_runtime_test.py
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aiq_sandbox_sprites-0.1.0.tar.gz.
File metadata
- Download URL: aiq_sandbox_sprites-0.1.0.tar.gz
- Upload date:
- Size: 23.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdaa7715cd2ec0251020ac2a82df6e259afa9c40801e287e1249355e9fc49bad
|
|
| MD5 |
176cc6bba6ebd2dfd08c14395a88e20d
|
|
| BLAKE2b-256 |
61e49a02c31ab80e6c4922dc132b1bb5b0f20d2079d5d158de231a9e6d887848
|
Provenance
The following attestation bundles were made for aiq_sandbox_sprites-0.1.0.tar.gz:
Publisher:
publish.yml on superfly/aiq-sandbox-sprites
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aiq_sandbox_sprites-0.1.0.tar.gz -
Subject digest:
cdaa7715cd2ec0251020ac2a82df6e259afa9c40801e287e1249355e9fc49bad - Sigstore transparency entry: 2658517918
- Sigstore integration time:
-
Permalink:
superfly/aiq-sandbox-sprites@34269e9a3e3a4f7cd70db48f92a33297cad3dde2 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/superfly
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@34269e9a3e3a4f7cd70db48f92a33297cad3dde2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file aiq_sandbox_sprites-0.1.0-py3-none-any.whl.
File metadata
- Download URL: aiq_sandbox_sprites-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e42f23afd8021c456b04538605d71c007159d3e6d8d60541e3a9a4ddd5713d7
|
|
| MD5 |
4f510f05cf5c53b7f51402b5d0fe8f9c
|
|
| BLAKE2b-256 |
dac00d6193a65ed847a9e55a2e95bb3b99d8d271fbcd899427fb2358725ffe9a
|
Provenance
The following attestation bundles were made for aiq_sandbox_sprites-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on superfly/aiq-sandbox-sprites
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aiq_sandbox_sprites-0.1.0-py3-none-any.whl -
Subject digest:
1e42f23afd8021c456b04538605d71c007159d3e6d8d60541e3a9a4ddd5713d7 - Sigstore transparency entry: 2658517950
- Sigstore integration time:
-
Permalink:
superfly/aiq-sandbox-sprites@34269e9a3e3a4f7cd70db48f92a33297cad3dde2 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/superfly
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@34269e9a3e3a4f7cd70db48f92a33297cad3dde2 -
Trigger Event:
push
-
Statement type: