Skip to content

OwnerOfJK/odin

Repository files navigation

Odin - Thorlabs Support Agent

A Next.js-based conversational AI agent that helps users discover, research, and purchase Thorlabs photonics products. The system uses a filesystem-first retrieval approach with PageIndex Cloud and the Vercel AI SDK to provide accurate product information and enable e-commerce functionality.

🎯 Overview

Odin is an intelligent support agent that combines:

  • Documentation Search: Query product manuals and datasheets using structured document trees
  • Inventory Management: Real-time stock checking and product availability
  • Shopping Cart: Full e-commerce functionality with account-based discounts
  • Delivery Visualization: Animated map showing delivery routes from Berlin warehouse to customer

The system demonstrates a retrieval-first approach where the AI agent uses structured document nodes (from PageIndex Cloud) to answer questions, reducing hallucination and improving accuracy compared to traditional RAG systems.

✨ Features

Core Capabilities

  • Product Discovery: Search across product documentation using natural language queries
  • Technical Specifications: Get detailed specs, parameters, and technical data from product manuals
  • Inventory Checking: Real-time stock levels and pricing for all products
  • Documentation Navigation: Browse product documentation in a hierarchical sidebar (toggle with Cmd+B / Ctrl+B)
  • Source Citations: Clickable links to specific document sections with popup previews

E-Commerce Features

  • Shopping Cart: Add products to cart with quantity management
  • Account-Based Discounts: Automatic discount calculation (Academic 15%, Government 12%, Commercial 10%)
  • Checkout Flow: Order processing with inventory validation
  • Delivery Animation: Visual map showing delivery route from Berlin warehouse to destination
  • Order History: Track orders in order-sessions.json

Product Management

  • PDF Upload: Upload product PDFs via web interface
  • Automatic Processing: Python scripts automatically extract document trees and generate summaries
  • Tree Structure: Documents stored as hierarchical JSON trees with node IDs, titles, and summaries

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Frontend (Next.js)                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚  β”‚   Chat UI    β”‚  β”‚  Cart Sidebarβ”‚  β”‚ Docs Sidebar β”‚      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                  β”‚                  β”‚
          β–Ό                  β–Ό                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              API Gateway (/api/chat)                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚         Vercel AI SDK Agent (ToolLoopAgent)           β”‚   β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚   β”‚
β”‚  β”‚  β”‚ queryDoc   β”‚  β”‚ checkInv   β”‚  β”‚ addToCart   β”‚     β”‚   β”‚
β”‚  β”‚  β”‚ querySum   β”‚  β”‚ purchase   β”‚  β”‚ estimate   β”‚     β”‚   β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                  β”‚                  β”‚
          β–Ό                  β–Ό                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Data Layer                                β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚  β”‚ Documentationβ”‚  β”‚  Inventory    β”‚  β”‚ User Accountsβ”‚      β”‚
β”‚  β”‚  (JSON trees)β”‚  β”‚  (JSON)       β”‚  β”‚  (JSON)      β”‚      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Components

  • Frontend: Next.js App Router with React components
  • Agent Runtime: Vercel AI SDK ToolLoopAgent with OpenAI GPT-4o
  • Retrieval: PageIndex Cloud for document processing and tree extraction
  • Tools: TypeScript functions for document querying, inventory, cart management
  • State Management: Zustand for cart state
  • Maps: Mapbox GL for delivery visualization

πŸš€ Getting Started

Prerequisites

  • Node.js 18+ and pnpm (or npm/yarn)
  • Python 3.8+ (for document processing scripts)
  • OpenAI API key
  • PageIndex API key (for PDF processing)
  • Mapbox access token (for delivery map - optional)

