Chatbot Interface
Relevant source files
The following files were used as context for generating this wiki page:The Chatbot Interface is a key feature of the AI for Thai EMS application, providing an interactive AI assistant for users. It is implemented as a floating widget that can be opened and closed, allowing users to communicate with a Google Gemini-powered AI model through text or voice. The chatbot is designed to assist with queries related to emergency medical services, leveraging advanced AI capabilities such as real-time transcription, web search, and map integration.
The component is self-contained, managing its own state, user interactions, and communication with the backend AI service. It is integrated into the main application shell and is available across all sections of the site. The interface supports streaming responses for a more interactive feel, displays sources for grounded answers, and allows for dynamic configuration of the AI's behavior.
Sources: components/Chatbot.tsx:30, App.tsx:110, services/geminiService.ts, metadata.json:4
Architecture and Components
The chatbot is built as a single React component, Chatbot, which encapsulates all UI, state management, and logic. It is rendered within the main App component, ensuring it persists across the application.
Sources: components/Chatbot.tsx:30, App.tsx:110
Component Structure
The Chatbot component is composed of several sub-elements:
- A floating action button to toggle visibility.
- The main chat window, which includes a header, a message display area, and an input form.
- A
SimpleMarkdowncomponent for rendering bot responses. Togglecomponents for enabling/disabling features like "Thinking Mode," "Search," and "Maps."- Various icons to enhance the user interface.
This diagram shows the high-level component composition.
State Management
The component uses React's useState hook to manage its internal state.
| 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 value of the text input field. |
isLoading | boolean | Indicates if the chatbot is waiting for a response from the AI. |
error | string | null | Stores any error message that occurs during API calls. |
isThinkingMode | boolean | Toggles the use of the gemini-2.5-pro model for more complex queries. |
useSearch | boolean | Toggles the googleSearch tool for the AI. |
useMaps | boolean | Toggles the googleMaps tool for the AI. |
isRecording | boolean | Indicates if the microphone is currently recording audio. |
Sources: components/Chatbot.tsx:31-43
Data Structures
The primary data structure is the Message type, which defines the shape of each entry in the conversation.
type Message = {
id: number;
text: string;
sender: 'user' | 'model';
sources?: any[];
};
Sources: components/Chatbot.tsx:11-16
Core Functionality
The chatbot has two main modes of interaction: text messaging and audio input. Both are handled by dedicated logic within the component, which then interfaces with the geminiService.
Text Messaging Flow
When a user sends a text message, the handleSendMessage function orchestrates the entire process. It updates the UI, prepares the message history, calls the AI service, and processes the streaming response.
The following sequence diagram illustrates the text messaging flow.
Audio Input and Transcription
The chatbot supports voice input using the browser's MediaRecorder API and Google GenAI's live session capabilities for real-time transcription.
- Start Recording: The
startRecordingfunction requests microphone access. If granted, it creates aMediaRecorderinstance. - Connect to AI: It establishes a live connection to the
gemini-2.5-flash-native-audio-preview-09-2025model usingai.live.connect. - Transcription: As the user speaks, audio data is captured. When recording stops, the audio blob is converted to base64 and sent to the live session.
- Update UI: The AI service streams back transcription results, which are appended to the chat input field. The session is closed upon completion.
This functionality requires microphone permissions, which are requested in the project's metadata.json.
The sequence diagram below shows the audio transcription process.
AI Service Integration
All communication with the Google Gemini API is abstracted away in geminiService.ts. The sendMessageToChatStream function is the primary method used by the chatbot.
Dynamic Model and Tool Configuration
The service dynamically configures the API request based on the user's settings in the chatbot UI.
| Feature | State Variable | Effect in geminiService.ts |
|---|---|---|
| Thinking Mode | isThinkingMode | If true, uses the gemini-2.5-pro model and sets a thinkingBudget. Otherwise, uses gemini-2.5-flash. |
| Search | useSearch | If true, adds { googleSearch: {} } to the tools array in the API request. |
| Maps | useMaps | If true, adds { googleMaps: {} } to the tools array in the API request. |
This allows users to control the AI's capabilities and computational expense on-the-fly.
Sources: services/geminiService.ts:94-105, components/Chatbot.tsx:263-265
Configuration and Dependencies
The chatbot relies on several key configuration points and external libraries.
API Key Management
The Gemini API key is managed as an environment variable (GEMINI_API_KEY). The Vite build configuration is responsible for making this key available to the application client-side via process.env.API_KEY.
Sources: vite.config.ts:12-13, services/geminiService.ts:4
External Libraries
The application uses an importmap in index.html to load the @google/genai library directly from Google's CDN. This avoids the need to bundle the large library with the application code.
<script type="importmap">
{
"imports": {
"@google/genai": "https://aistudiocdn.com/@google/genai@^1.28.0",
...
}
}
</script>
Sources: index.html:19-27, package.json:13
Summary
The Chatbot Interface is a robust and feature-rich component that serves as the primary user-facing AI interaction point in the application. It demonstrates modern frontend practices by integrating complex functionalities like real-time audio transcription and streaming API responses within a modular React component. Its direct integration with the Google Gemini API, complete with dynamic tool and model selection, makes it a powerful and flexible assistant for EMS-related tasks.