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ê.

order-bot/
Arquivos enviados4 / 200
Bytes enviados1,355 / 900,000
index.tsEntrypoint
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

../shared/x.tsnode_modules/package.json

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.

index.ts
npx zavudev fn init --name order-bot --template blank
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.

  1. supersededno que uma versão se torna quando outra mais nova assume. Continua legível, e voltar para ela é uma chamada só.

DeploymentGET /v1/functions/deployments/{deploymentId}
{
  "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.

$ npx zavudev fn rollback 4

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.

RequestPOST /v1/functions/{functionId}/triggers
{
  "eventTypes": [
    "message.inbound"
  ],
  "senderIds": [
    null
  ]
}
Response201
{
  "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.

01

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.

02

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.

03

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.

04

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.

Functions | Agentes e ferramentas em TypeScript — Zavu | Zavu