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
Build one DialClient, pass it to dialTools, and spread
the result into the tools field. Every tool shares that one client (a single
connection pool). 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.