AquaGPT — AI Assistant
The in-app AI assistant — a streaming, multi-agent chatbot that answers natural-language questions about your water data ("Analyse my water balance and share insights", "Show current water consumption across all meters").
- Route:
/aquagpt(in every app) →AquaAi(libs/aquaAi/src/AquaAi.jsx) - Permission:
AQUAGPT(gates the sidebar entry — the route itself is unwrapped; see Permissions) - Library:
libs/aquaAi/— the live implementation
"AquaGPT" is the product/route name; the live experience is served by
libs/aquaAi/ (its header just reads "AI"). Two other AI libs exist but are
not wired to any route — see Variants & legacy.
Which AI library is which
| Library | Status | Where it runs | What it is |
|---|---|---|---|
aquaAi | Current | /aquagpt in all 5 apps | Streaming multi-agent chatbot (this page) |
aquagpt | Legacy | Not routed (build alias only) | First-gen, non-streaming chatbot with saved history |
demoAquaGpt | Demo | Not routed (demo alias only) | Dummy-data sales prototype |
How a message flows
Summary: The assistant talks to a separate AI-Agent microservice (not the main API). Your message is streamed over Server-Sent Events; the backend orchestrates several agents and streams their progress as thought cards, then streams the final answer token-by-token as markdown.
Backend & auth (it's a separate service)
AquaAi does not use the shared apiClient or the raw-JWT Authorization
header. It calls a dedicated AI-Agent backend (Urls.getAIAgentBaseUrl(),
always the Azure prod service) with fetch, using a session established from
your AquaGen login:
| Endpoint | Method | Purpose |
|---|---|---|
/auth/token-login | POST | Create an AI session from your AquaGen loginResponse (on mount) |
/auth/validate | POST | Revalidate a cached session (ecogpt_session) |
/chat/stream | POST (SSE) | Send a message and stream the agent run + answer |
/feedback | POST | Submit a 👍 / 👎 on an answer |
/auth/logout | POST | End the session (on unmount) |
A X-Source-Host header (the current hostname) tells the backend which app /
industry context the question belongs to.
Components
| Component | What it is | On click |
|---|---|---|
Composer | Multiline input (4000-char limit) with a live counter | Send / Enter → streams the message |
Header | "AI" logo + actions | Stop aborts the stream; New Chat resets the conversation |
MessageList | Groups messages; shows the welcome screen when empty | — |
WelcomeScreen | Empty state with example prompts | A prompt card sends that question |
UserBubble | Your message + relative timestamp | — |
AssistantBubble | The streamed markdown answer (tables, code) | Copy, Like, Dislike (feedback) |
ThoughtCard | Collapsible timeline of live agent activity | Expand/collapse; a search chip opens a web search |
Edge cases & guards
| Case | Handling |
|---|---|
| Not logged in | "Please login to AquaGen first" (needs a valid loginResponse token) |
| Initializing | "Initializing AI…" spinner until the session is ready |
| Empty / too-long message | Rejected (empty; > 4000 chars) |
| While answering | Thinking shimmer + thought cards; a blinking cursor during token streaming |
| Send failure / abort | Aborts silently on Stop; other errors surface as an error message + error thought card |
| Conversation history | None — there is no history API; New Chat wipes the session's messages |
Underlying libraries
| Purpose | Library |
|---|---|
| Markdown answers | react-markdown + remark-gfm |
| Code highlighting | react-syntax-highlighter |
| Relative times | date-fns (note: this lib uses date-fns, not the app-standard moment) |
| Streaming | native fetch + ReadableStream (no AI SDK) |
Variants & legacy
aquagpt — Legacy (orphaned)
The first-generation AquaGPT chatbot: a sidebar of past conversations, non-streaming
answers via the shared apiClient (gpt/aqua, gpt/responses/ndays), emoji
reactions, and typing animation. Not imported by any route — only referenced in
build aliases. Superseded by aquaAi.
demoAquaGpt — Demo (orphaned)
A sales/demo prototype built on canned dummy data (dummyData/previousChat.js,
previousMessages.js). It posts an OpenAI-style chat-completions payload to a dev
endpoint. Not routed anywhere — the demo app's /aquagpt route also renders the
live aquaAi.
Code reference
| File | Role |
|---|---|
AquaAi.jsx | Page entry + provider |
store/AquaAiStore.jsx | Context + reducer (messages, thought cards, session) |
dataSource/authService.js · chatService.js | Session auth + SSE streaming |
controller/useChatStream.js · useSessionManager.js | Send/parse messages; auto session login |
components/ChatWindow.jsx + bubbles/cards | The chat UI |
Related
- Alerts & Notifications · Dashboard — where AI insights complement the data
- Application Routes · Permissions
- API Call Flow — note AquaAi uses a separate backend, not the shared client