Agent frameworks / Vercel AI SDK
Vercel AI SDK
Give an agent built on the Vercel AI SDK the two AIX operations as tools, through the MCP server or defined in code, with the timing rules the model needs.
The Vercel AI SDK is the TypeScript library most JavaScript chat agents are built on. It has nothing to do with where your app is hosted. An AIX integration gives the model two tools: submit_intent after any turn that states or changes what the shopper wants to buy, and report_handoff before the shopper is sent to a store. Both run on your server with your key; the browser never sees it.
Two ways to get there. Through the MCP server the tools appear by themselves; defined in code you control the schema and keep AIX out of the model's tool list until you need it.
Through the MCP server
Install the MCP client package next to ai, then connect with your key from the environment. The tools AIX exposes for a publisher key are submit_intent, report_handoff, delete_session and get_activity. The MCP submit_intent tool takes one argument, intent, with the same body as POST /intents (its turn input is reserved for Brambles-managed publishers; the model must send exactly one of the two).
npm install ai @ai-sdk/mcpimport { streamText } from "ai";import { createMCPClient } from "@ai-sdk/mcp";
const mcpClient = await createMCPClient({ transport: { type: "http", url: "https://aix.brambles.ai/api/aix/mcp", headers: { Authorization: `Bearer ${process.env.AIX_PUBLISHER_KEY}` }, },});
const tools = await mcpClient.tools();
const result = await streamText({ model: yourModel, system: AIX_RULES, // see below tools, messages, onEnd: async () => { await mcpClient.close(); },});For a one-shot call use generateText with the same tools and close the client in a finally block.
Defined in code
No extra package: two tool() definitions and one fetch helper with a three-second timeout. AIX must never slow down or break the shopper's experience, so every failure returns a skipped result instead of throwing. submit_intent takes the same { intent } argument as the MCP tool, so one prompt works whichever way the tools arrive.
import { tool } from "ai";import { z } from "zod";
const AIX = "https://aix.brambles.ai/api/aix";
async function aix(path: string, body: unknown) { const key = process.env.AIX_PUBLISHER_KEY; if (!key) return { status: "skipped", reason: "no_key" }; try { const res = await fetch(`${AIX}/${path}`, { method: "POST", headers: { authorization: `Bearer ${key}`, "content-type": "application/json" }, body: JSON.stringify(body), signal: AbortSignal.timeout(3000), }); return res.ok ? await res.json() : { status: "skipped", reason: `http_${res.status}` }; } catch { return { status: "skipped", reason: "timeout" }; // never block the shopper }}
const fact = z.object({ attribute: z.enum(["brand", "width", "size", "department", "use_case", "feature", "merchant", "deal"]), value: z.string(), strength: z.enum(["required", "preferred", "excluded"]),});
export const aixTools = { submit_intent: tool({ description: "Report the shopper's current shopping task to AIX. Call after any turn that states or changes what they want to buy. Shopping requirements only, never personal data.", inputSchema: z.object({ intent: z.object({ session_id: z.string().min(1).max(128), country: z.string().length(2), task: z.object({ category: z.string(), summary: z.string().max(1600), budget: z.object({ currency: z.string().length(3), max_cents: z.number().int() }).optional(), facts: z.array(fact), }), }), }), execute: ({ intent }) => aix("intents", intent), }), report_handoff: tool({ description: "Report that the shopper is being sent to a store or product page (the store's own URL). Returns landing_url, the store URL with AIX's id appended; use it as that page's URL, inside your affiliate link if you use one.", inputSchema: z.object({ session_id: z.string(), destination_url: z.string().url(), consent: z.enum(["granted", "denied"]).optional(), }), execute: (input) => aix("handoffs", input), }),};Then streamText({ model, system: AIX_RULES, tools: aixTools, messages }). The schemas mirror the intent and handoff bodies; session_id is your conversation id and AIX stores only a keyed hash of it.
The rules the model needs
Whichever way the tools arrive, the model has to know when to use them. Add this to your system prompt:
You can send shopping intent to the Agentic Intent Exchange (AIX).- After any user turn that states or changes what they want to buy, call submit_intent with one argument, intent: an object holding the conversation's session_id, the shopper's two-letter country, and the task: a category, a one-line summary, the budget when they gave one, and facts with attribute, value and strength (required, preferred or excluded). Send only shopping requirements: never names, emails, phone numbers, addresses, account or order numbers, or the conversation itself.- Before you give the user a link to a store or product page, call report_handoff with the same session_id and the store's page URL, then use the returned landing_url as that page's URL (inside your own affiliate or ad link, if you use one).- If either tool fails or is slow, carry on without it. Never ask the user for a key.Set country on the server from your host's geolocation header rather than asking the shopper. Shoppers in the EEA, the UK or Switzerland are shared only with consent: show one line under your assistant, "Clicking a store link shares your shopping request with that store", and pass consent: "granted" on handoffs from those clicks. Health, sexual wellness, religion, politics and the other sensitive topics are suppressed by AIX on arrival; never reword a task to get it through.
Receiving side
A store's agent uses the same connection with AIX_RECEIVER_KEY. The tools then list deliveries (subscribe_intents), read one receipt (get_intent_context), acknowledge it (acknowledge_delivery) and redeem a handoff id from a landing or a checkout (redeem_handoff; with a sandbox key it returns a free test delivery for any well-formed id). Verification and acknowledgment belong on your server; see Receiving agents.
Test it
- Create a free sending agent in the AIX console and store the sandbox key as
AIX_PUBLISHER_KEY. - Run one conversation that names a product and ends with a store link. The intent answers
accepted; the handoff answerstest_deliveredwith areceiver_preview. GET /activitywith the same key, or the AIX console, shows the test. Create the production key there and set it in production.