Functions
Seu agente não é um formulário.É um arquivo do seu repo.
Declare o agente e as ferramentas que ele pode chamar em TypeScript. Faça deploy do diretório. A Zavu constrói, guarda os secrets, executa nos seus eventos ou em horário, e reconcilia o agente ativo com o que o arquivo diz.
- Runtime
- nodejs24
- Fixado no primeiro deploy e mantido, então nenhum deploy posterior o move por baixo.
- Timeout
- 1–180 s
- Padrão 30. Qual teto vale depende do trigger.
- Memória
- 128 · 256 · 512 · 1024
- MB por invocação. A maioria dos handlers cabe no menor.
- Código
- 200 arquivos · 900.000 bytes
- Pacotes npm são declarados, não enviados.
01 — Escreva
Um diretório, um entrypoint e o que ele importar.
O deploy começa no entrypoint e segue os imports relativos. O que ele alcança sobe; o que ninguém importa fica na sua máquina.
O que realmente sobe
Escolha um arquivo. O painel diz se ele viaja com o deploy, e por quê.
import { defineAgent, defineTool } from "@zavudev/functions"
import { formatOrder, lookupOrder } from "./lib/orders"
import { HOST_PROMPT } from "./prompts/host"
defineAgent({
senderId: process.env.SENDER_ID!,
name: "Bella",
provider: "zavu",
model: "openai/gpt-4o-mini",
prompt: HOST_PROMPT,
})
defineTool({
name: "lookup_order",
description: "Get current status of an order. Use when the customer asks about one.",
parameters: {
type: "object",
properties: { orderId: { type: "string" } },
required: ["orderId"],
},
handler: async ({ orderId }, ctx) => {
ctx.log("lookup", orderId)
return formatOrder(await lookupOrder(orderId))
},
})O entrypoint. O deploy o lê primeiro e percorre os imports relativos a partir daqui. O padrão é index.ts — use entrypoint via REST, ou --source na CLI, para nomear outro.
Caminhos recusados
A CLI e a API são a mesma superfície.
Use a que encaixa no seu jeito de trabalhar. Nada aqui existe em apenas uma delas.
import { defineAgent, defineTool } from "@zavudev/functions"
defineAgent({
senderId: process.env.SENDER_ID!,
name: "Bella",
provider: "zavu",
model: "openai/gpt-4o-mini",
prompt: "You are Bella, host at the restaurant. Be brief.",
})
defineTool({
name: "check_availability",
description: "Get free reservation slots for a date.",
parameters: {
type: "object",
properties: { date: { type: "string" }, partySize: { type: "number" } },
required: ["date", "partySize"],
},
handler: async ({ date, partySize }) => {
return { available: true, slots: ["19:00", "21:00"] }
},
})02 — Faça deploy
Um deploy é um registro que dá para acompanhar, e ao qual dá para voltar.
O deploy responde na hora com um id. Você consulta. Cada versão é guardada, com a saída do build que a explica.
Ciclo de vida do deployment
Avance passo a passo, ou deixe rodar. Quebre um import para seguir o outro caminho.
superseded — no que uma versão se torna quando outra mais nova assume. Continua legível, e voltar para ela é uma chamada só.
{
"id": "fnd_8c21ab5f",
"functionId": "fn_4kq2m9x",
"version": 7,
"status": "pending",
"sourceCodeBytes": 18432,
"bundleBytes": null,
"errorMessage": null,
"deployedAt": null,
"createdAt": "2026-03-14T09:41:12.000Z"
}Consulte até status ser active ou failed. Ambos são terminais.
Rollback
Você volta nomeando um id de deployment. O código, as dependências e o runtime dele são copiados para o draft e implantados de novo como mais uma versão, então o histórico só cresce. Os secrets não voltam: eles são atuais, não versionados.
Deploy pelo GitHub
Ligue um repositório e um push na branch faz o deploy. Como o link se autentica quem decide é o servidor, não você: com o GitHub App da Zavu instalado, repositórios privados funcionam e não há nada a acrescentar no repositório. Sem ele você recebe um link manual, e o secret do webhook é impresso exatamente uma vez. Ligar não confere o repositório no GitHub — um owner/repo que a instalação não enxerga é aceito e falha no primeiro deploy.
- connection
- app ou manual — o servidor escolhe
- branch
- só os pushes aqui fazem deploy
- rootDir
- o subdiretório, para monorepos
- autoDeploy
- em false mantém o link e ignora os pushes
- lastStatus
- deploying, deployed ou failed
- lastError
- por que o último push não entrou
03 — Execute
Nos seus eventos, ou no relógio.
Um trigger inscreve a função em um tipo de evento, para um sender ou para todos. O tipo especial cron a executa em horário.
Construtor de triggers
Escolha tipos de evento e senders. O request e os triggers que ele cria aparecem à direita, e uma expressão cron é resolvida para as próximas execuções em UTC.
Tipos de evento
Senders
Adicione o tipo de evento cron acima para executar a função em horário em vez de inscrevê-la em uma mensagem. Aceita uma expressão de cinco campos em UTC, e uma função pode ter várias com horários diferentes.
{
"eventTypes": [
"message.inbound"
],
"senderIds": [
null
]
}{
"added": 1,
"skipped": 0,
"triggers": [
{
"id": "fnt_0001",
"eventType": "message.inbound",
"senderId": null,
"active": true
}
]
}Um trigger por tipo de evento × sender. Um trigger cron ignora o eixo de senders, então conta uma vez, quantos senders você escolher. Duplicados voltam como skipped, não são criados duas vezes.
Vale saber
O timeout que você define nem sempre é o teto que vale.
Execuções por evento e por cron
Assíncronas. Ninguém espera a resposta, então um timeout longo só limita o custo de uma execução travada.
Uma ferramenta em plena conversa
Síncrona. A resposta ao cliente espera pelo seu handler, então mantenha esses bem abaixo do limite, não colados nele.
Uma função exposta por HTTP
Também limitada pelo teto de resposta HTTP da plataforma. Aumentar timeoutSec não aumenta esse.
04 — Opere
Secrets, logs e um endpoint quando você quiser.
Secrets entram e não voltam
Listá-los devolve cada chave e os últimos quatro caracteres do valor, nunca o valor. As chaves são maiúsculas no estilo variável de ambiente, e os prefixos AWS_ e LAMBDA_ são reservados. Definir um marca a função como fora de sincronia em vez de reiniciá-la por baixo; o próximo deploy aplica.
Uma API key que você não teve que ligar
Criar uma função provisiona uma key da Zavu com escopo restrito e a injeta como ZAVU_API_KEY, então um handler chama a API de volta sem você gerenciar credencial. Para mais escopo, crie sua própria key e defina como secret.
Logs, filtrados e paginados
Busque os logs de invocação limitados por janela de tempo ou filtrados por padrão, e pagine com nextToken. A mesma saída é acompanhada ao vivo pela CLI enquanto você trabalha.
Um endpoint HTTPS, com interruptor
Ligar a URL pública vale para a função já implantada — sem redeploy. Desligada, a URL guardada para de servir e não é mais devolvida, então publicUrl vem null em vez de desatualizada.
Escreva, faça deploy, olhe os logs.
Comece grátis, sem cartão. A CLI fala com a mesma API que o seu código vai usar.