System Design
V2 Architecture
How CopilotKit, LangGraph, and the AG-UI Protocol work together to create an Agent-Native shopping experience.
High-Level Overview
V2 replaces the traditional request-response pattern with a shared state architecture. The frontend and agent maintain a synchronized state object, enabling bidirectional communication and real-time updates.
Component Deep Dive
1.MerchandiserProvider
React Context that manages shared state on the frontend. In a full CopilotKit integration, this would use the useCoAgent hook.
// src/components/v2/MerchandiserProvider.tsx
interface MerchandiserContextType {
state: SharedState;
products: Map<string, Product>;
isLoading: boolean;
error: string | null;
generateLayout: () => Promise<void>;
refineLayout: (critique: string) => Promise<void>;
setPersona: (persona: 'hunter' | 'gatherer') => void;
updateContext: (context: Partial<ShoppingContext>) => void;
}2.CopilotKit Endpoint
API route that bridges the frontend and the LangGraph agent. Handles action routing and state transformation.
// src/app/api/copilotkit/route.ts
interface CopilotKitRequest {
action: 'generate' | 'refine' | 'update_inventory';
state?: Partial<SharedState>;
message?: string; // For refinement critique
}
// Invokes merchandiser agent and returns updated state3.Merchandiser Agent (LangGraph)
StateGraph-based agent that handles layout generation, refinement, and inventory updates. Uses conditional routing based on state.
// src/lib/agents/merchandiser/graph.ts
const graph = new StateGraph(MerchandiserState)
.addNode('load_inventory', loadInventoryNode)
.addNode('generate', generateLayoutNode)
.addNode('refine', refineLayoutNode)
.addNode('handle_stock', handleStockUpdateNode)
.addConditionalEdges(START, routeAfterStart, {...})
// ... routing logicData Flow
Initial Load
Frontend mounts MerchandiserProvider → Initial state created with persona and context → Auto-triggers generateLayout()
Layout Generation
API receives generate action → Agent loads inventory → GPT-4o generates layout → Response updates frontend state
Refinement (Spotify Loop)
User submits critique → API receives refine action → Agent generates new layout incorporating feedback → Response includes refinement history
Inventory Update
Stock changes detected → Agent identifies out-of-stock products → Automatically triggers refinement to find replacements
File Structure
src/
├── app/
│ ├── api/
│ │ └── copilotkit/
│ │ └── route.ts # CopilotKit API endpoint
│ └── shop/
│ └── page.tsx # V2 shop page
│
├── components/
│ └── v2/
│ ├── MerchandiserProvider.tsx # Shared state context
│ ├── V2ShopExperience.tsx # Main V2 component
│ ├── V2LayoutRenderer.tsx # State-driven layout
│ ├── RefinementChat.tsx # Spotify Loop UI
│ └── RefinementHistory.tsx # Adaptation history
│
└── lib/
├── agents/
│ └── merchandiser/
│ ├── index.ts # Agent exports
│ ├── state.ts # LangGraph state schema
│ ├── nodes.ts # Agent node functions
│ └── graph.ts # StateGraph composition
│
└── shared-state/
└── schemas.ts # SharedState Zod schemas