Installation

  1. Clone the repository

    git clone https://github.com/OwnerOfJK/odin.git
    cd odin
  2. Install dependencies

    pnpm install
  3. Set up Python environment (for document processing)

    cd app/python
    python3 -m venv .venv
    source .venv/bin/activate 
    pip install -r requirements.txt
  4. Configure environment variables

    Create a .env.local file in the root directory:

    # Required
    OPENAI_API_KEY=sk-your-openai-key
    PAGEINDEX_API_KEY=your-pageindex-key
    
    # Optional (for delivery map)
    NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN=pk.your-mapbox-token
  5. Start the development server

    pnpm dev
  6. Open your browser Navigate to http://localhost:3000

πŸ“ Project Structure

odin/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ actions/              # Server actions
β”‚   β”‚   β”œβ”€β”€ getAllDocuments.ts    # Fetch all documentation files
β”‚   β”‚   └── getNode.ts            # Get specific document node
β”‚   β”œβ”€β”€ api/                  # API routes
β”‚   β”‚   β”œβ”€β”€ chat/             # Main chat endpoint
β”‚   β”‚   β”œβ”€β”€ checkout/         # Order processing
β”‚   β”‚   β”œβ”€β”€ accounts/         # User account management
β”‚   β”‚   └── upload-product/   # PDF upload & processing
β”‚   β”œβ”€β”€ components/           # React components
β”‚   β”‚   β”œβ”€β”€ cart/             # Shopping cart components
β”‚   β”‚   β”œβ”€β”€ map/              # Map visualization
β”‚   β”‚   β”œβ”€β”€ modals/           # Modal dialogs
β”‚   β”‚   β”œβ”€β”€ Message.tsx       # Chat message display
β”‚   β”‚   β”œβ”€β”€ ChatInput.tsx     # Message input
β”‚   β”‚   β”œβ”€β”€ NodesSidebar.tsx  # Documentation browser
β”‚   β”‚   └── ShoppingCart.tsx  # Cart container
β”‚   β”œβ”€β”€ data/                 # Data files
β”‚   β”‚   β”œβ”€β”€ documentation/    # Product PDFs and JSON trees
β”‚   β”‚   β”œβ”€β”€ inventory.json    # Product inventory
β”‚   β”‚   β”œβ”€β”€ user-accounts.json # Customer accounts
β”‚   β”‚   β”œβ”€β”€ order-sessions.json # Order history
β”‚   β”‚   └── summary.json      # Product summaries
β”‚   β”œβ”€β”€ hooks/                # React hooks
β”‚   β”‚   β”œβ”€β”€ useCart.ts        # Cart operations
β”‚   β”‚   β”œβ”€β”€ useCheckout.ts    # Checkout logic
β”‚   β”‚   └── useMapAnimation.ts # Map animation
β”‚   β”œβ”€β”€ python/               # Python scripts
β”‚   β”‚   └── scripts/
β”‚   β”‚       β”œβ”€β”€ build-tree-from-pdf.py  # Extract document tree
β”‚   β”‚       β”œβ”€β”€ append-summary.py       # Generate summaries
β”‚   β”‚       └── summarize_tree.py      # Summary generation
β”‚   β”œβ”€β”€ stores/               # State management
β”‚   β”‚   └── cartStore.ts      # Zustand cart store
β”‚   β”œβ”€β”€ tools/                # AI agent tools
β”‚   β”‚   β”œβ”€β”€ search-product-documentation.ts      # Product documentation search
β”‚   β”‚   β”œβ”€β”€ search-product-summary.ts   # Product summary search
β”‚   β”‚   β”œβ”€β”€ check-inventory.ts # Stock checking
β”‚   β”‚   β”œβ”€β”€ add-to-cart.ts    # Add items to cart
β”‚   β”‚   β”œβ”€β”€ purchase-product.ts # Process purchases
β”‚   β”‚   └── estimate-delivery.ts # Delivery estimates
β”‚   └── utils/                # Utility functions
β”‚       β”œβ”€β”€ cartValidation.ts  # Cart validation
β”‚       β”œβ”€β”€ discountCalculator.ts # Discount logic
β”‚       └── stateCoordinates.ts # US state coordinates
β”œβ”€β”€ PRODUCT.md                 # Product specification
β”œβ”€β”€ SHOPPING_CART_README.md    # Shopping cart documentation
└── README.md                  # This file

