Vercel AI SDK integration
@getdial/ai-sdk packages Dial’s operations as Vercel AI SDK
tools, so a model can send messages and place calls as part of its reasoning. It’s
the TypeScript analog of the LangChain integration:
a thin adapter over @getdial/sdk — it adds nothing to
the REST contract, it just shapes Dial’s operations into AI SDK tool() definitions.
Not Vercel-only. The “Vercel AI SDK” is the open-source ai package — it runs
on any JS host (Next.js on any platform, Node, Hono, Cloudflare Workers, Deno, Bun)
and with any tool-calling model (Claude, GPT, Gemini, …). These tools work wherever
it does.
Install
ai and zod are peer dependencies — your app already has them. The package pulls
in @getdial/sdk as its Dial client.
Give the tools to a model
The quickest way is dialTools — construct it once with your API key and spread it
into the tools field. To switch models, change one line; the tools don’t change.
When fromNumberId is set, it’s the default for sendMessage and makeCall — the
model can omit it, mirroring the CLI’s saved default from_number_id.
Available tools
Each execute returns the structured Dial object (a Message, Call, etc.) — the
AI SDK serializes the tool result back into the model for you.
Or pick individual tools
When you only want a subset, import the factories directly:
Example: a Next.js chat route
A typical AI SDK app exposes a route handler that streams the model’s response. Drop
dialTools(...) into it and the chat can text and call people:
Now an end user typing “text the plumber at +14155550123 that I’ll be 10 minutes
late” gets the model to call sendMessage with the right to and body.
Send a code and await the reply
waitForMessage pairs with sendMessage so the model can verify a number inside a
single turn — send a one-time code, then block on the inbound reply:
waitForMessage opens the account event stream,
returns the first matching message.received, and times out after timeoutSeconds
(default 30).
sendMessage is a write action and isn’t idempotent — a re-invoke after a
failure can send a duplicate. makeCall accepts an idempotencyKey: a re-invoke
with the same key returns the already-placed call instead of dialing again. See
Retries and idempotency.
Receiving events beyond a single turn
waitForMessage is a one-shot wait, backed by a presence-based stream (not
at-least-once — missed events replay only on reconnect within ~2 minutes). To react
to inbound SMS or completed calls durably and continuously, don’t model it as a tool:
use the Node SDK’s newEventsConnection() directly, or
register a webhook (signed and retried
at-least-once), and feed events into your agent however suits your app.