diff --git a/genai/snippets/pom.xml b/genai/snippets/pom.xml
index 3c59e1fde38..a27c899bc68 100644
--- a/genai/snippets/pom.xml
+++ b/genai/snippets/pom.xml
@@ -51,17 +51,13 @@
com.google.genai
google-genai
- 1.23.0
+ 1.28.0
com.google.cloud
google-cloud-storage
test
-
- com.google.cloud
- google-cloud-storage
-
junit
junit
diff --git a/genai/snippets/src/main/java/genai/live/LiveCodeExecWithTxt.java b/genai/snippets/src/main/java/genai/live/LiveCodeExecWithTxt.java
new file mode 100644
index 00000000000..a75b829155f
--- /dev/null
+++ b/genai/snippets/src/main/java/genai/live/LiveCodeExecWithTxt.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package genai.live;
+
+// [START googlegenaisdk_live_code_exec_with_txt]
+
+import static com.google.genai.types.Modality.Known.TEXT;
+
+import com.google.genai.AsyncSession;
+import com.google.genai.Client;
+import com.google.genai.types.Content;
+import com.google.genai.types.LiveConnectConfig;
+import com.google.genai.types.LiveSendClientContentParameters;
+import com.google.genai.types.LiveServerContent;
+import com.google.genai.types.LiveServerMessage;
+import com.google.genai.types.Part;
+import com.google.genai.types.Tool;
+import com.google.genai.types.ToolCodeExecution;
+import java.util.concurrent.CompletableFuture;
+
+public class LiveCodeExecWithTxt {
+
+ public static void main(String[] args) {
+ // TODO(developer): Replace these variables before running the sample.
+ String modelId = "gemini-2.0-flash-live-preview-04-09";
+ generateContent(modelId);
+ }
+
+ // Shows how to generate content with the Code Execution tool and a text input.
+ public static String generateContent(String modelId) {
+ // Client Initialization. Once created, it can be reused for multiple requests.
+ try (Client client = Client.builder().location("us-central1").vertexAI(true).build()) {
+
+ // Connects to the live server.
+ CompletableFuture sessionFuture =
+ client.async.live.connect(
+ modelId,
+ LiveConnectConfig.builder()
+ .responseModalities(TEXT)
+ .tools(Tool.builder().codeExecution(ToolCodeExecution.builder().build()).build())
+ .build());
+
+ // Sends and receives messages from the live session.
+ CompletableFuture responseFuture =
+ sessionFuture.thenCompose(
+ session -> {
+ // A future that completes when the model signals the end of its turn.
+ CompletableFuture turnComplete = new CompletableFuture<>();
+ // A variable to concatenate the text response from the model.
+ StringBuilder modelResponse = new StringBuilder();
+ // Starts receiving messages from the live session.
+ session.receive(
+ message -> handleLiveServerMessage(message, turnComplete, modelResponse));
+ // Sends content to the live session and waits for the turn to complete.
+ return sendContent(session)
+ .thenCompose(unused -> turnComplete)
+ .thenCompose(
+ unused -> session.close().thenApply(result -> modelResponse.toString()));
+ });
+
+ String response = responseFuture.join();
+ System.out.println(response);
+ // Example output:
+ // > Compute the largest prime palindrome under 100000
+ //
+ // Okay, I understand. I need to find the largest prime number that is also a palindrome
+ // and is less than 100000. Here's my plan...
+ return response;
+ }
+ }
+
+ // Sends content to the live session.
+ private static CompletableFuture sendContent(AsyncSession session) {
+ String textInput = "Compute the largest prime palindrome under 100000";
+ System.out.printf("> %s\n", textInput);
+ return session.sendClientContent(
+ LiveSendClientContentParameters.builder()
+ .turns(Content.builder().role("user").parts(Part.fromText(textInput)).build())
+ .turnComplete(true)
+ .build());
+ }
+
+ // Concatenates the response messages from the model and signals
+ // `turnComplete` when the model is done generating the response.
+ private static void handleLiveServerMessage(
+ LiveServerMessage message, CompletableFuture turnComplete, StringBuilder response) {
+ message
+ .serverContent()
+ .flatMap(LiveServerContent::modelTurn)
+ .flatMap(Content::parts)
+ .ifPresent(
+ parts ->
+ parts.forEach(
+ part -> {
+ part.text().ifPresent(response::append);
+ part.executableCode().ifPresent(code -> System.out.println("code: " + code));
+ part.codeExecutionResult()
+ .ifPresent(result -> System.out.println("result: " + result));
+ }));
+ // Checks if the model's turn is over.
+ if (message.serverContent().flatMap(LiveServerContent::turnComplete).orElse(false)) {
+ turnComplete.complete(null);
+ }
+ }
+}
+// [END googlegenaisdk_live_code_exec_with_txt]
diff --git a/genai/snippets/src/main/java/genai/live/LiveGroundGoogSearchWithTxt.java b/genai/snippets/src/main/java/genai/live/LiveGroundGoogSearchWithTxt.java
new file mode 100644
index 00000000000..2807f09a4d1
--- /dev/null
+++ b/genai/snippets/src/main/java/genai/live/LiveGroundGoogSearchWithTxt.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package genai.live;
+
+// [START googlegenaisdk_live_ground_googsearch_with_txt]
+
+import static com.google.genai.types.Modality.Known.TEXT;
+
+import com.google.genai.AsyncSession;
+import com.google.genai.Client;
+import com.google.genai.types.Content;
+import com.google.genai.types.GoogleSearch;
+import com.google.genai.types.LiveConnectConfig;
+import com.google.genai.types.LiveSendClientContentParameters;
+import com.google.genai.types.LiveServerContent;
+import com.google.genai.types.LiveServerMessage;
+import com.google.genai.types.Part;
+import com.google.genai.types.Tool;
+import java.util.concurrent.CompletableFuture;
+
+public class LiveGroundGoogSearchWithTxt {
+
+ public static void main(String[] args) {
+ // TODO(developer): Replace these variables before running the sample.
+ String modelId = "gemini-2.0-flash-live-preview-04-09";
+ generateContent(modelId);
+ }
+
+ // Shows how to generate content with the Google Search tool and a text input.
+ public static String generateContent(String modelId) {
+ // Client Initialization. Once created, it can be reused for multiple requests.
+ try (Client client = Client.builder().location("us-central1").vertexAI(true).build()) {
+
+ // Connects to the live server.
+ CompletableFuture sessionFuture =
+ client.async.live.connect(
+ modelId,
+ LiveConnectConfig.builder()
+ .responseModalities(TEXT)
+ .tools(Tool.builder().googleSearch(GoogleSearch.builder().build()).build())
+ .build());
+
+ // Sends and receives messages from the live session.
+ CompletableFuture responseFuture =
+ sessionFuture.thenCompose(
+ session -> {
+ // A future that completes when the model signals the end of its turn.
+ CompletableFuture turnComplete = new CompletableFuture<>();
+ // A variable to concatenate the text response from the model.
+ StringBuilder modelResponse = new StringBuilder();
+ // Starts receiving messages from the live session.
+ session.receive(
+ message -> handleLiveServerMessage(message, turnComplete, modelResponse));
+ // Sends content to the live session and waits for the turn to complete.
+ return sendContent(session)
+ .thenCompose(unused -> turnComplete)
+ .thenCompose(
+ unused -> session.close().thenApply(result -> modelResponse.toString()));
+ });
+
+ String response = responseFuture.join();
+ System.out.println(response);
+ // Example output:
+ // > When did the last Brazil vs. Argentina soccer match happen?
+ //
+ // The most recent Brazil vs. Argentina soccer match was on March 25, 2025,
+ // as part of the 2026 World Cup qualifiers. Argentina won 4-1.
+ return response;
+ }
+ }
+
+ // Sends content to the live session.
+ private static CompletableFuture sendContent(AsyncSession session) {
+ String textInput = "When did the last Brazil vs. Argentina soccer match happen?";
+ System.out.printf("> %s\n", textInput);
+ return session.sendClientContent(
+ LiveSendClientContentParameters.builder()
+ .turns(Content.builder().role("user").parts(Part.fromText(textInput)).build())
+ .turnComplete(true)
+ .build());
+ }
+
+ // Concatenates the response messages from the model and signals
+ // `turnComplete` when the model is done generating the response.
+ private static void handleLiveServerMessage(
+ LiveServerMessage message, CompletableFuture turnComplete, StringBuilder response) {
+ message
+ .serverContent()
+ .flatMap(LiveServerContent::modelTurn)
+ .flatMap(Content::parts)
+ .ifPresent(parts -> parts.forEach(part -> part.text().ifPresent(response::append)));
+ // Checks if the model's turn is over.
+ if (message.serverContent().flatMap(LiveServerContent::turnComplete).orElse(false)) {
+ turnComplete.complete(null);
+ }
+ }
+}
+// [END googlegenaisdk_live_ground_googsearch_with_txt]
diff --git a/genai/snippets/src/main/java/genai/live/LiveTranscribeWithAudio.java b/genai/snippets/src/main/java/genai/live/LiveTranscribeWithAudio.java
new file mode 100644
index 00000000000..14ac56f2f82
--- /dev/null
+++ b/genai/snippets/src/main/java/genai/live/LiveTranscribeWithAudio.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package genai.live;
+
+// [START googlegenaisdk_live_transcribe_with_audio]
+
+import static com.google.genai.types.Modality.Known.AUDIO;
+
+import com.google.genai.AsyncSession;
+import com.google.genai.Client;
+import com.google.genai.types.AudioTranscriptionConfig;
+import com.google.genai.types.Content;
+import com.google.genai.types.LiveConnectConfig;
+import com.google.genai.types.LiveSendClientContentParameters;
+import com.google.genai.types.LiveServerContent;
+import com.google.genai.types.LiveServerMessage;
+import com.google.genai.types.Part;
+import com.google.genai.types.Transcription;
+import java.util.concurrent.CompletableFuture;
+
+public class LiveTranscribeWithAudio {
+
+ public static void main(String[] args) {
+ // TODO(developer): Replace these variables before running the sample.
+ String modelId = "gemini-live-2.5-flash-preview-native-audio";
+ generateContent(modelId);
+ }
+
+ // Shows how to transcribe audio.
+ public static String generateContent(String modelId) {
+ // Client Initialization. Once created, it can be reused for multiple requests.
+ try (Client client = Client.builder().location("us-central1").vertexAI(true).build()) {
+
+ // Connects to the live server.
+ CompletableFuture sessionFuture =
+ client.async.live.connect(
+ modelId,
+ LiveConnectConfig.builder()
+ .responseModalities(AUDIO)
+ .inputAudioTranscription(AudioTranscriptionConfig.builder().build())
+ .outputAudioTranscription(AudioTranscriptionConfig.builder().build())
+ .build());
+
+ // Sends and receives messages from the live session.
+ CompletableFuture responseFuture =
+ sessionFuture.thenCompose(
+ session -> {
+ // A future that completes when the model signals the end of its turn.
+ CompletableFuture turnComplete = new CompletableFuture<>();
+ // A variable to concatenate the text response from the model.
+ StringBuilder modelResponse = new StringBuilder();
+ // Starts receiving messages from the live session.
+ session.receive(
+ message -> handleLiveServerMessage(message, turnComplete, modelResponse));
+ // Sends content to the live session and waits for the turn to complete.
+ return sendContent(session)
+ .thenCompose(unused -> turnComplete)
+ .thenCompose(
+ unused -> session.close().thenApply(result -> modelResponse.toString()));
+ });
+
+ String response = responseFuture.join();
+ System.out.println(response);
+ // Example output:
+ // > Hello? Gemini, are you there?
+ //
+ // Yes, I'm here. How can I help you today?
+ return response;
+ }
+ }
+
+ // Sends content to the live session.
+ private static CompletableFuture sendContent(AsyncSession session) {
+ String textInput = "Hello? Gemini, are you there?";
+ System.out.printf("> %s\n", textInput);
+ return session.sendClientContent(
+ LiveSendClientContentParameters.builder()
+ .turns(Content.builder().role("user").parts(Part.fromText(textInput)).build())
+ .turnComplete(true)
+ .build());
+ }
+
+ // Concatenates the output transcription from the model and signals
+ // `turnComplete` when the model is done generating the response.
+ private static void handleLiveServerMessage(
+ LiveServerMessage message, CompletableFuture turnComplete, StringBuilder response) {
+
+ message
+ .serverContent()
+ .ifPresent(
+ serverContent -> {
+ serverContent
+ .modelTurn()
+ .ifPresent(modelTurn -> System.out.println("Model turn: " + modelTurn.parts()));
+
+ serverContent
+ .inputTranscription()
+ .flatMap(Transcription::text)
+ .ifPresent(text -> System.out.println("Input transcript: " + text));
+
+ serverContent
+ .outputTranscription()
+ .flatMap(Transcription::text)
+ .ifPresent(response::append);
+ // Checks if the model's turn is over.
+ if (serverContent.turnComplete().orElse(false)) {
+ turnComplete.complete(null);
+ }
+ });
+ }
+}
+// [END googlegenaisdk_live_transcribe_with_audio]
diff --git a/genai/snippets/src/main/java/genai/live/LiveWithTxt.java b/genai/snippets/src/main/java/genai/live/LiveWithTxt.java
new file mode 100644
index 00000000000..3607b92f67e
--- /dev/null
+++ b/genai/snippets/src/main/java/genai/live/LiveWithTxt.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package genai.live;
+
+// [START googlegenaisdk_live_with_txt]
+
+import static com.google.genai.types.Modality.Known.TEXT;
+
+import com.google.genai.AsyncSession;
+import com.google.genai.Client;
+import com.google.genai.types.Content;
+import com.google.genai.types.HttpOptions;
+import com.google.genai.types.LiveConnectConfig;
+import com.google.genai.types.LiveSendClientContentParameters;
+import com.google.genai.types.LiveServerContent;
+import com.google.genai.types.LiveServerMessage;
+import com.google.genai.types.Part;
+import java.util.concurrent.CompletableFuture;
+
+public class LiveWithTxt {
+
+ public static void main(String[] args) {
+ // TODO(developer): Replace these variables before running the sample.
+ String modelId = "gemini-2.0-flash-live-preview-04-09";
+ generateContent(modelId);
+ }
+
+ // Shows how to send a text prompt and receive messages from the live session.
+ public static String generateContent(String modelId) {
+ // Client Initialization. Once created, it can be reused for multiple requests.
+ try (Client client =
+ Client.builder()
+ .location("us-central1")
+ .vertexAI(true)
+ .httpOptions(HttpOptions.builder().apiVersion("v1beta1").build())
+ .build()) {
+
+ // Connects to the live server.
+ CompletableFuture sessionFuture =
+ client.async.live.connect(
+ modelId, LiveConnectConfig.builder().responseModalities(TEXT).build());
+
+ // Sends and receives messages from the live session.
+ CompletableFuture responseFuture =
+ sessionFuture.thenCompose(
+ session -> {
+ // A future that completes when the model signals the end of its turn.
+ CompletableFuture turnComplete = new CompletableFuture<>();
+ // A variable to concatenate the text response from the model.
+ StringBuilder modelResponse = new StringBuilder();
+ // Starts receiving messages from the live session.
+ session.receive(
+ message -> handleLiveServerMessage(message, turnComplete, modelResponse));
+ // Sends content to the live session and waits for the turn to complete.
+ return sendContent(session)
+ .thenCompose(unused -> turnComplete)
+ .thenCompose(
+ unused -> session.close().thenApply(result -> modelResponse.toString()));
+ });
+
+ String response = responseFuture.join();
+ System.out.println(response);
+ // Example output:
+ // > Hello? Gemini, are you there?
+ //
+ // Yes, I am here. How can I help you today?
+ return response;
+ }
+ }
+
+ // Sends content to the live session.
+ private static CompletableFuture sendContent(AsyncSession session) {
+ String textInput = "Hello? Gemini, are you there?";
+ System.out.printf("> %s\n", textInput);
+ return session.sendClientContent(
+ LiveSendClientContentParameters.builder()
+ .turns(Content.builder().role("user").parts(Part.fromText(textInput)).build())
+ .turnComplete(true)
+ .build());
+ }
+
+ // Concatenates the output transcription from the model and signals
+ // `turnComplete` when the model is done generating the response.
+ private static void handleLiveServerMessage(
+ LiveServerMessage message, CompletableFuture turnComplete, StringBuilder response) {
+ message
+ .serverContent()
+ .flatMap(LiveServerContent::modelTurn)
+ .flatMap(Content::parts)
+ .ifPresent(parts -> parts.forEach(part -> part.text().ifPresent(response::append)));
+ // Checks if the model's turn is over.
+ if (message.serverContent().flatMap(LiveServerContent::turnComplete).orElse(false)) {
+ turnComplete.complete(null);
+ }
+ }
+}
+// [END googlegenaisdk_live_with_txt]
diff --git a/genai/snippets/src/test/java/genai/live/LiveIT.java b/genai/snippets/src/test/java/genai/live/LiveIT.java
new file mode 100644
index 00000000000..cc8226eb233
--- /dev/null
+++ b/genai/snippets/src/test/java/genai/live/LiveIT.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package genai.live;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class LiveIT {
+
+ private static final String GEMINI_FLASH_LIVE_PREVIEW = "gemini-2.0-flash-live-preview-04-09";
+ private static final String GEMINI_FLASH_LIVE_PREVIEW_NATIVE_AUDIO =
+ "gemini-live-2.5-flash-preview-native-audio";
+ private ByteArrayOutputStream bout;
+ private PrintStream out;
+
+ // Check if the required environment variables are set.
+ public static void requireEnvVar(String envVarName) {
+ assertWithMessage(String.format("Missing environment variable '%s' ", envVarName))
+ .that(System.getenv(envVarName))
+ .isNotEmpty();
+ }
+
+ @BeforeClass
+ public static void checkRequirements() {
+ requireEnvVar("GOOGLE_CLOUD_PROJECT");
+ }
+
+ @Before
+ public void setUp() {
+ bout = new ByteArrayOutputStream();
+ out = new PrintStream(bout);
+ System.setOut(out);
+ }
+
+ @After
+ public void tearDown() {
+ System.setOut(null);
+ bout.reset();
+ }
+
+ @Test
+ public void testLiveCodeExecWithTxt() {
+ String response = LiveCodeExecWithTxt.generateContent(GEMINI_FLASH_LIVE_PREVIEW);
+ assertThat(response).isNotEmpty();
+ }
+
+ @Test
+ public void testLiveGroundGoogSearchWithTxt() {
+ String response = LiveGroundGoogSearchWithTxt.generateContent(GEMINI_FLASH_LIVE_PREVIEW);
+ assertThat(response).isNotEmpty();
+ }
+
+ @Test
+ public void testLiveTranscribeWithAudio() {
+ String response =
+ LiveTranscribeWithAudio.generateContent(GEMINI_FLASH_LIVE_PREVIEW_NATIVE_AUDIO);
+ assertThat(response).isNotEmpty();
+ }
+
+ @Test
+ public void testLiveWithTxt() {
+ String response = LiveWithTxt.generateContent(GEMINI_FLASH_LIVE_PREVIEW);
+ assertThat(response).isNotEmpty();
+ }
+}