Loading...
Loading...
Build serverless TypeScript functions on Zavu Cloud — declare agents + tools in code with defineAgent / defineTool, deploy with `zavu deploy`, debug with `zavu agents executions`. Use this skill whenever the user wants code-driven AI agents, custom tool handlers, or event-driven business logic.
npx skill4agent add zavudev/zavu-skills functionsimport { defineAgent, defineTool } from "@zavu/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"] }
},
})zavu deploy| Use case | Use |
|---|---|
| Customer wants a code-first agent with custom tool handlers in their own language | Functions |
| Tools need to query the user's database, call internal APIs, or transform data before returning | Functions |
| User wants reproducible config from a git repo (one source of truth) | Functions |
| User wants no-code config via the dashboard | imperative |
User needs event-driven handlers ( | Functions |
defineAgentdefineToolzavu deployai-agentzavubrew install zavudev/tools/zavu
# or grab a standalone binary from https://github.com/zavudev/zavu-cli/releases
zavu loginzavu login~/.zavu/credentials.jsonzavu fn init order-bot --template blank
cd order-botblankrestaurant-bookingschool-parent-notifyecommerce-order-botindex.tspackage.json.zavu/config.jsonzavu fn secrets set SENDER_ID jx7abc123def456
zavu fn secrets set DATABASE_URL "postgres://..."
zavu fn secrets list
zavu fn secrets unset OLD_KEYzavu senders listindex.tsimport { defineAgent, defineTool, defineFunction } from "@zavu/functions"
defineAgent({
senderId: process.env.SENDER_ID!,
name: "Bella",
provider: "zavu", // Zavu's AI gateway (charged from project balance)
// Or "openai" / "anthropic" / "google" / "mistral" with BYOK + apiKey
model: "openai/gpt-4o-mini", // For "zavu" provider, prefix with the underlying provider
prompt: "You are Bella…", // System prompt
channels: ["whatsapp"], // Optional: default ["*"] = all channels the sender supports
// apiKey: process.env.OPENAI_API_KEY // only for non-zavu providers
})
defineTool({
name: "lookup_order",
description: "Get current status of an order. Use when the customer asks about an order they placed.",
parameters: {
type: "object",
properties: { orderId: { type: "string" } },
required: ["orderId"],
},
handler: async (args, ctx) => {
// ctx: { projectId, functionId, slug, awsRequestId, messageId?, contactPhone?, sessionId?, log }
const res = await fetch(`https://pos.example.com/orders/${args.orderId}`, {
headers: { Authorization: `Bearer ${process.env.POS_API_KEY}` },
})
return await res.json()
},
})
// Optional: handle raw events (message.inbound from triggers, HTTP calls).
// NOT needed if you only declare agent + tools.
export default defineFunction(async (event, ctx) => {
ctx.log("got event", event.type)
})zavu deploy✓ Deployed in 6.4s
Agents:
+ Bella (sender_abc, whatsapp)
Tools:
+ lookup_order → Bella0 created, 0 updated, 0 deleted# Call a tool handler with synthetic args
zavu fn invoke --tool lookup_order --args '{"orderId":"ORD-001"}'
# Simulate an inbound event for defineFunction
zavu fn invoke --event message.inbound --data '{"from":"+14155551234","text":"hi"}'# 1. Did the inbound reach the agent?
zavu agents executions list --sender <senderId>
# 2. Detail of any failed run
zavu agents executions get <executionId> --sender <senderId>
# 3. Live tool handler logs (your console.log calls)
zavu fn logs --tail--jsonexecutions listerrorMessagedefineAgent({
senderId: string, // Required. The sender that receives inbound + dispatches the agent.
name: string, // Required. Displayed in dashboard.
provider: "zavu" | "openai" | "anthropic" | "google" | "mistral",
model: string, // For "zavu": prefix with underlying provider e.g. "openai/gpt-4o-mini"
prompt: string, // System prompt.
apiKey?: string, // Required for non-"zavu" providers.
channels?: string[], // Default ["*"]. Subset of: sms, whatsapp, telegram, email, instagram, voice
messageTypes?: string[], // Default ["text"]. Filter by message type.
temperature?: number, // 0-2.
maxTokens?: number, // Cap on output tokens.
contextWindowMessages?: number,// Past N messages included as context. Default 10.
sessionTimeoutMinutes?: number,// Reset conversation context after N minutes. Default 60.
includeContactMetadata?: boolean, // Inject contact's metadata into the system prompt. Default true.
enabled?: boolean, // Default true.
})defineTool({
name: string, // Required. snake_case, max 64 chars.
description: string, // Required. The LLM reads this to decide WHEN to call the tool.
parameters: {
type: "object",
properties: { /* JSON Schema */ },
required?: string[],
},
handler: async (args, ctx) => any, // Required. Return any JSON-serializable value.
agent?: string, // Optional: which agent owns this tool. Defaults to the only agent in the file.
enabled?: boolean, // Default true.
})ctx{
projectId: string,
functionId: string,
slug: string,
awsRequestId: string,
messageId?: string, // ID of the triggering inbound (when called by agent)
contactPhone?: string,
sessionId?: string, // Active flow session if any
log: (...args) => void, // console.log proxy that appears in `zavu fn logs --tail`
}httpEnabled: truemessage.inboundbroadcast.completedzavu fn triggers addexport default defineFunction(async (event, ctx) => {
if (event.type === "message.inbound") {
// event.data: { from, text, channel, messageId, ... }
}
return { ok: true }
})defineFunctionzavu fn triggers list
zavu fn triggers add --events message.inbound --senders <senderId>
zavu fn triggers add --events broadcast.completed --senders any
zavu fn triggers toggle <triggerId>
zavu fn triggers rm <triggerId>
zavu fn triggers events # list available event typeszavu deployzavu fn versions list # alias: zavu fn history
zavu fn rollback 4 # go back to version 4zavu deploy --update-runtime # opt-in upgrade to latest runtimezavu deploy| Memory | Units per call |
|---|---|
| 128 MB | 1 |
| 256 MB | 2 |
| 512 MB | 4 |
| 1024 MB | 8 |
| Plan | Included units | Overage rate |
|---|---|---|
| Free | 100k | Hard cap (invocations blocked) |
| Hobby | 1M | $5 / 1M |
| Standard | 5M | $4 / 1M |
| Growth | 10M | $3 / 1M |
zavu agents createsenderId + namemanagedByFunctionIdzavu fn deletedefineAgent({
senderId: process.env.NODE_ENV === "production"
? process.env.PROD_SENDER_ID!
: process.env.DEV_SENDER_ID!,
// ...
})zavu fn secrets set NODE_ENV production... developmentapiKeydefineAgent({
senderId: process.env.SENDER_ID!,
provider: "openai",
model: "gpt-4o-mini",
apiKey: process.env.OPENAI_API_KEY,
prompt: "...",
})zavu fn secrets set OPENAI_API_KEY sk-...defineAgentdefineTool({
name: "lookup_order",
agent: "Bella", // Match by agent's name field
// ...
})ZAVU_API_KEYimport { Zavudev } from "@zavudev/sdk"
const zavu = new Zavudev({ apiKey: process.env.ZAVU_API_KEY })
defineTool({
name: "send_followup",
handler: async (args, ctx) => {
await zavu.messages.send({
to: ctx.contactPhone!,
text: "Thanks for your order!",
})
return { sent: true }
},
})messages:sendmessages:readcontacts:readhttps://dashboard.zavu.dev/functions/<id>[A-Z_][A-Z0-9_]*AWS_LAMBDA__HANDLER_X_AMZNsenders.agent.createsenderIdprocess.env.SENDER_IDconsole.log