Saltar a contenido

Proveedores del agente

Desde 0.10.0 (Novedades de 0.10.0).

El agente de sbx.agent llama a su modelo sólo a través de la pasarela de secretos: la clave vive en Secrets Manager, rayd la inyecta en la cabecera y el runtime (OpenCode o deepagents) sólo ve un marcador. Además de Bedrock, Anthropic y openai_compatible_gateway, hay un preset por proveedor con clave de API estática. Cada preset fija el upstream, la cabecera y las rutas permitidas, y se combina con un AgentModel.

Todo se configura en tres pasos: guardas la clave en Secrets Manager, pasas el preset en gateways= al crear el sandbox y apuntas el AgentModel a esa pasarela (ejemplo).

¿Cuál elijo?

Tu situación Elige
Ya trabajas en AWS y quieres una sola factura Bedrock (bedrock_gateway): la pasarela limita también qué modelos se llaman, y es la ruta más probada
Tienes clave de OpenAI OpenAI
Tu organización usa Azure Azure OpenAI: el modelo es un despliegue de tu recurso, con su cuota
Quieres Gemini Gemini: como en Bedrock, la pasarela limita los modelos
Quieres probar muchos modelos con una sola clave OpenRouter
Buscas velocidad o precio bajo Groq, DeepSeek o Mistral
Tienes clave de xAI (Grok) xAI
Ya tienes un proxy de LiteLLM, o quieres modelos locales LiteLLM: claves virtuales con presupuesto y cualquier modelo que sirva el proxy
Tienes una suscripción de consumo (ChatGPT, Claude Pro/Max, Copilot, SuperGrok) no se admite: Proveedores no admitidos

Si dudas, empieza por Bedrock o por LiteLLM delante de Bedrock: son las rutas probadas con un modelo real (Qué se ha probado).

