Skip to content

Agentic homepage: chat-first storefront on Sonnet 4.6 via OpenRouter #3

Description

@hev

Goal

Replace the static homepage at `web/app/page.tsx` with a chat-first shopping experience. The agent has tools to search products, search reviews, fetch product detail, and list categories. Streams via Vercel AI SDK; product results render inline as full ProductGrid cards.

Model + provider

  • Model: `anthropic/claude-sonnet-4.6` via OpenRouter
  • SDK: `@ai-sdk/openai` with `baseURL=https://openrouter.ai/api/v1\` (OpenRouter is OpenAI-compatible — no separate provider package)
  • Secret: reuse the existing indexer `OPENROUTER_API_KEY` Kubernetes secret; mount in the web pod via `valueFrom: secretKeyRef`

Tools (server-side handlers proxy to the in-cluster indexer)

Tool Wraps Notes
`search_products({query, top_k?, category?})` `POST /search` top_k default 6
`search_reviews({asin, query, top_k?})` `GET /search/reviews` top_k default 4
`get_product({asin})` + `get_similar({asin, top_k?})` `GET /product/{asin}` + similar lookup
`list_categories()` `GET /meta` for "what do you have?" prompts

UX

  • Streaming tokens via `useChat` from `@ai-sdk/react`
  • Tool calls render as a collapsible "Searching reviews for B00…" indicator
  • Product results from `search_products` / `get_similar` / `get_product` render inline as the existing ProductGrid card style (image + title + price + tags), clicks open `/product/[asin]`
  • `maxSteps: 5` per turn
  • No conversation persistence in v1 (per-tab, lost on refresh)
  • `/search` and `/product/[asin]` remain reachable by URL (no link from homepage) — preserves SEO and gives a fallback when the model is down

Files

  • `web/app/page.tsx` — rewrite as client chat UI
  • `web/app/api/chat/route.ts` — new, AI SDK `streamText` route handler
  • `web/lib/tools.ts` — Zod tool schemas + handlers
  • `web/components/ChatMessage.tsx`, `web/components/ChatProductCard.tsx` — new
  • `web/package.json` — add `ai`, `@ai-sdk/react`, `@ai-sdk/openai`, `zod`
  • `helm/hev-shop/templates/web.yaml` — `OPENROUTER_API_KEY` env from existing indexer secret
  • `helm/hev-shop/values.yaml` — secret ref

Out of scope (v1)

  • No auth / per-user conversation history
  • No cost guard (the indexer's daily-usage-cap pattern is appropriate later, not v1)
  • No rate limiting
  • No tool-call cost metrics dashboard

Acceptance

  • `hev-shop.com` loads to a chat input; "find me a brass desk lamp" returns product cards inline within a few seconds.
  • "does the bose qc45 have good battery life?" triggers `search_reviews` and returns a grounded answer citing actual review chunks.
  • `/search?q=…` and `/product/[asin]` still work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions