Skip to main content

AquaGPT - AI Assistant

AI-powered conversational assistant that provides natural language insights about water consumption, trends, alerts, and analytics. Ask questions in plain English and get instant, intelligent responses about your water data.


Overview

AquaGPT is an intelligent chatbot interface that leverages AI to help users understand their water data without complex dashboards or reports. It supports conversation history, like/dislike feedback, and provides contextual responses based on your organization's real-time and historical water data.

Location: libs/aquagpt/

Route: /aquagpt

Permission Required: AQUAGPT


Key Features

1. Natural Language Queries

Ask questions in plain English:

Example Queries:

  • "Tell me about summary data of today"
  • "Give me insights on yesterday's data"
  • "What is my yesterday's water balance?"
  • "Show me consumption trends for the past week"
  • "Which units had leakage alerts today?"
  • "What was my total water usage last month?"

2. Conversation Starters (FAQ)

Pre-defined quick-start prompts for common queries:

const conversationStarters = [
{
icon: <FeedOutlinedIcon />,
label: 'Tell me about summary data of today',
prompt: 'Tell me about summary data of today'
},
{
icon: <WaterDropOutlinedIcon />,
label: "Give me insights on yesterday's data",
prompt: "Give me insights on yesterday's data"
},
{
icon: <LegendToggleOutlinedIcon />,
label: "What is my yesterday's water balance",
prompt: "What is my yesterday's water balance"
}
];

3. Chat History & Session Management

Features:

  • Session-Based Conversations - Each chat session has a unique ID
  • Persistent History - View past conversations (Today, Yesterday, Past 4 Days)
  • Chat Sidebar - Browse previous chats organized by date
  • Continue Conversations - Click on old chats to view and continue

Session ID Format:

const sessionId = `${userId}_${timestamp}`;
// Example: "user123_1709123456789"

4. Interactive Responses

Response Features:

  • Typing Animation - Character-by-character streaming effect
  • HTML Rendering - Supports formatted responses with links, lists, tables
  • Copy Functionality - One-click copy of AI responses
  • Like/Dislike - Provide feedback on response quality

5. Real-Time Data Integration

AquaGPT queries your live water data:

  • Current consumption and stock levels
  • Recent alerts and anomalies
  • Water quality readings
  • Flow rates and trends
  • Historical patterns

Architecture

Data Flow

Key Components

1. AquaGptContextProvider

  • Purpose: Global state management for AquaGPT
  • Location: libs/aquagpt/src/store/AquaGptStore.js
  • State Variables:
    • previousChatData - Historical chats (today, yesterday, past 4 days)
    • currentChatArray - Active conversation messages
    • chatResponse - Latest AI response
    • isLoading - Initial loading state
    • isGettingResponse - Response generation in progress
    • selectedChat - Currently viewing old chat
    • sessionId - Unique conversation identifier

Context Value:

{
previousChatData: {
today: [...],
yesterday: [...],
past4Days: [...]
},
currentChatArray: [
{ prompt: "...", type: "prompt", sessionId: "..." },
{ response: "...", type: "response", id: "...", showLikedComponent: true }
],
chatResponse: { id, prompt, response, date, showLikedComponent },
isLoading: false,
isGettingResponse: false,
selectedChat: null,
sessionId: "user123_1709123456789",
getGptResponse: (prompt) => {},
patchReplyLikeStatus: (messageId, isLiked, prompt) => {}
}

2. AquaGpt (Main Component)

  • Purpose: Main AquaGPT page layout
  • Location: libs/aquagpt/src/AquaGpt.jsx
  • Features:
    • Sidebar with chat history
    • Main chat area
    • Responsive drawer for mobile
    • New chat button

3. AquaGptChat

  • Purpose: Current conversation interface
  • Location: libs/aquagpt/src/components/AquaGptChat.jsx
  • Features:
    • Conversation starter cards (FAQ)
    • Message list with auto-scroll
    • Input field with send button
    • Typing animation for responses

4. OldChatComponent

  • Purpose: Display previous conversations
  • Location: libs/aquagpt/src/components/OldChatComponent.jsx
  • Features:
    • Read-only chat view
    • Like/dislike feedback
    • Copy functionality

5. AiSideBar

  • Purpose: Chat history sidebar
  • Location: libs/aquagpt/src/components/AiSideBar.jsx
  • Features:
    • New chat button
    • Chat grouping by date (Today, Yesterday, Past 4 Days)
    • Click to load old conversations
    • Responsive collapse/expand

