SDK y clientes
Sonoe no necesita un SDK propio: los SDK oficiales de TypeSafe funcionan con él sin cambios, y cualquier cliente HTTP también.
Los SDK de TypeSafe
Los dos SDK leen su configuración del entorno. Para usar Sonoe, define la URL base y una key de Sonoe:
export TYPESAFE_BASE_URL="https://api.sonoeai.com"
export TYPESAFE_API_KEY="sk_sonoe_..."
export TYPESAFE_DEFAULT_MODEL="sonoe-latest" # opcional: los SDK usan jev-latest por defecto, que Sonoe también aceptaPython
pip install typesafe-sdkfrom typesafe_sdk import Choice, Noul, Score, TypeSafeClient
client = TypeSafeClient() # o TypeSafeClient(api_key=..., base_url="https://api.sonoeai.com")
result = client.system_one(
"Me cobraron dos veces. Ayúdenme, por favor.",
{
"reembolso": Noul(instructions="¿Pide un reembolso?"),
"tono": Choice(instructions="¿Cuál es el tono?", criteria={"tranquilo": None, "molesto": None}),
"urgencia": Score(instructions="¿Qué tan urgente es?", criteria=["baja", "media", "alta"]),
},
)
print(result.nouls["reembolso"].noul, result.choices["tono"].choice, result.scores["urgencia"].score)
print(result.usage.input_tokens, result.request_id)import asyncio
from typesafe_sdk import AsyncTypeSafeClient, Noul
async def main() -> None:
async with AsyncTypeSafeClient() as client:
result = await client.system_one(
{"caso": "reembolso del pedido 18"},
{"reembolso": Noul(instructions="¿Pide un reembolso?")},
)
print(result.nouls["reembolso"].noul)
asyncio.run(main())JavaScript y TypeScript
npm install @typesafe-ai/sdkimport { choice, noul, score, TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient(); // o new TypeSafeClient({ apiKey, baseURL: "https://api.sonoeai.com" })
const { answers, usage } = await client.systemOne({
state: { documento: "Me cobraron dos veces. Arréglenlo lo antes posible." },
questions: {
categoria: choice("¿De qué trata este caso?", { facturacion: null, tecnico: null, otro: null }),
urgente: noul("¿Es urgente?"),
enojo: score("¿Qué tan molesto está el cliente?", ["tranquilo", "molesto", "furioso"]),
},
});
console.log(answers.categoria.choice, answers.urgente.noul, answers.enojo.score, usage);Qué funciona
Probado con typesafe-sdk 0.7.5 y @typesafe-ai/sdk 0.7.0:
- Preguntas Noul, Choice y Score, y respuestas tipadas.
- Clientes síncrono y asíncrono (Python),
withResponse()e ids de solicitud (JavaScript). models.list().- Cuerpos comprimidos con zstd (los SDK comprimen desde 1 KiB).
- Reintentos automáticos en
429y5xx, siguiendoRetry-After. - Errores como las propias excepciones de los SDK (
AuthenticationError,UnprocessableEntityError,RateLimitError…).
Las imágenes (image(), withAssets, box()) no funcionan: Sonoe solo lee texto y devuelve 422.
Cualquier cliente HTTP
La API es JSON sobre HTTPS. Manda Authorization: Bearer <key> y Content-Type: application/json:
import os
import requests
r = requests.post(
"https://api.sonoeai.com/v1/systemone",
headers={"Authorization": f"Bearer {os.environ['SONOE_API_KEY']}"},
json={
"model": "sonoe-latest",
"state": "¡Ayuda! Mis pagos llevan 3 días fallando.",
"questions": {"urgente": {"type": "noul", "instructions": "¿Es urgente?"}},
},
timeout=10,
)
if r.status_code == 429:
espera = int(r.headers.get("Retry-After", "10"))
r.raise_for_status()
print(r.json()["answers"]["urgente"]["noul"])const r = await fetch("https://api.sonoeai.com/v1/systemone", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.SONOE_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
model: "sonoe-latest",
state: "¡Ayuda! Mis pagos llevan 3 días fallando.",
questions: { urgente: { type: "noul", instructions: "¿Es urgente?" } },
}),
signal: AbortSignal.timeout(10_000),
});
const cuerpo = await r.json();
if (!r.ok) throw new Error(cuerpo.error?.message ?? `Sonoe: ${r.status}`);
console.log(cuerpo.answers.urgente.noul);Si escribes tu propio cliente:
- Reintenta los
429y503después deRetry-Aftersegundos (o con una espera corta). No reintentes los demás4xx. - Guarda en tus registros el encabezado
x-request-id; identifica la solicitud si necesitas ayuda. - Llama a Sonoe solo desde tu servidor. La key nunca debe llegar a un navegador ni a una app.