Proveedor Preset (Python / TypeScript) Upstream Cabecera (valor del secreto) Rutas permitidas AgentModel
OpenAI openai_gateway(secret) / openaiGateway(secret) https://api.openai.com authorization (Bearer sk-…) POST /v1/responses, POST /v1/chat/completions provider="openai"
Gemini (AI Studio) gemini_gateway(secret, models=[…]) / geminiGateway(secret, { models }) https://generativelanguage.googleapis.com x-goog-api-key (la clave tal cual) por modelo: POST /v1beta/models/<m>:streamGenerateContent y :generateContent provider="google"
Azure OpenAI v1 azure_openai_gateway(secret, resource="…") / azureOpenaiGateway(secret, { resource }) https://<resource>.openai.azure.com api-key (la clave tal cual) POST /openai/v1/responses, POST /openai/v1/chat/completions provider="azure"
OpenRouter openrouter_gateway(secret) / openrouterGateway(secret) https://openrouter.ai authorization (Bearer …) POST /api/v1/chat/completions provider="openai-compatible", base_path="/api/v1"
Groq groq_gateway(secret) / groqGateway(secret) https://api.groq.com authorization (Bearer …) POST /openai/v1/chat/completions provider="openai-compatible", base_path="/openai/v1"
Mistral mistral_gateway(secret) / mistralGateway(secret) https://api.mistral.ai authorization (Bearer …) POST /v1/chat/completions provider="openai-compatible", base_path="/v1"
DeepSeek deepseek_gateway(secret) / deepseekGateway(secret) https://api.deepseek.com authorization (Bearer …) POST /chat/completions provider="openai-compatible" sin base_path
xAI xai_gateway(secret) / xaiGateway(secret) https://api.x.ai authorization (Bearer xai-…) POST /v1/responses, POST /v1/chat/completions provider="openai"
LiteLLM (proxy propio) litellm_gateway(secret, upstream="https://…", base_path="/v1") / litellmGateway(secret, { upstream, basePath }) el upstream que pases (https://host) authorization (Bearer <clave virtual>) POST <base_path>/responses, POST <base_path>/chat/completions provider="openai-compatible", base_path igual al del preset

Todos aceptan rate_per_minute / ratePerMinute. Los valores exactos están en testdata/agent/provider-catalogue.json, el fichero que comprueban los tests de los dos SDKs.

Notas por proveedor:

  • Gemini. models es obligatorio y lleva el id sin el prefijo models/ (gemini-2.5-flash). Incluye también el small_model del agente: OpenCode lo usa para los títulos y la pasarela rechaza cualquier modelo que no esté en la lista.
  • Azure OpenAI. resource es el subdominio del recurso (1-63 caracteres [a-z0-9-], sin guion al principio ni al final). El id del AgentModel es el nombre del despliegue. Los dos runtimes usan la Responses API (/openai/v1/responses) con la clave en api-key: OpenCode con @ai-sdk/azure y deepagents con AzureChatOpenAI.
  • xAI usa el proveedor openai: OpenCode y deepagents le hablan con la Responses API como a OpenAI, contra otro upstream.
  • LiteLLM. El proxy tiene que estar detrás de HTTPS y ser alcanzable desde la VPC del sandbox. Un localhost de tu portátil no lo es: el preset rechaza localhost, loopback (127.0.0.0/8), 0.0.0.0 y enlace local (169.254.0.0/16).
  • vLLM, LM Studio, Ollama, Together, Fireworks… siguen yendo por openai_compatible_gateway, con las mismas condiciones que LiteLLM.

Ejemplo

El secreto guarda el valor completo de la cabecera (Bearer … para las APIs al estilo de OpenAI). Con OpenAI:

from rayito import AgentModel, AgentSpec, Sandbox, SecretStore, openai_gateway

SecretStore().create("openai-key", "Bearer <clave de API de OpenAI>")

spec = AgentSpec(model=AgentModel(provider="openai", id="gpt-5-mini", gateway="openai"))

with Sandbox.create(
    template="rayito-agent",
    allow_internet_access=False,
    gateways={"openai": openai_gateway("openai-key", rate_per_minute=60)},
) as sbx:
    result = sbx.agent.run("Resume el README.", spec=spec)
    print(result.text)
from rayito import AgentModel, AgentSpec, AsyncSandbox, gemini_gateway

MODELS = ["gemini-2.5-flash", "gemini-2.5-flash-lite"]


async def main() -> None:
    spec = AgentSpec(
        model=AgentModel(provider="google", id=MODELS[0], gateway="gemini"),
        small_model=MODELS[1],
    )
    async with await AsyncSandbox.create(
        template="rayito-agent",
        allow_internet_access=False,
        gateways={"gemini": gemini_gateway("gemini-key", models=MODELS)},
    ) as sbx:
        result = await sbx.agent.run("Resume el README.", spec=spec)
        print(result.text)
import { AgentModel, AgentSpec, Sandbox, openrouterGateway } from "rayito";

const spec = new AgentSpec({
  model: new AgentModel({
    provider: "openai-compatible",
    id: "anthropic/claude-haiku-4.5",
    gateway: "openrouter",
    basePath: "/api/v1",
  }),
});

await using sbx = await Sandbox.create({
  template: "rayito-agent",
  allowInternetAccess: false,
  gateways: { openrouter: openrouterGateway("openrouter-key", { ratePerMinute: 60 }) },
});
const result = await sbx.agent.run("Resume el README.", { spec });
console.log(result.text);

Coste y activación

  • Activa: pasar el preset en gateways= / gateways de Sandbox.create y usarlo desde un AgentModel. Construir un preset no llama a AWS ni carga ningún peer opcional.
  • Recursos y llamadas AWS: los de la pasarela de secretos: una lectura de Secrets Manager (GetSecretValue) por cabecera y TTL de la caché al aplicar la pasarela. Ningún recurso nuevo.
  • Coste aproximado: $0,05 por 10 000 lecturas más $0,40 al mes por secreto (us-east-1, consultado el 2026-10-07, precios de Secrets Manager). Lo domina el modelo, que factura el proveedor por tokens.
  • IAM: secretsmanager:GetSecretValue sobre el secreto (RayitoSecretsReader).
  • Cómo apagarla: no pasar la pasarela ni llamar a sbx.agent.

Configurar cada proveedor

Cada apartado crea el secreto (una vez, desde tu máquina o tu backend), construye el preset y el AgentModel. Los dos se pasan como en el ejemplo: el preset en gateways= y el modelo en AgentSpec. La clave que uses en gateways= (Python) o gateways (TypeScript) es el nombre al que apunta AgentModel.gateway: por ejemplo gateways={"openai": gateway} con AgentModel(gateway="openai"); si no coinciden, sbx.agent.run() falla con InvalidArgumentException. Los ids de modelo son ejemplos: usa los que ofrezca tu cuenta.

OpenAI

Crea la clave en un proyecto propio de la plataforma de OpenAI y fija ahí el presupuesto mensual y los modelos permitidos. Referencia: platform.openai.com.

from rayito import AgentModel, SecretStore, openai_gateway

SecretStore().create("openai-key", "Bearer <clave de API de OpenAI>")
gateway = openai_gateway("openai-key")
model = AgentModel(provider="openai", id="gpt-5-mini", gateway="openai")
import { AgentModel, SecretStore, openaiGateway } from "rayito";

await new SecretStore().create("openai-key", "Bearer <clave de API de OpenAI>");
const gateway = openaiGateway("openai-key");
const model = new AgentModel({ provider: "openai", id: "gpt-5-mini", gateway: "openai" });

Gemini (AI Studio)

El secreto guarda la clave tal cual, sin Bearer. Es el único preset no Bedrock que limita el modelo en la pasarela: pon en models también el small_model. Fija además la cuota y la facturación del proyecto de Google. Referencia: ai.google.dev.

from rayito import AgentModel, SecretStore, gemini_gateway

SecretStore().create("gemini-key", "<clave de API de Gemini>")
gateway = gemini_gateway("gemini-key", models=["gemini-2.5-flash", "gemini-2.5-flash-lite"])
model = AgentModel(provider="google", id="gemini-2.5-flash", gateway="gemini")
import { AgentModel, SecretStore, geminiGateway } from "rayito";

await new SecretStore().create("gemini-key", "<clave de API de Gemini>");
const gateway = geminiGateway("gemini-key", { models: ["gemini-2.5-flash", "gemini-2.5-flash-lite"] });
const model = new AgentModel({ provider: "google", id: "gemini-2.5-flash", gateway: "gemini" });

Azure OpenAI

El secreto guarda la clave tal cual (cabecera api-key). El id es el nombre del despliegue. Crea sólo los despliegues que necesites y limita su cuota (TPM). Funciona con OpenCode y con deepagents. Referencia: learn.microsoft.com.

from rayito import AgentModel, SecretStore, azure_openai_gateway

SecretStore().create("azure-openai-key", "<clave del recurso de Azure OpenAI>")
gateway = azure_openai_gateway("azure-openai-key", resource="mi-recurso")
model = AgentModel(provider="azure", id="mi-despliegue", gateway="azure")
import { AgentModel, SecretStore, azureOpenaiGateway } from "rayito";

await new SecretStore().create("azure-openai-key", "<clave del recurso de Azure OpenAI>");
const gateway = azureOpenaiGateway("azure-openai-key", { resource: "mi-recurso" });
const model = new AgentModel({ provider: "azure", id: "mi-despliegue", gateway: "azure" });

OpenRouter

Pon un límite de crédito en la clave: la documentación de OpenRouter avisa de que un agente desbocado puede gastar todo el saldo. Referencia: openrouter.ai.

from rayito import AgentModel, SecretStore, openrouter_gateway

SecretStore().create("openrouter-key", "Bearer <clave de OpenRouter>")
gateway = openrouter_gateway("openrouter-key")
model = AgentModel(provider="openai-compatible", id="anthropic/claude-haiku-4.5", gateway="openrouter", base_path="/api/v1")
import { AgentModel, SecretStore, openrouterGateway } from "rayito";

await new SecretStore().create("openrouter-key", "Bearer <clave de OpenRouter>");
const gateway = openrouterGateway("openrouter-key");
const model = new AgentModel({ provider: "openai-compatible", id: "anthropic/claude-haiku-4.5", gateway: "openrouter", basePath: "/api/v1" });

Groq

Revisa los límites de uso de la organización en la consola de Groq. Referencia: console.groq.com.

from rayito import AgentModel, SecretStore, groq_gateway

SecretStore().create("groq-key", "Bearer <clave de Groq>")
gateway = groq_gateway("groq-key")
model = AgentModel(provider="openai-compatible", id="<modelo de Groq>", gateway="groq", base_path="/openai/v1")
import { AgentModel, SecretStore, groqGateway } from "rayito";

await new SecretStore().create("groq-key", "Bearer <clave de Groq>");
const gateway = groqGateway("groq-key");
const model = new AgentModel({ provider: "openai-compatible", id: "<modelo de Groq>", gateway: "groq", basePath: "/openai/v1" });

Mistral

Fija los límites de gasto del workspace en la consola de Mistral. Referencia: docs.mistral.ai.

from rayito import AgentModel, SecretStore, mistral_gateway

SecretStore().create("mistral-key", "Bearer <clave de Mistral>")
gateway = mistral_gateway("mistral-key")
model = AgentModel(provider="openai-compatible", id="<modelo de Mistral>", gateway="mistral", base_path="/v1")
import { AgentModel, SecretStore, mistralGateway } from "rayito";

await new SecretStore().create("mistral-key", "Bearer <clave de Mistral>");
const gateway = mistralGateway("mistral-key");
const model = new AgentModel({ provider: "openai-compatible", id: "<modelo de Mistral>", gateway: "mistral", basePath: "/v1" });

DeepSeek

Sin base_path: la API cuelga de la raíz. DeepSeek es de prepago: el saldo cargado es el tope. Referencia: api-docs.deepseek.com.

from rayito import AgentModel, SecretStore, deepseek_gateway

SecretStore().create("deepseek-key", "Bearer <clave de DeepSeek>")
gateway = deepseek_gateway("deepseek-key")
model = AgentModel(provider="openai-compatible", id="<modelo de DeepSeek>", gateway="deepseek")
import { AgentModel, SecretStore, deepseekGateway } from "rayito";

await new SecretStore().create("deepseek-key", "Bearer <clave de DeepSeek>");
const gateway = deepseekGateway("deepseek-key");
const model = new AgentModel({ provider: "openai-compatible", id: "<modelo de DeepSeek>", gateway: "deepseek" });

xAI

Usa el proveedor openai contra otro upstream. Fija los límites de gasto del equipo en la consola de xAI. Referencia: docs.x.ai.

from rayito import AgentModel, SecretStore, xai_gateway

SecretStore().create("xai-key", "Bearer <clave de API de xAI>")
gateway = xai_gateway("xai-key")
model = AgentModel(provider="openai", id="<modelo de xAI>", gateway="xai")
import { AgentModel, SecretStore, xaiGateway } from "rayito";

await new SecretStore().create("xai-key", "Bearer <clave de API de xAI>");
const gateway = xaiGateway("xai-key");
const model = new AgentModel({ provider: "openai", id: "<modelo de xAI>", gateway: "xai" });

LiteLLM (tu propio proxy)

Si ya tienes un proxy de LiteLLM, el agente puede usar cualquier modelo que ese proxy sirva (de cualquier proveedor o local) con una sola clave virtual. Condiciones:

  • El proxy escucha en HTTPS y es alcanzable desde la VPC del sandbox. upstream es https://host o https://host:puerto, sin ruta. El preset rechaza http://, localhost, loopback, 0.0.0.0 y enlace local.
  • El secreto guarda Bearer <clave virtual>. Crea la clave virtual con presupuesto (max_budget) y lista de modelos: es el único tope real, porque la pasarela no ve el modelo.
  • base_path es /v1 por defecto; el del AgentModel tiene que ser el mismo. Se permiten POST <base_path>/chat/completions y POST <base_path>/responses.
from rayito import AgentModel, SecretStore, litellm_gateway

SecretStore().create("litellm-key", "Bearer <clave virtual de LiteLLM>")
gateway = litellm_gateway("litellm-key", upstream="https://llm.example.com")
model = AgentModel(provider="openai-compatible", id="<modelo del proxy>", gateway="litellm", base_path="/v1")
import { AgentModel, SecretStore, litellmGateway } from "rayito";

await new SecretStore().create("litellm-key", "Bearer <clave virtual de LiteLLM>");
const gateway = litellmGateway("litellm-key", { upstream: "https://llm.example.com" });
const model = new AgentModel({ provider: "openai-compatible", id: "<modelo del proxy>", gateway: "litellm", basePath: "/v1" });

Modelos locales

vLLM, LM Studio, Ollama y similares funcionan si los publicas detrás de HTTPS en una dirección que la VPC del sandbox alcance (un balanceador interno, por ejemplo). Puedes apuntar a ellos directamente con openai_compatible_gateway(secret, upstream=, base_path=) / openaiCompatibleGateway(secret, { upstream, basePath }), o ponerlos detrás de LiteLLM para tener claves virtuales y presupuestos. El localhost de tu portátil nunca es alcanzable desde la microVM.

Límites del lado del proveedor

Sólo Bedrock y Gemini llevan el modelo en la ruta, así que la allowlist de la pasarela lo limita. En Anthropic (anthropic_gateway, sólo POST /v1/messages) y en las APIs al estilo de OpenAI (OpenAI, Azure OpenAI, xAI, OpenRouter, Groq, Mistral, DeepSeek, LiteLLM) el modelo va en el cuerpo, que la pasarela reenvía sin leer: el código del sandbox puede pedir cualquier modelo que la clave permita, fuera del presupuesto de tokens del SDK (SECURITY.md T29). Fija el tope en el proveedor:

  • OpenAI: un proyecto propio para la clave, con presupuesto mensual y modelos permitidos.
  • OpenRouter: límite de crédito en la clave. Su propia documentación avisa de que un agente desbocado puede gastar todo el saldo.
  • Azure OpenAI: sólo los despliegues que necesites y su cuota (TPM).
  • Anthropic: un workspace propio para la clave, con límite de gasto.
  • LiteLLM: presupuesto y modelos permitidos por clave virtual.
  • Groq, Mistral, DeepSeek, xAI: límites de gasto o de uso de la cuenta o del equipo.

rate_per_minute también ayuda: limita las peticiones que pasan por la pasarela, las haga el agente o cualquier otro código del sandbox.

Qué se ha probado

Ruta Cómo se probó
Bedrock (bedrock_gateway), OpenCode y deepagents con modelo real, en AWS real (MicroVMs), desde Python y TypeScript, en la aceptación de cada release
API compatible con OpenAI de Bedrock (bedrock-runtime /openai/v1 y bedrock-mantle) por openai_compatible_gateway con modelo real, en el entorno local con el egress cerrado: herramientas, sesión y uso de tokens
provider="openai" (Responses API) contra bedrock-mantle con modelo real, en local, una vuelta sin herramientas
LiteLLM (litellm_gateway) delante de Bedrock con modelo real, en local: herramientas, sesión y uso de tokens
OpenAI, Gemini, Azure OpenAI, OpenRouter, Groq, Mistral, DeepSeek y xAI sólo contra un upstream falso: cada preset con OpenCode y deepagents, desde Python y TypeScript, completa una vuelta, la clave llega en su cabecera, el marcador nunca sale y una ruta fuera de la lista recibe 403

Las ocho últimas no se han probado con una clave real del proveedor. Con una clave tuya, la prueba de humo hace una vuelta corta contra la API real por menos de 0,01 USD por proveedor.

Proveedores no admitidos

Rayito sólo admite claves de API. Estas formas de acceso se revisaron (consultado el 2026-10-07) y no se admiten:

Opción Decisión Por qué
Plan de ChatGPT con el OAuth que trae OpenCode Rechazada Usa el client_id de otra aplicación y el backend-api de ChatGPT. OpenAI pide expresamente no apuntar a esos endpoints (models-and-inference). Además exige el refresh token dentro del sandbox, donde el agente podría leerlo.
Plan de ChatGPT con "Sign in with ChatGPT" Aplazada OpenAI lo documenta para apps open-source y alojadas en local; para una app alojada en remoto pide rellenar un formulario de interés (overview). Queda pendiente de que OpenAI confirme este caso. Para uso programático, OpenAI recomienda clave de API (Codex auth).
Claude Pro/Max Rechazada Los términos de consumo de Anthropic y la página legal and compliance de Claude Code no permiten que terceros enruten peticiones con credenciales de planes de consumo. OpenCode quitó ese acceso (docs de proveedores). Usa una clave de API de Anthropic o Bedrock.
GitHub Copilot Rechazada GitHub admite Copilot en OpenCode para uso interactivo (changelog), pero no hay términos para flotas desatendidas (su política de uso aceptable limita la actividad automatizada masiva), y exigiría reutilizar el OAuth de OpenCode.
SuperGrok Rechazada xAI lo ofrece en OpenCode (anuncio), pero no hay términos publicados para automatización. Usa la clave de API de xAI.

Tampoco se pueden colar por otro camino: provider, enabled_providers y plugin son claves reservadas de raw_config (así no se carga un plugin OAuth de Copilot, Codex o Gemini), ningún tipo del SDK tiene campo de credencial, y el adaptador de OpenCode nunca escribe un auth.json ni las claves auth o plugin.