Strumenti
Uno strumento è un’azione denominata che l’AI può invocare, con input tipizzati — ad es.send_email(to, subject, body). Gli strumenti sono dichiarati nel file tools.ts di una skill e, per gli strumenti che la tua app fornisce, supportati da una rotta HTTP in uno dei tuoi componenti. Questa pagina è la fonte di verità per il contratto dello strumento; Skills spiega dove si trova tools.ts.
Dichiarare uno strumento
Ogni voce intools.ts ha un name sicuro per il provider, un displayName descrittivo, una description, uno schema Zod input e un target che specifica cosa Kazzle invoca.
Target
target è l’indirizzo riutilizzabile per uno strumento o un pulsante di azione richiesta. Una chiamata diretta dello strumento AI e un clic del pulsante possono usare lo stesso oggetto target, quindi entrambi eseguono lo stesso codice.
I target HTTP usano gli stessi campi di richiesta:
body: '${input}'.
Riferimenti
Kazzle risolve i riferimenti nei campiquery, headers, body e url del target HTTP prima dell’invio:
${input}— l’intero input dello strumento, o l’intero input del pulsante.${input.path}— un valore annidato dall’input.${env.NAME}— una variabile d’ambiente denominata dallaenv.collectiondichiarata del componente app proprietario +env.environment.
$${input.name} quando hai bisogno del testo letterale ${input.name}.
Richiesta del handler
Per un targetapp, aggiungi la rotta corrispondente nel componente target. Con body: '${input}', Kazzle invia l’input tipizzato come corpo JSON:
app ricevono anche:
I target app non possono impostare
Authorization tramite headers; Kazzle possiede quell’header. Leggi il contesto con toolContext(req) da @kazzle/app/tools quando l’handler deve distinguere tra thread e Tools API.
Uno strumento dichiarato senza una rotta corrispondente non è utile — aggiungili entrambi. tools.json non è supportato; il compilatore dell’app fallisce se ne trova uno.
Risposta del handler
Restituisci testo semplice, o JSON con fino a tre canali:content— il risultato semplice che l’AI legge (fornito al modello). Obbligatorio.markdown— opzionale. Un breve riepilogo in testo ricco renderizzato nella scheda dello strumento (react-markdown; l’HTML grezzo è sfuggito). Adatto per una frase, un piccolo elenco, un link inline. Un percorso relativo nudo viene renderizzato come testo preformattato morto — i link devono essere assoluti.embedUrl— opzionale. Un URL assoluto che la tua app fornisce; la scheda lo renderizza in un iframe sandbox. Questo è il modo per mostrare un’interfaccia utente reale e a larghezza intera — una schermata di connessione, una dashboard, un grafico. La tua app ospita e possiede la pagina, quindi può essere completamente interattiva con il tuo backend, i cookie e OAuth. Nulla viene scritto nel drive.
embedUrl ha la precedenza su markdown quando entrambi sono impostati. Mantieni sempre un content significativo — è quello che l’AI legge.
Azione richiesta
Uno strumento app può mettere in pausa il thread quando ha bisogno di un’azione dell’utente (o del dispositivo). Restituiscitype: 'action_required' con un titolo della scheda e pulsanti. Valido solo quando toolContext(req).source === 'thread' — tramite Tools API (source: 'api'), restituisci invece un errore di dominio normale.
/chat/resume dopo che un pulsante è stato premuto. I client corrispondenti vedono i pulsanti dell’autore; i client non corrispondenti vedono ancora Skip/Cancel più “Continue on ”. Un pulsante senza target invia il suo input come risultato dello strumento. Un pulsante con un target esegue prima quel target, quindi usa il risultato del target come risultato dello strumento.
Interfaccia utente ricca — incorpora una pagina ospitata dall’app
Quando il risultato di uno strumento è visivo o interattivo (una schermata di connessione, un grafico, una dashboard di riepilogo), fornisci la pagina da uno dei tuoi componenti e restituisci il suo URL assoluto comeembedUrl. Costruisci l’URL dall’URL del componente iniettato — mai un percorso relativo.
embedUrl rispetto all’emissione di stringhe HTML: la tua app fornisce già pagine, l’interfaccia utente rimane interattiva e versionata con il tuo codice, e nessun artefatto per chiamata viene scritto da nessuna parte.