Skip to main content
This walkthrough mirrors 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.
The action descriptors (name, input schema, risk) live in .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 adds vendo_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 in VendoProvider 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

Open http://localhost:3000.

The demo script

All three value props in one thread:
  1. “What’s the weather in Paris?” Normal tool use. The model calls vendo_host_get_weather; the guard runs it (risk read under the cautious policy), audits it, and returns plain data the model narrates.
  2. “Make me a dashboard comparing the weather in Paris, London and Tokyo.” The model calls vendo_create_app, gets a vendo/app-ref@1 envelope back immediately, and the app builds inline in <VendoAppEmbed> while the build streams over the wire.
  3. “Email that trip report to boss@example.com.” The model calls vendo_host_send_trip_report; the guard parks it and returns a vendo/approval-ref@1 envelope, 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.
Vendo approval card rendered inline in the AI SDK quickstart chat

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.