Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Note
This feature is currently in public preview. This preview is provided without a service-level agreement, and is not recommended for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see Supplemental Terms of Use for Microsoft Azure Previews.
A common scenario with voice agents is when users interrupt the audio playback of agent responses. The Voice Live service generates and returns audio responses to the client, but users might not listen to complete responses—they often interrupt by speaking again before the response finishes. This creates a mismatch between the actual audio conversation and the transcribed conversation results used to log conversation history.
In this case, the session context should be updated to reflect what the user actually heard. Otherwise, the LLM would assume it said something that was never actually delivered to the user.
Prerequisites
Before you start, complete the following:
- Complete the Quickstart: Create a Voice Live real-time voice agent.
- A working Voice Live setup.
- A working event loop handling Voice Live events.
Important
Auto truncation requires azure-ai-voicelive >= 1.2.0b2 and API version 2026-01-01-preview. Install the preview SDK with:
pip install azure-ai-voicelive --pre
This SDK is currently in preview. Features and APIs might change before general availability.
Important
Auto truncation requires Azure.AI.VoiceLive >= 1.1.0-beta.1 and API version 2026-01-01-preview. Install the preview SDK with:
dotnet add package Azure.AI.VoiceLive --prerelease
This SDK is currently in preview. Features and APIs might change before general availability.
Important
Auto truncation requires azure-ai-voicelive >= 1.0.0-beta.3 and API version 2026-01-01-preview. Add the preview dependency to your pom.xml:
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-ai-voicelive</artifactId>
<version>1.0.0-beta.3</version>
</dependency>
This SDK is currently in preview. Features and APIs might change before general availability.
Important
Auto truncation requires @azure/ai-voicelive >= 1.0.0-beta.2 and API version 2026-01-01-preview. This SDK requires Node.js 20 or later. Install the preview SDK with:
npm install @azure/ai-voicelive@1.0.0-beta.2
This SDK is currently in preview. Features and APIs might change before general availability.
Parameters
The following two Voice Live API parameters handle this scenario:
auto_truncate
When auto_truncate is set to true in VAD configuration, the service automatically truncates the last turn's response when it detects user speech during playback. The service assumes the response is played at real-time speed.
Dependencies:
interrupt_responsemust be set totrue(default). Auto truncation only makes sense when response interruption is enabled—if the response continues playing after the user speaks, there's nothing to truncate.
When truncation occurs:
- The session context is updated to include only the portion of the response played before the user started speaking.
- A
conversation.item.truncatedmessage is returned to the client.
appended_text_after_truncation
Note
The appended_text_after_truncation parameter is a server-side feature that can be set via JSON payloads. SDK support for this parameter is not yet available in the current preview versions. Use the JSON payload approach shown in the example configuration section.
Sometimes developers may want to inform the LLM that the user interrupted the response, rather than simply truncating it silently. In this case, appended_text_after_truncation can be set to a string value.
When truncation occurs, the service appends this string to the truncated response before updating the session context.
Example:
appended_text_after_truncation:" [The user interrupted me.]"- Original response:
"Hello, how can I help you today?" - User interrupts after:
"Hello, how" - Final context stored:
"Hello, how [The user interrupted me.]"
Important
When using this feature, update your system prompt to inform the LLM about this behavior and test carefully to avoid unexpected results.
Supported VAD types
| VAD type | auto_truncate |
appended_text_after_truncation |
|---|---|---|
azure_semantic_vad |
✅ | ✅ |
azure_semantic_vad_multilingual |
✅ | ✅ |
server_vad |
✅ | ❌ |
semantic_vad (OpenAI) |
✅ | ❌ |
Example configuration
from azure.ai.voicelive.models import (
RequestSession,
AzureSemanticVad,
)
# Configure session with auto truncation enabled
session_config = RequestSession(
instructions="You are a helpful assistant.",
turn_detection=AzureSemanticVad(
interrupt_response=True,
auto_truncate=True
)
)
await conn.session.update(session=session_config)
using Azure.AI.VoiceLive;
// Configure session with auto truncation enabled
var sessionOptions = new VoiceLiveSessionOptions
{
Instructions = "You are a helpful assistant.",
TurnDetection = new AzureSemanticVadTurnDetection
{
InterruptResponse = true,
AutoTruncate = true
}
};
// Update session configuration
var sessionUpdatePayload = new
{
type = "session.update",
session = new
{
instructions = sessionOptions.Instructions,
turn_detection = new
{
type = "azure_semantic_vad",
interrupt_response = true,
auto_truncate = true
}
}
};
BinaryData eventData = BinaryData.FromObjectAsJson(sessionUpdatePayload);
await session.SendCommandAsync(eventData, cancellationToken).ConfigureAwait(false);
import com.azure.ai.voicelive.models.*;
// Configure session with auto truncation enabled
AzureSemanticVadTurnDetection turnDetection = new AzureSemanticVadTurnDetection()
.setInterruptResponse(true)
.setAutoTruncate(true);
VoiceLiveSessionOptions sessionOptions = new VoiceLiveSessionOptions()
.setInstructions("You are a helpful assistant.")
.setTurnDetection(turnDetection);
// Send session update
session.sendEvent(new ClientEventSessionUpdate(sessionOptions)).subscribe();
// Configure session with auto truncation enabled
await session.sendEvent({
type: "session.update",
session: {
instructions: "You are a helpful assistant.",
turn_detection: {
type: "azure_semantic_vad",
interrupt_response: true,
auto_truncate: true
}
}
});
The equivalent JSON payload for the session configuration:
{
"type": "session.update",
"session": {
"instructions": "You are a helpful assistant.",
"turn_detection": {
"type": "azure_semantic_vad",
"interrupt_response": true,
"auto_truncate": true
}
}
}
Use appended_text_after_truncation via JSON
To use the appended_text_after_truncation feature (which is not yet available in SDK typed classes), send the entire session configuration as a raw JSON payload. You don't need to call the SDK methods first—a single raw JSON session.update replaces any previous configuration:
{
"type": "session.update",
"session": {
"instructions": "You are a helpful assistant.",
"turn_detection": {
"type": "azure_semantic_vad",
"interrupt_response": true,
"auto_truncate": true,
"appended_text_after_truncation": " [The user interrupted me.]"
}
}
}
In your code, use the raw JSON approach:
# Send session update with appended_text_after_truncation via raw dict
# Note: conn.send() accepts a dict - the SDK handles JSON serialization internally
session_update = {
"type": "session.update",
"session": {
"instructions": "You are a helpful assistant.",
"turn_detection": {
"type": "azure_semantic_vad",
"interrupt_response": True,
"auto_truncate": True,
"appended_text_after_truncation": " [The user interrupted me.]"
}
}
}
await conn.send(session_update)
// Send session update with appended_text_after_truncation via JSON
var sessionUpdatePayload = new
{
type = "session.update",
session = new
{
instructions = "You are a helpful assistant.",
turn_detection = new
{
type = "azure_semantic_vad",
interrupt_response = true,
auto_truncate = true,
appended_text_after_truncation = " [The user interrupted me.]"
}
}
};
BinaryData eventData = BinaryData.FromObjectAsJson(sessionUpdatePayload);
await session.SendCommandAsync(eventData, cancellationToken).ConfigureAwait(false);
import com.azure.core.util.BinaryData;
// Send session update with appended_text_after_truncation via raw JSON
// Note: appended_text_after_truncation is not available in typed SDK classes
String sessionUpdate = """
{
"type": "session.update",
"session": {
"instructions": "You are a helpful assistant.",
"turn_detection": {
"type": "azure_semantic_vad",
"interrupt_response": true,
"auto_truncate": true,
"appended_text_after_truncation": " [The user interrupted me.]"
}
}
}
""";
session.send(BinaryData.fromString(sessionUpdate)).subscribe();
// Send session update with appended_text_after_truncation via JSON
await session.sendEvent({
type: "session.update",
session: {
instructions: "You are a helpful assistant.",
turn_detection: {
type: "azure_semantic_vad",
interrupt_response: true,
auto_truncate: true,
appended_text_after_truncation: " [The user interrupted me.]"
}
}
});
Handle the truncation event
When truncation occurs, the service sends a conversation.item.truncated event. You can handle this event in your event loop:
async def _handle_event(self, event):
if event.type == ServerEventType.CONVERSATION_ITEM_TRUNCATED:
print(f"Response was truncated. Item ID: {event.item_id}")
print(f"Truncated at index: {event.content_index}")
# Log or handle the truncation as needed
private async Task HandleSessionUpdateAsync(SessionUpdate serverEvent, CancellationToken cancellationToken)
{
if (serverEvent is SessionUpdateConversationItemTruncated truncatedEvent)
{
Console.WriteLine($"Response was truncated. Item ID: {truncatedEvent.ItemId}");
Console.WriteLine($"Truncated at index: {truncatedEvent.ContentIndex}");
// Log or handle the truncation as needed
}
}
private void handleServerEvent(SessionUpdate event) {
if (event.getType() == ServerEventType.CONVERSATION_ITEM_TRUNCATED) {
SessionUpdateConversationItemTruncated truncatedEvent =
(SessionUpdateConversationItemTruncated) event;
System.out.println("Response was truncated. Item ID: " + truncatedEvent.getItemId());
System.out.println("Truncated at index: " + truncatedEvent.getContentIndex());
// Log or handle the truncation as needed
}
}
const subscription = session.subscribe({
onConversationItemTruncated: async (event, context) => {
console.log(`Response was truncated. Item ID: ${event.itemId}`);
console.log(`Truncated at index: ${event.contentIndex}`);
// Log or handle the truncation as needed
}
});
Next steps
- Learn more about How to use the Voice Live API
- See the Voice Live API reference
- Explore How to add proactive messages
- Explore How to improve tool calling and latency wait times