> ## AI Agent Context > Get the complete documentation index at: https://aistudio.google.com/docs/llms.txt > Use this file to discover all available pages. > For the full documentation in a single file, fetch: https://aistudio.google.com/docs/llms-full.txt # Thinking in the Live API The Gemini Live API enables real-time, bidirectional voice conversations with Gemini models. Standard voice models work well for immediate back-and-forth dialogue. You speak to the model, and it generates a spoken reply right away. But when a request requires planning, complex analysis, or external tools, direct responses hit a limit. The model must either answer without reasoning or pause silently while waiting for tools to finish. Thinking in the Live API (`gemini-3.8-live-extended-thinking`) adds background reasoning to real-time voice sessions. The model plans and calls asynchronous tools in the background while speaking natural conversational fillers to keep the interaction active. This architecture changes the conversational lifecycle in two key ways: - **Conversational fillers**: The model speaks intermediate updates (such as "Checking flight options now") while executing tools in the background. - **Interaction status tracking**: Because the model can speak multiple times during a single request, the server emits `interaction_status: "IN_PROGRESS"` during background processing and `interaction_status: "IDLE"` when the overall task completes. The following diagram compares the interaction lifecycles between standard Live voice sessions and Thinking with background reasoning: ![](https://www.gstatic.com/cloud-cms/d358052eb48e0aed4b9d7b95d66c61c0.svg) ## Choosing the right model {% id="choosing-a-model" %} When deciding between `gemini-3.8-live` and `gemini-3.8-live-extended-thinking`, weigh three main considerations: response latency, task complexity, and client state handling. ### When to use Gemini 3.8 Live {% id="when-to-use-live" %} Use `gemini-3.8-live` for low-latency conversational voice agents where immediate turn-taking is essential and tasks are direct. - **Conversational voice assistants**: Customer service triage, language practice, voice search, and interactive storytelling. - **Fast tool execution**: Workflows where external tools return within milliseconds (such as reading sensor values or controlling smart devices). - **Simple client logic**: Applications where each user turn receives a single model response, and `turnComplete: true` reliably signals when the session is idle. ### When to use Gemini 3.8 Live Extended Thinking {% id="when-to-use-thinking" %} Use `gemini-3.8-live-extended-thinking` when your agent must evaluate complex data, plan multiple steps, or handle tools that take several seconds to run. - **Multi-step diagnostics and support**: Technical support agents diagnosing system issues across multiple logs, error codes, and configuration checks. - **Coordinated data retrieval**: Travel and booking agents that search flights, query hotels, and compare prices across parallel API calls. - **STEM and code tutoring**: Educational agents that verify formulas, debug code, or work through multi-step logic before speaking an explanation. - **Masking tool latency**: Voice experiences where long-running functions would otherwise create awkward silence for the listener. ### Key differences summary {% id="key-differences" %} The following table summarizes the technical differences between both models: {% table %} * Feature * Gemini 3.8 Live * Gemini 3.8 Live Extended Thinking --- * **Primary use cases** * Low-latency voice agents, direct commands, fast tools * Multi-step problem solving, complex planning, multi-tool workflows --- * **Model endpoint** * `gemini-3.8-live` * `gemini-3.8-live-extended-thinking` --- * **Reasoning architecture** * Interleaved reasoning with fixed latency profile (`thinking_level` not supported) * Configurable background reasoning (`thinking_level`: `low`, `medium`, `high`; `MINIMAL` not supported) --- * **Turn boundaries** * `turnComplete: true` closes the turn and returns to idle * `turnComplete: true` finishes an utterance; `interaction_status` controls session lifecycle --- * **Conversational fillers** * Model waits for tool execution before speaking * Model streams intermediate conversational fillers while processing --- * **Tool execution** * Supports synchronous (`BLOCKING`) and asynchronous (`NON_BLOCKING`) tools * Requires asynchronous (`NON_BLOCKING`) tool declarations {% /table %} ## Migration and integration paths {% id="migration-paths" %} Follow these steps to upgrade existing voice applications or integrate Thinking into your Live API sessions. ### Upgrading from Gemini 3.1 Flash Live {% id="upgrading-from-31" %} For existing voice applications using `gemini-3.1-flash-live-preview`, upgrading to `gemini-3.8-live` requires updating the model string and omitting `thinking_level` (or `thinking_config`) from your setup configuration, as `thinking_level` is not supported for `gemini-3.8-live`: ```json { "setup": { "model": "models/gemini-3.8-live" } } ``` The turn lifecycle and `turnComplete` signals remain identical. ### Adopting Thinking {% id="adopting-thinking" %} To adopt `gemini-3.8-live-extended-thinking`, update three integration points: 1. **Track `interaction_status` instead of `turnComplete`**: In Thinking sessions, the model can emit intermediate conversational fillers while reasoning. Inspect the `interaction_status` field on incoming server messages to manage UI state. Only return to idle when `interaction_status` is `IDLE`. {% tabs %} {% tab label="Python" %} ```python status = getattr(message, "interaction_status", None) if status == "IDLE": # Ready for user input set_ui_state("listening") elif status == "IN_PROGRESS": # Reasoning or executing tools set_ui_state("thinking") ``` {% /tab %} {% tab label="JavaScript" %} ```js if (message.interactionStatus === 'IDLE') { // Ready for user input setUiState('listening'); } else if (message.interactionStatus === 'IN_PROGRESS') { // Reasoning or executing tools setUiState('thinking'); } ``` {% /tab %} {% /tabs %} 1. **Declare non-blocking functions**: Set `"behavior": "NON_BLOCKING"` on all function declarations. Thinking models run tools asynchronously in the background while streaming verbal updates. Synchronous blocking tools return an error. {% tabs %} {% tab label="Python" %} ```python search_flights = types.FunctionDeclaration( name="search_flights", description="Searches for available flights.", behavior="NON_BLOCKING", parameters={ "type": "OBJECT", "properties": { "destination": {"type": "STRING"}, }, "required": ["destination"], }, ) ``` {% /tab %} {% tab label="JavaScript" %} ```js const searchFlights = { name: 'search_flights', description: 'Searches for available flights.', behavior: 'NON_BLOCKING', parameters: { type: 'OBJECT', properties: { destination: { type: 'STRING' }, }, required: ['destination'], }, }; ``` {% /tab %} {% /tabs %} 1. **Configure reasoning depth**: Set `thinking_config` in your session configuration to adjust reasoning levels (`low`, `medium`, or `high`; `MINIMAL` is not supported). {% tabs %} {% tab label="Python" %} ```python config = types.LiveConnectConfig( response_modalities=["AUDIO"], thinking_config=types.ThinkingConfig( thinking_level="low", ), tools=[types.Tool(function_declarations=[search_flights])], ) ``` {% /tab %} {% tab label="JavaScript" %} ```js const config = { responseModalities: [Modality.AUDIO], thinkingConfig: { thinkingLevel: 'low', }, tools: [{ functionDeclarations: [searchFlights] }], }; ``` {% /tab %} {% /tabs %} ## Protocol side-by-side comparison {% id="protocol-comparison" %} This section compares the WebSocket messages exchanged during each phase of a Live API session. ### Step 1: Session setup {% id="step-1-setup" %} Both models connect to the same WebSocket endpoint: ```text wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContent?key=$API_KEY ``` - **Identical**: WebSocket URL and API key authentication. - **Model string**: `gemini-3.8-live` versus `gemini-3.8-live-extended-thinking`. - **Thinking configuration**: Thinking adds `thinkingConfig` to adjust reasoning depth. - **Tool behavior**: Thinking requires `"behavior": "NON_BLOCKING"` on function declarations. {% tabs %} {% tab label="Gemini 3.8 Live" %} ```json { "setup": { "model": "models/gemini-3.8-live", "generationConfig": { "responseModalities": ["AUDIO"], "speechConfig": { "voiceConfig": { "prebuiltVoiceConfig": { "voiceName": "Puck" } } } } } } ``` {% /tab %} {% tab label="Gemini 3.8 Live Extended Thinking" %} ```json { "setup": { "model": "models/gemini-3.8-live-extended-thinking", "generationConfig": { "responseModalities": ["AUDIO"], "speechConfig": { "voiceConfig": { "prebuiltVoiceConfig": { "voiceName": "Puck" } } }, "thinkingConfig": { "thinkingLevel": "LOW" } }, "tools": [{ "functionDeclarations": [{ "name": "searchFlights", "description": "Searches for flights between cities.", "behavior": "NON_BLOCKING", "parameters": { "type": "OBJECT", "properties": { "destination": { "type": "STRING" } }, "required": ["destination"] } }] }] } } ``` {% /tab %} {% /tabs %} Both models receive the same server acknowledgment upon connection: ```json { "setupComplete": {} } ``` ### Step 2: User audio input {% id="step-2-user-input" %} Audio streaming is identical across both models. Real-time 16kHz raw PCM audio chunks are streamed using `realtimeInput`: ```json { "realtimeInput": { "audio": { "data": "UklGRiQAAABXQVZF...", "mimeType": "audio/pcm;rate=16000" } } } ``` ### Step 3: Model response and state lifecycle {% id="step-3-model-response" %} Both models stream 24kHz PCM audio chunks in `serverContent.modelTurn`. However, lifecycle management differs: #### Gemini 3.8 Live response flow 1. The server streams audio chunks for the turn. 2. The server sends `turnComplete: true`, indicating the model is finished speaking and the session is idle. ```json // 1. Audio stream chunks { "serverContent": { "modelTurn": { "parts": [ { "inlineData": { "mimeType": "audio/pcm;rate=24000", "data": "..." } } ] } } } // 2. Turn completion -> Signals client to switch UI to Idle/Listening { "serverContent": { "turnComplete": true } } ``` #### Gemini 3.8 Live Extended Thinking response flow 1. **Spoken filler**: The model emits intermediate speech (such as *"Checking flights to Seattle..."*) with `turnComplete: true` and `interactionStatus: "IN_PROGRESS"`. 2. **Asynchronous tool call**: The server emits the tool call while `interactionStatus` remains `"IN_PROGRESS"`, indicating that the server is actively processing the multi-step turn and waiting for the tool response. 3. **Tool response**: The client executes the function and returns the output. 4. **Final response**: The server delivers the complete answer with `turnComplete: true` and `interactionStatus: "IDLE"`. ```json // 1. Spoken verbal filler while background reasoning proceeds { "serverContent": { "modelTurn": { "parts": [ { "inlineData": { "mimeType": "audio/pcm;rate=24000", "data": "..." } } ] }, "turnComplete": true, "interactionStatus": "IN_PROGRESS" } } // 2. Asynchronous tool call emitted with IN_PROGRESS status { "toolCall": { "functionCalls": [ { "id": "call_123", "name": "searchFlights", "args": { "destination": "Seattle" } } ] }, "interactionStatus": "IN_PROGRESS" } // 3. Client executes function and returns result { "toolResponse": { "functionResponses": [ { "response": { "output": { "flight": "DL 145", "price": "$145" } }, "id": "call_123" } ] } } // 4. Final spoken answer delivered -> session transitions to IDLE when done { "serverContent": { "modelTurn": { "parts": [ { "inlineData": { "mimeType": "audio/pcm;rate=24000", "data": "..." } } ] }, "interactionStatus": "IDLE", "turnComplete": true } } ``` ## SDK implementation examples {% id="sdk-examples" %} The following examples show how to configure Thinking and handle `interaction_status` using the Google GenAI SDK. {% tabs %} {% tab label="Python" %} ```python import asyncio from google import genai from google.genai import types client = genai.Client() model = "gemini-3.8-live-extended-thinking" # Define non-blocking function declaration search_flights = types.FunctionDeclaration( name="search_flights", description="Searches for available flights to a destination.", behavior="NON_BLOCKING", parameters={ "type": "OBJECT", "properties": { "destination": {"type": "STRING"} }, "required": ["destination"] } ) config = types.LiveConnectConfig( response_modalities=["AUDIO"], thinking_config=types.ThinkingConfig( thinking_level="low" ), tools=[types.Tool(function_declarations=[search_flights])] ) async def main(): async with client.aio.live.connect(model=model, config=config) as session: print("Session connected with Thinking") async for message in session.receive(): # Inspect interaction status for server lifecycle tracking status = getattr(message, "interaction_status", None) if status: print(f"Interaction status: {status}") # Handle audio output parts if message.server_content and message.server_content.model_turn: for part in message.server_content.model_turn.parts: if part.inline_data: # Process 24kHz audio chunk pass # Handle asynchronous tool call if message.tool_call: for call in message.tool_call.function_calls: print(f"Executing tool: {call.name}") # Simulate function execution response = types.FunctionResponse( id=call.id, name=call.name, response={"result": "Flight DL 145 ($145)"} ) await session.send_tool_response( function_responses=[response] ) # Status is IDLE when reasoning and all turns are complete if status == "IDLE": print("Session is idle and ready for user input.") if __name__ == "__main__": asyncio.run(main()) ``` {% /tab %} {% tab label="JavaScript" %} ```js import { GoogleGenAI, Modality } from '@google/genai'; const ai = new GoogleGenAI({}); const model = 'gemini-3.8-live-extended-thinking'; const searchFlights = { name: 'search_flights', description: 'Searches for available flights to a destination.', behavior: 'NON_BLOCKING', parameters: { type: 'OBJECT', properties: { destination: { type: 'STRING' } }, required: ['destination'] } }; const config = { responseModalities: [Modality.AUDIO], thinkingConfig: { thinkingLevel: 'low' }, tools: [{ functionDeclarations: [searchFlights] }] }; async function main() { const session = await ai.live.connect({ model: model, config: config, callbacks: { onopen: () => console.log('Session connected'), onmessage: async (event) => { const message = JSON.parse(event.data); if (message.interactionStatus) { console.log(`Interaction status: ${message.interactionStatus}`); } if (message.toolCall) { for (const call of message.toolCall.functionCalls) { console.log(`Executing tool: ${call.name}`); session.sendToolResponse({ functionResponses: [{ id: call.id, name: call.name, response: { result: 'Flight DL 145 ($145)' } }] }); } } if (message.interactionStatus === 'IDLE') { console.log('Session is idle and waiting for input.'); } } } }); } main(); ``` {% /tab %} {% /tabs %} ## What's next {% id="whats-next" %} - Read the [Gemini 3.8 Live](/docs/models/gemini-3.8-live) and [Gemini 3.8 Live Extended Thinking](/docs/models/gemini-3.8-live-extended-thinking) model pages. - Check the [Model comparison](/docs/live-api/capabilities#model-comparison) table for detailed feature comparisons across all Live API models. - Learn more about function calling in the [Live API Tool use](/docs/live-api/tools) guide. - Review [Session management](/docs/live-api/session-management) to handle session resumption and context lifecycle.