Skip to content

Ravinx001/Auto-Auction-AI-Chatbot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🚗 Auto-Auction AI Chatbot System

🤖 A Complete Ecosystem for AI-Driven Vehicle Sales, CRM Management & WhatsApp Integration

Intelligent Vehicle Dealer Network — Sri Lanka / New Zealand Market Inventory CRM · LangGraph AI Brain · WhatsApp Cloud API Delivery Layer

Platform Laravel 12 Python LangGraph Flask PostgreSQL Redis OpenAI GPT-4o-mini DeepSeek LangSmith Pinecone

🎯 Project Overview

The Auto-Auction AI Chatbot is a production-grade, multi-tier vehicle sales automation ecosystem built for automobile dealerships operating in Sri Lanka and the New Zealand import market. Rather than a single monolithic bot, the system is deliberately split into three distinct micro-projects — each with a single, focused responsibility — that communicate over HTTP and share a common PostgreSQL database.

The architecture enforces strict separation of concerns:

Layer Project Responsibility
📊 Data Layer aai-chatbot-crm (Laravel 12) Inventory entry, dealer management, RBAC
🧠 Intelligence Layer ai-chatbot-aai-v2 (Python / LangGraph) Conversational AI, query routing, DB reads
💬 Delivery Layer whatsapp-hook-aai-v2 (Python / Flask + Waitress) WhatsApp webhook, batching, rich UI cards

💡 Persona: The AI presents itself as Ravi, a vehicle sales agent with 10 years of experience at Lanka Motors, Colombo, Sri Lanka — responding only in English and always in NZD (New Zealand Dollars).


🏗️ Full System Architecture & Integration Diagram

flowchart TB
    subgraph CRM["🏢 aai-chatbot-crm (Laravel 12)"]
        direction TB
        Admin["👨‍💼 Admin / Dealer Staff"]
        LaravelApp["Laravel Application\n(PHP 8.2 + Breeze Auth)"]
        LaravelDB["PostgreSQL\nInventory Database"]
        Admin -->|"CRUD via Web UI"| LaravelApp
        LaravelApp -->|"Eloquent ORM"| LaravelDB
    end

    subgraph AI["🧠 ai-chatbot-aai-v2 (FastAPI + LangGraph)"]
        direction TB
        FastAPI["FastAPI Server\n:9095"]
        LangGraph["LangGraph State Machine\nguardrail → agent → tools → response_guardrail → handle_response"]
        GPT["GPT-4o-mini\n(Primary LLM)"]
        DeepSeek["DeepSeek Chat\n(Fallback LLM)"]
        Tools["8 LangChain Tools\nsearch_local_db · browse_inventory\ncheck_stock_with_fallback · get_models_by_brand\nsearch_nhtsa · update_db · register_user_request\nget_current_datetime"]
        Redis["Redis\nSession Store (3h TTL)"]
        FastAPI --> LangGraph
        LangGraph --> GPT
        GPT -.->|"on error"| DeepSeek
        LangGraph --> Tools
        LangGraph -->|"session R/W"| Redis
    end

    subgraph WA["💬 whatsapp-hook-aai-v2 (Flask)"]
        direction TB
        MetaAPI["Meta WhatsApp\nCloud API"]
        FlaskServer["**Flask + Waitress Server\n:8000**"]
        Batcher["Message Batcher\n4-second window"]
        Formatter["Rich UI Formatter\nImages · Buttons · Pagination"]
        MetaAPI <-->|"HTTPS Webhook"| FlaskServer
        FlaskServer --> Batcher
        Batcher --> Formatter
    end

    User["👤 WhatsApp User"] <-->|"WhatsApp messages"| MetaAPI
    FlaskServer <-->|"POST /chat\nlocalhost:9095"| FastAPI
    Tools <-->|"READ ONLY\nSQLAlchemy"| LaravelDB
Loading

🔄 End-to-End Message Flow

How a single user message travels through all three projects from entry to delivery:

sequenceDiagram
    participant U as 👤 WhatsApp User
    participant M as Meta Cloud API
    participant F as Flask Webhook
    participant B as Message Batcher
    participant A as FastAPI Agent
    participant G as LangGraph
    participant D as PostgreSQL DB
    participant R as Redis

    U->>M: "show honda black under 10000"
    M->>F: POST /webhook (JSON payload)
    F->>F: Validate webhook signature
    F->>B: Queue message for wa_id
    Note over B: Wait 4 seconds for more messages
    B->>A: POST /chat {message, session_id, dealer_whatsapp_number}
    A->>R: Load conversation history (session_id)
    A->>G: Invoke LangGraph with AgentState
    G->>G: guardrail_node → check_guardrail
    G->>G: agent_node (GPT-4o-mini + tools)
    G->>D: browse_inventory(make=Honda, color=Black, max_price=10000)
    D-->>G: Returns matching vehicles
    G->>G: response_guardrail_node
    G->>G: handle_response (format JSON)
    G-->>A: {response, inventory_items, pagination, model_buttons, variant_buttons}
    A->>R: Update session history
    A-->>F: ChatResponse JSON
    F->>M: Send vehicle image + caption (hero card)
    F->>M: Send "📷 More Photos" button
    F->>M: Send "➡️ Next 6 Vehicles" button (if paginated)
    M->>U: Rich WhatsApp UI with vehicle cards
Loading

📦 Project Modules In Depth


1️⃣ aai-chatbot-crm — Inventory & Administration CRM

Overview

aai-chatbot-crm is the data entry and administration portal built with Laravel 12 (PHP 8.2). It is the single authoritative source of truth for all vehicle inventory. Staff and administrators log in to manage the full vehicle lifecycle — from first entry to final sale — across two distinct stock types:

  • Local / Showroom Stock (inventory table): Vehicles physically present at the dealership.
  • Nichibo / Auction Import Stock (nichibo_stock table): Vehicles sourced from Japanese auction houses (Nichibo), with detailed auction-grade condition reports.

Technology Stack

Technology Version Role
Laravel 12.x MVC web framework
PHP ≥ 8.2 Runtime
Laravel Breeze 2.3 Authentication scaffolding
Tailwind CSS 3.x Frontend utility styling
Vite 6.x Frontend bundler
PostgreSQL Primary database
SQLite Local/dev database (default .env)
Redis Session, cache, queue backend

🗂️ Database Schema & Models

The CRM manages a rich, normalized schema. Below is a breakdown of every Eloquent model and its purpose:

Core Entity Models

