Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.zavu.dev/llms.txt

Use this file to discover all available pages before exploring further.

Quickstart

We’ll build a restaurant booking agent that lives on a WhatsApp sender. By the end, customers can text the number and the agent will show the menu, check availability, and confirm reservations.
You’ll need an active WhatsApp sender in your Zavu project. If you don’t have one yet, connect WhatsApp first.

1. Install the CLI

brew install zavudev/tools/zavu
Already installed? Upgrade with brew upgrade zavu. Verify:
zavu --version

2. Log in

zavu login
This opens your browser, you sign in, pick the project this agent will live in, and click Authorize. The CLI saves the API key to ~/.zavu/credentials.json (chmod 0600). Confirm you’re on the right project:
zavu whoami
Project:  Acme Restaurants
Project ID: jh72w2dnzytttrxjqjtaq267nn7wcw6y
Team:     Acme
Mode:     live
API URL:  https://api.zavu.dev
Key ending: …1bmmn

3. Find your sender

zavu senders list
Copy the ID of the WhatsApp sender you’ll attach the agent to:
id                                name           phone           whatsapp
jn76vnxet8g5nq661by3v06y1581bmmn  Pizzeria Main  +15076323077    yes
export SENDER_ID="jn76vnxet8g5nq661by3v06y1581bmmn"

4. Scaffold the function

zavu fn init --template restaurant-booking -y
cd reservations
You’ll get an index.ts like this (truncated):
import { defineAgent, defineTool } from "@zavu/functions"

defineAgent({
  senderId: process.env.SENDER_ID!,
  name: "Bella",
  provider: "zavu",
  model: "openai/gpt-4o-mini",
  channels: ["whatsapp"],
  prompt: `Eres Bella, anfitriona de Bella Pizzeria…`,
})

defineTool({
  name: "view_menu",
  description: "Get the restaurant menu.",
  parameters: { type: "object", properties: { filter: { type: "string" } } },
  handler: async (args) => ({ menu: [/* … */] }),
})
// + check_availability, create_reservation, view_reservation
The template uses provider: "zavu" — our managed AI gateway. No BYOK required; LLM costs are billed from your Zavu balance.

5. Set the sender ID as a secret

zavu fn secrets set SENDER_ID "$SENDER_ID"
Output:
✓ Created SENDER_ID (…1bmmn)
  Lambda env var updates on the next `zavu deploy`. Run it now to apply.

6. Deploy

zavu deploy
Watch the output:
› Deploying Restaurant reservations agent (reservations)…
  deployment id: nx7ztwe6cwg1dfp14bk6v7nb2s86hpn6
› status: bundling
› status: uploading
› status: publishing
› status: active
✓ Deployed in 14s
  Agents synced:
    + Bella
  Tools synced:
    + view_menu
    + check_availability
    + create_reservation
    + view_reservation
Your agent is live. The WhatsApp sender will now hand off every inbound to it.

7. Try it on WhatsApp

From your phone (not the sender’s number), send the sender:
hola, qué tienen vegano?
Expected flow:
👤 hola, qué tienen vegano?
🤖 [calls view_menu(filter="vegan")]
🤖 Tenemos Vegan Buddha Bowl ($11). ¿Te lo reservo?

👤 sí, mañana viernes a las 9 para 2
🤖 [calls check_availability(date="friday", partySize=2)]
🤖 Tengo 19:30 y 21:00. ¿Cuál preferís?

👤 21
🤖 [calls create_reservation(date="friday", time="21:00", partySize=2, customerName="…")]
🤖 ¡Listo! Reserva RES-LXXY confirmada para 2 personas el viernes a las 21:00.

8. Watch it run

In three terminals:
# Live tool calls (your function's console.log + handler activity)
zavu fn logs --tail
# Agent executions: which tools, tokens used, cost, latency
zavu agents executions --sender "$SENDER_ID"
# Every message in & out
zavu messages list --limit 10

9. Iterate

Edit index.ts — say, add a cancel_reservation tool — and redeploy:
zavu deploy
The summary shows what changed:
✓ Deployed in 11s
  Tools synced:
    + cancel_reservation
The new tool is immediately available to the agent on the next user message. You don’t need to update prompts — the LLM reads the tool’s description and parameters schema directly.

Common pitfalls

Run zavu agents get --sender "$SENDER_ID" and confirm enabled: true. If false, check that defineAgent is being called (deploy must show Agents synced: + Bella).
Check that the tool description is specific enough. The LLM uses the description to decide when to call the tool, so vague descriptions ("do stuff") don’t trigger. Rewrite each description as the answer to “when should the model call this?”.Also confirm zavu agents tools list --sender "$SENDER_ID" shows the 4 tools with enabled: true.
Watch zavu fn logs --tail while you trigger the tool. The error stack appears live. Common causes: missing env var (run zavu fn secrets list to confirm what’s set), JSON parse errors on response, unhandled async exceptions.
AWS Lambda function names cap at 64 chars, and we prefix yours with zavu-fn-<projectId>- (41 chars used). Slugs over 23 chars get rejected server-side with a clear message. Pick something short — bella, not restaurant-reservations-agent-v2.

Next steps

Define agents in depth

Providers, models, prompts, triggers.

Define tools in depth

Schemas, handlers, returning structured data.

Customer support example

Knowledge base lookup + ticket creation.

Ecommerce example

Order status + smart recommendations.