Chatbot Component (Chatbot.tsx)
Relevant source files
The following files were used as context for generating this wiki page:
The Chatbot is a floating, interactive React component that serves as an AI assistant for the Thai EMS application. It provides a conversational interface for users to ask questions and receive information, leveraging the Google Gemini API for its backend processing. The component supports text and audio input, streams responses in real-time, and can be configured to use different AI models and tools like Google Search and Google Maps.
The component is rendered within the main App.tsx layout, making it accessible across the entire application. It manages its own state for visibility, conversation history, and interaction with the AI service. Microphone permissions are requested to enable the audio transcription feature.
Sources: components/Chatbot.tsx, App.tsx:87, metadata.json:4-6
Architecture and State Management
The Chatbot is a self-contained functional component that manages its UI and logic through React hooks.
State Variables
The component's behavior is controlled by several state variables initialized with useState.
| State Variable | Type | Description |
|---|---|---|
isOpen | boolean | Controls the visibility of the chat window. |
messages | Message[] | An array of message objects representing the conversation history. |
input | string | The current text in the message input field. |
isLoading | boolean | Indicates if the component is waiting for a response from the AI. |
error | string | null | Stores any error message that occurs during API calls. |
isThinkingMode | boolean | A toggle to switch between gemini-2.5-flash and gemini-2.5-pro models. |
useSearch | boolean | A toggle to enable the googleSearch tool in the Gemini API call. |
useMaps | boolean | A toggle to enable the googleMaps tool in the Gemini API call. |
isRecording | boolean | Indicates if the microphone is currently recording audio. |
Sources: components/Chatbot.tsx:30-44
Data Structures
The primary data structure is the Message type, which defines the shape of each entry in the conversation history.
// components/Chatbot.tsx:12-17
type Message = {
id: number;
text: string;
sender: 'user' | 'model';
sources?: any[];
};
The sender property is strictly typed as 'user' or 'model' to align with the roles required by the Gemini API history.
Sources: components/Chatbot.tsx:12-17
Core Functionality
The chatbot's primary functions revolve around sending user input to the Gemini API and handling the response. This includes text messages and audio transcription.
Text Message Handling
The process of sending a text message is initiated by the handleSendMessage function.
This diagram illustrates the sequence of events when a user sends a text message.
The handleSendMessage function is a useCallback-memoized function that:
- Validates that the input is not empty.
- Creates a
usermessage object and appends it to themessagesstate. - Clears the input field and sets
isLoadingtotrue. - Formats the existing
messages(excluding the initial greeting) into ahistoryarray compatible with the Gemini API. - Calls
sendMessageToChatStreamfromgeminiService.tswith the history, new message, and configuration toggles. - Creates a new, empty
modelmessage in themessagesstate to hold the incoming response. - Asynchronously iterates over the response stream, appending each text chunk to the model's message text.
- Sets
isLoadingtofalseupon completion or error.
Sources: components/Chatbot.tsx:68-109, services/geminiService.ts:77-99
Audio Input and Transcription
The chatbot uses the browser's MediaRecorder API for audio capture and the @google/genai Live API for real-time transcription.
This diagram shows the flow for recording and transcribing audio.
startRecording():- Requests microphone access using
navigator.mediaDevices.getUserMedia. - Initializes a
MediaRecorderinstance. - Sets up
ondataavailableto collect audio data into chunks. - Defines the
onstopevent handler, which is the core of the transcription logic. - Starts recording and sets
isRecordingtotrue.
- Requests microphone access using
onstophandler:- Combines audio chunks into a single
Blob. - Connects to the
gemini-2.5-flash-native-audio-preview-09-2025model viaai.live.connect. - The
onmessagecallback updates theinputstate with the transcribed text received from the server. - When the
turnCompletemessage is received, the session is closed. - The audio blob is converted to a base64 string and sent to the live session.
- Combines audio chunks into a single
stopRecording(): Simply callsmediaRecorderRef.current?.stop()and setsisRecordingtofalse.
Sources: components/Chatbot.tsx:111-182
AI Configuration Toggles
The user can modify the behavior of the AI through three toggle switches. These toggles directly influence the parameters passed to the sendMessageToChatStream function.
| Toggle | State | Controlled Parameter in geminiService | Description |
|---|---|---|---|
| Thinking Mode | isThinkingMode | model | If true, uses the gemini-2.5-pro model. If false, uses gemini-2.5-flash. |
| Search | useSearch | tools | If true, adds { googleSearch: {} } to the tools array, enabling web search capabilities. |
| Maps | useMaps | tools | If true, adds { googleMaps: {} } to the tools array, enabling location-based queries. |
These configurations are passed to the ai.chats.create() and chat.sendMessageStream() methods within the service.
Sources: components/Chatbot.tsx:271-275, services/geminiService.ts:85-96
UI and Rendering
The component's UI is built with React and styled using Tailwind CSS. It consists of a main floating button and a chat window that appears when the button is clicked.
Component Breakdown
- Floating Action Button: A fixed-position button that toggles the
isOpenstate. It displays aChatBubbleLeftRightIconwhen closed and anXMarkIconwhen open. - Chat Window: A container that appears when
isOpenistrue. It has three main sections:- Header: Displays the title "EMS AI Assistant" and a close button.
- Message Area: An auto-scrolling
divthat maps over themessagesarray to display each message. User and model messages are styled differently. It also displays a "Thinking..." animation whenisLoadingis true. - Input Area: Contains the configuration toggles, a
textareafor user input, a record/stop button, and a send button.
SimpleMarkdownRenderer: A small internal component that performs basic Markdown-to-HTML conversion for**bold**,*italic*, and`code`formatting in bot responses.- Icons: All icons used in the UI (e.g.,
PaperAirplaneIcon,MicrophoneIcon,SparklesIcon) are imported as separate React components fromcomponents/Icons.tsx.
This diagram shows the component hierarchy.
Dependencies and Environment
The chatbot relies on external libraries and environment variables to function correctly.
@google/genai: This library is the primary interface to the Google Gemini API for both chat and live transcription. It is imported via animportmapinindex.html.GEMINI_API_KEY: An API key is required to authenticate with the Gemini API. This key is loaded from environment variables and made available to the application through the Vite configuration file (vite.config.ts) asprocess.env.API_KEY.
Sources: index.html:19-27, vite.config.ts:9-13, services/geminiService.ts:4
Summary
The Chatbot.tsx component is a sophisticated, feature-rich module that provides a primary user interaction point for the AI capabilities of the Thai EMS application. It effectively encapsulates state management, user input handling (text and audio), real-time response streaming, and dynamic AI configuration. Its integration with geminiService.ts provides a clean separation of concerns between the frontend UI and the backend AI communication logic, making it a robust and central feature of the project.