How Operator's central orchestrator classifies intents, parses dates, and coordinates RAG.
The core intelligence lives in src/server/services/orchestrator.ts under orchestratorService.processMessage().
When a message is received:
1. Idempotency Verification: Checks idempotencyManager using a hash of {organizationId, conversationId, userMessage}. Repeated rapid clicks return the cached response.
2. Identity Resolution: Links the channel identity to a leadProfiles record.
3. Intent Detection: Passes the message to intentService.classifyIntent() to determine customer goal.
4. Context Injection: Injects business profile, operating hours, and active services via businessContextService.
5. Knowledge Retrieval: Queries ragService for document chunks matching the query.
6. Availability Resolution: If the intent is booking-related, calls availabilityService to determine candidate time slots.
7. LLM Generation: Synthesizes a natural, concise, friendly response.
8. Action Execution: Executes dynamic actions (e.g., booking an appointment or escalating).
The intent classification engine detects:
- booking_inquiry: Customer wants to know available times or schedule.
- booking_confirm: Customer selects a specific proposed slot.
- service_inquiry: Questions about treatments, offerings, or durations.
- pricing_inquiry: Questions about costs, fees, or deposits.
- hours_inquiry: Questions about open/close times or weekend hours.
- location_inquiry: Questions about address, directions, or parking.
- cancellation: Requests to cancel an existing booking.
- reschedule: Requests to move a booking to another date.
- escalate_human: Requests to speak with human staff.
- faq_inquiry: General policy questions (e.g., insurance, return policy).
- greeting / chitchat: Polite conversational openers.
The system uses parseNaturalDateTime from src/lib/date.ts to interpret varied conversational time expressions against the business's timezone:
- *"Tomorrow at 2pm"* -> Next business day at 14:00 local time.
- *"Next Tuesday morning"* -> Nearest Tuesday between 09:00 and 11:30.
- *"Friday the 15th at 10:30"* -> Exact calendar date and time.
Web widget users frequently double-click buttons or send identical messages during high latency. Operator enforces idempotency keys with a 60-second TTL to guarantee no duplicate bookings or duplicated AI responses.