Gemini Service (geminiService.ts)
Relevant source files
The following files were used as context for generating this wiki page:The geminiService.ts module is a crucial service layer that acts as an intermediary between the frontend components of the AI-for-Thai-EMS application and the Google Gemini API. It encapsulates the logic for making API calls, handling specific model configurations, and processing responses. The service provides two primary functionalities: analyzing emergency call transcripts to extract structured data for the AI in Action: Emergency Dispatch demo, and managing streaming, tool-enabled conversations for the EMS AI Assistant chatbot.
This service is responsible for initializing the Gemini client, formatting prompts, defining response schemas, and selecting appropriate AI models and tools based on user interaction. It is consumed by the AiDemo.tsx and Chatbot.tsx components to power their respective AI features.
Sources: services/geminiService.ts, components/AiDemo.tsx, components/Chatbot.tsx, README.md
Core Dependencies and Configuration
The service is built upon the @google/genai library, which is the official Google client for the Gemini API.
Sources: package.json:13
Initialization
A singleton instance of the GoogleGenAI class is created at the module level. This instance is configured with an API key.
Sources: services/geminiService.ts:4
API Key Configuration
The API key is expected to be available as an environment variable process.env.API_KEY. The Vite build configuration (vite.config.ts) is responsible for injecting the GEMINI_API_KEY from the environment into the application build, making it accessible as process.env.API_KEY.
// vite.config.ts
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, '.', '');
return {
// ...
define: {
'process.env.API_KEY': JSON.stringify(env.GEMINI_API_KEY),
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY)
},
// ...
};
});
Sources: vite.config.ts:6-14, services/geminiService.ts:4
Emergency Call Analysis (analyzeEmergencyCallWithGemini)
This asynchronous function is designed to process a raw string of an emergency call transcript. It sends the transcript to the Gemini API and receives a structured JSON object containing a detailed analysis of the incident. This is a core feature of the "AI in Action" demonstration.
Sources: services/geminiService.ts:9-62, components/AiDemo.tsx:43-54
Data Flow
The function follows a clear flow: it receives a transcript, constructs a prompt, calls the Gemini model with a specific JSON schema, validates the response, and returns the parsed JSON object.
The following diagram illustrates the process for analyzing an emergency call transcript.
Response Schema (AiAnalysisResult)
To ensure a structured response, the function defines a strict JSON schema that is sent with the API request. The Gemini API is instructed to return its analysis in this format. The structure is defined by the AiAnalysisResult interface.
Sources: services/geminiService.ts:10-30, types.ts:12-21
The diagram below shows the entity relationship for the AiAnalysisResult schema.
The properties of the requested JSON object are detailed below:
| Field | Type | Description | Required |
|---|---|---|---|
incidentType | string | e.g., Cardiac Emergency, Trauma, Fire | Yes |
location | string | The full address of the incident | Yes |
severity | string | One of: "Critical", "Urgent", "Non-Urgent" | Yes |
recommendedAction | string | e.g., Dispatch ALS Ambulance | Yes |
extractedData | object | Contains patient-specific details | Yes |
extractedData.name | string | Name of the patient | Yes |
extractedData.age | string | Age of the patient | Yes |
extractedData.condition | string | Summary of the patient's condition | Yes |
Sources: services/geminiService.ts:11-29
API Call and Error Handling
The function uses the gemini-2.5-flash model and configures the request to expect a JSON response.
// services/geminiService.ts
const response = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: prompt,
config: {
responseMimeType: "application/json",
responseSchema: schema,
},
});
Sources: services/geminiService.ts:39-47
After receiving the response, it performs a simple validation to ensure the text is a JSON string before parsing. If the API call fails or the response is not valid JSON, a descriptive error is thrown, which is then caught and displayed in the AiDemo component.
Sources: services/geminiService.ts:50-61, components/AiDemo.tsx:49-52
Chatbot Stream (sendMessageToChatStream)
This function manages the interactive conversation for the EMS AI Assistant chatbot. It is designed to handle conversation history, send new user messages, and return a streaming response for a real-time chat experience. It also dynamically configures the model and tools based on user-selected settings in the UI.
Sources: services/geminiService.ts:67-97, components/Chatbot.tsx:77-99
Sequence Diagram
The following diagram shows the sequence of events when a user sends a message through the Chatbot component.
Dynamic Configuration
The function accepts several boolean flags to alter its behavior, providing a more advanced and context-aware chat experience.
| Parameter | Type | Description |
|---|---|---|
history | object[] | An array of previous user and model messages. |
message | string | The new message from the user. |
isThinkingMode | boolean | If true, uses the gemini-2.5-pro model and enables a larger thinking budget. If false, uses gemini-2.5-flash. |
useSearch | boolean | If true, enables the googleSearch tool for the model. |
useMaps | boolean | If true, enables the googleMaps tool for the model. |
Sources: services/geminiService.ts:67-74, components/Chatbot.tsx:77-99
The model and tools are configured dynamically based on these parameters:
// services/geminiService.ts
export async function sendMessageToChatStream(
// ... params
) {
const model = isThinkingMode ? 'gemini-2.5-pro' : 'gemini-2.5-flash';
const tools: any[] = [];
if (useSearch) tools.push({ googleSearch: {} });
if (useMaps) tools.push({ googleMaps: {} });
const config: any = {};
if (isThinkingMode) {
config.thinkingConfig = { thinkingBudget: 32768 };
}
if (tools.length > 0) {
config.tools = tools;
}
// ...
}
Sources: services/geminiService.ts:75-90
This dynamic configuration allows the chatbot to perform more complex reasoning or access external tools like Google Search and Maps on demand, as controlled by the user through the UI toggles in Chatbot.tsx.
Sources: services/geminiService.ts:79-81, components/Chatbot.tsx:232-234