6. TypingAnimation

  • Purpose: Animate AI response character-by-character
  • Location: libs/aquagpt/src/components/TypingAnimation.jsx
  • Features:
    • Streaming text effect
    • Auto-scroll as text appears
    • HTML content rendering

7. EmojiComponent

  • Purpose: Like/dislike feedback and copy buttons
  • Location: libs/aquagpt/src/components/EmojiComponent.jsx
  • Features:
    • Thumbs up/down icons
    • Copy to clipboard button
    • Feedback submission to backend

API Integration

Get GPT Response

POST /gpt/aqua
Request Body: {
prompt: "Tell me about summary data of today",
sessionId: "user123_1709123456789",
baseURL: "https://aquagen.example.com"
}

Response: {
data: {
id: "gpt_msg_12345",
date: "25/02/2026",
prompt: "Tell me about summary data of today",
response: "<p>Here's today's water summary...</p>",
showLikedComponent: true
}
}

Response Types:

Success:

{
id: "gpt_msg_12345",
date: "25/02/2026",
prompt: "What is my water usage?",
response: "<p>Your total water usage today is <strong>1,234 kL</strong>...</p>",
showLikedComponent: true
}

Connection Error:

{
id: "generated_id",
date: "25/02/2026",
prompt: "...",
response: "Failed to connect to the server!",
showLikedComponent: false
}

Understanding Error:

{
id: "generated_id",
date: "25/02/2026",
prompt: "...",
response: "I was unable to understand. I can help you with understanding of your consumption trend, stock usage etc.",
showLikedComponent: false
}

Get Past Responses

GET /getGptPastResponse
Params: {
numberOfDays: 3
}

Response: {
data: [
{
today: [
{
id: "msg1",
date: "25/02/2026",
prompt: "Today's summary",
response: "...",
isLiked: true
}
],
yesterday: [...],
past4Days: [...]
}
]
}

Submit Like/Dislike Feedback

PATCH /patchLikeStatus
Request Body: {
id: "gpt_msg_12345",
isLiked: true, // or false
prompt: "Tell me about summary data of today"
}

Response: {
status: 200,
message: "Feedback submitted successfully"
}

Usage Examples

1. Initialize AquaGPT

import AquaGpt from '@aquagen-mf-webapp/aquagpt';

function AquaGPTPage() {
return <AquaGpt />;
}

2. Access AquaGPT Context

import { useContext } from 'react';
import { AquaGptContext } from '@aquagen-mf-webapp/aquagpt';

function CustomAIComponent() {
const aiStore = useContext(AquaGptContext);

const handleAskQuestion = () => {
aiStore.getGptResponse("What is my water consumption today?");
};

return (
<div>
<button onClick={handleAskQuestion}>Ask AI</button>
{aiStore.isGettingResponse && <Loader />}
</div>
);
}

3. Submit User Query

const handleGetResponse = (e) => {
e.preventDefault();

if (!question.trim()) return;

// Send question to AI
aiStore.getGptResponse(question);

// Clear input
setQuestion('');
};

4. Use Conversation Starters

const handleStarterClick = (starterPrompt) => {
// Send predefined question
aiStore.getGptResponse(starterPrompt);

// Update input field
setQuestion(starterPrompt);
};

<ButtonBase onClick={() => handleStarterClick("Tell me about summary data of today")}>
<FeedOutlinedIcon />
<Typography>Tell me about summary data of today</Typography>
</ButtonBase>

5. Provide Feedback

const handleLikeFeedback = async (messageId, isLiked, prompt) => {
const response = await aiStore.patchReplyLikeStatus(
messageId,
isLiked,
prompt
);

if (response.status === 200) {
console.log('Feedback submitted successfully');
}
};

// Like
<IconButton onClick={() => handleLikeFeedback(message.id, true, message.prompt)}>
<ThumbUpIcon />
</IconButton>

// Dislike
<IconButton onClick={() => handleLikeFeedback(message.id, false, message.prompt)}>
<ThumbDownIcon />
</IconButton>

6. View Old Conversations

const handleViewOldChat = (chat) => {
// Set selected chat to view mode
aiStore.setSelectedChat(chat);

// Clear current conversation
aiStore.setCurrentChatArray([]);
aiStore.setChatResponse(null);
};

7. Start New Chat

import { GptHelper } from '@aquagen-mf-webapp/aquagpt/helper/gptHelper';

const handleNewChat = () => {
GptHelper.openNewChat(aiStore);

// This will:
// - Clear current conversation
// - Reset selected chat
// - Generate new session ID
};

Message Format

User Prompt Message

{
prompt: "What is my water usage today?",
sessionId: "user123_1709123456789",
type: "prompt"
}