Model Table Purpose
User users Admin/staff accounts with RBAC
Dealer dealers Dealership profiles, WhatsApp numbers, stock preferences
Vehicle vehicles Vehicle catalogue (make, model, variant, specs)
Inventory inventory Showroom stock — physical vehicles available for sale
InventoryImage inventory_images Ordered gallery images per showroom inventory item
NichiboStock nichibo_stock Auction/import stock from Japanese auctions
NichiboStockVehiclePhoto nichibo_stock_vehicle_photos Gallery images for Nichibo stock

Attribute / Lookup Models

Model Table Purpose
Make makes Vehicle brand catalogue (Toyota, Honda, etc.)
FuelType fuel_types Petrol, Diesel, Hybrid, Electric
Transmission transmissions Automatic, Manual
DriveType drive_types 2WD, 4WD, AWD
Colour colours Available body colours
Grade grades Auction grades (auction quality rating)
Option options Vehicle extras (drivetrain, stereo, transmission option, trim material, airbags, etc.)
Comment comments Auction notes (notes, options, condition, accessories)

Condition Assessment Models (Nichibo Specific)

Model Table Purpose
ExteriorCondition exterior_conditions Panel damage count, tyre tread, bumper damage, underbody
InteriorCondition interior_conditions Smell, dirt, dashboard scratches, cigarette burns, dashboard damage
InstrumentsAndControl instruments_and_controls Mirror conditions, power window status, front screen damage
CigaretteBurn cigarette_burns Cigarette burn severity lookup
DashboardScratch dashboard_scratches Dashboard scratch level lookup
DashboardDamage dashboard_damages Dashboard damage type lookup
Dirt dirt Interior dirt level lookup
Smell smells Interior odour type lookup
LeftSideMirror left_side_mirror Left mirror condition lookup
RightSideMirror right_side_mirror Right mirror condition lookup
PowerWindow power_windows Power window status lookup
FrontWindowScreenDamage front_window_screen_damages Windscreen damage lookup
Drivechain drivechains Drivetrain type lookup
Stereo stereos Audio system type lookup
TransmissionOption transmission_options Gearbox type lookup
UnderbodyType underbody_types Underbody condition lookup

Security Model

Model Table Purpose
Permission permissions Named permission slugs (e.g. vehicles.create)
User ↔ Permission user_permissions Many-to-many assignment

Key Model Relationships

Vehicle (1) ──< Inventory (M) ──< InventoryImage (M)
Vehicle (1) ──< NichiboStock (M) ──< NichiboStockVehiclePhoto (M)
NichiboStock (M) >── Grade (1)
NichiboStock (M) >── Comment (1)
NichiboStock (M) >── Option (1) >── Drivechain, Stereo, TransmissionOption
NichiboStock (M) >── ExteriorCondition (1) >── UnderbodyType
NichiboStock (M) >── InteriorCondition (1) >── Smell, Dirt, DashboardScratch, CigaretteBurn, DashboardDamage
NichiboStock (M) >── InstrumentsAndControl (1) >── LeftSideMirror, RightSideMirror, PowerWindow, FrontWindowScreenDamage
User (M) ><< Permission (M)  [via user_permissions]
Inventory (M) >── Dealer (1)

🔀 Routes & Controllers

All routes are protected by Laravel's auth middleware. Granular CRUD access is enforced per-resource by a custom permission middleware.

Permission Scopes

vehicles.view / vehicles.create / vehicles.edit / vehicles.delete
dealers.view / dealers.create / dealers.edit / dealers.delete
inventory.view / inventory.create / inventory.edit / inventory.delete
nichibo_stock.view / nichibo_stock.create / nichibo_stock.edit / nichibo_stock.delete
vehicle_attributes.view / vehicle_attributes.create / vehicle_attributes.edit / vehicle_attributes.delete
nichibo_attributes.view / nichibo_attributes.create / nichibo_attributes.edit / nichibo_attributes.delete
admins.view / admins.create / admins.edit / admins.delete

Controller Summary

Controller File Responsibilities
VehicleController VehicleController.php CRUD for vehicle catalogue (make/model/variant/specs)
DealerController DealerController.php CRUD for dealer profiles, generates DLR#### IDs
InventoryController InventoryController.php (23 KB) Showroom stock CRUD, image uploads, status management
NichiboStockController NichiboStockController.php (35 KB) Auction stock CRUD, full condition report management
VehicleAttributeController VehicleAttributeController.php (10 KB) CRUD for makes, fuel types, transmissions, drive types, colours
NichiboStockAttributeController NichiboStockAttributeController.php (19 KB) CRUD for all 14 Nichibo attribute lookup tables
ExportController ExportController.php (14 KB) CSV/Excel export for showroom and Nichibo inventory
Admin/AdminController Admin/AdminController.php Admin/staff user management, permission assignment, status toggle
ProfileController ProfileController.php Authenticated user profile edit/delete

API Endpoints (Internal AJAX)

GET  /api/makes               → JSON list of all makes
GET  /api/fuel-types          → JSON list of fuel types
GET  /api/transmissions       → JSON list of transmissions
GET  /api/drive-types         → JSON list of drive types
GET  /api/colours             → JSON list of colours

GET  /export/inventory        → Download showroom stock as CSV/Excel
GET  /export/nichibo-stock    → Download auction stock as CSV/Excel

🔐 Authentication & Authorization

  • Laravel Breeze provides session-based authentication with login, registration, and password reset.
  • User::isSuperAdmin() — bypasses all permission checks.
  • User::hasPermission(string $permission) — checks user_permissions pivot table.
  • Custom permission middleware reads the permission slug from the route and checks against the authenticated user.

🌐 Environment Variables

APP_NAME=Laravel
APP_ENV=local
APP_KEY=                          # Generated via artisan key:generate
APP_URL=http://localhost
DB_CONNECTION=pgsql               # Switch to pgsql for production
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=vehicle_db
DB_USERNAME=
DB_PASSWORD=
SESSION_DRIVER=database
CACHE_STORE=database
QUEUE_CONNECTION=database
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

📁 Project Structure

aai-chatbot-crm/
├── app/
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── Admin/AdminController.php       # Admin user management
│   │   │   ├── DealerController.php             # Dealer CRUD
│   │   │   ├── ExportController.php             # CSV/Excel exports
│   │   │   ├── InventoryController.php          # Showroom stock CRUD (23KB)
│   │   │   ├── NichiboStockController.php       # Auction stock CRUD (35KB)
│   │   │   ├── NichiboStockAttributeController.php # 14 attribute tables
│   │   │   ├── VehicleAttributeController.php   # Make/fuel/transmission/colour
│   │   │   └── VehicleController.php            # Vehicle catalogue CRUD
│   │   ├── Middleware/
│   │   │   └── PermissionMiddleware.php         # Custom RBAC middleware
│   │   └── Requests/                            # Form request validation
│   ├── Models/                                  # 32 Eloquent models
│   ├── Providers/
│   └── View/
├── database/
│   ├── migrations/                              # 11 schema migration files
│   └── seeders/
├── routes/
│   ├── web.php                                  # All 80+ named routes
│   └── auth.php                                 # Breeze auth routes
├── resources/
│   └── views/                                   # Blade templates (Tailwind)
├── config/
├── composer.json
└── package.json

