Skip to main content
buyTool(options) returns the buy tool for one shopper. The model calls it with the shopper’s words, and Agentcard finds the products, builds the cart and places the order once the shopper approves. Each framework reads its own fields from the same object, so you pick no adapter.
agent.ts
textShopper stands for your own code. The model calls buy, shows the shopper the cart, and confirms the cart only after the shopper says yes. Build the tool once per shopper and keep it. In a chat app, open a turn from it for each message.

Create the tool

Name your company’s AgentcardClient and the shopper, or pass one shopper’s own access token. The function throws a TypeError when you pass both agentcard and accessToken, or neither.

Options

sendLink, onResult, onReaction and onWorking hear every call the tool makes, whichever shopper message the call answers. To keep the links and answers of one message apart from those of another message, pass them to buy.turn instead. A throw from sendLink on a product link leaves that product’s linkSent false, and the call goes on. A throw from onResult costs only that call to it. With onProgress, or with earlyCards and sendLink, the tool asks Agentcard to stream the call. Pass stream: false to wait for each whole answer.

Acknowledgements

Left out, ack reacts through onReaction when the tool or the turn has one, and sends text through onWorking otherwise. 'text' sends text even with an onReaction. 'none' and false send nothing. A function writes the instant reply from the shopper’s words, and an empty answer sends none. The acknowledging guide shows both modes.

Members of the tool

run, execute and handle each return JSON.stringify(buy.forModel(result)). handle rejects a call with input outside the schema before anything reaches Agentcard. A call that fails rejects with a message that names no link, and error.cause keeps the original error for your logs. answer throws the AgentcardApiError itself. Call instantAck or instantReaction the moment a message arrives, before your model runs. When either returns a reply, the tool sends none of its own for that turn, and the model reads shopper_already_told_looking: true.

Frameworks

Pass buy as it is. toOpenRouterTool(buy, { tool, z }) takes your own tool from @openrouter/agent and z from zod, so the package installs no dependencies. toOpenRouterTool accepts the tool or a turn. toAnthropicTool(buy) is deprecated and returns buy itself.

The model’s input

The model sends five fields and nothing else. The schema marks all five required and sets additionalProperties to false. parseBuyToolInput accepts an object or its JSON text. The function trims product_id and store_id, reads an empty string as null, and throws a TypeError when both are set. Your own code may leave product_id and store_id out.

BuyToolResult

buy.answer returns the whole answer for your code.

Status

Waits

A call that lands while Agentcard is still placing the order pauses once for 12 seconds and reads the conversation. A call that finds the order already placed reads it at once. A request that takes Agentcard more than 110 seconds comes back before its cart is ready, so the tool reads the conversation every 5 seconds for up to a minute and returns the cart once Agentcard finishes. Pass wait to replace the timer between reads. Each link has a kind. The fields below belong to the kinds named in the second column. The tool sends up to eight product links and eight store links per answer. The Sending each link guide shows how to render each kind.

BuyToolProduct

productAction(merchant) returns reserve for reservations, book for flights, hotels, tickets and classes, and buy for every other merchant.

BuyToolStore

What the model reads

buy.forModel(result) returns BuyToolModelView, the answer with every link taken out. An address with a path or a scheme is removed, and a bare one, such as walmart.com, reads as the site’s name. BuyToolModelCart has store, items, fees, fee_lines, tip, total, total_is_estimate, total_leaves_out and max_charge. Each item has product_id, name, qty, price, line_total, options and variant. Prices are text such as \$13.31.

Standalone helpers

The package root exports the functions the tool uses, for a loop that reads results itself. The instantAck options work as follows: previous is the reply you sent last, so the next one comes from another template. nextAction is the last answer’s next_action. asked is the last message the shopper read. stores holds the names of the stores the last answer listed.
ack.ts
The first call returns a reply that names the request, and the second returns null because yes starts no search.