examples/ai-sdk-agent
in the repo: the unmodified
AI SDK Next.js quickstart chatbot
(useChat + streamText + the weather tool) plus four touches. In the
example every added line sits inside --- vendo / --- /vendo comment
fences, so you can grep the whole integration.
Read the overview first for the tool pack and envelope
contract.
Touch 1: the Vendo composition
One new file holds the whole server-side Vendo surface:createVendo plus
the host actions it guards. The quickstart’s inline weather tool moves
here, so the lookup runs through policy, approval, and audit like everything
else the agent can touch. A second, deliberately risky action exercises
approvals.
.vendo/tools.json, exactly where vendo init extracts them in a real app.
The example writes them by hand:
Touch 2: the wire route
The stock catch-all route, unchanged from the quickstart. It serves apps and approvals to the embeds.Touch 3: the tools spread
One spread in the chat route. Your loop and your model stay yours; the pack addsvendo_host_get_weather, vendo_host_send_trip_report,
vendo_create_app, and vendo_delegate.
vendoTools is built per request because tool execution needs a
principal-scoped context. Resolve the caller’s principal server-side first;
pass sessionId too if you want the host session id in Vendo’s audit trail.
Touch 4: the embeds
Wrap the chat inVendoProvider once, and hand finished tool outputs to
<VendoToolResult>. In the AI SDK’s useChat, vendo_* tools stream as
dynamic-tool message parts.
One config line
Next.js bundles route modules, and Vendo carries native and wasm dependencies that must stay external:Run it
The demo script
All three value props in one thread:- “What’s the weather in Paris?” Normal tool use. The model calls
vendo_host_get_weather; the guard runs it (riskreadunder thecautiouspolicy), audits it, and returns plain data the model narrates. - “Make me a dashboard comparing the weather in Paris, London and
Tokyo.” The model calls
vendo_create_app, gets avendo/app-ref@1envelope back immediately, and the app builds inline in<VendoAppEmbed>while the build streams over the wire. - “Email that trip report to boss@example.com.” The model calls
vendo_host_send_trip_report; the guard parks it and returns avendo/approval-ref@1envelope, which renders as an approval card. Click Approve and the wire executes the parked call; the card resolves in place to the executed result. Deny resolves to “declined”; walking away expires it on the parked-call TTL.

Step 3 in the quickstart's own chat: the approval card for the parked send, with the exact inputs the call will run with.
Tests
The example ships a hermetic fixture e2e (examples/ai-sdk-agent/e2e/byo-agent.e2e.test.ts): one real streamText
turn per value prop over a real createVendo composition, with both model
seams scripted so no keys are needed. Run it with pnpm test in the example.