Fantastica AI Assistant · Technical overview

Fantastica AI Assistant: technical overview

Independent Rainier Labs technology demonstration built using publicly available Fantastica Water Solutions information. This is not an official Fantastica Water Solutions service. Fantastica has not reviewed, endorsed or authorized it.

Purpose

Fantastica Water Solutions sells and installs water softeners, reverse osmosis (RO) systems, whole-house filtration, commercial systems, water coolers and replacement filters across the San Francisco Bay Area. Prospective customers usually arrive with a problem ("my water is hard", "the tap water tastes like chlorine") rather than a product name.

This demo shows how an AI assistant could, 24/7, on the website and on the phone:

  1. answer questions using only what Fantastica publishes,
  2. help customers understand which kind of system fits their concern,
  3. qualify interest, and
  4. turn it into a structured consultation or callback request.

Business value

Current manual path

Customer → website → form / call → wait for response → Fantastica employee qualifies lead

AI-assisted path

Customer → chat / phone → instant answer → education → qualification → consultation request → structured lead → Fantastica follows up

The assistant does the repetitive first conversation (what's the difference between RO and a whole-house filter, do you service my city, how much is this model) at any hour. Staff receive a lead that already contains the name, contact details, ZIP, concern, product interest, preferred time and an AI summary, instead of a blank form.

We have not measured conversion, response-time or revenue impact for Fantastica, so this demo makes no ROI claims.

System architecture

             fantasticawatersolutions.com (WordPress + WooCommerce, public)
                               │  allowlisted crawler (robots.txt, rate-limited)
                               ▼
  ┌──────────── Knowledge sync (server/knowledge) ──────────────┐
  │ WP REST pages → text, Elementor price cards, FAQs, contacts │
  │ WooCommerce Store API → product catalog + links             │
  │ chunk → Azure OpenAI embeddings → Postgres + pgvector       │
  └──────────────────────────────┬───────────────────────────────┘
                                 ▼
                 Postgres (Railway, pgvector) ◄── admin dashboard (/admin)
                                 ▲
  ┌──────────── Shared brain (server/brain) ─────────────────────┐
  │ router (intent + water concern) → product / service-area     │
  │ lookup + hybrid retrieval (vector + full text) → Azure       │
  │ OpenAI answer → policy enforcement (prices, appointments,    │
  │ transfers) → lead extraction + qualification → notification  │
  └───────────────┬──────────────────────────────┬───────────────┘
                  │                              │
     Web chat (SSE): widget.js →        Retell voice agent: +1 510-340-2594
     /assistant iframe → /api/chat      → tools /api/voice/ask, /api/voice/lead
                                        → webhooks /api/retell/inbound, /api/retell/webhook

One Node.js (Express, TypeScript) service hosts everything: the demo pages, chat API, voice tool endpoints, Retell webhooks, admin dashboard and the scheduled knowledge sync.

Path What it is
/ Fantastica's public website in a full-page frame with the chat launcher (bottom right) and a disclaimer ribbon
/demo Rainier demo landing page: examples, Try Chat, Call AI Demo, How It Works
/assistant Full-page chat (also the iframe the widget opens)
/widget.js Embeddable launcher
/sources Every indexed page, product and sync run
/admin Lead dashboard (password protected)
/health Health and knowledge status (JSON)
/readme This document

Fantastica source ingestion

server/knowledge/sync.ts (run at startup when the knowledge base is empty, every SYNC_INTERVAL_HOURS, or with npm run sync:all):

WordPress / WooCommerce integration

Read-only, public endpoints only: /wp-json/wp/v2/pages, /wp-json/wc/store/v1/products and the sitemaps. No credentials, plugins or changes on Fantastica's site.

WooCommerce product prices are published as $0 (Fantastica prices on the category pages instead), so the assistant never uses WooCommerce prices. It uses the price cards and links each card to its WooCommerce product page when the model matches.

RAG (retrieval-augmented generation)

  1. Route: a deterministic router classifies the intent (product, price, comparison, service area, consultation, callback, transfer, …) and the water concern (hard water, chlorine taste, well water, …).
  2. Structured lookups: products by model or category with their published price; service area from the published county list plus a Bay Area city→county map.
  3. Hybrid retrieval over knowledge_chunks: pgvector cosine similarity + Postgres full-text search, merged with reciprocal-rank fusion.
  4. Grounded generation: the model receives only these facts and must not go beyond them.
  5. Policy enforcement after generation: any dollar amount not present in the published facts is replaced with "Fantastica would need to provide a quote"; appointment wording is forced to "Your preferred time has been recorded. This demonstration does not confirm an appointment."; transfer requests get the demo wording; voice output is stripped of URLs and markdown.
  6. Sources: up to three links (View product / Source / Learn more), always to fantasticawatersolutions.com.

If nothing relevant is found, the assistant says it couldn't verify that from Fantastica's published information.

Azure OpenAI

Uses Rainier's existing Azure OpenAI resource: gpt-4o for answers and lead extraction, text-embedding-3-large at 1,536 dimensions for embeddings. Without Azure credentials the app still runs in a retrieval-only fallback mode.

Web chatbot

Installing the widget on WordPress (future, after authorization)

<script src="https://fantastica.rainierlabs.io/widget.js" data-widget="fantastica" defer></script>

Then add the site's origin to WIDGET_EMBED_ORIGINS so the chat iframe may be framed there. Nothing has been installed on Fantastica's live site.

Voice agent

npm run retell:sync creates or updates the Retell LLM and agent from retell/agent.json, publishes it, and binds +15103402594 (the script refuses to touch any other number).

Shared conversation engine

Chat and voice use one Assistant (server/brain/assistant.ts), one KnowledgeService, one LeadService and one conversations table (channel = CHAT | VOICE). Only the presentation differs: markdown and cards for chat, short URL-free sentences for voice.

Lead capture

SMS

Implemented with explicit consent ("I can text that information to the number you're calling from. Would you like me to?"). Consent is stored on the lead and in sms_messages, and the text is non-marketing (acknowledgement, a Fantastica page link or a consultation summary, plus "Reply STOP to opt out").

It is off (RETELL_SMS_ENABLED=false) until the number completes A2P 10DLC registration. Web chat has no SMS.

Consultation workflow

  1. The customer shows buying intent (a price for their home, a water test, an installation, "can someone call me").
  2. The assistant offers a free consultation and collects name, best phone (or email), ZIP or city, concern, and optionally a preferred time and home vs. business.
  3. It records the request, says "Your preferred time has been recorded. This demonstration does not confirm an appointment.", and mentions that, because this is a demo line, the request is saved for testing (it goes to the Rainier demo dashboard, not to Fantastica).
  4. A notification (if configured) goes to DEMO_LEAD_NOTIFICATION_EMAIL, a Rainier-controlled inbox. Fantastica is never emailed.

There is no scheduling integration. Scheduling would be designed around Fantastica's real process if they adopt the system.

Admin dashboard

/admin uses HTTP Basic auth (ADMIN_PASSWORD; returns 404 when unset). The header menu has two pages: Dashboard and Knowledge sources.

Request callback (web chat)

A Request callback button sits just below the chat title. It opens an inline form for name, phone or email, ZIP, best time and a message (prefilled with the last question). The form posts to POST /api/callback, which validates the fields, rate-limits requests (5 per 10 minutes per client), and records a CALLBACK_REQUESTED lead through the same LeadService as chat and voice.

Security

Privacy

Deployment

Key environment variables (see .env.example):

Source freshness

Limitations

What would change if Fantastica adopted it

  1. Remove the demo disclaimer after authorization.
  2. Embed the widget on the actual WordPress website.
  3. Configure official business phone forwarding (or port/forward a number to the agent).
  4. Configure approved transfer behavior (when and to whom).
  5. Send leads to Fantastica (email to their team, or their CRM).
  6. Connect email/SMS notifications (with A2P registration for SMS).
  7. Determine their actual scheduling process.
  8. Add scheduling integration only if useful.
  9. Determine whether they use a CRM.
  10. Integrate the CRM only if useful.

None of these integrations has been built.

Built by Rainier Labs. No GoHighLevel or other third-party CRM is used.