Repository navigation
Releases
v0.2.0: cached knowledge, thinking kept, fetch handlers
Every package moves to 0.2.0 together. Nothing existing changes: every addition is optional, and a 0.1.1 bot runs unchanged.
Added
knowledge: the half of the prompt that never changes. A real agent's system prompt is mostly stable material: the policy, the catalogue, the price list. new Agent({ knowledge, instructions }) sends the stable part first and the per-message part after it, and the provider receives the split as GenerateRequest.systemParts. @wappajs/anthropic puts a cache breakpoint after the knowledge, so every message of every chat reads it from the prompt cache at about a tenth of the input price. Docs
handleFetch(request) on the webhook transports. @wappajs/twilio and @wappajs/cloud-api now mount into any host that speaks WHATWG Request/Response: Bun, Deno, Cloudflare Workers, Hono, Next.js route handlers, SvelteKit, Remix. Same semantics as handleRequest; path routing belongs to the host. Twilio · Cloud API
Anthropic provider options. effort (output_config.effort; chat is usually best at 'low' or 'medium'), thinking (passed through as given) and extraParams (merged into every request last, for Messages API fields the provider does not model). Docs
providerData. GenerateResult.providerData and ChatMessage.providerData let a provider keep whatever it needs to replay an assistant turn exactly as its API produced it. The Agent copies it onto the message it appends, session stores persist it, and ScriptedProvider passes it through. Custom provider contract
Recipes for keeping a transcript and for a database session store. scripts/version.mjs now moves the examples' ranges along with the packages.
Fixed
@wappajs/anthropic keeps and replays thinking blocks. The current models think before they answer, and inside a tool loop the Messages API requires the thinking block of the tool-calling turn to come back unchanged. The provider dropped it, so the second call of a tool loop could be rejected on adaptive-thinking models, the default claude-sonnet-5 among them. It now keeps the content blocks of any turn that holds more than text and replays them, rebuilt with request fields only, since the API rejects the response-only fields (citations, caller).
A turn the model refuses is logged at warn level with its stop_details. The @wappajs/twilio README named the sender option wrongly (whatsappNumber, not from).
Upgrading
npm install @wappajs/core@0.2.0 @wappajs/anthropic@0.2.0 @wappajs/twilio@0.2.0 # and the rest you useTo use the cache, move the stable part of your instructions into knowledge and keep only what changes per message in instructions; the support-agent example shows the split.
v0.1.1: first public release
First public release of wappa, a TypeScript framework for building WhatsApp agents. You
define an agent (instructions, tools, LLM provider), pick a transport, and run it.
Install
npm create wappa-agent my-bot -- --transport baileys --provider anthropicOr add it to an existing ESM project:
npm install @wappajs/core @wappajs/baileys @wappajs/anthropic zodimport { Agent, Bot, defineTool } from '@wappajs/core';
import { BaileysTransport } from '@wappajs/baileys';
import { AnthropicProvider } from '@wappajs/anthropic';
import { z } from 'zod';
const agent = new Agent({
instructions: 'You are a helpful assistant reachable over WhatsApp. Keep replies short.',
provider: new AnthropicProvider(),
tools: [
defineTool({
name: 'get_time',
description: 'Get the current date and time.',
parameters: z.object({}),
execute: () => new Date().toString(),
}),
],
});
await new Bot({ transport: new BaileysTransport(), agent }).start();Packages
| Package | What it does |
|---|---|
@wappajs/core |
Bot, Agent, defineTool, sessions, middleware |
@wappajs/baileys |
Personal number transport, QR login |
@wappajs/cloud-api |
Official Meta WhatsApp Cloud API transport |
@wappajs/twilio |
Twilio WhatsApp (BSP) transport |
@wappajs/anthropic |
Claude provider |
@wappajs/openai |
OpenAI provider, plus any OpenAI compatible server |
create-wappa-agent |
Project scaffolder |
Highlights
- Transport agnostic core.
@wappajs/corenever imports a WhatsApp library. It speaks
a normalized message model, and adapters translate. Switching from Baileys to the Cloud
API is a one line change. - Provider agnostic agent loop. The core owns the tool call loop and conversation
memory. A provider maps onegenerate()call to its SDK. - Typed tools with zod.
defineToolinfers argument types from a schema, validates
what the model sends, and turns failures into retryable tool results instead of crashes. - Middleware first. grammY style
use(ctx, next), pluscommand()andhears()
routing. Auth, rate limiting, logging and human handoff are all just middleware. - Sessions built in. Per chat history and durable data, with in memory and file backed
stores, and a lost update safe pause and resume flag for handoff. - Testable offline.
@wappajs/core/testingshipsMockTransportand
ScriptedProvider, so you can unit test a whole bot with no WhatsApp and no LLM key. - Per chat concurrency. Messages in one chat process strictly in order, different chats
run concurrently, and shutdown drains in flight turns.
Requirements
Node 20 or newer. The packages are ESM only, so your project needs "type": "module".
Documentation
A note on naming
An earlier partial release published wappa-baileys, wappa-cloud-api and
wappa-anthropic as unscoped packages at 0.1.0. Those versions are broken, since they
depend on a wappa core package that was never published. Use the @wappajs packages
instead. Version 0.1.0 was skipped here because npm does not allow reusing a version
number.