From 700f2c23a4aa773314bc44ac7f179317bea5f5a2 Mon Sep 17 00:00:00 2001 From: Rohan Vijay Date: Tue, 11 Aug 2026 14:14:10 +0530 Subject: [PATCH 1/2] feat(core): add method to build realtime input parameters based on blob type - Introduced `buildRealtimeInputParameters` method in `GeminiLlmConnection` to determine whether to use audio or video fields based on the blob's MIME type. - Updated `sendRealtime` method to utilize the new parameter building method. - Added unit tests to verify correct behavior for audio and video blobs in `GeminiLlmConnectionTest`. --- .../adk/models/GeminiLlmConnection.java | 16 +++++++++--- .../adk/models/GeminiLlmConnectionTest.java | 26 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/adk/models/GeminiLlmConnection.java b/core/src/main/java/com/google/adk/models/GeminiLlmConnection.java index 35dadd9fd..06f5b1b11 100644 --- a/core/src/main/java/com/google/adk/models/GeminiLlmConnection.java +++ b/core/src/main/java/com/google/adk/models/GeminiLlmConnection.java @@ -41,6 +41,7 @@ import io.reactivex.rxjava3.processors.PublishProcessor; import java.net.SocketException; import java.util.List; +import java.util.Locale; import java.util.Objects; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -287,9 +288,18 @@ private List extractFunctionResponses(Content content) { public Completable sendRealtime(Blob blob) { return Completable.fromFuture( sessionFuture.thenCompose( - session -> - session.sendRealtimeInput( - LiveSendRealtimeInputParameters.builder().media(blob).build()))); + session -> session.sendRealtimeInput(buildRealtimeInputParameters(blob)))); + } + + static LiveSendRealtimeInputParameters buildRealtimeInputParameters(Blob blob) { + LiveSendRealtimeInputParameters.Builder builder = LiveSendRealtimeInputParameters.builder(); + String mimeType = blob.mimeType().orElse("").toLowerCase(Locale.ROOT); + if (mimeType.startsWith("video/") || mimeType.startsWith("image/")) { + builder.video(blob); + } else { + builder.audio(blob); + } + return builder.build(); } /** Helper to send client content parameters. */ diff --git a/core/src/test/java/com/google/adk/models/GeminiLlmConnectionTest.java b/core/src/test/java/com/google/adk/models/GeminiLlmConnectionTest.java index b15a65852..cd1d41de2 100644 --- a/core/src/test/java/com/google/adk/models/GeminiLlmConnectionTest.java +++ b/core/src/test/java/com/google/adk/models/GeminiLlmConnectionTest.java @@ -20,9 +20,11 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.genai.types.Blob; import com.google.genai.types.Content; import com.google.genai.types.FunctionCall; import com.google.genai.types.GenerateContentResponseUsageMetadata; +import com.google.genai.types.LiveSendRealtimeInputParameters; import com.google.genai.types.LiveServerContent; import com.google.genai.types.LiveServerMessage; import com.google.genai.types.LiveServerSetupComplete; @@ -39,6 +41,30 @@ @RunWith(JUnit4.class) public final class GeminiLlmConnectionTest { + @Test + public void buildRealtimeInputParameters_withAudioBlob_usesAudioField() { + Blob blob = Blob.builder().mimeType("audio/pcm;rate=16000").data(new byte[] {1, 2}).build(); + + LiveSendRealtimeInputParameters parameters = + GeminiLlmConnection.buildRealtimeInputParameters(blob); + + assertThat(parameters.audio()).hasValue(blob); + assertThat(parameters.video()).isEmpty(); + assertThat(parameters.media()).isEmpty(); + } + + @Test + public void buildRealtimeInputParameters_withVideoBlob_usesVideoField() { + Blob blob = Blob.builder().mimeType("video/mp4").data(new byte[] {1, 2}).build(); + + LiveSendRealtimeInputParameters parameters = + GeminiLlmConnection.buildRealtimeInputParameters(blob); + + assertThat(parameters.video()).hasValue(blob); + assertThat(parameters.audio()).isEmpty(); + assertThat(parameters.media()).isEmpty(); + } + @Test public void convertToServerResponse_withInterruptedTrue_mapsInterruptedField() { LiveServerContent serverContent = From c5ab5d8c6051c6321ab2dfa562217705acb1beba Mon Sep 17 00:00:00 2001 From: Rohan Vijay Date: Tue, 11 Aug 2026 14:20:33 +0530 Subject: [PATCH 2/2] feat(core): add modelVersion to response builders for improved token logging - Enhanced response builders in `OllamaBaseLM` to include `modelVersion`, allowing downstream token logging to resolve the model name instead of defaulting to "unknown". - Updated multiple response building methods to ensure consistent model versioning across different response types. --- .../src/main/java/com/google/adk/models/OllamaBaseLM.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/adk/models/OllamaBaseLM.java b/core/src/main/java/com/google/adk/models/OllamaBaseLM.java index abd6126c7..9f60c592e 100644 --- a/core/src/main/java/com/google/adk/models/OllamaBaseLM.java +++ b/core/src/main/java/com/google/adk/models/OllamaBaseLM.java @@ -336,6 +336,9 @@ public Flowable generateContent(LlmRequest llmRequest, boolean stre if (usageMetadata != null) { responseBuilder.usageMetadata(usageMetadata); } + // Populate modelVersion so downstream token logging (e.g. rae_tokens) can resolve + // the model name instead of falling back to "unknown". + responseBuilder.modelVersion(this.model()); return Flowable.just(responseBuilder.build()); } @@ -590,6 +593,7 @@ private Flowable createRobustStreamingResponse( if (usageMetadata != null) { aggregatedResponseBuilder.usageMetadata(usageMetadata); } + aggregatedResponseBuilder.modelVersion(this.model()); responsesToEmit.add(aggregatedResponseBuilder.build()); } @@ -612,6 +616,7 @@ private Flowable createRobustStreamingResponse( if (usageMetadata != null) { functionResponseBuilder.usageMetadata(usageMetadata); } + functionResponseBuilder.modelVersion(this.model()); responsesToEmit.add(functionResponseBuilder.build()); } catch (Exception funcEx) { @@ -653,6 +658,7 @@ private LlmResponse createTextResponse(String text, boolean partial) { return LlmResponse.builder() .content(Content.builder().role("model").parts(Part.fromText(text)).build()) .partial(partial) + .modelVersion(this.model()) .build(); } @@ -1276,4 +1282,4 @@ public static void main(String[] args) { e.printStackTrace(); } } -} +} \ No newline at end of file