Human-in-the-loop for the Vercel AI SDK
Let your Vercel AI SDK agent ask a human on their phone.
Install @pushary/ai-sdk and call createPusharyTools({ externalId }). It returns an askHuman tool you spread into the tools of generateText or streamText. When the model calls it, Pushary sends a push notification to that user's phone, and the tool blocks until the person approves, denies, or types an answer. The result flows back as a normal tool result, so the agent loop continues on the human's decision. It is fail-closed, so no answer means no approval.
import { generateText, stepCountIs } from "ai"
import { openai } from "@ai-sdk/openai"
import { createPusharyTools, enroll } from "@pushary/ai-sdk"
// Connect the end-user's phone once. Keyless, one tap, no app to install.
await enroll({ apiKey: process.env.PUSHARY_API_KEY! }, user.id)
const { text } = await generateText({
model: openai("gpt-4o"),
tools: createPusharyTools({ apiKey: process.env.PUSHARY_API_KEY!, externalId: user.id }),
stopWhen: stepCountIs(10),
prompt: "Issue the refund only if a human approves it.",
})Why you need it
Vercel AI SDK pauses the agent. Pushary reaches the human.
The AI SDK tool loop runs the model and its tools, and it does not deliver a question to a person, hold a durable wait, or keep a record of who approved. Pushary completes that with an askHuman tool. The externalId is your own end-user, so the agent you shipped can ask each user about their own decision, not just ask you.
How it works
From ask to resume
Connect the phone once, then ask a human from the tool or step that guards the action. The waiting, the delivery, and the record are handled for you.
- 01
Install and connect a phone
Run npm i @pushary/ai-sdk. Connect each end-user's phone once with a keyless one-tap enroll link keyed to your own externalId.
- 02
Add the askHuman tool
Call createPusharyTools({ externalId }) and spread the returned tools into your tools object in generateText or streamText. Keep your existing stopWhen loop.
- 03
Tell the model when to ask
In your prompt, say when the model should ask a human, for example before issuing a refund or deleting a record. The model calls askHuman at that step.
- 04
Act on the decision
The tool blocks until the person answers, then returns the outcome to the model as a tool result. A declined, expired, or unanswered confirm is reported as not approved.
A decision is a yes or no confirm, a multiple-choice select, or a free-text input. Every one is stored with its outcome and kept in the audit log.
For your users
Your agent asks your users, not just you
Ship the agent to real users and let each of them approve their own decisions from their phone, under your brand.
Your users answer on their own phones
The externalId is your own id for the end-user. Connect their phone once with a keyless one-tap link, and every approval lands with the right person. No account, no app, no key on their side.
Durable, fail-closed waits
The agent stays open on a durable wait backed by a decisions ledger. If nobody answers in the window you set, the decision comes back denied, so a timeout or a restart never turns into an unapproved action.
Phone-first delivery
Pushary reaches the person on the device they carry: native app push first, then PWA push notifications, then Slack if you route it there. You do not build a delivery pipeline.
Signed webhooks and an audit trail
Every decision is written to a durable ledger you can query and export, and resolved decisions post a signed webhook to your callback URL. You have the record of who approved what and when.
FAQ
Questions, answered
Human-in-the-loop for other frameworks
Let your Vercel AI SDK agent ask a human.
Connect a user with one tap, ask a human with one call, and act on a fail-closed decision. The durable store and the audit log come with it.
Partner plan, $99 a month. Your users never see a Pushary login or bill.