🚀 Setup & Run

# Navigate to project directory
cd aai-chatbot-crm

# Install PHP dependencies
composer install

# Copy and configure environment
cp .env.example .env
php artisan key:generate

# Configure database in .env (PostgreSQL or SQLite for dev)
# Run migrations
php artisan migrate --seed

# Install and build frontend assets
npm install && npm run build

# Start development server (runs server + queue + logs + vite concurrently)
composer run dev
# OR just the HTTP server
php artisan serve

2️⃣ ai-chatbot-aai-v2 — The AI Brain (LangGraph Agent)

Overview

ai-chatbot-aai-v2 is the intelligence engine of the entire system. It is a FastAPI application running on port 9095 that hosts a stateful LangGraph conversational agent. The agent uses GPT-4o-mini as its primary reasoning model (with DeepSeek as a fallback), has access to 8 specialized LangChain tools to query the shared PostgreSQL database, maintains per-user conversation history in Redis, and returns structured JSON responses that the WhatsApp layer can render as rich UI.

This project strictly follows Clean Architecture (Domain → Application → Infrastructure → Interfaces), keeping all business logic in the domain layer and all external concerns in the infrastructure layer.

Technology Stack

Technology Version Role
FastAPI Async REST API server
Uvicorn ASGI server
LangGraph Deterministic agent state machine
LangChain Tool definition, message history, LLM binding
GPT-4o-mini OpenAI Primary reasoning LLM (fast, low-cost)
DeepSeek Chat DeepSeek Fallback LLM when OpenAI fails
Google Gemini Google Optional LLM (via langchain-google-genai)
SQLAlchemy ORM for PostgreSQL
psycopg2 PostgreSQL adapter
Redis Per-user session state (3-hour TTL)
Pinecone Vector store (optional, for semantic search)
Sentence Transformers Local embeddings
LangSmith Tracing and observability
python-dotenv Environment variable loading

🧠 LangGraph State Machine

The entire conversational logic is implemented as a directed graph with conditional edges, ensuring deterministic, testable execution paths.

# src/application/agent/graph.py
graph = StateGraph(AgentState)
graph.add_node("guardrail",          guardrail_node)
graph.add_node("agent",              agent_node)
graph.add_node("tools",              tool_node)
graph.add_node("response_guardrail", response_guardrail_node)
graph.add_node("handle_response",    handle_response)
graph.add_node("confirm_variant",    confirm_variant)

graph.set_entry_point("guardrail")
graph.add_conditional_edges("guardrail", check_guardrail, {
    "allowed": "agent",
    "blocked": END
})
graph.add_conditional_edges("agent", should_continue, {
    "tools":           "tools",
    "handle_response": "response_guardrail"
})
graph.add_edge("response_guardrail", "handle_response")
graph.add_edge("tools",              "agent")
graph.add_edge("handle_response",    END)
graph.add_edge("confirm_variant",    END)

app = graph.compile()

Graph Nodes Explained

Node Function Description
guardrail guardrail_node Input safety filter — blocks off-topic, harmful, or irrelevant queries before they reach the main agent
agent agent_node Core reasoning step — GPT-4o-mini with 8 bound tools analyzes the message and decides what tool to call
tools tool_node Tool executor — runs the LangChain tool the agent chose and returns the result back to the agent
response_guardrail response_guardrail_node Output safety filter — validates the agent's proposed response before delivery
handle_response handle_response Response formatter — converts agent output into structured JSON for the WhatsApp layer
confirm_variant confirm_variant Variant confirmation — handles the UI flow when a user is confirming a specific vehicle variant

AgentState Schema

class AgentState(TypedDict):
    messages:      Annotated[Sequence[BaseMessage], add_messages]  # Full conversation history
    user_id:       str           # Session / WhatsApp ID
    phase:         str           # Current conversation phase ("initial", "confirm_variant", etc.)
    data:          dict          # Arbitrary state data passed between nodes
    dealer_id:     Optional[str] # Active dealer identifier
    dealer_config: Optional[Any] # DealerConfig object with stock preferences

🔧 LangChain Tools (Agent Capabilities)

The agent has access to 8 tools — all thin wrappers around domain services following Clean Architecture:

tools = [
    search_local_db,            # Full-text search of inventory by natural language query
    search_nhtsa,               # Query NHTSA external vehicle safety database
    update_db,                  # Update vehicle status (mark as sold/reserved)
    check_stock_with_fallback,  # Primary vehicle lookup by make/model/variant/filters
    register_user_request,      # Log user contact/interest requests to DB
    browse_inventory,           # Exploratory browsing by budget, fuel, body type
    get_current_datetime,       # Return current date/time in Asia/Colombo timezone
    get_models_by_brand,        # List all available models for a given make (showroom + import)
]

Tool Details

get_models_by_brand(make, dealer_id=None)

  • Called when user says "show toyota" or "what Honda cars do you have?"
  • Searches both showroom and import stock depending on dealer config and system stock switch priority
  • Returns model list with counts, price ranges, variants, and button payloads for WhatsApp interactive buttons

browse_inventory(make, model, fuel_type, color, max_price, min_price, min_year, max_year, max_mileage, dealer_id)

  • Exploratory search — returns grouped make/model listings
  • Used for TYPE A queries: "show me petrol cars under 8000", "family SUV", "affordable hatchback"
  • Preserves all filter parameters across multi-turn conversations

check_stock_with_fallback(make, model, variant, color, max_price, min_year, max_mileage, dealer_id)

  • Specific lookup — returns paginated vehicle cards with full details and images
  • Applies stock-switch logic: tries showroom first, falls back to import stock if empty (based on dealer config)
  • Supports pagination: returns 6 vehicles per page with remaining_items for "Next 6" button

search_local_db(query, dealer_id)

  • Full-text search across all vehicle attributes

search_nhtsa(query)

  • Queries the NHTSA (National Highway Traffic Safety Administration) API for US safety data and specs

register_user_request(user_id, request_type, details)

  • Logs customer interest/contact requests to the database for dealer follow-up

update_db(stock_type, stock_id, status)

  • Updates vehicle status (Available → Sold/Reserved) — write access controlled by the agent only

