npm package: @styledgenie/catalog-agent
Description: LangChain.js shopping agent for StyledGenie product discovery and recommendations
Author: StyledGenie
Latest version: 1.2.0

# StyledGenie Catalog Agent

[![npm version](https://badge.fury.io/js/%40styledgenie%2Fcatalog-agent.svg)](https://badge.fury.io/js/%40styledgenie%2Fcatalog-agent)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
[![LangChain](https://img.shields.io/badge/LangChain-0.3+-green.svg)](https://langchain.com/)

A powerful TypeScript package that provides an AI-powered shopping agent for StyledGenie's product catalog. Built with LangChain.js and OpenAI, it runs a deterministic four-step pipeline to keep every response grounded in real catalog data.

## ✨ Features

- 🤖 **AI-Powered Agent**: Uses OpenAI GPT-4 for intelligent product recommendations
- 🔍 **Semantic Search**: Advanced embedding-based search for complex queries
- 🎯 **Smart Filtering**: Precise product filtering by attributes, categories, and brands
- 💬 **Conversational Interface**: Natural language interaction with memory
- ⚡ **Deterministic Pipeline**: Always runs the same four-step workflow for consistent answers
- 🧭 **Configurable Intent Matching**: Catalog-driven synonym support via `intent-synonyms.json`
- 🧠 **Session Management**: Multi-user conversation tracking
- 📊 **Comprehensive Analytics**: Detailed response metadata and performance metrics
- 🔧 **YAML Configuration**: Easy customization without code changes
- 🛡️ **Type Safety**: Full TypeScript support with Zod validation
- 🧪 **Smoke Test**: Quick end-to-end check via `npm test`

## 🚀 Quick Start

### Installation

```bash
npm install @styledgenie/catalog-agent@1.2.0
```

### Basic Usage

```typescript
import { createSimpleCatalogAgent } from '@styledgenie/catalog-agent';

// Initialize the agent (automatically detects configuration mode)
const agent = await createSimpleCatalogAgent(
  process.env.OPENAI_API_KEY!,
  process.env.SUPABASE_FUNCTIONS_URL!,
  process.env.GPT_ACTIONS_API_KEY!
);

// Send a message
const response = await agent.invoke('I need a red dress for a wedding');

console.log(response.message);
// "I found some beautiful red dresses perfect for a wedding! Here are my top recommendations..."

if (response.products) {
  response.products.forEach(product => {
    console.log(`${product.title} - ${product.url}`);
  });
}
```

## ⚙️ Configuration Modes

The catalog agent supports two configuration modes to accommodate different deployment scenarios:

### Filesystem Mode (Default)
- **When**: `AGENT_CONFIG=0` or unset
- **Use case**: Local development, traditional deployments
- **Configuration source**: Local files in `./config` directory or packaged defaults
- **Files required**: `instructions.yaml`, `actions.yaml`, `DiscoverProducts.json`, `intent-synonyms.json`, `tool-playbook.md`

### Supabase Storage Mode
- **When**: `AGENT_CONFIG=1`
- **Use case**: Serverless deployments (Vercel, Netlify), cloud functions
- **Configuration source**: Supabase Storage bucket
- **Files required**: Same as filesystem mode, uploaded to Supabase Storage

### Configuration Priority
1. **Explicit `configPath`** → Always filesystem mode
2. **`CATALOG_AGENT_CONFIG_PATH` env var** → Always filesystem mode
3. **`AGENT_CONFIG=1`** → Supabase Storage mode
4. **`AGENT_CONFIG=0` or unset** → Filesystem mode (default)

### Environment Variables

#### Required (All Modes)
```bash
OPENAI_API_KEY=sk-proj-...
SUPABASE_FUNCTIONS_URL=https://psnfturxvltaejaopvvg.functions.supabase.co
GPT_ACTIONS_API_KEY=your_gpt_actions_api_key
```

#### Configuration Mode
```bash
# 0 = filesystem (default), 1 = Supabase Storage
AGENT_CONFIG=0
```

#### Supabase Storage Mode (only needed if AGENT_CONFIG=1)
```bash
# WARNING: SUPABASE_SERVICE_ROLE_KEY must be kept server-side only!
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key_here
SUPABASE_CATALOG_BUCKET_PATH=agent-config/catalog-agent/v1.2.0
```

#### Optional
```bash
SHOP_DOMAIN=shop.styledgenie.com
OPENAI_MODEL=gpt-4
NODE_ENV=development
CATALOG_AGENT_CONFIG_PATH=./custom-config  # Override config path (filesystem only)
```

### Smoke Test

```bash
npm test
```

This runs a lightweight build + initialisation check. To trigger a real agent invocation (which requires valid credentials and network access) set `CATALOG_AGENT_SMOKE_FULL=1` before running the command.

### Intent Smoke Test

```bash
npm run intent-smoke -- "show me a red dress for women"
```

Prints the intent analysis (matched attributes/categories/vendors) using the v4 catalog metadata and synonym map.

### Configuration Health Check

```bash
npm run config-health
```

Validates your configuration setup for both filesystem and Supabase modes. Shows which files are present and their status.

## 🗄️ Supabase Storage Setup

For serverless deployments, you can store configuration files in Supabase Storage:

### 1. Create Supabase Storage Bucket

1. Go to your Supabase project dashboard
2. Navigate to Storage → Buckets
3. Create a new bucket named `agent-config`
4. Set the bucket to **public** (or configure RLS policies)

### 2. Upload Configuration Files

Upload these files to your bucket with the path structure:
```
agent-config/
└── catalog-agent/
    └── v1.2.0/
        ├── instructions.yaml
        ├── actions.yaml
        ├── DiscoverProducts.json
        ├── intent-synonyms.json
        └── tool-playbook.md
```

### 3. Set Environment Variables

```bash
AGENT_CONFIG=1
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key_here
SUPABASE_CATALOG_BUCKET_PATH=agent-config/catalog-agent/v1.2.0
```

### 4. Security Considerations

- **Never expose `SUPABASE_SERVICE_ROLE_KEY`** in client-side code
- Use environment variables in your deployment platform
- Consider using Supabase RLS policies for additional security
- Rotate service role keys regularly

## 📖 Documentation

### Core Concepts

The v4 agent follows a deterministic four-step workflow on every request:

1. **Catalog Load** – Read `DiscoverProducts.json` once per session to understand attributes, categories, vendors, and stats.
2. **Intent Matching** – Score the user query against catalog metadata (with synonym support) and require ≥2 high-confidence matches.
3. **filterProducts** – Apply matched facets (fuzzy first, exact on repeats) to narrow candidates.
4. **searchEmbedding** – Run strict semantic ranking over the filtered handles; fallback to boost mode with no filters after two failed intent attempts.

### API Reference

#### `createCatalogAgent(config)`

Creates a new agent with full configuration options.

```typescript
import { createCatalogAgent, AgentConfig, resolveDefaultConfigPath } from '@styledgenie/catalog-agent';

const config: AgentConfig = {
  openAiApiKey: 'sk-proj-...',
  supabaseFunctionsUrl: 'https://...supabase.co',
  gptActionsApiKey: 'your-key',
  configPath: resolveDefaultConfigPath(),
  shopDomain: 'shop.styledgenie.com',
  model: 'gpt-4',
  temperature: 0.1,
  maxTokens: 2000,
  debug: false
};

const agent = await createCatalogAgent(config);
```

#### `agent.invoke(message, sessionId?)`

Process a user message and return a response.

```typescript
const response = await agent.invoke('I need a red dress for a wedding', 'user-123');

// Response structure
{
  message: string;           // Agent's response text
  products?: ProductResult[]; // Found products (if any)
  metadata?: {              // Response metadata
    sessionId: string;
    duration_ms: number;
    tools_used: string[];
    workflow: string;
  };
  success: boolean;
}
```

> **Note:** Streaming is not available in the deterministic v4 workflow. Use `agent.invoke` for all requests.

#### Session Management

```typescript
// Get session state
const sessionState = agent.getSessionState('user-123');

// Update user preferences
agent.updateUserPreferences({
  sizes: ['M', 'L'],
  colors: ['red', 'blue'],
  brands: ['Nike', 'Adidas']
}, 'user-123');

// Reset conversation history
agent.resetSession('user-123');

// Get all active sessions
const sessions = agent.getActiveSessions();
```

### Workflow & Tools

The v4 agent executes a strict four-step workflow:

1. **Load Catalog Data** – Parse `config/DiscoverProducts.json` once per session for metadata and stats.
2. **Intent Matching** – Score user queries against vendors, categories, and attribute values (with synonyms).
3. **filterProducts** – Apply high-confidence facets (fuzzy first, exact on repeated queries) to shrink the catalog.
4. **searchEmbedding** – Run strict semantic ranking on the filtered handles (fallback to boost mode if intent fails twice).

Only two tools are exposed:

1. **`filterProducts`** – Attributes/categories/vendors filtering via Supabase.
2. **`searchEmbedding`** – Semantic ranking with optional handle filters.

There is no discover/list/relax tooling in v4; all logic is codified in configuration plus the intent service.

### Configuration

The agent behavior is controlled by configuration assets under `config`:

- **`instructions.yaml`**: Agent personality, workflow rules, and response guidelines.
- **`actions.yaml`**: Minimal OpenAPI schema exposing `filterProducts` and `searchEmbedding`.
- **`knowledge-base.yaml`**: Links to operational playbooks.
- **`DiscoverProducts.json`**: Catalog metadata (attributes, categories, vendors, stats).
- **`intent-synonyms.json`**: Domain-specific synonym map used during intent matching.

When the agent starts it looks for a `./config` directory in your project; if it is missing, the packaged defaults under `node_modules/@styledgenie/catalog-agent/config` are used automatically. Override `CATALOG_AGENT_CONFIG_PATH` (or pass `configPath`) to point somewhere else.

## 🎯 Use Cases

### E-commerce Chatbots
```typescript
// Next.js API route
export async function POST(request: Request) {
  const { message, sessionId } = await request.json();
  const response = await agent.invoke(message, sessionId);
  return Response.json(response);
}
```

### Product Recommendation Systems
```typescript
// Get personalized recommendations
const response = await agent.invoke(
  'I need something for a summer garden party',
  userId
);

// Display products with confidence scores
response.products?.forEach(product => {
  console.log(`${product.title} (${(product.score! * 100).toFixed(1)}% match)`);
});
```

### Style Consultation
```typescript
// Multi-turn conversation with memory
await agent.invoke('I have a wedding next month', userId);
await agent.invoke('I prefer elegant styles', userId);
await agent.invoke('What do you recommend?', userId);
```

## 🧪 Testing

### Run Tests
```bash
# Unit tests
npm test

# Watch mode
npm run test:watch

# Coverage
npm run test:coverage
```

### Test Examples
```typescript
import { createSimpleCatalogAgent } from '@styledgenie/catalog-agent';

describe('Catalog Agent', () => {
  it('should find products for wedding dress query', async () => {
    const agent = await createSimpleCatalogAgent(
      'test-key',
      'https://test.supabase.co',
      'test-gpt-key'
    );
    
    const response = await agent.invoke('I need a red dress for a wedding');
    
    expect(response.success).toBe(true);
    expect(response.message).toContain('dress');
  });
});
```

## 📦 Examples

Check out the [`examples/`](./examples/) directory for complete implementations:

- **Next.js App Router**: Minimal POST API wired to `agent.invoke`
- **Simple Chat**: CLI interface for testing
- **Session Management**: Multi-user conversation handling

## 🔧 Development

### Setup
```bash
# Clone and install
git clone https://github.com/styledgenie/catalog-agent.git
cd catalog-agent
npm install

# Build
npm run build

# Test
npm test

# Development mode
npm run dev
```

### Project Structure
```
src/
├── agent/
│   ├── catalog-agent.ts    # Main agent implementation
│   └── tools.ts            # LangChain tool definitions
├── config/
│   └── config-loader.ts    # YAML configuration parser
├── types/
│   └── index.ts            # TypeScript type definitions
└── index.ts                # Package exports

config/
├── v4/
│   ├── instructions.yaml     # v4 agent behavior
│   ├── actions.yaml          # filterProducts & searchEmbedding schemas
│   ├── knowledge-base.yaml   # Tool playbook references
│   ├── DiscoverProducts.json # Catalog metadata (attributes/categories/vendors)
│   └── intent-synonyms.json  # Intent matching synonyms
└── (legacy folders)          # Older config versions (optional)

test/                      # Test suite
├── setup.ts              # Test utilities and mocks
├── agent.test.ts         # Agent functionality tests
├── tools.test.ts         # Tool integration tests
└── config-loader.test.ts # Configuration parsing tests

examples/                  # Integration examples
├── nextjs-api-route.ts   # Next.js App Router example
├── simple-chat.ts        # CLI chat interface
└── README.md             # Examples documentation
```

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

### Development Workflow
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request

## 📄 License

MIT License - see [LICENSE](LICENSE) for details.

## 🆘 Support

- 📚 [Documentation](https://github.com/styledgenie/catalog-agent/docs)
- 🐛 [Issue Tracker](https://github.com/styledgenie/catalog-agent/issues)
- 💬 [Discussions](https://github.com/styledgenie/catalog-agent/discussions)

## 🙏 Acknowledgments

- [LangChain.js](https://langchain.com/) for the agent framework
- [OpenAI](https://openai.com/) for the language model
- [Supabase](https://supabase.com/) for the backend infrastructure
- [StyledGenie](https://styledgenie.com/) for the product catalog

---

Made with ❤️ by the StyledGenie team