Skip to main content

Ferramentas

Uma ferramenta é uma ação nomeada que a IA pode chamar, com entradas tipadas — por exemplo, send_email(to, subject, body). As ferramentas são declaradas no tools.ts de uma skill e, para ferramentas que seu app oferece, são respaldadas por uma rota HTTP em um de seus componentes. Esta página é a fonte de verdade para o contrato de ferramentas; Skills cobre onde tools.ts fica.

Declarando uma ferramenta

Cada entrada em tools.ts tem um name seguro para o provedor, um displayName amigável, uma description, um schema Zod input e um target que diz o que Kazzle invoca.

Targets

target é o endereço reutilizável para uma ferramenta ou botão de ação obrigatória. Uma chamada de ferramenta de IA direta e um clique de botão podem usar o mesmo objeto target, então ambos executam o mesmo código. Os targets HTTP usam os mesmos campos de requisição:
Não há padrões de requisição implícitos. Se seu handler deve receber a entrada bruta da ferramenta como JSON, escreva body: '${input}'.

Referências

Kazzle resolve referências nos campos query, headers, body e url do target HTTP antes do envio:
  • ${input} — toda a entrada da ferramenta, ou toda a entrada do botão.
  • ${input.path} — um valor aninhado da entrada.
  • ${env.NAME} — uma variável de ambiente nomeada da env.collection declarada do componente do app proprietário + env.environment.
A resolução é de uma única passagem. Se uma referência está faltando ou desconhecida, a ferramenta falha em vez de substituir um valor vazio. Use $${input.name} quando você precisar do texto literal ${input.name}.

Requisição do handler

Para um target app, adicione a rota correspondente no componente target. Com body: '${input}', Kazzle envia a entrada tipada como o corpo JSON:
Os targets app também recebem: Os targets de app não podem definir Authorization através de headers; Kazzle é o proprietário desse header. Leia o contexto com toolContext(req) de @kazzle/app/tools quando o handler deve ramificar thread vs Tools API. Uma ferramenta declarada sem uma rota correspondente não faz nada útil — adicione ambas juntas. tools.json não é suportado; o compilador do app falha se encontrar um.

Resposta do handler

Retorne texto simples ou JSON com até três canais:
  • content — o resultado simples que a IA lê (alimentado ao modelo). Obrigatório.
  • markdown — opcional. Um resumo de texto rico curto renderizado no cartão da ferramenta (react-markdown; HTML bruto é escapado). Bom para uma frase, uma pequena lista, um link inline. Um caminho relativo simples renderiza como texto pré-formatado morto — links devem ser absolutos.
  • embedUrl — opcional. Uma URL absoluta que seu app oferece; o cartão a renderiza em um iframe em sandbox. É assim que você mostra uma UI real e de largura total — uma tela de conexão, um painel, um gráfico. Seu app hospeda e é proprietário da página, então pode ser totalmente interativa contra seu próprio backend, cookies e OAuth. Nada é escrito no drive.
embedUrl vence sobre markdown quando ambos estão definidos. Sempre mantenha um content significativo — é isso que a IA lê.

Ação obrigatória

Uma ferramenta de app pode pausar a thread quando precisa de uma ação do usuário (ou dispositivo). Retorne type: 'action_required' com um título de cartão e botões. Válido apenas quando toolContext(req).source === 'thread' — sobre a Tools API (source: 'api'), retorne um erro de domínio normal em vez disso.
Kazzle salva o cartão na chamada da ferramenta e retoma através de /chat/resume após um botão ser pressionado. Os clientes correspondentes veem os botões do autor; clientes não correspondentes ainda veem Pular/Cancelar mais “Continuar em ”. Um botão sem target envia sua input como o resultado da ferramenta. Um botão com um target executa esse target primeiro, depois usa o resultado do target como o resultado da ferramenta.

UI Rica — incorporar uma página hospedada pelo app

Quando o resultado de uma ferramenta é visual ou interativo (uma tela de conexão, um gráfico, um painel de resumo), ofereça a página de um de seus componentes e retorne sua URL absoluta como embedUrl. Construa a URL a partir da URL do componente injetada — nunca um caminho relativo.
A página é executada em um iframe de origem cruzada (sua própria origem, cookies e scripts). Para dimensionar o cartão, poste sua altura para o pai — o cartão escuta isso e redimensiona (limitado a 70% da viewport):
Prefira embedUrl em vez de emitir strings HTML: seu app já oferece páginas, a UI permanece interativa e versionada com seu código, e nenhum artefato por chamada é escrito em lugar algum.