get_current_datetime()

  • Returns the current date/time in Asia/Colombo timezone for time-aware responses

🤖 LLM Configuration

# Primary: GPT-4o-mini (fast, reliable, cost-effective)
llm_openai = ChatOpenAI(model="gpt-4o-mini", max_retries=2, timeout=30)

# Guardrail-specific fast model
llm_fast = ChatOpenAI(model="gpt-4o-mini", max_retries=1, timeout=15)

# Fallback: DeepSeek (independent API, high availability)
llm_deepseek = ChatOpenAI(
    model="deepseek-chat",
    base_url="https://api.deepseek.com",
    max_retries=1, timeout=30
)

# Chained with automatic fallback
llm_with_tools = llm_openai_with_tools.with_fallbacks([llm_deepseek_with_tools])

🗂️ System Prompt & Persona

The agent is instructed via a comprehensive ChatPromptTemplate that enforces:

  • Persona: "Ravi", 10-year veteran vehicle sales agent at Lanka Motors, Colombo
  • Currency: All prices must be NZD — never LKR, "million", or "M"
  • Language: English only
  • Format rules: Strict WhatsApp markdown formatting (bold via *, italic via _, code via backtick)
  • Greeting policy: Respond to greetings with exactly "Hi, what kind of vehicle are you looking for?"
  • Filter preservation: Budget, color, year, mileage filters must be carried forward through ALL subsequent tool calls
  • Query type classification (4 types):
    • TYPE A — Exploratory (no make/model): Use browse_inventory
    • TYPE B — Brand only: Use get_models_by_brand
    • TYPE C — Brand + Model: Use check_stock_with_fallback
    • TYPE D — Brand + Model + Variant: Use check_stock_with_fallback with variant

📦 Stock Switch System

The AI implements a configurable dual-stock system with three priority modes:

Priority Mode Behavior
high (System Override) Always show BOTH showroom + import stock combined
low (Dealer-Controlled) Dealer config decides when to show import stock
off Only showroom stock is ever shown

Per-dealer configuration in DealerConfig:

show_external_stock_when_unavailable: bool  # Show auction if local empty?
prefer_local_stock: bool                    # Try local first?
auto_switch_on_empty: bool                  # Auto-fallback without asking user?

🏛️ Clean Architecture Layers

src/
├── application/            # Use cases & agent orchestration
│   ├── agent/
│   │   ├── graph.py        # LangGraph state machine definition
│   │   ├── nodes.py        # All 6 graph node implementations (78KB)
│   │   ├── state.py        # AgentState TypedDict
│   │   └── tools.py        # 8 LangChain tool definitions (57KB)
│   └── dtos/               # Data Transfer Objects
│
├── core/                   # Configuration & cross-cutting concerns
│   ├── config.py           # All env vars, LangSmith, stock switch config
│   ├── dealer_config.py    # DealerConfig dataclass + DB/memory retrieval
│   └── logger.py           # Structured logging
│
├── domain/                 # Business models & pure logic
│   ├── models.py           # Domain entities
│   ├── repositories/       # Repository interfaces (contracts)
│   │   ├── agent_repository.py
│   │   ├── auction_repository.py
│   │   ├── contact_log_repository.py
│   │   ├── dealer_repository.py
│   │   ├── inventory_repository.py
│   │   └── vehicle_repository.py
│   └── services/           # Domain services (business rules)
│       ├── auction_service.py        # Auction stock query logic
│       ├── contact_service.py        # Agent assignment, lead logging
│       ├── dealer_service.py         # Dealer lookup & config
│       ├── duty_calculation_service.py # Import duty computations
│       ├── inventory_service.py      # Showroom stock query logic
│       ├── more_info_service.py      # Extended vehicle detail fetcher
│       ├── pricing_service.py        # Price calculation helpers
│       ├── stock_switch_service.py   # Dual-stock switching logic (19KB)
│       └── vehicle_service.py        # Vehicle info aggregation
│
└── infrastructure/         # External concerns & adapters
    ├── database/
    │   ├── models.py        # SQLAlchemy ORM models (mirrors CRM schema)
    │   ├── postgres.py      # SessionLocal, engine setup
    │   └── redis.py         # Redis client connection
    ├── external/
    │   └── nhtsa.py         # NHTSA API client
    ├── repositories/        # Concrete DB implementations
    │   ├── postgres_inventory_repository.py
    │   ├── postgres_vehicle_repository.py
    │   ├── postgres_dealer_repository.py
    │   └── auction_repository_impl.py
    └── services/
        ├── session.py        # Redis-backed session R/W (3h TTL)
        └── user_requests.py  # Customer request logging

🌐 REST API Endpoints

The FastAPI application exposes the following endpoints on localhost:9095:

Chat

POST /chat
Body: {
  "message":                 "show honda black under 10000",
  "session_id":              "94771234567",     # WhatsApp ID
  "dealer_whatsapp_number":  "+94771234567"     # Dealer phone → identifies which dealer
}
Response: {
  "response":        "Text reply from AI",
  "intro_message":   "Separate intro text to send first",
  "inventory_items": [...],      # Vehicle cards with images for WhatsApp
  "pagination":      {...},      # total, page_size, has_more, remaining_items
  "model_buttons":   [...],      # Interactive buttons for brand query
  "variant_buttons": [...],      # Interactive buttons for model selection
  "session_id":      "...",
  "dealer_id":       "DLR0001",
  "data":            {}
}

Session Management (Admin, Bearer token required)

GET    /session/{whatsapp_number}     # Get session state & history count
DELETE /session/{whatsapp_number}     # Clear a specific user's session
GET    /sessions                      # List all active sessions
DELETE /sessions/clear-all            # Wipe all sessions

Vehicle Info

GET /vehicle/more-info/{stock_type}/{stock_id}
# stock_type: "showroom" or "import"
# Returns extended vehicle details for "More Info" button

Dealer Management

GET  /dealers         # List all dealers
POST /dealers         # Create a new dealer

Contact / Lead System

POST /contact/request?user_phone=&dealer_id=&stock_type=&stock_id=&contact_method=
# Round-robin assigns a sales agent and generates a pre-filled WhatsApp link

GET /contact/agents/{dealer_id}   # List all agents for a dealer (admin)

🌐 Environment Variables

# Core
OPENAI_API_KEY=                           # Required — GPT-4o-mini
DB_URL=postgresql://user:pass@host:5432/vehicle_db
REDIS_URL=redis://127.0.0.1:6379
SESSION_TTL=10800                         # 3 hours in seconds

# LangSmith Tracing
LANGSMITH_TRACING=true
LANGSMITH_API_KEY=
LANGSMITH_PROJECT=Vehicle_Dealer_Bot