AI Response Message

{
id: "gpt_msg_12345",
date: "25/02/2026",
prompt: "What is my water usage today?",
response: "<p>Your total water usage today is <strong>1,234 kL</strong>...</p>",
type: "response",
showLikedComponent: true,
isLiked: null // or true/false after feedback
}

Chat History Grouping

Date Types:

AquaGptEnum.DateType = {
today: 'Today',
yesterday: 'Yesterday',
ndays: 'Past 4 Days'
};

Sidebar Structure:

├── Today
│ ├── Chat 1 (10:30 AM)
│ ├── Chat 2 (02:15 PM)
│ └── Chat 3 (04:45 PM)
├── Yesterday
│ ├── Chat 1 (09:00 AM)
│ └── Chat 2 (05:30 PM)
└── Past 4 Days
├── Chat 1 (Feb 23)
└── Chat 2 (Feb 22)

Responsive Design

Desktop (md+):

  • Sidebar visible by default
  • Main chat area 80% width
  • Menu button hidden when sidebar open

Mobile (xs-sm):

  • Sidebar collapsed by default
  • Menu button visible
  • Full-width chat area
  • Drawer overlay for sidebar

Breakpoint Logic:

const isMobile = useMediaQuery(theme.breakpoints.down('md'));

useEffect(() => {
if (isMobile) {
setOpenSideBar(false);
} else {
setOpenSideBar(true);
}
}, [isMobile]);

Auto-Scroll Behavior

Auto-Scroll Logic:

const [isAutoScroll, setIsAutoScroll] = useState(true);

const scrollToBottom = () => {
if (!isAutoScroll) return;
chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
};

const handleScroll = () => {
const container = chatContainerRef.current;
const isUserNearBottom =
container.scrollHeight - container.scrollTop <= container.clientHeight;
setIsAutoScroll(isUserNearBottom);
};

Features:

  • Auto-scrolls when new messages arrive
  • Disables auto-scroll if user scrolls up
  • Re-enables when user scrolls to bottom

Error Handling

1. Connection Failure

if (!gptResponse || gptResponse.status !== 200) {
return {
data: {
id: generateId(),
date: today(),
prompt: params.prompt,
response: 'Failed to connect to the server!',
showLikedComponent: false
}
};
}

2. Empty or Invalid Response

if (!gptResponse.data || gptResponse.data.data.response.length === 0) {
return {
data: {
id: generateId(),
date: today(),
prompt: params.prompt,
response: 'I was unable to understand. I can help you with understanding of your consumption trend, stock usage etc.',
showLikedComponent: false
}
};
}

3. Graceful Degradation

  • Shows error message in chat interface
  • Allows user to retry with different question
  • Maintains chat history even with errors

Analytics Integration

Track User Interactions:

// Page view
AnalyticsService.sendEvent(AnalyticEvents.PAGE_VIEW, {}, true);

// Question sent
AnalyticsService.sendEvent(AnalyticEvents.AQUAGPT_SEND, {
prompt: prompt
});

// Feedback submitted
AnalyticsService.sendEvent(AnalyticEvents.AQUAGPT_LIKE, {
isLiked: isLiked,
prompt: prompt
});

Best Practices

1. Always Use Context Provider

<AquaGptContextProvider>
<YourComponent />
</AquaGptContextProvider>

2. Handle Loading States

const { isLoading, isGettingResponse } = useContext(AquaGptContext);

if (isLoading) return <Loader />;

<button disabled={isGettingResponse || !question}>
Send
</button>

3. Sanitize HTML Responses

Responses are rendered using dangerouslySetInnerHTML - ensure backend sanitizes HTML to prevent XSS attacks.

<div dangerouslySetInnerHTML={{ __html: message.response }} />

4. Clear Input After Sending

const handleSubmit = (e) => {
e.preventDefault();
aiStore.getGptResponse(question);
setQuestion(''); // Clear input
};

5. Provide Conversation Starters

Help users understand what questions they can ask:

const starters = [
"Today's water summary",
"Yesterday's consumption trends",
"Water balance analysis"
];

Troubleshooting

Chat History Not Loading

Cause: API error or missing numberOfDays param Solution: Check console and verify API response

const response = await AquagptController.getGptPastResponse({ numberOfDays: 3 });

Response Not Streaming

Cause: TypingAnimation not mounted or chatResponse not set Solution: Ensure chatResponse is set after getGptResponse

setChatResponse(gptResponse.data);

Cause: Responsive breakpoint issue Solution: Check isMobile state and openSideBar toggle



Last Updated: February 2026 Module Location: libs/aquagpt/