---
title: Agent
description: The shopping assistant - AI-powered product discovery, cart management, and generative UI.
type: guide
prerequisites:
  - /docs/getting-started
---

# Agent



The storefront includes an opt-in AI shopping assistant built with [AI SDK](https://ai-sdk.dev). It can search products, browse collections, manage the cart, answer store-policy questions, and render rich product cards through natural conversation. The default model is Google Gemini 3.5 Flash through the Vercel AI Gateway.

## How it works

**Feature-flagged, single-file runtime.** The assistant defaults to disabled through `agent.enabled` in `shop.config.ts`, which reads `NEXT_PUBLIC_ENABLE_AGENT` (`"1"` to enable, `"0"` to disable). When disabled, the button is hidden and `POST /api/chat` returns `404` before reading the request body or creating a cart. The model, loop limit, prompts, and tool registry all live together in `lib/agent/server.ts`, since they form one runtime implementation rather than a storefront configuration API: `AgentPanel` (`useChat`) posts to `/api/chat`, which runs a request-scoped `ToolLoopAgent` against the Shopify tools and streams the result back.

**Trusted page context, not client-supplied state.** The route derives context from the same-origin `Referer` header rather than trusting a client-supplied product or collection object. Product and collection handles are resolved through Shopify before being added to the system prompt, so the assistant can understand phrases like "this product" while prices, variants, and availability stay authoritative. A request-scoped `AsyncLocalStorage` exposes the current locale, cart ID, chat ID, and page context to every tool during that request.

**Generative UI settles before it renders.** The model's response streams through json-render's `pipeJsonRender`, which adds structured UI data parts to the normal AI SDK stream; `useJsonRenderMessage` reconstructs the spec on the client for `<Renderer>`. Cards render only after the turn settles, so a partial spec never flashes an incorrect card. `CartReconciler` watches completed cart-tool calls in the message stream and updates the global cart context — opening the overlay on a successful mutation, updating state silently for a plain `getCart`.

## Out of the box

**Product discovery**

| Tool                        | Purpose                                                                              |
| --------------------------- | ------------------------------------------------------------------------------------ |
| `searchProducts`            | Keyword search with sorting (best matches, price low/high); returns up to 10 results |
| `getProductDetails`         | Full product info: description, prices, variants, availability, and images           |
| `getProductRecommendations` | Complementary and related products (up to 5)                                         |
| `listCollections`           | All store categories                                                                 |
| `browseCollection`          | Products within a collection with sorting                                            |

**Cart management** — `addToCart`, `getCart`, `updateCartItemQuantity`, `removeFromCart`, and `addCartNote`, all funneled through `lib/shopify/operations/cart.ts` so existing cache invalidation applies. The route creates a cart before streaming when needed and returns its httpOnly cookie in the response headers.

**Navigation** — `navigateUser` generates links to product pages, collections, search, cart, checkout, account, and orders.

**Native Shopify (Storefront MCP)** — `searchCatalog`, `getCatalogProduct`, and `searchShopPoliciesAndFaqs` call Shopify's hosted [Storefront MCP](https://shopify.dev/docs/apps/build/storefront-mcp) endpoint as an alternative discovery path. `searchCatalog` accepts natural-language intent and enriches results with storefront handles so they can feed normal navigation and cart flows. Set `UCP_AGENT_PROFILE_URL` only when the store requires an agent profile.

**Generative UI components** — `AgentProductCard`, `AgentProductGrid`, `AgentCartSummary`, `AgentCartConfirmation`, and `AgentVariantPicker`, registered in the json-render catalog in `lib/agent/index.ts`.

**Chat UI and persistence** — a compact-to-capped panel with streaming "Thinking…" state, bottom pinning, click-outside behavior, and clear/minimize controls. The chat ID, draft input, and UI messages persist to `localStorage` under `template-agent-chat:v3`, so a conversation survives reloads until cleared — persistence is browser-local; there is no durable server-side session.

## Common customizations

The agent doesn't ship these, but they're worth adding before real traffic or production use.

* **Abuse protection** — `POST /api/chat` is anonymous when enabled; the feature flag is a deployment guard, not abuse protection. Add [Vercel BotID](https://vercel.com/docs/botid) to reject automated traffic, per-IP rate limiting backed by shared infrastructure such as Vercel Runtime Cache, and a model output/token cap to bound worst-case gateway spend — run bot and rate-limit checks before `request.json()` and before cart creation. If the route already sits behind a WAF, prefer that policy and keep the model cap.
* **Durable chat sessions** — conversation history is browser-local only today; swapping in a server-durable store (a database, or a Workflow session) would let a conversation survive a device switch or a cleared cache.
* **Additional tools** — new capabilities are added the same way as the shipped ones: an AI SDK `tool()` under `lib/agent/tools/` that calls the normal Shopify operation layer, then registered in `lib/agent/server.ts`.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)