Saltar a contenido

Novedades de 0.8.0

Publicada el 2026-10-07: SDK Python rayito 0.8.0, SDK TypeScript rayito 0.8.0 y rayd 0.8.0.

0.8.0 trae un agente de código que corre dentro del sandbox (sbx.agent, con OpenCode o deepagents), las piezas para que su primera respuesta llegue rápido (AgentTemplate con prefetch, pausa entre turnos y PoolConfig.warmup), presets de pasarela para llamar al modelo sin que el agente pueda leer la credencial, y una página de Precios que separa lo que cuesta la VM de lo que cuestan los tokens. Como siempre, todo lo que tiene coste está apagado por defecto: sin llamar a sbx.agent, sin construir un AgentTemplate y sin pasar warmup=, un sandbox no hace ninguna llamada nueva a AWS.

Hay un cambio que rompe: register_webhook / registerWebhook rechaza ahora las URLs a localhost y a IPs no públicas (Cómo actualizar desde 0.7.x).

De un vistazo

Novedad Python TypeScript Necesita Coste propio Guía
Agente en el sandbox sbx.agent.run() / .stream() / .prepare() sbx.agent.run() / .stream() / .prepare() una imagen con el runtime (AgentTemplate) y una pasarela al modelo (gateways=) $0 del SDK; los tokens del modelo y la pasarela Agente en el sandbox
Presets de pasarela bedrock_gateway, anthropic_gateway, openai_compatible_gateway bedrockGateway, anthropicGateway, openaiCompatibleGateway el secreto del modelo en Secrets Manager el de la pasarela de secretos El secreto y la pasarela
Imagen del agente AgentTemplate(...).build(), rayito agent template build new AgentTemplate({...}).build() la pila templates ≈ $0,057/semana por versión de imagen Templates de agente
Calentamiento del pool PoolConfig(warmup=agent_pool_warmup(...)) new SandboxPool({ warmup: agentPoolWarmup(...) }) un pool con allow_internet_access=False ≈ $0,64/plaza/mes (frente a $0,60 de una plaza base) Pool
Precios — — — — Precios

Un agente de código dentro del sandbox

sbx.agent corre un agente de código dentro del propio MicroVM: ve el mismo filesystem, los mismos comandos y el mismo egress que el resto del código del sandbox, y llama a su modelo sólo a través de la pasarela de secretos. El agente usa la credencial del modelo, pero nunca puede leerla.

from rayito import AgentModel, AgentSpec, Sandbox, bedrock_gateway

MODEL_ID = "us.anthropic.claude-haiku-4-5-20251001-v1:0"

spec = AgentSpec(
    model=AgentModel(provider="bedrock", id=MODEL_ID, gateway="bedrock", region="us-east-1"),
    instructions="Responde en español y no modifiques ficheros fuera de /home/user.",
)

with Sandbox.create(
    template="rayito-agent",
    allow_internet_access=False,
    gateways={
        "bedrock": bedrock_gateway("bedrock-key", region="us-east-1", models=[MODEL_ID], rate_per_minute=60),
    },
) as sbx:
    result = sbx.agent.run("Lista los ficheros de /home/user y resume qué hay.", spec=spec)
    print(result.text, result.steps, result.usage.total)
import { AgentModel, AgentSpec, Sandbox, bedrockGateway } from "rayito";

const MODEL_ID = "us.anthropic.claude-haiku-4-5-20251001-v1:0";

const spec = new AgentSpec({
  model: new AgentModel({ provider: "bedrock", id: MODEL_ID, gateway: "bedrock", region: "us-east-1" }),
});

await using sbx = await Sandbox.create({
  template: "rayito-agent",
  allowInternetAccess: false,
  gateways: {
    bedrock: bedrockGateway("bedrock-key", { region: "us-east-1", models: [MODEL_ID], ratePerMinute: 60 }),
  },
});
const result = await sbx.agent.run("Lista los ficheros de /home/user y resume qué hay.", { spec });
console.log(result.text, result.steps, result.usage.total);

