Outils
Un outil est une action nommée que l’IA peut appeler, avec des entrées typées — par exemplesend_email(to, subject, body). Les outils sont déclarés dans le fichier tools.ts d’une compétence et, pour les outils que votre application propose, soutenus par une route HTTP dans l’un de vos composants. Cette page est la source de vérité pour le contrat d’outil ; Compétences couvre l’emplacement de tools.ts.
Déclarer un outil
Chaque entrée danstools.ts a un name sûr pour le fournisseur, un displayName convivial, une description, un schéma Zod input, et une target qui indique ce que Kazzle invoque.
Cibles
target est l’adresse réutilisable pour un outil ou un bouton d’action requise. Un appel d’outil IA direct et un clic de bouton peuvent utiliser le même objet cible, donc les deux exécutent le même code.
Les cibles HTTP utilisent les mêmes champs de requête :
body: '${input}'.
Références
Kazzle résout les références dans les champsquery, headers, body et url de la cible HTTP avant la distribution :
${input}— l’entrée d’outil entière, ou l’entrée de bouton entière.${input.path}— une valeur imbriquée de l’entrée.${env.NAME}— une variable d’environnement nommée de laenv.collectiondéclarée du composant d’application propriétaire +env.environment.
$${input.name} quand vous avez besoin du texte littéral ${input.name}.
Requête du gestionnaire
Pour une cibleapp, ajoutez la route correspondante dans le composant cible. Avec body: '${input}', Kazzle envoie l’entrée typée comme corps JSON :
app reçoivent également :
Les cibles d’application ne peuvent pas définir
Authorization via headers ; Kazzle possède cet en-tête. Lisez le contexte avec toolContext(req) depuis @kazzle/app/tools quand le gestionnaire doit différencier thread vs Tools API.
Un outil déclaré sans route correspondante ne fait rien d’utile — ajoutez les deux ensemble. tools.json n’est pas supporté ; le compilateur d’application échoue s’il en trouve un.
Réponse du gestionnaire
Retournez du texte brut, ou du JSON avec jusqu’à trois canaux :content— le résultat brut que l’IA lit (fourni au modèle). Obligatoire.markdown— optionnel. Un court résumé en texte enrichi rendu dans la carte d’outil (react-markdown ; le HTML brut est échappé). Bon pour une phrase, une petite liste, un lien en ligne. Un chemin relatif nu s’affiche comme du texte préformaté mort — les liens doivent être absolus.embedUrl— optionnel. Une URL absolue que votre application propose ; la carte la rend dans une iframe en bac à sable. C’est ainsi que vous montrez une véritable interface pleine largeur — un écran de connexion, un tableau de bord, un graphique. Votre application héberge et possède la page, elle peut donc être entièrement interactive avec votre propre backend, cookies et OAuth. Rien n’est écrit sur le lecteur.
embedUrl prime sur markdown quand les deux sont définis. Gardez toujours un content significatif — c’est ce que l’IA lit.
Action requise
Un outil d’application peut mettre en pause le thread quand il a besoin d’une action utilisateur (ou appareil). Retourneztype: 'action_required' avec un titre de carte et des boutons. Valide uniquement quand toolContext(req).source === 'thread' — sur l’API Tools (source: 'api'), retournez une erreur de domaine normale à la place.
/chat/resume après qu’un bouton soit appuyé. Les clients correspondants voient les boutons de l’auteur ; les clients non correspondants voient toujours Ignorer/Annuler plus « Continuer sur ». Un bouton sans target soumet son input comme résultat d’outil. Un bouton avec une cible exécute d’abord cette cible, puis utilise le résultat de la cible comme résultat d’outil.
Interface riche — intégrer une page hébergée par l’application
Quand le résultat d’un outil est visuel ou interactif (un écran de connexion, un graphique, un tableau de bord récapitulatif), proposez la page depuis l’un de vos composants et retournez son URL absolue commeembedUrl. Construisez l’URL à partir de l’URL du composant injectée — jamais un chemin relatif.
embedUrl à l’émission de chaînes HTML : votre application propose déjà des pages, l’interface reste interactive et versionnée avec votre code, et aucun artefact par appel n’est écrit nulle part.