# Optional LLMs
DEEPSEEK_API_KEY=                         # Fallback LLM
GOOGLE_API_KEY=                           # Gemini integration

# Optional Vector Store
PINECONE_API_KEY=
PINECONE_INDEX_NAME=vehicle-dealer-bot-v2
PINECONE_ENVIRONMENT=us-east-1

# Image URL Configuration
LARAVEL_STORAGE_BASE_URL=https://your-domain.com/storage
DEFAULT_VEHICLE_IMAGE=https://your-domain.com/storage/default/no-image.jpg

# Stock Switch
SYSTEM_STOCK_SWITCH_ENABLED=true
SYSTEM_STOCK_SWITCH_PRIORITY=high         # high | low | off

# Security
AUTH_TOKEN=aai-admin-secret-2026

🚀 Setup & Run

cd ai-chatbot-aai-v2

# Install dependencies
pip install -r requirements.txt

# Configure environment
cp .env.example .env
# Edit .env with your actual API keys and DB connection string

# Run the FastAPI server
python main.py
# Starts on http://localhost:9095

3️⃣ whatsapp-hook-aai-v2 — The WhatsApp Delivery Layer

Overview

whatsapp-hook-aai-v2 is a lightweight Flask application that acts as the bridge between the Meta WhatsApp Cloud API and the internal AI Agent. It handles all aspects of the WhatsApp protocol: webhook verification, incoming message parsing, intelligent message batching, response formatting into rich WhatsApp UI components, and outbound message delivery. It is intentionally kept thin and stateless — all AI logic lives in the agent.

Technology Stack

Technology Role
Flask Lightweight Python web framework (+ Waitress WSGI)
Requests HTTP calls to the AI agent and Meta Graph API
python-dotenv Environment variable loading
Threading Async message processing (non-blocking webhook response)

📡 WhatsApp Cloud API Integration

The hook communicates with Meta's Graph API v15.0+:

POST https://graph.facebook.com/{VERSION}/{PHONE_NUMBER_ID}/messages
Authorization: Bearer {ACCESS_TOKEN}

Message types used:

  • Text message — plain "type": "text" for conversational replies
  • Image message"type": "image" with "link" for vehicle hero photos
  • Interactive button message"type": "interactive" with up to 3 reply buttons for model/variant selection and pagination

🔀 Flask Routes

GET  /webhook                          # Meta webhook verification (hub.challenge)
POST /webhook                          # Incoming WhatsApp message handler

# Session Management (proxied to AI Agent)
GET    /session/<whatsapp_number>      # View session state
DELETE /session/<whatsapp_number>      # Clear a user's session
GET    /sessions                       # List all sessions
DELETE /sessions/clear-all             # Clear all sessions

# Vehicle Info (proxied to AI Agent)
GET    /vehicle/more-info/<stock_type>/<stock_id>

All admin endpoints require Authorization: Bearer aai-admin-secret-2026.

⏱️ Message Batching System

WhatsApp users frequently send multiple short messages in rapid succession (e.g., "hello", "I want", "toyota"). Sending each message independently to the AI would result in incomplete, confusing queries.

The batcher solves this with a 4-second sliding window:

BATCH_DELAY = 4  # seconds
MESSAGE_BATCHES = {}  # {wa_id: {"messages": [], "app": Flask, "dealer_whatsapp_number": str}}

# When a new message arrives for wa_id:
# 1. Append message text to MESSAGE_BATCHES[wa_id]
# 2. Cancel any existing timer for wa_id
# 3. Start a new 4-second Timer → calls process_message_batch()
# 4. If another message arrives within 4 seconds, repeat steps 1-3
# 5. After 4 seconds of silence → combine all messages with "\n\n" separator
#    → POST to http://localhost:9095/chat

🖼️ Rich UI Message Delivery

The formatter module renders AI responses as WhatsApp-native UI elements:

Vehicle Card Rendering

For each vehicle in inventory_items:

  1. Hero image sent with vehicle description as caption (≤ 1024 chars)
  2. Additional images stored in PENDING_IMAGES[wa_id] for "Show More" button
  3. Interactive button panel sent after each card:
    • 📷 N More Photos → triggers show_more_{idx} button ID
    • ℹ️ More Info → triggers more_info_{stock_type}_{stock_id} button ID
    • 📞 Contact → triggers contact_{dealer_id} button ID

Google Drive URL Conversion

Vehicle images stored in Google Drive are automatically converted for WhatsApp delivery:

# From: https://drive.google.com/file/d/{FILE_ID}/view
# To:   https://drive.google.com/thumbnail?id={FILE_ID}&sz=w1000

Model Selection Buttons

When agent returns model_buttons (brand query like "show toyota"):

[Interactive message]
Body: "🚗 TOYOTA Cars Available Now\n1. *AQUA* (NZD 7,478 - 9,985)\n..."
Buttons: ["View Aqua"] ["View Corolla"] ["View Prius"]

Variant Selection Buttons

When agent returns variant_buttons (model query like "show toyota aqua"):

[Interactive message]
Body: "🚗 TOYOTA AQUA Variants Available Now\n1. *S* (3 vehicles)\n..."
Buttons: ["S"] ["X-URBAN"] ["G"]

📄 Pagination System

When a search returns more than 6 vehicles, the hook manages pagination entirely:

  1. First page (6 vehicles) sent as individual cards
  2. PENDING_PAGINATION[wa_id] stores remaining vehicles in memory
  3. "➡️ Next N Vehicles" button sent at the bottom
  4. When user clicks next_page:
    • get_next_page_items() retrieves next 6 from memory
    • Sends next batch of vehicle cards
    • Repeats until inventory exhausted
  5. Final message: "✅ You've seen all available vehicles!"

🔐 Security: Webhook Signature Validation

The @signature_required decorator on POST /webhook validates that the incoming payload was genuinely sent by Meta:

# app/decorators/security.py
# Validates X-Hub-Signature-256 header using APP_SECRET

The GET /webhook endpoint handles Meta's initial webhook subscription by verifying hub.verify_token matches VERIFY_TOKEN from .env.

🔘 Button Interaction Handler

When a user taps an interactive button, the Flask hook detects the interactive message type and routes accordingly:

Button ID Pattern Action
show_more_{N} Retrieve and send additional vehicle images from PENDING_IMAGES
next_page Send next 6 vehicles from PENDING_PAGINATION
show_model_{make}_{model} Forward to AI agent as a model selection message
more_info_{type}_{id} Fetch extended vehicle info from /vehicle/more-info/{type}/{id}
contact_{dealer_id} Fetch agent contact info and generate WhatsApp deep-link