Lo que trae, igual en Python síncrono, asyncio y TypeScript:

  • Tres llamadas. run() corre el agente hasta el final y devuelve un AgentResult (text, session_id, steps, usage, tool_calls) o lanza AgentException / AgentError. stream() devuelve un AgentStream que nunca lanza por un fallo del agente: el último evento es Done o AgentFailed. prepare() lanza los pasos de calentamiento del runtime en segundo plano y vuelve enseguida.
  • Dos runtimes. OpenCode por defecto y deepagents con runtime="deepagents" o runtime=DeepAgents(entrypoint="pkg.mod:build") (TypeScript: runtime: "deepagents" o new DeepAgents({...})), con los mismos eventos, los mismos límites y el modelo sólo por la pasarela (deepagents).
  • AgentSpec describe la ejecución y se valida al construirla, sin llamar a AWS: AgentModel (Bedrock, Anthropic o una API compatible con OpenAI, siempre por una entrada de gateways=), instructions, AgentPermissions (question, webfetch y websearch denegadas por defecto), SubAgent y servidores MCP (McpLocal, McpRemote).
  • Límites del SDK con AgentLimits: 50 pasos, 600 s, 16 MiB de salida y 1 000 000 de tokens por defecto. max_steps y max_total_tokens los impone el propio SDK sobre los eventos, no el runtime.
  • Eventos: StepStarted, Text, TextDelta (deepagents), Reasoning, ToolCall, StepFinished (con usage), AgentFailed y Done. Sesiones con session_id / sessionId para seguir una conversación, y abort() o un AbortSignal para cortarla (stream, sesiones, abortar y límites).
  • Errores con reason cerrado y un mensaje fijo en español: nunca el texto del proveedor, el prompt ni contenido del sandbox (AgentException / AgentError).
  • Presets de pasarela por proveedor, con allow restringido a lo imprescindible: bedrock_gateway sólo abre converse/converse-stream de los models que pases, nunca /model/*. Los tres aceptan rate_per_minute / ratePerMinute.
  • Telemetría opcional: con tracer_provider= / tracerProvider, cada ejecución abre un span rayito.agent.run con atributos gen_ai.* y de tokens; nunca el prompt, la respuesta ni los argumentos de herramienta (OpenTelemetry).

sbx.agent no manda ningún RPC hasta el primer run()/stream(), y en Python import rayito no carga el agente hasta que usas uno de sus nombres.

Los permisos no son una frontera de seguridad

El runtime ejecuta lo que el modelo pida dentro de lo permitido, sin preguntar. La frontera real es la MicroVM más el egress cerrado: Sandbox.create lo deja abierto por defecto, así que pasa allow_internet_access=False tú mismo. Amenazas y mitigaciones en Seguridad.

Guía completa: Agente en el sandbox.

Arranque rápido

El primer exec de OpenCode en una VM recién creada es lento (lee el binario desde el disco de la VM restaurada). Para la mayoría de los casos no hace falta ningún pool: ese coste se paga una vez por conversación. La guía tiene un árbol de decisión, ¿Qué uso?, con cuatro opciones que se combinan:

Opción Qué hace Cuándo Coste por encima de la VM
A. AgentTemplate con prefetch la imagen trae un demonio que, tras cada restauración, espera a que el guest se calme y precarga los binarios siempre que construyas la imagen con AgentTemplate (es el valor por defecto) ≈ $0
B. pause() entre turnos una VM por conversación, suspendida entre turnos; connect() la reanuda (≈ 3 s hasta el primer token) el caso general: conversaciones de menos de 8 h ≈ $0,005–0,006 por ciclo + ≈ $0,0001/h pausada
C. Pool con warmup agent_pool_warmup("opencode") corre el binario en cada plaza antes de aparcarla (≈ 5 s hasta el primer token desde la toma) muchas conversaciones nuevas cuyo primer mensaje tiene que ser rápido ≈ $0,64/plaza ociosa/mes
D. Pool con opencode serve residente agent_pool_warmup("opencode", serve=True); run se engancha con --attach no recomendada: apenas gana a C ≈ $0,82/plaza ociosa/mes

Las cifras están medidas en AWS real (AWS_API_NOTES.md Q146–Q154): Arranque rápido.

La opción D se retira en 0.9.0

serve=True, attach y el opencode serve residente desaparecen en 0.9.0 sin periodo de obsolescencia. Usa C (agent_pool_warmup("opencode")) o el arranque normal; ver la nota de Novedades.

La imagen del agente. AgentTemplate instala OpenCode y ripgrep fijados por sha256, el venv de deepagents con --require-hashes (salvo --no-deepagents / runtimes: ["opencode"]), su runner y el manifiesto rayito.agent-template/1, todo de root:

from rayito import AgentTemplate

AgentTemplate(
    name="rayito-agent",
    base="rayito-base-caps",
    runtimes=("opencode", "deepagents"),
    prefetch=True,
    memory_mib=2048,
).build(bucket="amzn-s3-demo-bucket")
import { AgentTemplate } from "rayito";

await new AgentTemplate({
  name: "rayito-agent",
  base: "rayito-base-caps",
  runtimes: ["opencode", "deepagents"],
  prefetch: true,
  memoryMib: 2048,
}).build({ bucket: "amzn-s3-demo-bucket" });
rayito agent template build --name rayito-agent --bucket amzn-s3-demo-bucket

Detalle y coste de build: Templates de agente.

El pool calentado. PoolConfig gana warmup (pasos que cada plaza corre antes de aparcarse; un paso fallido es un calentamiento fallido), allow_internet_access y network:

from rayito import PoolConfig, agent_pool_warmup

config = PoolConfig(
    size=3,
    template="rayito-agent",
    allow_internet_access=False,
    warmup=agent_pool_warmup("opencode"),
)
import { SandboxPool, agentPoolWarmup } from "rayito";

await using pool = await new SandboxPool({
  size: 3,
  template: "rayito-agent",
  allowInternetAccess: false,
  warmup: agentPoolWarmup("opencode"),
}).start();

Detalle y medidas: Pool.

Coste y activación

Nada de esto cuesta sin pedirlo. AgentTemplate sólo cuesta si construyes la imagen (≈ 3,1 GB de snapshots, ≈ $0,057/semana por versión); warmup sólo si se lo pasas a un pool (≈ $0,64/plaza/mes, o ≈ $0,82 con serve=True); sbx.agent no tiene coste propio del SDK más allá de la VM, los tokens del modelo y la pasarela. Cada símbolo lleva su bloque "Coste y activación" y su fila en Funciones opcionales.

Precios: la VM frente a los tokens

La página Precios reúne el coste de cada componente de las MicroVMs (lanzamiento, cómputo, snapshots, suspensión), del pool por plaza y de un agente, separando lo que cuesta la VM de lo que cuestan los tokens del modelo. Cada cifra va marcada como precio de lista (con su fecha de consulta) o como medida en AWS real. Para un agente, el modelo suele pesar más que la VM: Coste de un agente y qué opción de arranque rápido elegir.

Otras correcciones y cambios

Agente (todo nuevo en 0.8.0; corregido antes de la release tras la aceptación en AWS real):

  • abort() y los límites max_steps / max_total_tokens paran también lo que lanzó la herramienta de shell del agente (un sleep o un servidor ya no sobreviven), el runtime no se queda gastando tokens en segundo plano y el siguiente run() no lo encuentra busy.
  • Un timeout de AgentLimits termina con reason="timeout", no con "runtime_error". El timeout sigue sin alcanzar a lo que lanzó el shell del agente (aviso).
  • El demonio de prefetch espera a que el guest lleve 1 s sin E/S (como mucho 60 s) antes de leer: antes competía con el arranque y create() tardaba ≈ 8 s más.
  • AgentTemplate instala el runner de deepagents (y su sha256 en el manifiesto); sin él, runtime="deepagents" fallaba en esas imágenes.
  • prepare() arranca sus pasos sin plazo: con serve=True el servidor residente ya no muere al agotar timeout_seconds / timeoutMs.
  • Con un opencode serve residente (opción D), el SDK relee del servidor los mensajes de cada vuelta y ya no devuelve protocol_error ni un Done sin texto.
  • deepagents: las herramientas de ficheros usan una ruta absoluta tal cual, como el shell.

Resto del SDK:

  • Montajes S3: el MountException / MountError con code="not_allowed" explica que el bucket falta en RAYITO_ALLOWED_MOUNT_BUCKETS y cómo republicar la imagen con él, sin nombrar el bucket (el allowlist de la imagen).
  • Python: import rayito vuelve a ser ligero. El agente y el adaptador boto3 de los eventos de ciclo de vida se importan en el primer acceso a sus nombres (unas 20 entradas menos en sys.modules).
  • rayito doctor conoce la serie 0.8: exige el rayd del tag rayd-v0.8.0 para el SDK 0.8 (Compatibilidad).

rayd 0.8.0: sin cambios en el agente. El agente de IA corre sobre los RPC que ya existían, y la versión sube en paso con los SDK.

Cómo actualizar desde 0.7.x

  1. Actualiza el SDK.

    pip install -U "rayito[cli]"
    
    pnpm add rayito@latest
    
  2. Republica tu imagen sobre rayd 0.8.0 (Imágenes). La serie de compatibilidad pasa a 0.8: rayito doctor exige el rayd del tag rayd-v0.8.0 para el SDK 0.8 y da FAIL en la comprobación compatibility con una imagen 0.7.

  3. Para usar el agente, construye su imagen con AgentTemplate o rayito agent template build (Templates de agente). Sin el runtime en la imagen, sbx.agent falla con reason="runtime_missing".
  4. Revisa el cambio que rompe:
Qué Antes (hasta 0.7.1) Desde 0.8.0
register_webhook / registerWebhook con una URL cuyo host es localhost (o *.localhost) o una IP literal no pública (loopback, privada, link-local, de metadatos, multicast, reservada, sin especificar o CGNAT, también como IPv6 con una IPv4 dentro o en formas numéricas como 0x7f.1) se guardaba, pero el deliverer la descartaba en cada entrega: nunca se entregó nada InvalidArgumentException / InvalidArgumentError antes de cualquier llamada a AWS

Migración: registra una URL https:// con un nombre público (por ejemplo https://hooks.example.com/rayito), detrás de tu terminación TLS. Un nombre DNS sigue sin resolverse al registrarlo; si apunta a una dirección no pública, lo para el deliverer al entregar (Respuestas y reintentos).

Fuera de esa fila, no hay cambios incompatibles en la API pública de 0.7.x.

Lo que no trae 0.8.0

  • Sandbox.create(domain=) y que get_host()/expose() devuelvan la URL del dominio propio: siguen en desarrollo.
  • Que rayd mate el árbol entero de procesos al agotar el timeout del agente, y el aviso del SDK cuando un agente corre con el egress abierto: próximamente.

Detalle completo, cambio a cambio: Changelog.