Skip to main content

Herramientas

Una herramienta es una acción nombrada que la IA puede invocar, con entradas tipadas — p. ej. send_email(to, subject, body). Las herramientas se declaran en el archivo tools.ts de una skill y, para herramientas que tu app sirve, están respaldadas por una ruta HTTP en uno de tus componentes. Esta página es la fuente de verdad para el contrato de herramientas; Skills cubre dónde vive tools.ts.

Declarar una herramienta

Cada entrada en tools.ts tiene un name seguro para proveedores, un displayName amigable, una description, un esquema Zod input, y un target que indica qué invoca Kazzle.

Destinos

target es la dirección reutilizable para una herramienta o botón de acción requerida. Una llamada directa de herramienta de IA y un clic de botón pueden usar el mismo objeto target, por lo que ambos ejecutan el mismo código. Los destinos HTTP usan los mismos campos de solicitud:
No hay valores por defecto implícitos en la solicitud. Si tu manejador debe recibir la entrada de herramienta sin procesar como JSON, escribe body: '${input}'.

Referencias

Kazzle resuelve referencias en los campos query, headers, body y url del destino HTTP antes del envío:
  • ${input} — toda la entrada de herramienta, o toda la entrada de botón.
  • ${input.path} — un valor anidado de la entrada.
  • ${env.NAME} — una variable de entorno nombrada de la env.collection declarada del componente de app propietario + env.environment.
La resolución es de un solo paso. Si falta una referencia o es desconocida, la herramienta falla en lugar de sustituir un valor vacío. Usa $${input.name} cuando necesites texto literal ${input.name}.

Solicitud del manejador

Para un destino app, añade la ruta coincidente en el componente destino. Con body: '${input}', Kazzle envía la entrada tipada como cuerpo JSON:
Los destinos app también reciben: Los destinos de app no pueden establecer Authorization a través de headers; Kazzle es propietario de ese encabezado. Lee el contexto con toolContext(req) desde @kazzle/app/tools cuando el manejador debe ramificarse entre thread y Tools API. Una herramienta declarada sin una ruta coincidente no hace nada útil — añade ambas juntas. tools.json no es compatible; el compilador de app falla si encuentra uno.

Respuesta del manejador

Devuelve texto sin formato, o JSON con hasta tres canales:
  • content — el resultado sin formato que la IA lee (alimentado al modelo). Requerido.
  • markdown — opcional. Un resumen de texto enriquecido corto renderizado en la tarjeta de herramienta (react-markdown; el HTML sin procesar se escapa). Bueno para una oración, una lista pequeña, un enlace en línea. Una ruta relativa sin procesar se renderiza como texto preformateado muerto — los enlaces deben ser absolutos.
  • embedUrl — opcional. Una URL absoluta que tu app sirve; la tarjeta la renderiza en un iframe aislado. Así es como muestras una interfaz real y de ancho completo — una pantalla de conexión, un panel, un gráfico. Tu app aloja y es propietaria de la página, por lo que puede ser completamente interactiva contra tu propio backend, cookies y OAuth. Nada se escribe en el drive.
embedUrl prevalece sobre markdown cuando ambos están establecidos. Siempre mantén un content significativo — eso es lo que la IA lee.

Acción requerida

Una herramienta de app puede pausar el thread cuando necesita una acción del usuario (o dispositivo). Devuelve type: 'action_required' con un título de tarjeta y botones. Solo válido cuando toolContext(req).source === 'thread' — sobre la Tools API (source: 'api'), devuelve un error de dominio normal en su lugar.
Kazzle guarda la tarjeta en la llamada de herramienta y reanuda a través de /chat/resume después de que se presiona un botón. Los clientes coincidentes ven los botones del autor; los clientes no coincidentes aún ven Omitir/Cancelar más “Continuar en ”. Un botón sin target envía su input como resultado de herramienta. Un botón con un destino ejecuta ese destino primero, luego usa el resultado del destino como resultado de herramienta.

Interfaz enriquecida — incrustar una página alojada en app

Cuando el resultado de una herramienta es visual o interactivo (una pantalla de conexión, un gráfico, un panel de resumen), sirve la página desde uno de tus componentes y devuelve su URL absoluta como embedUrl. Construye la URL a partir de la URL del componente inyectada — nunca una ruta relativa.
La página se ejecuta en un iframe de origen cruzado (su propio origen, cookies y scripts). Para dimensionar la tarjeta, publica su altura al padre — la tarjeta escucha esto y se redimensiona (limitado al 70% de la ventana gráfica):
Prefiere embedUrl sobre emitir cadenas HTML: tu app ya sirve páginas, la interfaz permanece interactiva y versionada con tu código, y ningún artefacto por llamada se escribe en ningún lugar.