⌨️ Typing Indicator

The hook sends a read receipt and typing indicator immediately upon receiving any valid message, improving the user experience:

send_typing_indicator(message_id)  # Marks message as read + shows typing...

🌐 Environment Variables

ACCESS_TOKEN=                  # Meta WhatsApp Cloud API Bearer token
PHONE_NUMBER_ID=               # WhatsApp Business phone number ID
VERSION=v15.0                  # Graph API version
APP_ID=                        # Meta App ID (for signature verification)
APP_SECRET=                    # Meta App Secret (for signature verification)
VERIFY_TOKEN=                  # Custom token for webhook subscription verification
CHATBOT_API_URL=http://localhost:9095  # AI Agent URL
ADMIN_AUTH_TOKEN=aai-admin-secret-2026 # Admin endpoint authorization

📁 Project Structure

whatsapp-hook-aai-v2/
├── app/
│   ├── __init__.py            # Flask app factory, blueprint registration
│   ├── config.py              # App configuration from env vars
│   ├── views.py               # Flask routes (webhook, session, vehicle proxy)
│   ├── decorators/
│   │   └── security.py        # Webhook payload signature validation
│   └── utils/
│       └── whatsapp_utils.py  # Core message processing logic (1341 lines, 64KB)
├── main.py                    # Flask app entry point
├── whatsapp.py                # Standalone script to send test template message
├── requirements.txt           # Flask, requests, python-dotenv
└── .env.example

🚀 Setup & Run

cd whatsapp-hook-aai-v2

# Install dependencies
pip install -r requirements.txt

# Configure environment
cp .env.example .env
# Edit .env with your Meta WhatsApp credentials

# Start the Flask server (served via Waitress WSGI)
python main.py
# Starts on http://0.0.0.0:8000

# Expose to Meta's servers via tunnel (required for production)
ngrok http 8000
# OR
cloudflared tunnel --url http://localhost:5000

# Register the public URL in Meta for Developers:
# https://developers.facebook.com/apps → WhatsApp → Configuration → Webhook URL
# Set: https://{your-ngrok-url}/webhook  (port 8000 proxied by ngrok)
# Verify token: (your VERIFY_TOKEN from .env)

🛠️ Complete System Tech Stack

Layer Technology Role
Admin UI / CRM Laravel 12 + Tailwind CSS Data entry, dealer management, RBAC
Agent Workflow LangGraph 0.x Deterministic state machine for AI flow
Primary LLM OpenAI GPT-4o-mini Intent understanding, conversation synthesis
Fallback LLM DeepSeek Chat High-availability LLM fallback
Optional LLM Google Gemini Additional AI capabilities
Messaging API WhatsApp Cloud API v15+ End-user front-end interface
Webhook Server Flask + Waitress (Python) Request handling, batching, UI formatting
Database PostgreSQL Single source of truth for all vehicle data
ORM (CRM) Laravel Eloquent PHP ORM for CRM data management
ORM (AI) SQLAlchemy Python ORM for AI read access
Caching/Sessions Redis Per-user conversational state (3h TTL)
Vector Store Pinecone Optional semantic search index
Embeddings Sentence Transformers Local vector embedding generation
Observability LangSmith AI trace logging and debugging
External APIs NHTSA API Vehicle safety data lookups
Image Storage Google Drive / Laravel Storage Vehicle photo hosting

🚀 Getting Started — Full System Setup

To run the complete ecosystem locally, you need all three services running simultaneously.

Prerequisites

  • PHP 8.2+ with Composer
  • Python 3.11+
  • PostgreSQL 14+
  • Redis 7+
  • Node.js 18+ (for CRM frontend assets)
  • ngrok or Cloudflare Tunnel (for WhatsApp webhook exposure)
  • Meta WhatsApp Business API credentials

Step 1 — Set Up PostgreSQL Database & CRM

# Create the shared database
createdb vehicle_db

# Navigate to CRM
cd aai-chatbot-crm

composer install
cp .env.example .env
# Edit .env: set DB_CONNECTION=pgsql, DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD
# Also set REDIS_HOST and REDIS_PORT

php artisan key:generate
php artisan migrate --seed
npm install && npm run build

# Start the CRM on localhost:8000
php artisan serve

Access the admin panel at http://localhost:8000 and create your first dealer profile.

Step 2 — Configure & Run the AI Agent

cd ai-chatbot-aai-v2

pip install -r requirements.txt
cp .env.example .env
# Edit .env:
# OPENAI_API_KEY=sk-...
# DB_URL=postgresql://user:pass@127.0.0.1:5432/vehicle_db  ← same DB as CRM
# REDIS_URL=redis://127.0.0.1:6379
# LANGSMITH_API_KEY=ls-...  (optional, for tracing)
# DEEPSEEK_API_KEY=...  (optional, for fallback)

# Start the agent on localhost:9095
python main.py

Test it: curl -X POST http://localhost:9095/chat -H "Content-Type: application/json" -d '{"message": "hello", "session_id": "test123"}'

Step 3 — Configure & Run the WhatsApp Webhook

cd whatsapp-hook-aai-v2

pip install -r requirements.txt
cp .env.example .env
# Edit .env:
# ACCESS_TOKEN=EAAx...   (from Meta for Developers)
# PHONE_NUMBER_ID=123... (from Meta for Developers)
# APP_ID=...
# APP_SECRET=...
# VERIFY_TOKEN=my-custom-token
# VERSION=v18.0

# Start the webhook on localhost:5000
python main.py

# Expose to internet for Meta
ngrok http 5000

Register https://{ngrok-url}/webhook with VERIFY_TOKEN in Meta for Developers.

Step 4 — Verify Integration

Send a WhatsApp message to your registered number:

Hello
→ Bot: "Hi, what kind of vehicle are you looking for?"

Show Toyota vehicles
→ Bot: Model list with interactive buttons

Show Toyota Aqua
→ Bot: Variant list (S, X-Urban, G) with buttons

Toyota Aqua S
→ Bot: Vehicle cards with images, More Photos button, Next 6 button

🔑 Environment Variables Reference

aai-chatbot-crm (Laravel CRM)

Variable Required Description
APP_KEY Laravel application encryption key
DB_CONNECTION pgsql for production
DB_HOST / DB_DATABASE / DB_USERNAME / DB_PASSWORD PostgreSQL connection
REDIS_HOST / REDIS_PORT Optional Redis for sessions & queues
SESSION_DRIVER Optional database or redis

ai-chatbot-aai-v2 (AI Agent)

