π€ PartSelect Parts Assistant (LLM-Assisted)
An AI-powered conversational appliance repair assistant designed to help users
diagnose issues, confirm part compatibility, and follow correct installation steps for dishwashers and refrigerators.
Unlike traditional chatbots, this system uses deterministic dialog routing with selective LLM augmentation, ensuring reliability and preventing dialog drift. 
π₯ Demo Video
Watch a full walkthrough of the system, including troubleshooting and installation flows:
π YouTube Demo:
π§ Tech Stack
- TypeScript
- Node.js
- Rule-based dialog state machine
- Groq LLM API (optional, fallback-only)
- REST-style backend API
βοΈ Features
- Guided, multi-turn troubleshooting flows
- Part β model compatibility confirmation
- Step-by-step installation guidance
- Intent stickiness (prevents intent stealing)
- Appliance pinning across turns
- Optional LLM fallback for ambiguous user input
- Demo support for order flow and human handoff
π Architecture Overview
High-Level Flow
Frontend β message + history β router.ts (main dialog brain)
Core Router Responsibilities
- Intent inference
- Appliance pinning (dishwasher / refrigerator)
- Dialog state tracking
- Intent stickiness across short replies
Routing Strategy
- Deterministic dialog flows (default)
- LLM fallback (Groq) only when rule-based parsing fails
Key design principle: The LLM never decides the dialog flow.
It is only used to parse ambiguous natural language when rules fail.
π§ Core Concepts
1. Intent Stickiness (No Intent Stealing)
Short or ambiguous replies like:
yespanelclampssidehumming
are consumed by the current dialog state, rather than being reclassified as new intents.
This prevents classic chatbot failures such as:
User: βclampsβ
Bot: βHereβs a replacement pump.β
2. Appliance Pinning
Once inferred, the appliance type remains pinned across turns:
User: My dishwasher isnβt draining User: yes User: humming
The system continues the dishwasher drain diagnostic flow without requiring the user to restate context.
3. Explicit Dialog State Machine
The router tracks fine-grained awaiting states such as:
pump_sounddishwasher_drain_speedinstall_steppanel_still_wont_drop_yesnoclamp_typeconnector_moving_or_stuck
Each user message is first handled by the current awaiting state before any re-routing logic is applied.
β‘ Where the LLM Is Used (Intentionally Limited)
The Groq LLM is not used to βchatβ.
It is only invoked when:
- The system expects a specific semantic classification
- Rule-based parsing returns
unknown
Example
User input:
βIt makes a weird buzzing noiseβ
- Rule-based parser β
unknown - Groq fallback β
"humming"
This allows the dialog flow to continue
without granting control of routing decisions to the LLM.
π Project Structure
src/
- router.ts β Main dialog router & state machine
- groqHelpers.ts β Narrow LLM helpers (classification only)
- tools.ts β Demo tools (compatibility, lookup, guides)
- types.ts β ChatRequest / ChatResponse / Intent
π GitHub Repository
Explore the source code and documentation for the Othello Game: