Novedades de 0.6.0¶
Publicada el 2026-10-03: SDK Python rayito 0.6.0, SDK TypeScript
rayito 0.6.0 y rayd 0.6.0.
0.6.0 trae seis funciones nuevas y un convenio único para desplegar su infraestructura en tu cuenta. Todas están apagadas por defecto: sin la opción correspondiente, un sandbox se comporta byte a byte como en 0.5.x y el SDK no hace ninguna llamada nueva a AWS (una traza de oro en los tests de cada SDK lo comprueba).
Actualiza a 0.6.1
0.6.1 corrige que redesplegar una pila opcional devolviera sus
parámetros a los valores por defecto y que reincarnate() perdiera
mounts=, events= y telemetry=:
Novedades de 0.6.1.
De un vistazo¶
| Función | Python | TypeScript | Imagen | Coste en reposo | Guía |
|---|---|---|---|---|---|
| Montajes S3 | mounts={"/mnt/x": S3Mount(...)} |
mounts: { "/mnt/x": new S3Mount({...}) } |
rayito-base-caps, rayd 0.6.0 |
$0 (sólo IAM) | Montajes S3 |
| Tamaños | size="4gb" |
size: "4gb" |
una imagen por tamaño (rayito image publish --sizes) |
snapshot por imagen publicada | Tamaños |
| Eventos y webhooks | events=LifecycleEvents() |
events: new LifecycleEvents() |
cualquiera con rayd 0.6.0 |
≈ $0,40/mes (pila events-webhooks) |
Eventos y webhooks |
| Exportación OTLP | telemetry=TelemetryExport(...) |
telemetry: new TelemetryExport({...}) |
rayd 0.6.0; caps con OtlpAuth.execution_role() |
$0 (sólo IAM) | Exportación OTLP |
| Templates declarativos | Template.build(t, "nombre", bucket=...) |
Template.build(t, "nombre", { bucket }) |
se compone sobre rayito-base publicada |
snapshot por versión construida | Templates |
| Pasarela de secretos | gateways={"api": SecretGateway(...)} |
gateways: { api: new SecretGateway({...}) } |
cualquiera con rayd 0.6.0 |
$0 (lecturas de Secrets Manager por uso) | Pasarela de secretos |
| Pilas opcionales | OptionalStacks().deploy(...) |
new OptionalStacks().deploy(...) |
— | el de cada componente | Pilas opcionales |
Todas aceptadas contra AWS real; cada guía cita sus mediciones en
AWS_API_NOTES.md. Las cifras y permisos de cada una, en una sola tabla:
Funciones opcionales y su coste.
Montajes S3¶
Un bucket (o un prefijo) como carpeta normal del sandbox, con Mountpoint
for Amazon S3. create() no devuelve el sandbox hasta que cada montaje
está mounted; si alguno falla, lo termina y lanza MountException
(TypeScript: MountError) con un code cerrado.
from rayito import S3Mount, Sandbox
with Sandbox.create(
"rayito-base-caps",
execution_role_arn="arn:aws:iam::123456789012:role/rayito-sandbox-caps",
mounts={"/mnt/data": S3Mount(bucket="amzn-s3-demo-bucket", prefix="team7/")},
) as sbx:
print(sbx.commands.run("ls /mnt/data").stdout)
print(sbx.mounts["/mnt/data"].state) # "mounted"
import { S3Mount, Sandbox } from "rayito";
await using sbx = await Sandbox.create({
template: "rayito-base-caps",
executionRoleArn: "arn:aws:iam::123456789012:role/rayito-sandbox-caps",
mounts: { "/mnt/data": new S3Mount({ bucket: "amzn-s3-demo-bucket", prefix: "team7/" }) },
});
console.log((await sbx.commands.run("ls /mnt/data")).stdout);
console.log((await sbx.mounts()).get("/mnt/data")?.state); // "mounted"
Necesita la política de la pila s3-mounts en el execution role y el
bucket en el allowlist de la imagen (RAYITO_ALLOWED_MOUNT_BUCKETS).
Catálogo de tamaños¶
Cinco tamaños con nombre (512mb, 1gb, 2gb, 4gb, 8gb) que el SDK
resuelve en el cliente, sin ningún RPC: size="4gb" lanza la imagen
rayito-base-4gb. Un tamaño intermedio se redondea hacia arriba con un
aviso. rayito image publish --sizes 512mb,4gb publica las imágenes de
cada tamaño desde el mismo artefacto.
Eventos de ciclo de vida y webhooks¶
rayd firma cada transición (created, paused, resumed, killed) y
una pila en tu cuenta las guarda en DynamoDB y las entrega a tus webhooks
con la firma de E2B: un receptor escrito para E2B las verifica sin
cambios (cómo verificar la firma).
from rayito import LifecycleEvents, Sandbox
events = LifecycleEvents() # la pila de `rayito events deploy`
with Sandbox.create(
execution_role_arn="arn:aws:iam::123456789012:role/rayito-sandbox",
logging="cloudwatch",
events=events,
) as sbx:
sbx.pause()
sbx.resume()
for event in events.get_events(sandbox_id=sbx.sandbox_id, order="asc"):
print(event.type) # sandbox.lifecycle.created, .paused, .resumed, .killed
import { LifecycleEvents, Sandbox } from "rayito";
const events = new LifecycleEvents(); // la pila de `rayito events deploy`
const sbx = await Sandbox.create({
executionRoleArn: "arn:aws:iam::123456789012:role/rayito-sandbox",
logging: "cloudwatch",
events,
});
await sbx.pause();
await sbx.resume();
await sbx.kill();
for (const event of await events.getEvents({ sandboxId: sbx.sandboxId, order: "asc" })) {
console.log(event.kind); // created, paused, resumed, killed
}
Exportación OTLP desde rayd¶
rayd exporta 7 métricas de CPU, memoria y disco a CloudWatch por
OTLP/HTTP cada interval_s (60 s por defecto), firmadas con SigV4 (el
execution role) o con un token guardado en Secrets Manager. Unos
$0,00002 por sandbox-hora.
import { OtlpAuth, Sandbox, TelemetryExport } from "rayito";
await using sbx = await Sandbox.create({
template: "rayito-base-caps",
executionRoleArn: "arn:aws:iam::123456789012:role/rayito-sandbox-caps",
telemetry: new TelemetryExport({ auth: OtlpAuth.executionRole() }),
});
console.log((await sbx.getTelemetryStatus()).exported);
Templates declarativos¶
El DSL Template de E2B v2, compilado en tu proceso a un Dockerfile
determinista sobre una imagen rayito-base publicada, y construido con
Lambda MicroVMs. Sin plano de control propio. En el shim, Template y
AsyncTemplate construyen de verdad con la firma de E2B.
from rayito import Sandbox, Template, wait_for_port
t = (
Template()
.from_base_image("rayito-base")
.pip_install(["pandas==2.2.3"])
.set_start_cmd("python3 -m http.server 8000", wait_for_port(8000))
)
info = Template.build(t, "mi-api", bucket="amzn-s3-demo-bucket")
with Sandbox.create(info.template_id) as sbx:
print(sbx.commands.run("curl -s localhost:8000").exit_code)
import { Sandbox, Template, waitForPort } from "rayito";
const t = new Template()
.fromBaseImage("rayito-base")
.pipInstall(["pandas==2.2.3"])
.setStartCmd("python3 -m http.server 8000", waitForPort(8000));
const info = await Template.build(t, "mi-api", { bucket: "amzn-s3-demo-bucket" });
await using sbx = await Sandbox.create({ template: info.templateId });
console.log((await sbx.commands.run("curl -s localhost:8000")).exitCode);
Pasarela de secretos¶
El código del sandbox usa una credencial sin poder leerla: rayd
abre una pasarela en loopback que comprueba una allowlist de método y ruta,
inyecta la cabecera real (leída de Secrets Manager) y reenvía al upstream
que declaraste. sbx.gateways.refresh() rota el secreto sin recrear el
sandbox.
from rayito import Sandbox, SecretGateway
with Sandbox.create(
gateways={
"anthropic": SecretGateway(
upstream="https://api.anthropic.com",
headers={"x-api-key": "anthropic"}, # nombre del secreto, no su valor
allow=[("POST", "/v1/messages")],
)
}
) as sbx:
url = sbx.gateways["anthropic"].url # http://127.0.0.1:<puerto>
sbx.commands.run("python agent.py", envs={"ANTHROPIC_BASE_URL": url})
import { Sandbox, SecretGateway } from "rayito";
await using sbx = await Sandbox.create({
gateways: {
anthropic: new SecretGateway({
upstream: "https://api.anthropic.com",
headers: { "x-api-key": "anthropic" }, // nombre del secreto, no su valor
allow: [["POST", "/v1/messages"]],
}),
},
});
const url = sbx.gateways.get("anthropic")?.url ?? "";
await sbx.commands.run("python agent.py", { envs: { ANTHROPIC_BASE_URL: url } });
Pilas opcionales y rayito stack¶
Cada función con infraestructura propia es un componente OptionalStack:
una plantilla de CloudFormation que despliegas tú, con
OptionalStacks.deploy/status/destroy o rayito stack. deploy imprime
siempre el coste y pide confirmación; nada se despliega solo.
Por dentro: ConfigureSandbox¶
Las funciones que viven dentro del sandbox (mounts, events,
telemetry y gateways) llegan a rayd por un único canal nuevo,
ConfigureSandbox, justo después del primer Health y antes de que
create() devuelva el sandbox. Si una sección falla, create() termina el
MicroVM que acaba de lanzar (salvo keep_on_failure=True) y relanza el
error: nunca recibes un sandbox a medio configurar. Contra una imagen con
un rayd anterior a 0.6.0, esas opciones fallan con UnimplementedError.
Diseño: ADR-015 y ADR-016 en
ARCHITECTURE.md.
Cómo actualizar desde 0.5.x¶
- Actualiza el SDK (
pip install -U "rayito[cli]"opnpm add rayito@latest). Sin opciones nuevas, tu código sigue igual. - Para usar
mounts,events,telemetry,gatewaysoset_start_cmd()de los templates, republica tu imagen sobrerayd0.6.x (Imágenes) y comprueba la compatibilidad conrayito doctor. - Despliega sólo las pilas de las funciones que uses
(
rayito stack deploy <componente>).
No hay cambios incompatibles en la API pública de 0.5.x. Lo único que
cambia para el shim de E2B: Template, AsyncTemplate,
TemplateException y BuildException pasan de lanzar
UnimplementedError a funcionar de verdad
(Paridad con E2B).
Lo que no trae 0.6.0¶
Volúmenes EFS (volumes=) y dominio propio (domain=) seguían en
desarrollo: sus opciones existían en la firma de create() y lanzaban
UnimplementedError sin llamar a AWS. Los volúmenes EFS y CustomDomain
(experimental) llegan en 0.7.0; domain= sigue
en desarrollo.
Detalle completo: Changelog.