Variable Required Description
OPENAI_API_KEY GPT-4o-mini access
DB_URL PostgreSQL connection string (same DB as CRM)
REDIS_URL Redis for session storage
SESSION_TTL Optional Session expiry in seconds (default: 10800 = 3h)
DEEPSEEK_API_KEY Optional Fallback LLM provider
GOOGLE_API_KEY Optional Gemini model access
LANGSMITH_API_KEY Optional Trace logging
PINECONE_API_KEY Optional Vector search
LARAVEL_STORAGE_BASE_URL Base URL for CRM-hosted images
DEFAULT_VEHICLE_IMAGE Optional Fallback image URL
SYSTEM_STOCK_SWITCH_PRIORITY Optional high (default), low, or off
AUTH_TOKEN Optional Admin endpoint authentication

whatsapp-hook-aai-v2 (Flask Webhook)

Variable Required Description
ACCESS_TOKEN Meta Graph API permanent access token
PHONE_NUMBER_ID WhatsApp Business number ID
APP_SECRET Meta App secret for signature verification
VERIFY_TOKEN Custom token for webhook subscription
VERSION Graph API version (e.g. v18.0)
CHATBOT_API_URL Optional AI Agent URL (default: http://localhost:9095)
ADMIN_AUTH_TOKEN Optional Admin endpoint token (default: aai-admin-secret-2026)

🔐 Security Architecture

The system is designed with layered security throughout:

Concern Implementation
CRM Access Laravel Breeze session auth + custom RBAC middleware
DB Write Access Only the Laravel CRM can write to the database; AI agent has read-only access
Webhook Integrity X-Hub-Signature-256 HMAC signature validation on all incoming WhatsApp webhooks
Admin API Security Bearer token authentication (aai-admin-secret-2026) on all session management endpoints
Secret Management All keys stored in .env files — never committed to git
Prompt Injection Guardrail node filters malicious or off-topic inputs before they reach the LLM
Response Safety Response guardrail node validates agent output before delivery
LLM Read-Only Rule The AI agent only has SELECT database access — it cannot modify inventory via SQL; update_db tool is the only write path and is constrained

🗺️ Data Flow Architecture

How the Shared Database Connects All Three Projects

CRM (writes) ─────┐
                  │
                  ▼
            ┌──────────────────────────────────────────┐
            │            PostgreSQL Database            │
            │                                          │
            │  vehicles          inventory             │
            │  nichibo_stock     dealers               │
            │  inventory_images  agents                │
            │  nichibo_stock_vehicle_photos            │
            │  ... (30+ tables)                        │
            └──────────────────────────────────────────┘
                  │
                  │ (READ ONLY)
                  ▼
          AI Agent (reads) → returns structured data
                  │
                  ▼
        WhatsApp Hook (formats & delivers)

Dealer Identification Flow

WhatsApp message received
      │
      ▼
Flask extracts dealer's WhatsApp display_phone_number from message metadata
      │
      ▼
Flask POSTs to /chat with dealer_whatsapp_number field
      │
      ▼
FastAPI calls identify_dealer(whatsapp_number=...) 
      │
      ▼
Queries dealers table WHERE whatsapp_number = ?
      │
      ▼
Returns DealerConfig → injected into AgentState
      │
      ▼
All tool calls scoped to that dealer_id
(only that dealer's inventory is shown)

📊 Conversation Type Examples

Example 1 — Exploratory Budget Search

User:  "under 10000"
Bot:   get_models_by_brand + browse_inventory
       → Shows make list: Toyota, Honda, Nissan (with price ranges)
       → Interactive buttons: [View Toyota] [View Honda] [View Nissan]

User:  [Taps "View Toyota"] or types "Toyota"
Bot:   browse_inventory(make=Toyota, max_price=10000)
       → Shows Toyota model list: Aqua (NZD 7,478-9,985), Corolla, Prius...

User:  "Aqua"
Bot:   check_stock_with_fallback(make=Toyota, model=Aqua, max_price=10000)
       → Shows variant list: S (3 vehicles), X-Urban (2), G (1)
       → Interactive buttons: [S] [X-Urban] [G]

User:  [Taps "S"]
Bot:   check_stock_with_fallback(make=Toyota, model=Aqua, variant=S, max_price=10000)
       → Sends vehicle cards: hero image + details, "📷 More Photos", "Next 6" button

Example 2 — Color + Brand Filtered Search

User:  "honda black color"
Bot:   browse_inventory(make=Honda, color=Black)
       → Shows Honda models available in black

User:  "VEZEL"
Bot:   check_stock_with_fallback(make=Honda, model=Vezel, color=Black)  ← color preserved!
       → Shows Vezel variants in black

User:  "Hybrid Z"
Bot:   check_stock_with_fallback(make=Honda, model=Vezel, variant="Hybrid Z", color=Black) ← all filters preserved!
       → Shows specific Vezel Hybrid Z vehicles in black

Example 3 — Import / Auction Stock

User:  "show nissan vehicles"
Bot:   get_models_by_brand(make=Nissan)
       → Searches both showroom AND import stock (SYSTEM_STOCK_SWITCH_PRIORITY=high)
       → Shows combined model list with source labels

User:  "Serena"
Bot:   check_stock_with_fallback(make=Nissan, model=Serena)
       → Tries showroom; if empty, automatically falls back to auction/Nichibo stock
       → Shows Nichibo auction vehicles with grade, FOB price, condition details

📁 Repository Structure

Auto-Auction-AI-Chatbot/
│
├── 📄 README.md                         ← This file
├── 📄 LICENSE
├── 📄 .gitattributes
│
├── 📂 aai-chatbot-crm/                  ← Project 1: Laravel CRM
│   ├── app/
│   │   ├── Http/
│   │   │   ├── Controllers/             # 9 controllers + Admin subdirectory
│   │   │   ├── Middleware/              # Permission middleware
│   │   │   └── Requests/               # Form validation
│   │   ├── Models/                      # 32 Eloquent models
│   │   ├── Providers/
│   │   └── View/
│   ├── database/
│   │   ├── migrations/                  # 11 migration files
│   │   └── seeders/
│   ├── routes/
│   │   ├── web.php                      # 80+ named routes
│   │   └── auth.php
│   ├── resources/views/                 # Blade templates
│   ├── config/
│   ├── composer.json                    # Laravel 12, PHP 8.2, Breeze
│   ├── package.json                     # Tailwind, Vite
│   └── .env.example
│
├── 📂 ai-chatbot-aai-v2/                ← Project 2: LangGraph AI Agent
│   ├── src/
│   │   ├── application/
│   │   │   ├── agent/
│   │   │   │   ├── graph.py             # LangGraph state machine
│   │   │   │   ├── nodes.py             # 6 graph nodes (78KB)
│   │   │   │   ├── state.py             # AgentState TypedDict
│   │   │   │   └── tools.py             # 8 LangChain tools (57KB)
│   │   │   └── dtos/
│   │   ├── core/
│   │   │   ├── config.py               # All environment config
│   │   │   ├── dealer_config.py        # Dealer config management
│   │   │   └── logger.py
│   │   ├── domain/
│   │   │   ├── models.py               # Domain entities
│   │   │   ├── repositories/           # 6 repository interfaces
│   │   │   └── services/               # 9 domain services
│   │   ├── infrastructure/
│   │   │   ├── database/               # SQLAlchemy models, postgres, redis
│   │   │   ├── external/               # NHTSA API client
│   │   │   ├── repositories/           # 4 concrete implementations
│   │   │   └── services/               # Session, user requests
│   │   └── interfaces/
│   │       └── api/
│   │           ├── main.py             # FastAPI app factory
│   │           ├── routes.py           # All API endpoints (415 lines)
│   │           ├── dealer_routes.py    # Dealer CRUD endpoints
│   │           └── models.py           # Pydantic request/response models
│   ├── graphs/                          # LangGraph visualization exports
│   ├── main.py                          # FastAPI entry point (port 9095)
│   ├── requirements.txt                 # 25 Python dependencies
│   └── .env.example
│
└── 📂 whatsapp-hook-aai-v2/             ← Project 3: Flask WhatsApp Webhook
    ├── app/
    │   ├── __init__.py                  # Flask app factory
    │   ├── config.py                    # App configuration
    │   ├── views.py                     # Flask routes (250 lines)
    │   ├── decorators/
    │   │   └── security.py             # HMAC signature validation
    │   └── utils/
    │       └── whatsapp_utils.py       # Core logic: batcher, formatter, sender (1341 lines)
    ├── main.py                          # Flask entry point
    ├── whatsapp.py                      # Standalone template message sender
    ├── requirements.txt                 # Flask, requests, python-dotenv
    └── .env.example

⚙️ Development Commands

Laravel CRM (aai-chatbot-crm)

composer run dev                         # Start all services concurrently (server + queue + logs + vite)
php artisan serve                        # HTTP server only
php artisan migrate                      # Run migrations
php artisan migrate:fresh --seed         # Reset and re-seed database
php artisan queue:listen                 # Process queued jobs
npm run dev                              # Vite HMR dev server
npm run build                            # Production assets
composer run test                        # Run PHPUnit tests
php artisan tinker                       # Interactive REPL

AI Agent (ai-chatbot-aai-v2)

python main.py                           # Start FastAPI server on :9095
uvicorn src.interfaces.api.main:app --reload --port 9095  # With hot reload
# Test chat endpoint:
curl -X POST http://localhost:9095/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "show toyota", "session_id": "test123", "dealer_whatsapp_number": "+94771234567"}'

WhatsApp Webhook (whatsapp-hook-aai-v2)

python main.py                           # Start Flask on :5000
ngrok http 5000                          # Expose to internet for Meta webhook
cloudflared tunnel --url http://localhost:5000  # Alternative tunnel
python whatsapp.py                       # Send a test template message

🧪 Testing & Quality Assurance

CRM Testing

php artisan test                         # Run all PHPUnit tests
php artisan test --filter=InventoryTest  # Run specific test class

AI Agent Testing

# Test chat locally
curl -X POST http://localhost:9095/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "hello", "session_id": "test_001"}'

# Test session management  
curl -X GET http://localhost:9095/sessions \
  -H "Authorization: Bearer aai-admin-secret-2026"

# Clear a test session
curl -X DELETE http://localhost:9095/session/test_001 \
  -H "Authorization: Bearer aai-admin-secret-2026"

WhatsApp Webhook Testing

# Simulate a WhatsApp text message
curl -X POST http://localhost:5000/webhook \
  -H "Content-Type: application/json" \
  -d '{"object":"whatsapp_business_account","entry":[{"changes":[{"value":{"messages":[{"type":"text","text":{"body":"hello"},"id":"msg_001"}],"contacts":[{"wa_id":"94771234567","profile":{"name":"Test User"}}],"metadata":{"display_phone_number":"+94777777777","phone_number_id":"123"}}}]}]}'

⚠️ Known Limitations

  • 🖥️ CRM is web-only — no mobile app for admin management
  • 🔒 AI agent is read-only by design — inventory status updates are the only write path
  • 💬 WhatsApp interactive buttons have a limit of 3 buttons per message (Meta constraint)
  • 📄 Pagination is in-memory — stored per Flask process; not persisted across restarts
  • 🌐 No HTTPS between Flask ↔ Agent in local dev — use a reverse proxy (nginx) in production
  • 🔄 Session state in Redis — loses conversation history on Redis restart unless persistence is enabled
  • 📸 Google Drive images depend on file sharing settings being public/link-accessible
  • 🔢 Button titles are limited to 20 characters by WhatsApp's API

🚩 Feature Flags & Configuration

Flag Project Default Description
SYSTEM_STOCK_SWITCH_ENABLED AI Agent true Master toggle for dual-stock system
SYSTEM_STOCK_SWITCH_PRIORITY AI Agent high high=both stocks, low=dealer decides, off=showroom only
SESSION_TTL AI Agent 10800 Redis session TTL in seconds (3h)
BATCH_DELAY WhatsApp Hook 4 Message batching window in seconds
LANGSMITH_TRACING AI Agent true Enable/disable LangSmith trace logging

🤝 Contributing

Contributions are welcome! Please follow these guidelines:

  • CRM changes: Keep Eloquent models thin, use form requests for validation, preserve migration history
  • AI changes: Maintain Clean Architecture layers — business logic stays in domain/, DB in infrastructure/
  • Tool changes: Keep LangChain tools as thin wrappers; move logic to domain services
  • WhatsApp changes: Keep formatting logic in whatsapp_utils.py, routes thin in views.py
  • System prompt changes: Test all 4 query type classifications before committing
  • Database changes: Add migrations to CRM first, then update SQLAlchemy models in AI agent to match

How to Contribute

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

📄 License

This project is proprietary and not licensed for public distribution. See individual project LICENSE files for details.


🚗 From Inventory Entry to WhatsApp Delivery 🚗

🌟 Three Specialized Micro-Projects. One Seamless Vehicle Sales Experience. 🌟

Built for Sri Lanka 🇱🇰 & New Zealand 🇳🇿 Vehicle Markets

About

The Auto-Auction AI Chatbot is a production-grade, multi-tier vehicle sales automation ecosystem built for automobile dealerships operating in Sri Lanka and the New Zealand import market.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors