This page describes the capabilities of the Live API when you use it via Firebase AI Logic , including:
-
Supported input modalities, including:
-
Advanced capabilities, including mid-session updates:
-
Lists of not supported features , many of which are coming soon!
You can also customize your implementation by using various configuration options , like adding transcription or setting the response voice.
Input modalities
This section describes how to send various types of inputs to a Live API model. Native audio models always require audio input (along with optional additional modalities of text or video input), and they always respond with audio output .
Stream audio input
Click your Gemini API provider to view provider-specific content and code on this page.
The most common capability of the Live API is bidirectional audio streaming, meaning real-time streaming of both audio input and output.
The Live API supports the following audio formats:
- Input audio format:Raw 16 bit PCM audio at 16kHz little-endian
-
Output audio format:Raw 16 bit PCM audio at 24kHz little-endian
-
Supported MIME types:
audio/x-aac,audio/flac,audio/mp3,audio/m4a,audio/mpeg,audio/mpga,audio/mp4,audio/ogg,audio/pcm,audio/wav,audio/webm
To convey the sample rate of input audio, set the MIME type of each
audio-containing Blob to a value like audio/pcm;rate=16000
.
Swift
To use the Live API
, create a LiveModel
instance and set the response modality
to audio
.
import
FirebaseAILogic
// Initialize the Gemini Developer API backend service
// Create a `liveModel` instance with a model that supports the Live API
let
liveModel
=
FirebaseAI
.
firebaseAI
(
backend
:
.
googleAI
()).
liveModel
(
modelName
:
"gemini-2.5-flash-native-audio-preview-12-2025"
,
// Configure the model to respond with audio
generationConfig
:
LiveGenerationConfig
(
responseModalities
:
[.
audio
]
)
)
do
{
let
session
=
try
await
liveModel
.
connect
()
// Load the audio file, or tap a microphone
guard
let
audioFile
=
NSDataAsset
(
name
:
"audio.pcm"
)
else
{
fatalError
(
"Failed to load audio file"
)
}
// Provide the audio data
await
session
.
sendAudioRealtime
(
audioFile
.
data
)
var
outputText
=
""
for
try
await
message
in
session
.
responses
{
if
case
let
.
content
(
content
)
=
message
.
payload
{
content
.
modelTurn
?.
parts
.
forEach
{
part
in
if
let
part
=
part
as
?
InlineDataPart
,
part
.
mimeType
.
starts
(
with
:
"audio/pcm"
)
{
// Handle 16bit pcm audio data at 24khz
playAudio
(
part
.
data
)
}
}
// Optional: if you don't require to send more requests.
if
content
.
isTurnComplete
{
await
session
.
close
()
}
}
}
}
catch
{
fatalError
(
error
.
localizedDescription
)
}
Kotlin
To use the Live API
, create a LiveModel
instance and set the response modality
to AUDIO
.
// Initialize the Gemini Developer API backend service
// Create a `liveModel` instance with a model that supports the Live API
val
liveModel
=
Firebase
.
ai
(
backend
=
GenerativeBackend
.
googleAI
()).
liveModel
(
modelName
=
"gemini-2.5-flash-native-audio-preview-12-2025"
,
// Configure the model to respond with audio
generationConfig
=
liveGenerationConfig
{
responseModality
=
ResponseModality
.
AUDIO
}
)
val
session
=
liveModel
.
connect
()
// This is the recommended approach.
// However, you can create your own recorder and handle the stream.
session
.
startAudioConversation
()
Java
To use the Live API
, create a LiveModel
instance and set the response modality
to AUDIO
.
ExecutorService
executor
=
Executors
.
newFixedThreadPool
(
1
);
// Initialize the Gemini Developer API backend service
// Create a `liveModel` instance with a model that supports the Live API
LiveGenerativeModel
lm
=
FirebaseAI
.
getInstance
(
GenerativeBackend
.
googleAI
()).
liveModel
(
"gemini-2.5-flash-native-audio-preview-12-2025"
,
// Configure the model to respond with audio
new
LiveGenerationConfig
.
Builder
()
.
setResponseModality
(
ResponseModality
.
AUDIO
)
.
build
()
);
LiveModelFutures
liveModel
=
LiveModelFutures
.
from
(
lm
);
ListenableFuture<LiveSession>
sessionFuture
=
liveModel
.
connect
();
Futures
.
addCallback
(
sessionFuture
,
new
FutureCallback<LiveSession>
()
{
@Override
public
void
onSuccess
(
LiveSession
ses
)
{
LiveSessionFutures
session
=
LiveSessionFutures
.
from
(
ses
);
session
.
startAudioConversation
();
}
@Override
public
void
onFailure
(
Throwable
t
)
{
// Handle exceptions
}
},
executor
);
Web
To use the Live API
, create a LiveGenerativeModel
instance and set the response modality
to AUDIO
.
import
{
initializeApp
}
from
"firebase/app"
;
import
{
getAI
,
getLiveGenerativeModel
,
GoogleAIBackend
,
ResponseModality
}
from
"firebase/ai"
;
// TODO(developer) Replace the following with your app's Firebase configuration
// See: https://firebase.google.com/docs/web/learn-more#config-object
const
firebaseConfig
=
{
// ...
};
// Initialize FirebaseApp
const
firebaseApp
=
initializeApp
(
firebaseConfig
);
// Initialize the Gemini Developer API backend service
const
ai
=
getAI
(
firebaseApp
,
{
backend
:
new
GoogleAIBackend
()
});
// Create a `LiveGenerativeModel` instance with a model that supports the Live API
const
liveModel
=
getLiveGenerativeModel
(
ai
,
{
model
:
"gemini-2.5-flash-native-audio-preview-12-2025"
,
// Configure the model to respond with audio
generationConfig
:
{
responseModalities
:
[
ResponseModality
.
AUDIO
],
},
});
const
session
=
await
liveModel
.
connect
();
// Start the audio conversation
const
audioConversationController
=
await
startAudioConversation
(
session
);
// ... Later, to stop the audio conversation
// await audioConversationController.stop()
Dart
To use the Live API
, create a LiveGenerativeModel
instance and set the response modality
to audio
.
import
'package:firebase_ai/firebase_ai.dart'
;
import
'package:firebase_core/firebase_core.dart'
;
import
'firebase_options.dart'
;
import
'package:your_audio_recorder_package/your_audio_recorder_package.dart'
;
late
LiveModelSession
_session
;
final
_audioRecorder
=
YourAudioRecorder
();
await
Firebase
.
initializeApp
(
options:
DefaultFirebaseOptions
.
currentPlatform
,
);
// Initialize the Gemini Developer API backend service
// Create a `liveGenerativeModel` instance with a model that supports the Live API
final
liveModel
=
FirebaseAI
.
googleAI
().
liveGenerativeModel
(
model:
'gemini-2.5-flash-native-audio-preview-12-2025'
,
// Configure the model to respond with audio
liveGenerationConfig:
LiveGenerationConfig
(
responseModalities:
[
ResponseModalities
.
audio
],
),
);
_session
=
await
liveModel
.
connect
();
final
audioRecordStream
=
_audioRecorder
.
startRecordingStream
();
// Map the Uint8List stream to InlineDataPart stream
final
mediaChunkStream
=
audioRecordStream
.
map
((
data
)
{
return
InlineDataPart
(
'audio/pcm'
,
data
);
});
await
_session
.
startMediaStream
(
mediaChunkStream
);
// In a separate thread, receive the audio response from the model
await
for
(
final
message
in
_session
.
receive
())
{
// Process the received message
}
Unity
To use the Live API
, create a LiveModel
instance and set the response modality
to Audio
.
using
Firebase
;
using
Firebase.AI
;
async
Task
SendTextReceiveAudio
()
{
// Initialize the Gemini Developer API backend service
// Create a `LiveModel` instance with a model that supports the Live API
var
liveModel
=
FirebaseAI
.
GetInstance
(
FirebaseAI
.
Backend
.
GoogleAI
()).
GetLiveModel
(
modelName
:
"gemini-2.5-flash-native-audio-preview-12-2025"
,
// Configure the model to respond with audio
liveGenerationConfig
:
new
LiveGenerationConfig
(
responseModalities
:
new
[]
{
ResponseModality
.
Audio
})
);
LiveSession
session
=
await
liveModel
.
ConnectAsync
();
// Start a coroutine to send audio from the Microphone
var
recordingCoroutine
=
StartCoroutine
(
SendAudio
(
session
));
// Start receiving the response
await
ReceiveAudio
(
session
);
}
IEnumerator
SendAudio
(
LiveSession
liveSession
)
{
string
microphoneDeviceName
=
null
;
int
recordingFrequency
=
16000
;
int
recordingBufferSeconds
=
2
;
var
recordingClip
=
Microphone
.
Start
(
microphoneDeviceName
,
true
,
recordingBufferSeconds
,
recordingFrequency
);
int
lastSamplePosition
=
0
;
while
(
true
)
{
if
(
!
Microphone
.
IsRecording
(
microphoneDeviceName
))
{
yield
break
;
}
int
currentSamplePosition
=
Microphone
.
GetPosition
(
microphoneDeviceName
);
if
(
currentSamplePosition
!=
lastSamplePosition
)
{
// The Microphone uses a circular buffer, so we need to check if the
// current position wrapped around to the beginning, and handle it
// accordingly.
int
sampleCount
;
if
(
currentSamplePosition
>
lastSamplePosition
)
{
sampleCount
=
currentSamplePosition
-
lastSamplePosition
;
}
else
{
sampleCount
=
recordingClip
.
samples
-
lastSamplePosition
+
currentSamplePosition
;
}
if
(
sampleCount
>
0
)
{
// Get the audio chunk
float
[]
samples
=
new
float
[
sampleCount
];
recordingClip
.
GetData
(
samples
,
lastSamplePosition
);
// Send the data, discarding the resulting Task to avoid the warning
_
=
liveSession
.
SendAudioAsync
(
samples
);
lastSamplePosition
=
currentSamplePosition
;
}
}
// Wait for a short delay before reading the next sample from the Microphone
const
float
MicrophoneReadDelay
=
0.5f
;
yield
return
new
WaitForSeconds
(
MicrophoneReadDelay
);
}
}
Queue
audioBuffer
=
new
();
async
Task
ReceiveAudio
(
LiveSession
liveSession
)
{
int
sampleRate
=
24000
;
int
channelCount
=
1
;
// Create a looping AudioClip to fill with the received audio data
int
bufferSamples
=
(
int
)(
sampleRate
*
channelCount
);
AudioClip
clip
=
AudioClip
.
Create
(
"StreamingPCM"
,
bufferSamples
,
channelCount
,
sampleRate
,
true
,
OnAudioRead
);
// Attach the clip to an AudioSource and start playing it
AudioSource
audioSource
=
GetComponent
();
audioSource
.
clip
=
clip
;
audioSource
.
loop
=
true
;
audioSource
.
Play
();
// Start receiving the response
await
foreach
(
var
message
in
liveSession
.
ReceiveAsync
())
{
// Process the received message
foreach
(
float
[]
pcmData
in
message
.
AudioAsFloat
)
{
lock
(
audioBuffer
)
{
foreach
(
float
sample
in
pcmData
)
{
audioBuffer
.
Enqueue
(
sample
);
}
}
}
}
}
// This method is called by the AudioClip to load audio data.
private
void
OnAudioRead
(
float
[]
data
)
{
int
samplesToProvide
=
data
.
Length
;
int
samplesProvided
=
0
;
lock
(
audioBuffer
)
{
while
(
samplesProvided
<
samplesToProvide
&&
audioBuffer
.
Count
>
0
)
{
data
[
samplesProvided
]
=
audioBuffer
.
Dequeue
();
samplesProvided
++
;
}
}
while
(
samplesProvided
<
samplesToProvide
)
{
data
[
samplesProvided
]
=
0.0f
;
samplesProvided
++
;
}
}
Stream text + audio input
Click your Gemini API provider to view provider-specific content and code on this page.
If needed, you can send text input along with the audio input and receive streamed audio output.
Swift
To use the Live API
, create a LiveModel
instance and set the response modality
to audio
.
import
FirebaseAILogic
// Initialize the Gemini Developer API backend service
// Create a `liveModel` instance with a model that supports the Live API
let
liveModel
=
FirebaseAI
.
firebaseAI
(
backend
:
.
googleAI
()).
liveModel
(
modelName
:
"gemini-2.5-flash-native-audio-preview-12-2025"
,
// Configure the model to respond with audio
generationConfig
:
LiveGenerationConfig
(
responseModalities
:
[.
audio
]
)
)
do
{
let
session
=
try
await
liveModel
.
connect
()
// Provide a text prompt
let
text
=
"tell a short story"
await
session
.
sendTextRealtime
(
text
)
var
outputText
=
""
for
try
await
message
in
session
.
responses
{
if
case
let
.
content
(
content
)
=
message
.
payload
{
content
.
modelTurn
?.
parts
.
forEach
{
part
in
if
let
part
=
part
as
?
InlineDataPart
,
part
.
mimeType
.
starts
(
with
:
"audio/pcm"
)
{
// Handle 16bit pcm audio data at 24khz
playAudio
(
part
.
data
)
}
}
// Optional: if you don't require to send more requests.
if
content
.
isTurnComplete
{
await
session
.
close
()
}
}
}
}
catch
{
fatalError
(
error
.
localizedDescription
)
}
Kotlin
To use the Live API
, create a LiveModel
instance and set the response modality
to AUDIO
.
// Initialize the Gemini Developer API backend service
// Create a `liveModel` instance with a model that supports the Live API
val
liveModel
=
Firebase
.
ai
(
backend
=
GenerativeBackend
.
googleAI
()).
liveModel
(
modelName
=
"gemini-2.5-flash-native-audio-preview-12-2025"
,
// Configure the model to respond with audio
generationConfig
=
liveGenerationConfig
{
responseModality
=
ResponseModality
.
AUDIO
}
)
val
session
=
liveModel
.
connect
()
// Provide a text prompt
val
text
=
"tell a short story"
session
.
send
(
text
)
session
.
receive
().
collect
{
if
(
it
.
turnComplete
)
{
// Optional: if you don't require to send more requests.
session
.
stopReceiving
();
}
// Handle 16bit pcm audio data at 24khz
playAudio
(
it
.
data
)
}
Java
To use the Live API
, create a LiveModel
instance and set the response modality
to AUDIO
.
ExecutorService
executor
=
Executors
.
newFixedThreadPool
(
1
);
// Initialize the Gemini Developer API backend service
// Create a `liveModel` instance with a model that supports the Live API
LiveGenerativeModel
lm
=
FirebaseAI
.
getInstance
(
GenerativeBackend
.
googleAI
()).
liveModel
(
"gemini-2.5-flash-native-audio-preview-12-2025"
,
// Configure the model to respond with text
new
LiveGenerationConfig
.
Builder
()
.
setResponseModality
(
ResponseModality
.
AUDIO
)
.
build
()
);
LiveModelFutures
model
=
LiveModelFutures
.
from
(
lm
);
ListenableFuture<LiveSession>
sessionFuture
=
model
.
connect
();
class
LiveContentResponseSubscriber
implements
Subscriber<LiveContentResponse>
{
@Override
public
void
onSubscribe
(
Subscription
s
)
{
s
.
request
(
Long
.
MAX_VALUE
);
// Request an unlimited number of items
}
@Override
public
void
onNext
(
LiveContentResponse
liveContentResponse
)
{
// Handle 16bit pcm audio data at 24khz
liveContentResponse
.
getData
();
}
@Override
public
void
onError
(
Throwable
t
)
{
System
.
err
.
println
(
"Error: "
+
t
.
getMessage
());
}
@Override
public
void
onComplete
()
{
System
.
out
.
println
(
"Done receiving messages!"
);
}
}
Futures
.
addCallback
(
sessionFuture
,
new
FutureCallback<LiveSession>
()
{
@Override
public
void
onSuccess
(
LiveSession
ses
)
{
LiveSessionFutures
session
=
LiveSessionFutures
.
from
(
ses
);
// Provide a text prompt
String
text
=
"tell me a short story?"
;
session
.
send
(
text
);
Publisher<LiveContentResponse>
publisher
=
session
.
receive
();
publisher
.
subscribe
(
new
LiveContentResponseSubscriber
());
}
@Override
public
void
onFailure
(
Throwable
t
)
{
// Handle exceptions
}
},
executor
);
Web
To use the Live API
, create a LiveGenerativeModel
instance and set the response modality
to AUDIO
.
import
{
initializeApp
}
from
"firebase/app"
;
import
{
getAI
,
getLiveGenerativeModel
,
GoogleAIBackend
,
ResponseModality
}
from
"firebase/ai"
;
// TODO(developer) Replace the following with your app's Firebase configuration
// See: https://firebase.google.com/docs/web/learn-more#config-object
const
firebaseConfig
=
{
// ...
};
// Initialize FirebaseApp
const
firebaseApp
=
initializeApp
(
firebaseConfig
);
// Initialize the Gemini Developer API backend service
const
ai
=
getAI
(
firebaseApp
,
{
backend
:
new
GoogleAIBackend
()
});
// Create a `LiveGenerativeModel` instance with a model that supports the Live API
const
liveModel
=
getLiveGenerativeModel
(
ai
,
{
model
:
"gemini-2.5-flash-native-audio-preview-12-2025"
,
// Configure the model to respond with audio
generationConfig
:
{
responseModalities
:
[
ResponseModality
.
AUDIO
],
},
});
const
session
=
await
liveModel
.
connect
();
// Provide a text prompt
const
prompt
=
"tell a short story"
;
session
.
send
(
prompt
);
// Handle the model's audio output
const
messages
=
session
.
receive
();
for
await
(
const
message
of
messages
)
{
switch
(
message
.
type
)
{
case
"serverContent"
:
if
(
message
.
turnComplete
)
{
// TODO(developer): Handle turn completion
}
else
if
(
message
.
interrupted
)
{
// TODO(developer): Handle the interruption
break
;
}
else
if
(
message
.
modelTurn
)
{
const
parts
=
message
.
modelTurn
?
.
parts
;
parts
?
.
forEach
((
part
)
=>
{
if
(
part
.
inlineData
)
{
// TODO(developer): Play the audio chunk
}
});
}
break
;
case
"toolCall"
:
// Ignore
case
"toolCallCancellation"
:
// Ignore
}
}
Dart
To use the Live API
, create a LiveGenerativeModel
instance and set the response modality
to audio
.
import
'package:firebase_ai/firebase_ai.dart'
;
import
'package:firebase_core/firebase_core.dart'
;
import
'firebase_options.dart'
;
import
'dart:async'
;
import
'dart:typed_data'
;
late
LiveModelSession
_session
;
Future<Stream<Uint8List>
>
textToAudio
(
String
textPrompt
)
async
{
WidgetsFlutterBinding
.
ensureInitialized
();
await
Firebase
.
initializeApp
(
options:
DefaultFirebaseOptions
.
currentPlatform
,
);
// Initialize the Gemini Developer API backend service
// Create a `liveGenerativeModel` instance with a model that supports the Live API
final
liveModel
=
FirebaseAI
.
googleAI
().
liveGenerativeModel
(
model:
'gemini-2.5-flash-native-audio-preview-12-2025'
,
// Configure the model to respond with audio
liveGenerationConfig:
LiveGenerationConfig
(
responseModalities:
[
ResponseModalities
.
audio
],
),
);
_session
=
await
liveModel
.
connect
();
final
prompt
=
Content
.
text
(
textPrompt
);
await
_session
.
send
(
input:
prompt
);
return
_session
.
receive
().
asyncMap
((
response
)
async
{
if
(
response
is
LiveServerContent
&&
response
.
modelTurn
?
.
parts
!=
null
)
{
for
(
final
part
in
response
.
modelTurn
!
.
parts
)
{
if
(
part
is
InlineDataPart
)
{
return
part
.
bytes
;
}
}
}
throw
Exception
(
'Audio data not found'
);
});
}
Future<void>
main
()
async
{
try
{
final
audioStream
=
await
textToAudio
(
'Convert this text to audio.'
);
await
for
(
final
audioData
in
audioStream
)
{
// Process the audio data (e.g., play it using an audio player package)
print
(
'Received audio data:
${
audioData
.
length
}
bytes'
);
// Example using flutter_sound (replace with your chosen package):
// await _flutterSoundPlayer.startPlayer(fromDataBuffer: audioData);
}
}
catch
(
e
)
{
print
(
'Error:
$
e
'
);
}
}
Unity
To use the Live API
, create a LiveModel
instance and set the response modality
to Audio
.
using
Firebase
;
using
Firebase.AI
;
async
Task
SendTextReceiveAudio
()
{
// Initialize the Gemini Developer API backend service
// Create a `LiveModel` instance with a model that supports the Live API
var
liveModel
=
FirebaseAI
.
GetInstance
(
FirebaseAI
.
Backend
.
GoogleAI
()).
GetLiveModel
(
modelName
:
"gemini-2.5-flash-native-audio-preview-12-2025"
,
// Configure the model to respond with audio
liveGenerationConfig
:
new
LiveGenerationConfig
(
responseModalities
:
new
[]
{
ResponseModality
.
Audio
})
);
LiveSession
session
=
await
liveModel
.
ConnectAsync
();
// Provide a text prompt
var
prompt
=
ModelContent
.
Text
(
"Convert this text to audio."
);
await
session
.
SendAsync
(
content
:
prompt
,
turnComplete
:
true
);
// Start receiving the response
await
ReceiveAudio
(
session
);
}
Queue<float>
audioBuffer
=
new
();
async
Task
ReceiveAudio
(
LiveSession
session
)
{
int
sampleRate
=
24000
;
int
channelCount
=
1
;
// Create a looping AudioClip to fill with the received audio data
int
bufferSamples
=
(
int
)(
sampleRate
*
channelCount
);
AudioClip
clip
=
AudioClip
.
Create
(
"StreamingPCM"
,
bufferSamples
,
channelCount
,
sampleRate
,
true
,
OnAudioRead
);
// Attach the clip to an AudioSource and start playing it
AudioSource
audioSource
=
GetComponent<AudioSource>
();
audioSource
.
clip
=
clip
;
audioSource
.
loop
=
true
;
audioSource
.
Play
();
// Start receiving the response
await
foreach
(
var
message
in
session
.
ReceiveAsync
())
{
// Process the received message
foreach
(
float
[]
pcmData
in
message
.
AudioAsFloat
)
{
lock
(
audioBuffer
)
{
foreach
(
float
sample
in
pcmData
)
{
audioBuffer
.
Enqueue
(
sample
);
}
}
}
}
}
// This method is called by the AudioClip to load audio data.
private
void
OnAudioRead
(
float
[]
data
)
{
int
samplesToProvide
=
data
.
Length
;
int
samplesProvided
=
0
;
lock
(
audioBuffer
)
{
while
(
samplesProvided
<
samplesToProvide
&&
audioBuffer
.
Count
>
0
)
{
data
[
samplesProvided
]
=
audioBuffer
.
Dequeue
();
samplesProvided
++
;
}
}
while
(
samplesProvided
<
samplesToProvide
)
{
data
[
samplesProvided
]
=
0.0f
;
samplesProvided
++
;
}
}
Note that you can also send text as incremental content updates during an active session.
Stream video + audio input
Providing input video content provides visual context for the input audio.
The Live API expects a sequence of discrete image frames and supports video frames input at 1 frame per second (FPS).
-
Recommended input: native 768x768 resolution at 1 FPS.
-
Supported MIME types:
video/x-flv,video/quicktime,video/mpeg,video/mpegs,video/mpg,video/mp4,video/webm,video/wmv,video/3gpp
Streaming video + audio input is a more advanced implementation, so check out a sample app to learn how to implement this capability: Swift- coming soon! | Android- sample app | Web- coming soon! | Flutter- sample app | Unity- coming soon!
Advanced capabilities
The Live API models support the following advanced capabilities for mid-session updates :
-
Update system instructions (for Vertex AI Gemini API only)
Add incremental content updates
You can add incremental updates during an active session. Use this to send text input, establish session context, or restore session context.
-
For longer contexts, we recommend providing a single message summary to free up the context window for subsequent interactions.
-
For short contexts, you can send turn-by-turn interactions to represent the exact sequence of events, like the snippet below.
Swift
// Define initial turns (history/context).
let
turns
:
[
ModelContent
]
=
[
ModelContent
(
role
:
"user"
,
parts
:
[
TextPart
(
"What is the capital of France?"
)]),
ModelContent
(
role
:
"model"
,
parts
:
[
TextPart
(
"Paris"
)]),
]
// Send history, keeping the conversational turn OPEN (false).
await
session
.
sendContent
(
turns
,
turnComplete
:
false
)
// Define the new user query.
let
newTurn
:
[
ModelContent
]
=
[
ModelContent
(
role
:
"user"
,
parts
:
[
TextPart
(
"What is the capital of Germany?"
)]),
]
// Send the final query, CLOSING the turn (true) to trigger the model response.
await
session
.
sendContent
(
newTurn
,
turnComplete
:
true
)
Kotlin
Not
yet
supported
for
Android
apps
-
check
back
soon
!
Java
Not
yet
supported
for
Android
apps
-
check
back
soon
!
Web
const
turns
=
[{
text
:
"Hello from the user!"
}];
await
session
.
send
(
turns
,
false
// turnComplete: false
);
console
.
log
(
"Sent history. Waiting for next input..."
);
// Define the new user query.
const
newTurn
[{
text
:
"And what is the capital of Germany?"
}];
// Send the final query, CLOSING the turn (true) to trigger the model response.
await
session
.
send
(
newTurn
,
true
// turnComplete: true
);
console
.
log
(
"Sent final query. Model response expected now."
);
Dart
// Define initial turns (history/context).
final
List
turns
=
[
Content
(
"user"
,
[
Part
.
text
(
"What is the capital of France?"
)],
),
Content
(
"model"
,
[
Part
.
text
(
"Paris"
)],
),
];
// Send history, keeping the conversational turn OPEN (false).
await
session
.
send
(
input:
turns
,
turnComplete:
false
,
);
// Define the new user query.
final
List
newTurn
=
[
Content
(
"user"
,
[
Part
.
text
(
"What is the capital of Germany?"
)],
),
];
// Send the final query, CLOSING the turn (true) to trigger the model response.
await
session
.
send
(
input:
newTurn
,
turnComplete:
true
,
);
Unity
// Define initial turns (history/context).
List
turns
=
new
List
{
new
ModelContent
(
"user"
,
new
ModelContent
.
TextPart
(
"What is the capital of France?"
)
),
new
ModelContent
(
"model"
,
new
ModelContent
.
TextPart
(
"Paris"
)
),
};
// Send history, keeping the conversational turn OPEN (false).
foreach
(
ModelContent
turn
in
turns
)
{
await
session
.
SendAsync
(
content
:
turn
,
turnComplete
:
false
);
}
// Define the new user query.
ModelContent
newTurn
=
ModelContent
.
Text
(
"What is the capital of Germany?"
);
// Send the final query, CLOSING the turn (true) to trigger the model response.
await
session
.
SendAsync
(
content
:
newTurn
,
turnComplete
:
true
);
Update system instructions mid-session
You can update the system instructions during an active session. Use this to adapt the model's responses, for example to change the response language or modify the tone.
To update the system instructions mid-session, you can send text content with
the system
role. The updated system instructions will remain in effect for the
remainder of the session.
Swift
await
session
.
sendContent
(
[
ModelContent
(
role
:
"system"
,
parts
:
[
TextPart
(
"new system instruction"
)]
)],
turnComplete
:
false
)
Kotlin
Not
yet
supported
for
Android
apps
-
check
back
soon
!
Java
Not
yet
supported
for
Android
apps
-
check
back
soon
!
Web
Not
yet
supported
for
Web
apps
-
check
back
soon
!
Dart
try
{
await
_session
.
send
(
input:
Content
(
'system'
,
[
Part
.
text
(
'new system instruction'
)],
),
turnComplete:
false
,
);
}
catch
(
e
)
{
print
(
'Failed to update system instructions:
$
e
'
);
}
Unity
try
{
await
session
.
SendAsync
(
content
:
new
ModelContent
(
"system"
,
new
ModelContent
.
TextPart
(
"new system instruction"
)
),
turnComplete
:
false
);
}
catch
(
Exception
e
)
{
Debug
.
LogError
(
$"Failed to update system instructions: {e.Message}"
);
}
Not supported features
-
Features not yet supported by Firebase AI Logic when using the Live API , but they're coming soon!
-
Handling interruptions
-
Session management, including resuming a session across multiple connections, extending the session length, or compressing the context window.
-
Disabling and configuring voice activity detection (VAD)
-
Setting input media resolution
-
Adding a thinking configuration
-
Enabling affective dialogue or proactive audio
-
Receiving
UsageMetadatain the response
-
-
Features not supported by Firebase AI Logic when using the Live API , and they're unplanned right now.
-
Server prompt templates
-
Hybrid or on-device inference
-
AI monitoring in the Firebase console
-
What else can you do?
-
Customize your implementation by using various configuration options , like adding transcription or setting the response voice.
-
Supercharge your implementation by giving the model access to tools, like function calling and grounding with Google Search. Official documentation for using tools with the Live API is coming soon!
-
Learn about limits and specifications , for using the Live API , like session length, rate limits, supported languages, etc.