πŸ› οΈ Available Tools

The AI agent has access to the following tools:

Tool Description Use Case
searchProductDocumentationTool Search within specific product documentation "What are the specifications for the DFB15TK laser?"
searchProductSummariesTool Search product summaries to find relevant products "What lasers do you have?"
checkInventoryTool Check stock levels and pricing "Is APD130A in stock?"
addToCartTool Add products to shopping cart "Add 2 APD130A to my cart"
purchaseProductTool Process a purchase (usually via checkout UI) Checkout flow
estimateDeliveryTool Get delivery time estimates "How long will delivery take?"
manageAccountTool Manage user account information Account operations

πŸ“Š Data Structure

Documentation Files

Documentation is stored as hierarchical JSON trees in app/data/documentation/:

[
  {
    "title": "Chapter 1: Introduction",
    "node_id": "0001",
    "page_index": 1,
    "summary": "Brief summary of the chapter",
    "text": "Full chapter text...",
    "nodes": [
      {
        "title": "1.1 Overview",
        "node_id": "0002",
        "page_index": 2,
        "summary": "...",
        "text": "..."
      }
    ]
  }
]

Inventory

Products are stored in app/data/inventory.json:

{
  "products": [
    {
      "productCode": "APD130A",
      "name": "Avalanche Photodetector, Si, 400-1000 nm",
      "category": "APD130x-Avalanche-Photodetectors",
      "stock": 45,
      "price": 2499.00,
      "currency": "USD",
      "location": "Berlin Warehouse",
      "restockDate": null
    }
  ]
}

πŸ’¬ Usage Examples

Product Discovery

User: "What lasers do you have available?"
Agent: [Searches summaries, checks inventory, presents table]

Technical Questions

User: "What is the wavelength range of the DFB15TK laser?"
Agent: [Queries documentation, returns specs with source links]

Shopping

User: "Add 2 APD130A detectors to my cart"
Agent: [Adds to cart, shows confirmation]

Documentation Browsing

  • Press Cmd+B (Mac) or Ctrl+B (Windows/Linux) to toggle documentation sidebar
  • Click on any node to view its content in a popup
  • Navigate hierarchical structure with dropdowns

πŸ”§ Development

Adding a New Tool

  1. Create a new tool file in app/tools/:

    import { tool } from 'ai';
    import { z } from 'zod';
    
    export const myTool = tool({
      description: 'Tool description',
      inputSchema: z.object({
        param: z.string(),
      }),
      execute: async ({ param }) => {
        // Tool logic
        return { result: '...' };
      },
    });
  2. Export it from app/tools/index.ts

  3. Add it to the agent in app/api/chat/route.ts

Adding Product Documentation

  1. Upload PDF via the web interface (Admin β†’ Upload Product)
  2. Or manually:
    • Place PDF in app/data/documentation/
    • Run: python app/python/scripts/build-tree-from-pdf.py <pdf_path> <product_name> <output_dir>
    • Run: python app/python/scripts/append-summary.py <product_name> <tree_json_path> <summary_json_path>

Adding Products to Inventory

Edit app/data/inventory.json and add product entries following the existing structure.

🚒 Deployment

Vercel (Recommended)

  1. Push code to GitHub
  2. Import project in Vercel
  3. Add environment variables in Vercel dashboard
  4. Deploy

Manual Deployment

pnpm build
pnpm start

πŸ“ Environment Variables

Variable Required Description
OPENAI_API_KEY Yes OpenAI API key for the AI agent
PAGEINDEX_API_KEY Yes PageIndex Cloud API key for PDF processing
NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN No Mapbox token for delivery map visualization

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is private and proprietary.

πŸ™ Acknowledgments


For detailed shopping cart documentation, see SHOPPING_CART_README.md

For product specifications, see PRODUCT.md

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors