Documentation Index
Fetch the complete documentation index at: https://docs.jelou.ai/llms.txt
Use this file to discover all available pages before exploring further.
Validación de entrada
Cuando defines un esquema input, cada petición se valida antes de ejecutar el handler. Si la validación falla, el handler no se ejecuta y se retorna un 400:
{
"error": "Validation failed",
"details": [
{
"path": ["email"],
"message": "Invalid email",
"code": "invalid_string"
}
]
}
Ejemplo con esquema completo
import { define, z } from "@jelou/functions";
export default define({
name: "crear-ticket",
description: "Crea un ticket de soporte desde WhatsApp",
input: z.object({
nombre: z.string().min(1).describe("Nombre del cliente"),
email: z.string().email().describe("Email de contacto"),
asunto: z.string().max(200).describe("Asunto del ticket"),
prioridad: z.enum(["baja", "media", "alta"]).default("media"),
}),
output: z.object({
ticketId: z.string(),
estado: z.string(),
}),
handler: async (input, ctx) => {
ctx.log("Creando ticket", { cliente: input.nombre, prioridad: input.prioridad });
return { ticketId: "TKT-2024-0042", estado: "abierto" };
},
});
Tipos soportados
Puedes usar cualquier tipo de Zod dentro de z.object():
input: z.object({
nombre: z.string().min(1),
edad: z.number().int().positive(),
email: z.string().email(),
activo: z.boolean().default(true),
rol: z.enum(["admin", "usuario", "invitado"]),
tags: z.array(z.string()).optional(),
metadata: z.record(z.string(), z.unknown()).optional(),
})
Coerción en peticiones GET
Para peticiones GET, los query parameters son strings. Usa z.coerce para convertir tipos automáticamente:
import { define, z } from "@jelou/functions";
export default define({
name: "buscar-pedidos",
description: "Busca pedidos por estado",
input: z.object({
q: z.string(),
limit: z.coerce.number().default(10),
pagina: z.coerce.number().default(1),
activo: z.coerce.boolean().default(true),
}),
handler: async (input, ctx) => {
ctx.log("Buscando", { q: input.q, limit: input.limit });
return { resultados: [], total: 0 };
},
});
curl "https://buscar-pedidos.fn.jelou.ai/?q=pendiente&limit=5&pagina=2"
Anotaciones .describe()
Usa .describe() en cada campo para documentar los parámetros. Estas descripciones aparecen automáticamente en el esquema MCP, lo que ayuda a los agentes IA a entender cómo usar tu función:
input: z.object({
telefono: z.string().min(10).describe("Número de teléfono con código de país, ej: 593987654321"),
incluirHistorial: z.boolean().default(false).describe("Si incluir el historial de conversaciones"),
})
Validación de salida
Cuando defines un esquema output, el valor retornado por el handler se valida después de la ejecución. Si no coincide:
- Se registra una advertencia en los logs
- La respuesta se envía normalmente con status
200
La validación de output nunca bloquea la respuesta. Es una herramienta de desarrollo para detectar inconsistencias.
output: z.object({
nombre: z.string(),
saldo: z.number(),
})
Si el handler retorna { nombre: "María", saldo: "150" } (saldo como string), verás una advertencia en los logs pero el cliente recibe la respuesta sin cambios.
Cada error en el array details contiene:
| Campo | Tipo | Descripción |
|---|
path | string[] | Ruta al campo con error, ej: ["email"] o ["direccion", "ciudad"] |
message | string | Mensaje legible del error |
code | string | Código de error de Zod (ej: invalid_string, too_small, invalid_enum_value) |
{
"error": "Validation failed",
"details": [
{
"path": ["nombre"],
"message": "String must contain at least 1 character(s)",
"code": "too_small"
},
{
"path": ["prioridad"],
"message": "Invalid enum value. Expected 'baja' | 'media' | 'alta', received 'urgente'",
"code": "invalid_enum_value"
}
]
}