From a4486b966e8db6e35125d4be03fd66b66b6d2bae Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Mon, 31 Aug 2026 13:05:16 -0400 Subject: [PATCH 1/3] remove deprecated code --- ai-logic/firebase-ai/api.txt | 72 +---------------- .../kotlin/com/google/firebase/ai/AIModels.kt | 12 +-- .../com/google/firebase/ai/GroundingTests.kt | 4 +- .../com/google/firebase/ai/ToolTests.kt | 2 +- .../com/google/firebase/ai/FirebaseAI.kt | 2 - .../com/google/firebase/ai/GenerativeModel.kt | 12 --- .../com/google/firebase/ai/OnDeviceConfig.kt | 13 ++-- .../firebase/ai/common/APIController.kt | 5 +- .../CloudGenerativeModelProvider.kt | 1 - .../firebase/ai/java/LiveSessionFutures.kt | 14 ---- .../com/google/firebase/ai/type/Candidate.kt | 42 ++++------ .../firebase/ai/type/CountTokensResponse.kt | 15 +--- .../ai/type/GenerateContentResponse.kt | 12 --- .../firebase/ai/type/GenerativeBackend.kt | 22 ------ .../ai/type/LiveClientSetupMessage.kt | 2 +- .../firebase/ai/type/LiveServerMessage.kt | 19 ++--- .../google/firebase/ai/type/LiveSession.kt | 74 ++++++------------ .../com/google/firebase/ai/type/MediaData.kt | 41 ---------- .../com/google/firebase/ai/type/Part.kt | 6 -- .../google/firebase/ai/type/PromptFeedback.kt | 3 +- .../google/firebase/ai/type/UsageMetadata.kt | 21 ----- .../com/google/firebase/ai/type/Voices.kt | 78 ------------------- .../firebase/ai/GenerativeModelTesting.kt | 2 +- .../google/firebase/ai/SerializationTests.kt | 24 ------ .../firebase/ai/type/GenerativeBackendTest.kt | 11 --- .../ai/type/RealtimeInputConfigTest.kt | 8 +- .../java/com/google/firebase/ai/util/tests.kt | 10 +-- .../google/firebase/ai/JavaCompileTests.java | 6 +- .../firebase/ai/JavaSnippetCompileTests.java | 6 +- 29 files changed, 88 insertions(+), 451 deletions(-) delete mode 100644 ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/MediaData.kt delete mode 100644 ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Voices.kt diff --git a/ai-logic/firebase-ai/api.txt b/ai-logic/firebase-ai/api.txt index 59758115639..369269b0b1a 100644 --- a/ai-logic/firebase-ai/api.txt +++ b/ai-logic/firebase-ai/api.txt @@ -14,27 +14,22 @@ package com.google.firebase.ai { } @com.google.firebase.ai.type.PublicPreviewAPI public abstract class DownloadStatus { - ctor public DownloadStatus(); } public static final class DownloadStatus.DownloadCompleted extends com.google.firebase.ai.DownloadStatus { - ctor public DownloadStatus.DownloadCompleted(); } public static final class DownloadStatus.DownloadFailed extends com.google.firebase.ai.DownloadStatus { - ctor public DownloadStatus.DownloadFailed(com.google.firebase.ai.type.FirebaseAIException exception); method public com.google.firebase.ai.type.FirebaseAIException getException(); property public final com.google.firebase.ai.type.FirebaseAIException exception; } public static final class DownloadStatus.DownloadInProgress extends com.google.firebase.ai.DownloadStatus { - ctor public DownloadStatus.DownloadInProgress(long totalBytesDownloaded); method public long getTotalBytesDownloaded(); property public final long totalBytesDownloaded; } public static final class DownloadStatus.DownloadStarted extends com.google.firebase.ai.DownloadStatus { - ctor public DownloadStatus.DownloadStarted(long bytesToDownload); method public long getBytesToDownload(); property public final long bytesToDownload; } @@ -100,7 +95,6 @@ package com.google.firebase.ai { method public suspend Object? generateObject(com.google.firebase.ai.type.JsonSchema jsonSchema, String prompt, kotlin.coroutines.Continuation>); method public com.google.firebase.ai.OnDeviceExtension? getOnDeviceExtension(); method public com.google.firebase.ai.Chat startChat(java.util.List history = emptyList()); - method @Deprecated @com.google.firebase.ai.type.PublicPreviewAPI public suspend Object? warmUp(kotlin.coroutines.Continuation); property public final com.google.firebase.ai.OnDeviceExtension? onDeviceExtension; } @@ -273,10 +267,10 @@ package com.google.firebase.ai.java { method public static final com.google.firebase.ai.java.LiveSessionFutures from(com.google.firebase.ai.type.LiveSession session); method public abstract org.reactivestreams.Publisher receive(); method public abstract com.google.common.util.concurrent.ListenableFuture send(com.google.firebase.ai.type.Content content); + method public abstract com.google.common.util.concurrent.ListenableFuture send(com.google.firebase.ai.type.Content content, boolean turnComplete); method public abstract com.google.common.util.concurrent.ListenableFuture send(String text); method public abstract com.google.common.util.concurrent.ListenableFuture sendAudioRealtime(com.google.firebase.ai.type.InlineData audio); method public abstract com.google.common.util.concurrent.ListenableFuture sendFunctionResponse(java.util.List functionList); - method @Deprecated public abstract com.google.common.util.concurrent.ListenableFuture sendMediaStream(java.util.List mediaChunks); method public abstract com.google.common.util.concurrent.ListenableFuture sendStartActivityRealtime(); method public abstract com.google.common.util.concurrent.ListenableFuture sendStopActivityRealtime(); method public abstract com.google.common.util.concurrent.ListenableFuture sendTextRealtime(String text); @@ -464,7 +458,6 @@ package com.google.firebase.ai.type { } public final class CodeExecutionResultPart implements com.google.firebase.ai.type.Part { - ctor @Deprecated public CodeExecutionResultPart(String outcome, String output); method @com.google.firebase.ai.type.PublicPreviewAPI public static com.google.firebase.ai.type.CodeExecutionResultPart createWithThinking(String outcome, String output, boolean isThought, String? thoughtSignature); method public boolean executionSucceeded(); method public String getOutcome(); @@ -537,20 +530,15 @@ package com.google.firebase.ai.type { } public final class CountTokensResponse { - ctor public CountTokensResponse(int totalTokens, @Deprecated Integer? totalBillableCharacters = null, java.util.List promptTokensDetails = emptyList()); method public operator int component1(); - method public operator Integer? component2(); - method public operator java.util.List? component3(); + method public operator java.util.List component2(); method public java.util.List getPromptTokensDetails(); - method @Deprecated public Integer? getTotalBillableCharacters(); method public int getTotalTokens(); property public final java.util.List promptTokensDetails; - property @Deprecated public final Integer? totalBillableCharacters; property public final int totalTokens; } public final class ExecutableCodePart implements com.google.firebase.ai.type.Part { - ctor @Deprecated public ExecutableCodePart(String language, String code); method @com.google.firebase.ai.type.PublicPreviewAPI public static com.google.firebase.ai.type.ExecutableCodePart createWithThinking(String language, String code, boolean isThought, String? thoughtSignature); method public String getCode(); method public String getLanguage(); @@ -701,7 +689,6 @@ package com.google.firebase.ai.type { } public final class GenerateContentResponse { - ctor public GenerateContentResponse(java.util.List candidates, com.google.firebase.ai.type.PromptFeedback? promptFeedback, com.google.firebase.ai.type.UsageMetadata? usageMetadata); method public java.util.List getCandidates(); method public java.util.List getFunctionCalls(); method public com.google.firebase.ai.InferenceSource getInferenceSource(); @@ -781,8 +768,6 @@ package com.google.firebase.ai.type { method public static com.google.firebase.ai.type.GenerativeBackend agentPlatform(); method public static com.google.firebase.ai.type.GenerativeBackend agentPlatform(String location = "global"); method public static com.google.firebase.ai.type.GenerativeBackend googleAI(); - method @Deprecated public static com.google.firebase.ai.type.GenerativeBackend vertexAI(); - method @Deprecated public static com.google.firebase.ai.type.GenerativeBackend vertexAI(String location = "us-central1"); field public static final com.google.firebase.ai.type.GenerativeBackend.Companion Companion; } @@ -790,8 +775,6 @@ package com.google.firebase.ai.type { method public com.google.firebase.ai.type.GenerativeBackend agentPlatform(); method public com.google.firebase.ai.type.GenerativeBackend agentPlatform(String location = "global"); method public com.google.firebase.ai.type.GenerativeBackend googleAI(); - method @Deprecated public com.google.firebase.ai.type.GenerativeBackend vertexAI(); - method @Deprecated public com.google.firebase.ai.type.GenerativeBackend vertexAI(String location = "us-central1"); } public final class GoogleMaps { @@ -799,7 +782,6 @@ package com.google.firebase.ai.type { } public final class GoogleMapsGroundingChunk { - ctor public GoogleMapsGroundingChunk(String? uri, String? title, String? placeId); method public String? getPlaceId(); method public String? getTitle(); method public String? getUri(); @@ -812,18 +794,7 @@ package com.google.firebase.ai.type { ctor public GoogleSearch(); } - @Deprecated public final class GroundingAttribution { - ctor @Deprecated public GroundingAttribution(com.google.firebase.ai.type.Segment segment, Float? confidenceScore); - method @Deprecated public Float? getConfidenceScore(); - method @Deprecated public com.google.firebase.ai.type.Segment getSegment(); - property @Deprecated public final Float? confidenceScore; - property @Deprecated public final com.google.firebase.ai.type.Segment segment; - } - public final class GroundingChunk { - ctor public GroundingChunk(); - ctor public GroundingChunk(com.google.firebase.ai.type.WebGroundingChunk? web = null); - ctor public GroundingChunk(com.google.firebase.ai.type.WebGroundingChunk? web = null, com.google.firebase.ai.type.GoogleMapsGroundingChunk? maps = null); method public com.google.firebase.ai.type.GoogleMapsGroundingChunk? getMaps(); method public com.google.firebase.ai.type.WebGroundingChunk? getWeb(); property public final com.google.firebase.ai.type.GoogleMapsGroundingChunk? maps; @@ -831,14 +802,11 @@ package com.google.firebase.ai.type { } public final class GroundingMetadata { - ctor public GroundingMetadata(java.util.List webSearchQueries, com.google.firebase.ai.type.SearchEntryPoint? searchEntryPoint, java.util.List retrievalQueries, @Deprecated java.util.List groundingAttribution, java.util.List groundingChunks, java.util.List groundingSupports); - method @Deprecated public java.util.List getGroundingAttribution(); method public java.util.List getGroundingChunks(); method public java.util.List getGroundingSupports(); method public java.util.List getRetrievalQueries(); method public com.google.firebase.ai.type.SearchEntryPoint? getSearchEntryPoint(); method public java.util.List getWebSearchQueries(); - property @Deprecated public final java.util.List groundingAttribution; property public final java.util.List groundingChunks; property public final java.util.List groundingSupports; property public final java.util.List retrievalQueries; @@ -847,7 +815,6 @@ package com.google.firebase.ai.type { } public final class GroundingSupport { - ctor public GroundingSupport(com.google.firebase.ai.type.Segment segment, java.util.List groundingChunkIndices); method public java.util.List getGroundingChunkIndices(); method public com.google.firebase.ai.type.Segment getSegment(); property public final java.util.List groundingChunkIndices; @@ -1253,7 +1220,6 @@ package com.google.firebase.ai.type { } @com.google.firebase.ai.type.PublicPreviewAPI public final class LiveServerContent implements com.google.firebase.ai.type.LiveServerMessage { - ctor @Deprecated public LiveServerContent(com.google.firebase.ai.type.Content? content, boolean interrupted, boolean turnComplete, boolean generationComplete, com.google.firebase.ai.type.Transcription? inputTranscription, com.google.firebase.ai.type.Transcription? outputTranscription); method public com.google.firebase.ai.type.Content? getContent(); method public boolean getGenerationComplete(); method public com.google.firebase.ai.type.Transcription? getInputTranscription(); @@ -1269,7 +1235,6 @@ package com.google.firebase.ai.type { } @com.google.firebase.ai.type.PublicPreviewAPI public final class LiveServerGoAway implements com.google.firebase.ai.type.LiveServerMessage { - ctor public LiveServerGoAway(kotlin.time.Duration? timeLeft); method public kotlin.time.Duration? getTimeLeft(); property public final kotlin.time.Duration? timeLeft; } @@ -1278,17 +1243,14 @@ package com.google.firebase.ai.type { } @com.google.firebase.ai.type.PublicPreviewAPI public final class LiveServerSetupComplete implements com.google.firebase.ai.type.LiveServerMessage { - ctor public LiveServerSetupComplete(); } @com.google.firebase.ai.type.PublicPreviewAPI public final class LiveServerToolCall implements com.google.firebase.ai.type.LiveServerMessage { - ctor public LiveServerToolCall(java.util.List functionCalls); method public java.util.List getFunctionCalls(); property public final java.util.List functionCalls; } @com.google.firebase.ai.type.PublicPreviewAPI public final class LiveServerToolCallCancellation implements com.google.firebase.ai.type.LiveServerMessage { - ctor public LiveServerToolCallCancellation(java.util.List functionIds); method public java.util.List getFunctionIds(); property public final java.util.List functionIds; } @@ -1309,7 +1271,6 @@ package com.google.firebase.ai.type { method public suspend Object? send(String text, kotlin.coroutines.Continuation = true); method public suspend Object? sendAudioRealtime(com.google.firebase.ai.type.InlineData audio, kotlin.coroutines.Continuation); method public suspend Object? sendFunctionResponse(java.util.List functionList, kotlin.coroutines.Continuation); - method @Deprecated public suspend Object? sendMediaStream(java.util.List mediaChunks, kotlin.coroutines.Continuation); method public suspend Object? sendStartActivityRealtime(kotlin.coroutines.Continuation); method public suspend Object? sendStopActivityRealtime(kotlin.coroutines.Continuation); method public suspend Object? sendTextRealtime(String text, kotlin.coroutines.Continuation); @@ -1324,7 +1285,6 @@ package com.google.firebase.ai.type { } @com.google.firebase.ai.type.PublicPreviewAPI public final class LiveSessionResumptionUpdate implements com.google.firebase.ai.type.LiveServerMessage { - ctor public LiveSessionResumptionUpdate(String? newHandle = null, Boolean? resumable = null, Integer? lastConsumedClientMessageIndex = null); method public Integer? getLastConsumedClientMessageIndex(); method public String? getNewHandle(); method public Boolean? getResumable(); @@ -1333,14 +1293,6 @@ package com.google.firebase.ai.type { property public final Boolean? resumable; } - @Deprecated @com.google.firebase.ai.type.PublicPreviewAPI public final class MediaData { - ctor @Deprecated public MediaData(byte[] data, String mimeType); - method @Deprecated public byte[] getData(); - method @Deprecated public String getMimeType(); - property @Deprecated public final byte[] data; - property @Deprecated public final String mimeType; - } - public final class ModalityTokenCount { method public operator com.google.firebase.ai.type.ContentModality component1(); method public operator int component2(); @@ -1378,7 +1330,6 @@ package com.google.firebase.ai.type { } public final class PromptFeedback { - ctor public PromptFeedback(com.google.firebase.ai.type.BlockReason? blockReason, java.util.List safetyRatings, String? blockReasonMessage); method public com.google.firebase.ai.type.BlockReason? getBlockReason(); method public String? getBlockReasonMessage(); method public java.util.List getSafetyRatings(); @@ -1636,7 +1587,6 @@ package com.google.firebase.ai.type { } public final class SearchEntryPoint { - ctor public SearchEntryPoint(String renderedContent, String? sdkBlob); method public String getRenderedContent(); method public String? getSdkBlob(); property public final String renderedContent; @@ -1644,7 +1594,6 @@ package com.google.firebase.ai.type { } public final class Segment { - ctor public Segment(int startIndex, int endIndex, int partIndex, String text); method public int getEndIndex(); method public int getPartIndex(); method public int getStartIndex(); @@ -1874,7 +1823,6 @@ package com.google.firebase.ai.type { } public final class UsageMetadata { - ctor @Deprecated public UsageMetadata(int promptTokenCount, Integer? candidatesTokenCount, int totalTokenCount, java.util.List promptTokensDetails, java.util.List candidatesTokensDetails, int thoughtsTokenCount); method public java.util.List getCacheTokensDetails(); method public int getCachedContentTokenCount(); method public Integer? getCandidatesTokenCount(); @@ -1903,23 +1851,7 @@ package com.google.firebase.ai.type { property public final String voiceName; } - @Deprecated @com.google.firebase.ai.type.PublicPreviewAPI public final class Voices { - method @Deprecated public int getOrdinal(); - property @Deprecated public final int ordinal; - field @Deprecated public static final com.google.firebase.ai.type.Voices AOEDE; - field @Deprecated public static final com.google.firebase.ai.type.Voices CHARON; - field @Deprecated public static final com.google.firebase.ai.type.Voices.Companion Companion; - field @Deprecated public static final com.google.firebase.ai.type.Voices FENRIR; - field @Deprecated public static final com.google.firebase.ai.type.Voices KORE; - field @Deprecated public static final com.google.firebase.ai.type.Voices PUCK; - field @Deprecated public static final com.google.firebase.ai.type.Voices UNSPECIFIED; - } - - @Deprecated public static final class Voices.Companion { - } - public final class WebGroundingChunk { - ctor public WebGroundingChunk(String? uri, String? title, String? domain); method public String? getDomain(); method public String? getTitle(); method public String? getUri(); diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt index 0dab15ae6e6..a0f8d4ea578 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt @@ -32,13 +32,13 @@ public class AIModels { public var app: FirebaseApp? = null public val vertexAIFlashModel: GenerativeModel by lazy { - getGenerativeModel(GenerativeBackend.vertexAI("global"), "gemini-3.5-flash") + getGenerativeModel(GenerativeBackend.agentPlatform("global"), "gemini-3.5-flash") } public val vertexAIFlashLiteModel: GenerativeModel by lazy { - getGenerativeModel(GenerativeBackend.vertexAI("global"), "gemini-3.1-flash-lite") + getGenerativeModel(GenerativeBackend.agentPlatform("global"), "gemini-3.1-flash-lite") } public val vertexAI3_5FlashModel: GenerativeModel by lazy { - getGenerativeModel(GenerativeBackend.vertexAI("global"), "gemini-3.5-flash") + getGenerativeModel(GenerativeBackend.agentPlatform("global"), "gemini-3.5-flash") } public val googleAIFlashModel: GenerativeModel by lazy { getGenerativeModel(GenerativeBackend.googleAI(), "gemini-3.1-flash-lite") @@ -50,7 +50,7 @@ public class AIModels { getGenerativeModel(GenerativeBackend.googleAI(), "gemini-3.5-flash") } public val vertexAITemplateModel: TemplateGenerativeModel by lazy { - FirebaseAI.getInstance(app(), GenerativeBackend.vertexAI()).templateGenerativeModel() + FirebaseAI.getInstance(app(), GenerativeBackend.agentPlatform()).templateGenerativeModel() } public val googleAITemplateModel: TemplateGenerativeModel by lazy { FirebaseAI.getInstance(app(), GenerativeBackend.googleAI()).templateGenerativeModel() @@ -82,7 +82,7 @@ public class AIModels { config: GenerationConfig? = null ): List { return listOf( - getGenerativeModel(GenerativeBackend.vertexAI("global"), modelName, config), + getGenerativeModel(GenerativeBackend.agentPlatform("global"), modelName, config), getGenerativeModel(GenerativeBackend.googleAI(), modelName, config), ) } @@ -122,7 +122,7 @@ public class AIModels { modelName: String? = null, config: LiveGenerationConfig? = null ): LiveGenerativeModel { - return FirebaseAI.getInstance(app(), GenerativeBackend.vertexAI()) + return FirebaseAI.getInstance(app(), GenerativeBackend.agentPlatform()) .liveModel( modelName = modelName ?: "gemini-live-2.5-flash-native-audio", generationConfig = config, diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/GroundingTests.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/GroundingTests.kt index 5856c42e53a..86c255338a9 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/GroundingTests.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/GroundingTests.kt @@ -62,7 +62,7 @@ class GroundingTests { @Test fun groundingTests_canSearchWeather(): Unit = runBlocking { val model = - FirebaseAI.getInstance(app(), GenerativeBackend.vertexAI("global")) + FirebaseAI.getInstance(app(), GenerativeBackend.agentPlatform("global")) .generativeModel( modelName = "gemini-3.5-flash", tools = listOf(Tool.googleSearch()), @@ -79,7 +79,7 @@ class GroundingTests { @JvmStatic fun setupModel(config: ToolConfig): GenerativeModel { val model = - FirebaseAI.getInstance(app(), GenerativeBackend.vertexAI("global")) + FirebaseAI.getInstance(app(), GenerativeBackend.agentPlatform("global")) .generativeModel( modelName = "gemini-3.5-flash", toolConfig = config, diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ToolTests.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ToolTests.kt index 66553ae7aa2..093a1550e98 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ToolTests.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ToolTests.kt @@ -300,7 +300,7 @@ class ToolTests { @JvmStatic fun setupModel(vararg functions: FunctionDeclaration): GenerativeModel { val model = - FirebaseAI.getInstance(app(), GenerativeBackend.vertexAI("global")) + FirebaseAI.getInstance(app(), GenerativeBackend.agentPlatform("global")) .generativeModel( modelName = "gemini-3.5-flash", toolConfig = diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAI.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAI.kt index 9b348d32f8a..ea75a51d44b 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAI.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAI.kt @@ -115,7 +115,6 @@ internal constructor( ): GenerativeModel { val modelUri = when (backend.backend) { - GenerativeBackendEnum.VERTEX_AI, GenerativeBackendEnum.AGENT_PLATFORM -> "projects/${firebaseApp.options.projectId}/locations/${backend.location}/publishers/google/models/${modelName}" GenerativeBackendEnum.GOOGLE_AI -> @@ -287,7 +286,6 @@ internal constructor( private fun getTemplateUri(backend: GenerativeBackend): String = when (backend.backend) { - GenerativeBackendEnum.VERTEX_AI, GenerativeBackendEnum.AGENT_PLATFORM -> "projects/${firebaseApp.options.projectId}/locations/${backend.location}/templates/" GenerativeBackendEnum.GOOGLE_AI -> "projects/${firebaseApp.options.projectId}/templates/" diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/GenerativeModel.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/GenerativeModel.kt index 389d54434c5..a0476f8f81a 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/GenerativeModel.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/GenerativeModel.kt @@ -240,18 +240,6 @@ internal constructor( public suspend fun countTokens(prompt: Bitmap): CountTokensResponse = countTokens(listOf(content { image(prompt) })) - /** - * Warms up the model to reduce latency for the first request. - * - * @throws [FirebaseAIException] if the warmup failed. - */ - @Deprecated( - message = "Use onDeviceExtension?.warmUp() instead", - replaceWith = ReplaceWith("onDeviceExtension?.warmUp()") - ) - @PublicPreviewAPI - public suspend fun warmUp(): Unit = actualModel.warmUp() - internal fun hasFunction(call: FunctionCallPart): Boolean { return tools .flatMap { it.autoFunctionDeclarations ?: emptyList() } diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/OnDeviceConfig.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/OnDeviceConfig.kt index 7b613ebaf8c..684076ee5ff 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/OnDeviceConfig.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/OnDeviceConfig.kt @@ -184,30 +184,33 @@ public class OnDeviceModelStatus private constructor(private val value: String) /** An abstract class representing the status of an on-device model download operation. */ @PublicPreviewAPI -public abstract class DownloadStatus { +public abstract class DownloadStatus internal constructor() { /** Represents when a download has just started. */ - public class DownloadStarted(public val bytesToDownload: Long) : DownloadStatus() { + public class DownloadStarted internal constructor(public val bytesToDownload: Long) : + DownloadStatus() { override fun equals(other: Any?): Boolean = other is DownloadStarted && bytesToDownload == other.bytesToDownload override fun hashCode(): Int = bytesToDownload.hashCode() } /** Represents when a download is actively in progress. */ - public class DownloadInProgress(public val totalBytesDownloaded: Long) : DownloadStatus() { + public class DownloadInProgress internal constructor(public val totalBytesDownloaded: Long) : + DownloadStatus() { override fun equals(other: Any?): Boolean = other is DownloadInProgress && totalBytesDownloaded == other.totalBytesDownloaded override fun hashCode(): Int = totalBytesDownloaded.hashCode() } /** Represents when a download has failed. */ - public class DownloadFailed(public val exception: FirebaseAIException) : DownloadStatus() { + public class DownloadFailed internal constructor(public val exception: FirebaseAIException) : + DownloadStatus() { override fun equals(other: Any?): Boolean = other is DownloadFailed && exception == other.exception override fun hashCode(): Int = exception.hashCode() } /** Represents when a download has successfully completed. */ - public class DownloadCompleted : DownloadStatus() { + public class DownloadCompleted internal constructor() : DownloadStatus() { override fun equals(other: Any?): Boolean = other is DownloadCompleted override fun hashCode(): Int = javaClass.hashCode() } diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/common/APIController.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/common/APIController.kt index 8bbd8d67d2b..526f44963f5 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/common/APIController.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/common/APIController.kt @@ -214,9 +214,8 @@ internal constructor( .map { it.validate() } .catch { throw FirebaseAIException.from(it) } - private fun getBidiEndpoint(location: String): String = + private fun getLiveEndpoint(location: String): String = when (backend?.backend) { - GenerativeBackendEnum.VERTEX_AI, GenerativeBackendEnum.AGENT_PLATFORM, null -> "wss://firebasevertexai.googleapis.com/ws/google.firebase.vertexai.v1beta.LlmBidiService/BidiGenerateContent/locations/$location?key=$key" @@ -230,7 +229,7 @@ internal constructor( // the same timeout-protected path as HTTP methods, then set them synchronously inside the // lambda. val extraHeaders = extractHeaders(headerProvider) - return client.webSocketSession(getBidiEndpoint(location)) { + return client.webSocketSession(getLiveEndpoint(location)) { applyCommonHeaders() for ((tag, value) in extraHeaders) { header(tag, value) diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/generativemodel/CloudGenerativeModelProvider.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/generativemodel/CloudGenerativeModelProvider.kt index ea45132456a..e08f7813dcd 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/generativemodel/CloudGenerativeModelProvider.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/generativemodel/CloudGenerativeModelProvider.kt @@ -121,7 +121,6 @@ internal class CloudGenerativeModelProvider( when (generativeBackend.backend) { GenerativeBackendEnum.GOOGLE_AI -> CountTokensRequest.forGoogleAI(buildGenerateContentRequest(prompt)) - GenerativeBackendEnum.VERTEX_AI, GenerativeBackendEnum.AGENT_PLATFORM -> CountTokensRequest.forVertexAI(buildGenerateContentRequest(prompt)) } diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/java/LiveSessionFutures.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/java/LiveSessionFutures.kt index adeb6f1d9b5..6c8d79ff064 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/java/LiveSessionFutures.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/java/LiveSessionFutures.kt @@ -27,7 +27,6 @@ import com.google.firebase.ai.type.InlineData import com.google.firebase.ai.type.LiveAudioConversationConfig import com.google.firebase.ai.type.LiveServerMessage import com.google.firebase.ai.type.LiveSession -import com.google.firebase.ai.type.MediaData import com.google.firebase.ai.type.PublicPreviewAPI import com.google.firebase.ai.type.SessionAlreadyReceivingException import com.google.firebase.ai.type.Transcription @@ -232,16 +231,6 @@ public abstract class LiveSessionFutures internal constructor() { */ public abstract fun sendStopActivityRealtime(): ListenableFuture - /** - * Streams client data to the model. - * - * Calling this after [startAudioConversation] will play the response audio immediately. - * - * @param mediaChunks The list of [MediaData] instances representing the media data to be sent. - */ - @Deprecated("Use `sendAudioRealtime`, `sendVideoRealtime`, or `sendTextRealtime` instead") - public abstract fun sendMediaStream(mediaChunks: List): ListenableFuture - /** * Sends [data][Content] to the model. * @@ -325,9 +314,6 @@ public abstract class LiveSessionFutures internal constructor() { override fun sendStopActivityRealtime(): ListenableFuture = SuspendToFutureAdapter.launchFuture { session.sendStopActivityRealtime() } - override fun sendMediaStream(mediaChunks: List) = - SuspendToFutureAdapter.launchFuture { session.sendMediaStream(mediaChunks) } - @RequiresPermission(RECORD_AUDIO) override fun startAudioConversation( functionCallHandler: ((FunctionCallPart) -> FunctionResponsePart)? diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Candidate.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Candidate.kt index aad1a2c33a0..a44c8b1b8d4 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Candidate.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Candidate.kt @@ -414,12 +414,11 @@ public class FinishReason private constructor(public val name: String, public va * @property groundingSupports The list of [GroundingSupport] objects. Each object details how * specific segments of the model's response are supported by the `groundingChunks`. */ -public class GroundingMetadata( +public class GroundingMetadata +internal constructor( public val webSearchQueries: List, public val searchEntryPoint: SearchEntryPoint?, public val retrievalQueries: List, - @Deprecated("Use groundingChunks instead") - public val groundingAttribution: List, public val groundingChunks: List, public val groundingSupports: List, ) { @@ -428,8 +427,6 @@ public class GroundingMetadata( val webSearchQueries: List?, val searchEntryPoint: SearchEntryPoint.Internal?, val retrievalQueries: List?, - @Deprecated("Use groundingChunks instead") - val groundingAttribution: List?, val groundingChunks: List?, val groundingSupports: List?, ) { @@ -438,7 +435,6 @@ public class GroundingMetadata( webSearchQueries = webSearchQueries.orEmpty(), searchEntryPoint = searchEntryPoint?.toPublic(), retrievalQueries = retrievalQueries.orEmpty(), - groundingAttribution = groundingAttribution?.map { it.toPublic(content) }.orEmpty(), groundingChunks = groundingChunks?.map { it.toPublic() }.orEmpty(), groundingSupports = groundingSupports?.map { it.toPublic(content) }.orEmpty().filterNotNull() @@ -453,7 +449,8 @@ public class GroundingMetadata( * rendering, it's recommended to display this content within a `WebView`. * @property sdkBlob A blob of data for the client SDK to render the search entry point. */ -public class SearchEntryPoint( +public class SearchEntryPoint +internal constructor( public val renderedContent: String, public val sdkBlob: String?, ) { @@ -480,8 +477,7 @@ public class SearchEntryPoint( * @property maps Contains details if the grounding chunk is from a Google Maps source. */ public class GroundingChunk -@JvmOverloads -constructor( +internal constructor( public val web: WebGroundingChunk? = null, public val maps: GoogleMapsGroundingChunk? = null, ) { @@ -503,7 +499,8 @@ constructor( * @property placeId This Place's resource name, in `places/{place_id}` format. This can be used to * look up the place using the Google Maps API. */ -public class GoogleMapsGroundingChunk( +public class GoogleMapsGroundingChunk +internal constructor( public val uri: String?, public val title: String?, public val placeId: String?, @@ -522,7 +519,8 @@ public class GoogleMapsGroundingChunk( * @property domain The domain of the original URI from which the content was retrieved. This is * only populated when using the Vertex AI Gemini API. */ -public class WebGroundingChunk( +public class WebGroundingChunk +internal constructor( public val uri: String?, public val title: String?, public val domain: String? @@ -545,7 +543,8 @@ public class WebGroundingChunk( * `[1, 3, 4]` means that `groundingChunks[1]`, `groundingChunks[3]`, `groundingChunks[4]` are the * retrieved content supporting this part of the response. */ -public class GroundingSupport( +public class GroundingSupport +internal constructor( public val segment: Segment, public val groundingChunkIndices: List, ) { @@ -566,22 +565,6 @@ public class GroundingSupport( } } -@Deprecated("Use GroundingChunk instead") -public class GroundingAttribution( - public val segment: Segment, - public val confidenceScore: Float?, -) { - @Deprecated("Use GroundingChunk instead") - @Serializable - internal data class Internal( - val segment: Segment.Internal, - val confidenceScore: Float?, - ) { - internal fun toPublic(content: Content) = - GroundingAttribution(segment = segment.toPublic(content), confidenceScore = confidenceScore) - } -} - /** * Represents a specific segment within a [Content] object, often used to pinpoint the exact * location of text or data that grounding information refers to. @@ -596,7 +579,8 @@ public class GroundingAttribution( * included in the segment. * @property text The text corresponding to the segment from the response. */ -public class Segment( +public class Segment +internal constructor( public val startIndex: Int, public val endIndex: Int, public val partIndex: Int, diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/CountTokensResponse.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/CountTokensResponse.kt index ac485a2c0d9..e4ad1d3d92d 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/CountTokensResponse.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/CountTokensResponse.kt @@ -25,36 +25,27 @@ import kotlinx.serialization.Serializable * input. See [Pricing](https://firebase.google.com/docs/ai-logic/pricing) for details. * * @property totalTokens The total number of tokens in the input given to the model as a prompt. - * @property totalBillableCharacters The total number of billable characters in the text input given - * to the model as a prompt. **Important:** this property does not include billable image, video or - * other non-text input. See [Pricing](https://firebase.google.com/docs/ai-logic/pricing) for - * details. * @property promptTokensDetails The breakdown, by modality, of how many tokens are consumed by the * prompt. */ -public class CountTokensResponse( +public class CountTokensResponse +internal constructor( public val totalTokens: Int, - @Deprecated("This field is deprecated and will be removed in a future version.") - public val totalBillableCharacters: Int? = null, public val promptTokensDetails: List = emptyList(), ) { public operator fun component1(): Int = totalTokens - public operator fun component2(): Int? = totalBillableCharacters - - public operator fun component3(): List? = promptTokensDetails + public operator fun component2(): List = promptTokensDetails @Serializable internal data class Internal( val totalTokens: Int? = null, - val totalBillableCharacters: Int? = null, val promptTokensDetails: List? = null ) : Response { internal fun toPublic(): CountTokensResponse { return CountTokensResponse( totalTokens ?: 0, - totalBillableCharacters ?: 0, promptTokensDetails?.map { it.toPublic() } ?: emptyList() ) } diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/GenerateContentResponse.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/GenerateContentResponse.kt index 660d14b2eab..aabc89bcd60 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/GenerateContentResponse.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/GenerateContentResponse.kt @@ -38,18 +38,6 @@ internal constructor( public val modelVersion: String? ) { - // To maintain backwards compatibility with possible outside usage, we maintain a public - // constructor without the `InferenceSource`. Devs shouldn't be instantiating this class as it's - // for consumption only. - // Since any use previous to adding this parameter was for cloud inference, the source has been - // hard-coded to `IN_CLOUD` - @OptIn(PublicPreviewAPI::class) - public constructor( - candidates: List, - promptFeedback: PromptFeedback?, - usageMetadata: UsageMetadata?, - ) : this(candidates, InferenceSource.IN_CLOUD, promptFeedback, usageMetadata, null) - /** * Convenience field representing all the text parts in the response as a single string. * diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/GenerativeBackend.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/GenerativeBackend.kt index abb89546385..818599bfa7a 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/GenerativeBackend.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/GenerativeBackend.kt @@ -28,26 +28,6 @@ internal constructor(internal val location: String, internal val backend: Genera public fun googleAI(): GenerativeBackend = GenerativeBackend("", GenerativeBackendEnum.GOOGLE_AI) - /** - * References the VertexAI Gemini API backend. - * - * @param location passes a valid cloud server location, defaults to "us-central1" - */ - @Deprecated( - message = - "Use agentPlatform instead. Note that agentPlatform default location is \"global\" while" + - " vertexAI was \"us-central1\".", - replaceWith = ReplaceWith("agentPlatform(location)") - ) - @JvmStatic - @JvmOverloads - public fun vertexAI(location: String = "us-central1"): GenerativeBackend { - if (location.isBlank() || location.contains("/")) { - throw InvalidLocationException(location) - } - return GenerativeBackend(location, GenerativeBackendEnum.VERTEX_AI) - } - /** * References the Agent Platform Gemini API. * @@ -69,7 +49,6 @@ internal constructor(internal val location: String, internal val backend: Genera GenerativeBackendEnum.GOOGLE_AI -> { other.backend == this.backend } - GenerativeBackendEnum.VERTEX_AI, GenerativeBackendEnum.AGENT_PLATFORM -> { other.backend == this.backend && other.location == this.location } @@ -83,6 +62,5 @@ internal constructor(internal val location: String, internal val backend: Genera internal enum class GenerativeBackendEnum { GOOGLE_AI, - VERTEX_AI, AGENT_PLATFORM, } diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveClientSetupMessage.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveClientSetupMessage.kt index 638224e43a8..7764efdefa0 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveClientSetupMessage.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveClientSetupMessage.kt @@ -28,7 +28,7 @@ import kotlinx.serialization.Serializable @PublicPreviewAPI internal class LiveClientSetupMessage( val model: String, - // Some config options are supported in generateContent but not in bidi and vise versa; so bidi + // Some config options are supported in generateContent but not in live and conversely; so live // needs its own config class val generationConfig: LiveGenerationConfig.Internal?, val tools: List?, diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveServerMessage.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveServerMessage.kt index cf945f2b5fd..3b053fa2324 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveServerMessage.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveServerMessage.kt @@ -48,8 +48,7 @@ import kotlinx.serialization.json.jsonObject */ @PublicPreviewAPI public class LiveServerContent -@Deprecated("This class should not be constructed, only received from the Server") -public constructor( +internal constructor( /** * The content that the model has generated as part of the current conversation with the user. * @@ -131,7 +130,7 @@ public constructor( /** The model is ready to receive client messages. */ @PublicPreviewAPI -public class LiveServerSetupComplete : LiveServerMessage { +public class LiveServerSetupComplete internal constructor() : LiveServerMessage { @Serializable internal data class Internal(val setupComplete: JsonObject) : InternalLiveServerMessage { override fun toPublic() = LiveServerSetupComplete() @@ -156,8 +155,8 @@ public class LiveServerUnknownMessage private constructor() : LiveServerMessage * @property functionCalls A list of [FunctionCallPart] to run and return responses for. */ @PublicPreviewAPI -public class LiveServerToolCall(public val functionCalls: List) : - LiveServerMessage { +public class LiveServerToolCall +internal constructor(public val functionCalls: List) : LiveServerMessage { @Serializable internal data class Internal( val functionCalls: List = emptyList() @@ -186,8 +185,8 @@ public class LiveServerToolCall(public val functionCalls: List * [LiveServerToolCall], where only the provided `id`s should be cancelled. */ @PublicPreviewAPI -public class LiveServerToolCallCancellation(public val functionIds: List) : - LiveServerMessage { +public class LiveServerToolCallCancellation +internal constructor(public val functionIds: List) : LiveServerMessage { @Serializable internal data class Internal(val functionIds: List = emptyList()) @Serializable internal data class InternalWrapper(val toolCallCancellation: Internal) : @@ -208,7 +207,8 @@ public class LiveServerToolCallCancellation(public val functionIds: List * @property timeLeft The time remaining before the connection terminates. */ @PublicPreviewAPI -public class LiveServerGoAway(public val timeLeft: Duration?) : LiveServerMessage { +public class LiveServerGoAway internal constructor(public val timeLeft: Duration?) : + LiveServerMessage { @Serializable internal data class Internal(val timeLeft: String? = null) @Serializable @@ -235,7 +235,8 @@ public class LiveServerGoAway(public val timeLeft: Duration?) : LiveServerMessag * the state represented by this update. */ @PublicPreviewAPI -public class LiveSessionResumptionUpdate( +public class LiveSessionResumptionUpdate +internal constructor( public val newHandle: String? = null, public val resumable: Boolean? = null, public val lastConsumedClientMessageIndex: Int? = null diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveSession.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveSession.kt index 3e19a04fbb8..12bfbb662af 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveSession.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/LiveSession.kt @@ -389,8 +389,7 @@ internal constructor( */ public suspend fun sendFunctionResponse(functionList: List) { sendFrame( - BidiGenerateContentToolResponseSetup(functionList.map { it.toInternalFunctionResponse() }) - .toInternal() + LiveClientToolResponse(functionList.map { it.toInternalFunctionResponse() }).toInternal() ) } @@ -405,7 +404,7 @@ internal constructor( * results, send 16-bit PCM audio at 24kHz. */ public suspend fun sendAudioRealtime(audio: InlineData) { - sendFrame(BidiGenerateContentRealtimeInputSetup(audio = audio).toInternal()) + sendFrame(LiveRealtimeInput(audio = audio).toInternal()) } /** @@ -420,10 +419,10 @@ internal constructor( * * @param video Encoded image data extracted from a frame of the video, used to update the model * on the client's conversation, with the corresponding IANA standard MIME type of the video frame - * data (for example, `image/png`, `image/jpeg`, etc.). + * data (for example, `image/png`, `image/jpeg`, and so on). */ public suspend fun sendVideoRealtime(video: InlineData) { - sendFrame(BidiGenerateContentRealtimeInputSetup(video = video).toInternal()) + sendFrame(LiveRealtimeInput(video = video).toInternal()) } /** @@ -432,7 +431,7 @@ internal constructor( * @param text Text content to append to the current client's conversation. */ public suspend fun sendTextRealtime(text: String) { - sendFrame(BidiGenerateContentRealtimeInputSetup(text = text).toInternal()) + sendFrame(LiveRealtimeInput(text = text).toInternal()) } /** @@ -448,7 +447,7 @@ internal constructor( * Only required when automatic activity detection is disabled via [RealtimeInputConfig]. */ public suspend fun sendStartActivityRealtime() { - sendFrame(BidiGenerateContentRealtimeInputSetup(activityStart = true).toInternal()) + sendFrame(LiveRealtimeInput(activityStart = true).toInternal()) } /** @@ -462,24 +461,7 @@ internal constructor( * Only required when automatic activity detection is disabled via [RealtimeInputConfig]. */ public suspend fun sendStopActivityRealtime() { - sendFrame(BidiGenerateContentRealtimeInputSetup(activityEnd = true).toInternal()) - } - - /** - * Streams client data to the model. - * - * Calling this after [startAudioConversation] will play the response audio immediately. - * - * @param mediaChunks The list of [MediaData] instances representing the media data to be sent. - */ - @Deprecated("Use sendAudioRealtime, sendVideoRealtime, or sendTextRealtime instead") - public suspend fun sendMediaStream( - mediaChunks: List, - ) { - sendFrame( - BidiGenerateContentRealtimeInputSetup(mediaChunks.map { InlineData(it.data, it.mimeType) }) - .toInternal() - ) + sendFrame(LiveRealtimeInput(activityEnd = true).toInternal()) } /** @@ -492,9 +474,7 @@ internal constructor( */ @JvmOverloads public suspend fun send(content: Content, turnComplete: Boolean = true) { - sendFrame( - BidiGenerateContentClientContentSetup(listOf(content.toInternal()), turnComplete).toInternal() - ) + sendFrame(LiveClientContent(listOf(content.toInternal()), turnComplete).toInternal()) } /** @@ -709,44 +689,40 @@ internal constructor( * * Effectively, a message from the client to the model. */ - internal class BidiGenerateContentClientContentSetup( - val turns: List, - val turnComplete: Boolean - ) { + internal class LiveClientContent(val turns: List, val turnComplete: Boolean) { @Serializable - internal class Internal(val clientContent: BidiGenerateContentClientContent) { + internal class Internal(val clientContent: LiveClientContentData) { @Serializable - internal data class BidiGenerateContentClientContent( + internal data class LiveClientContentData( val turns: List, val turnComplete: Boolean ) } - fun toInternal() = Internal(Internal.BidiGenerateContentClientContent(turns, turnComplete)) + fun toInternal() = Internal(Internal.LiveClientContentData(turns, turnComplete)) } /** Client generated responses to a [LiveServerToolCall]. */ - internal class BidiGenerateContentToolResponseSetup( + internal class LiveClientToolResponse( val functionResponses: List ) { @Serializable - internal data class Internal(val toolResponse: BidiGenerateContentToolResponse) { + internal data class Internal(val toolResponse: LiveClientToolResponseData) { @Serializable - internal data class BidiGenerateContentToolResponse( + internal data class LiveClientToolResponseData( val functionResponses: List ) } - fun toInternal() = Internal(Internal.BidiGenerateContentToolResponse(functionResponses)) + fun toInternal() = Internal(Internal.LiveClientToolResponseData(functionResponses)) } /** * User input that is sent to the model in real time. * - * End of turn is derived from user activity (eg; end of speech). + * End of turn is derived from user activity (for example, end of speech). */ - internal class BidiGenerateContentRealtimeInputSetup( - val mediaChunks: List? = null, + internal class LiveRealtimeInput( val audio: InlineData? = null, val video: InlineData? = null, val text: String? = null, @@ -757,21 +733,19 @@ internal constructor( @Serializable internal class ActivityEnd @Serializable - internal class Internal(val realtimeInput: BidiGenerateContentRealtimeInput) { + internal class Internal(val realtimeInput: LiveRealtimeInputData) { @Serializable - internal data class BidiGenerateContentRealtimeInput( - val mediaChunks: List?, - val audio: InlineData.Internal?, - val video: InlineData.Internal?, - val text: String?, + internal data class LiveRealtimeInputData( + val audio: InlineData.Internal? = null, + val video: InlineData.Internal? = null, + val text: String? = null, val activityStart: ActivityStart? = null, val activityEnd: ActivityEnd? = null ) } fun toInternal() = Internal( - Internal.BidiGenerateContentRealtimeInput( - mediaChunks?.map { it.toInternal() }, + Internal.LiveRealtimeInputData( audio?.toInternal(), video?.toInternal(), text, diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/MediaData.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/MediaData.kt deleted file mode 100644 index e08f133527e..00000000000 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/MediaData.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 com.google.firebase.ai.type - -import android.util.Base64 -import kotlinx.serialization.Serializable - -/** - * Represents the media data to be sent to the server - * - * @param data Byte array representing the data to be sent. - * @param mimeType an IANA standard MIME type. For supported MIME type values see the - * [Firebase documentation](https://firebase.google.com/docs/ai-logic/input-file-requirements). - */ -@PublicPreviewAPI -@Deprecated("Use `InlineData` instead", ReplaceWith("InlineData")) -public class MediaData(public val data: ByteArray, public val mimeType: String) { - @Serializable - internal class Internal( - val data: String, - val mimeType: String, - ) - - internal fun toInternal(): Internal { - return Internal(Base64.encodeToString(data, BASE_64_FLAGS), mimeType) - } -} diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Part.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Part.kt index b1c391234b7..1164842be91 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Part.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Part.kt @@ -83,9 +83,6 @@ internal constructor( public val thoughtSignature: String? ) : Part { - @Deprecated("Part of the model response. Do not instantiate directly.") - public constructor(outcome: String, output: String) : this(outcome, output, false, null) - /** Indicates if the code execution was successful */ public fun executionSucceeded(): Boolean = (outcome.lowercase() == "outcome_ok") @@ -134,9 +131,6 @@ internal constructor( public val thoughtSignature: String? ) : Part { - @Deprecated("Part of the model response. Do not instantiate directly.") - public constructor(language: String, code: String) : this(language, code, false, null) - public companion object { /** * Creates an [ExecutableCodePart] with advanced thinking metadata. diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/PromptFeedback.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/PromptFeedback.kt index 5f9840263eb..8a072159b92 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/PromptFeedback.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/PromptFeedback.kt @@ -28,7 +28,8 @@ import kotlinx.serialization.Serializable * @param safetyRatings A list of relevant [SafetyRating]. * @param blockReasonMessage A message describing the reason that content was blocked, if any. */ -public class PromptFeedback( +public class PromptFeedback +internal constructor( public val blockReason: BlockReason?, public val safetyRatings: List, public val blockReasonMessage: String? diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/UsageMetadata.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/UsageMetadata.kt index 7dd1e546445..c17a0158111 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/UsageMetadata.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/UsageMetadata.kt @@ -47,27 +47,6 @@ internal constructor( public val toolUsePromptTokensDetails: List ) { - @Deprecated("Not intended for public use") - public constructor( - promptTokenCount: Int, - candidatesTokenCount: Int?, - totalTokenCount: Int, - promptTokensDetails: List, - candidatesTokensDetails: List, - thoughtsTokenCount: Int - ) : this( - promptTokenCount, - candidatesTokenCount, - totalTokenCount, - 0, - promptTokensDetails, - candidatesTokensDetails, - emptyList(), - thoughtsTokenCount, - 0, - emptyList() - ) - @Serializable internal data class Internal( val promptTokenCount: Int? = null, diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Voices.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Voices.kt deleted file mode 100644 index 62e775688cb..00000000000 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Voices.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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 com.google.firebase.ai.type - -import kotlinx.serialization.Serializable - -/** Various voices supported by the server */ -@Deprecated("Use the Voice class instead.", ReplaceWith("Voice")) -@PublicPreviewAPI -public class Voices private constructor(public val ordinal: Int) { - - @Serializable internal data class Internal(val voiceName: String) - - @Serializable - internal enum class InternalEnum { - CHARON, - AOEDE, - FENRIR, - KORE, - PUCK; - internal fun toPublic() = - when (this) { - CHARON -> Voices.CHARON - AOEDE -> Voices.AOEDE - FENRIR -> Voices.FENRIR - KORE -> Voices.KORE - else -> Voices.PUCK - } - } - - internal fun toInternal(): Internal { - return when (this) { - CHARON -> Internal(InternalEnum.CHARON.name) - AOEDE -> Internal(InternalEnum.AOEDE.name) - FENRIR -> Internal(InternalEnum.FENRIR.name) - KORE -> Internal(InternalEnum.KORE.name) - else -> Internal(InternalEnum.PUCK.name) - } - } - - public companion object { - /** - * Unspecified voice. - * - * Will use the default voice of the model. - */ - @JvmField public val UNSPECIFIED: Voices = Voices(0) - - /** Represents the Charon voice. */ - @JvmField public val CHARON: Voices = Voices(1) - - /** Represents the Aoede voice. */ - @JvmField public val AOEDE: Voices = Voices(2) - - /** Represents the Fenrir voice. */ - @JvmField public val FENRIR: Voices = Voices(3) - - /** Represents the Kore voice. */ - @JvmField public val KORE: Voices = Voices(4) - - /** Represents the Puck voice. */ - @JvmField public val PUCK: Voices = Voices(5) - } -} diff --git a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/GenerativeModelTesting.kt b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/GenerativeModelTesting.kt index 35dcb953e30..f230e3b5d50 100644 --- a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/GenerativeModelTesting.kt +++ b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/GenerativeModelTesting.kt @@ -375,7 +375,7 @@ internal class GenerativeModelTesting { CloudGenerativeModelProvider( TEST_MODEL_NAME, safetySettings = safetySettings, - generativeBackend = GenerativeBackend.vertexAI("us-central1"), + generativeBackend = GenerativeBackend.agentPlatform("us-central1"), controller = apiController ), requestOptions = RequestOptions() diff --git a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/SerializationTests.kt b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/SerializationTests.kt index 8047cc48eb2..d148b653b53 100644 --- a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/SerializationTests.kt +++ b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/SerializationTests.kt @@ -22,7 +22,6 @@ import com.google.firebase.ai.type.Candidate import com.google.firebase.ai.type.CountTokensResponse import com.google.firebase.ai.type.GenerateContentResponse import com.google.firebase.ai.type.GoogleSearch -import com.google.firebase.ai.type.GroundingAttribution import com.google.firebase.ai.type.GroundingChunk import com.google.firebase.ai.type.GroundingMetadata import com.google.firebase.ai.type.GroundingSupport @@ -228,7 +227,6 @@ internal class SerializationTests { "webSearchQueries": { "type": "array", "items": { "type": "string" } }, "searchEntryPoint": { "${'$'}ref": "SearchEntryPoint" }, "retrievalQueries": { "type": "array", "items": { "type": "string" } }, - "groundingAttribution": { "type": "array", "items": { "${'$'}ref": "GroundingAttribution" } }, "groundingChunks": { "type": "array", "items": { "${'$'}ref": "GroundingChunk" } }, "groundingSupports": { "type": "array", "items": { "${'$'}ref": "GroundingSupport" } } } @@ -385,28 +383,6 @@ internal class SerializationTests { expectedJsonAsString shouldEqualJson actualJson.toString() } - @Test - fun `test GroundingAttribution serialization as Json`() { - val expectedJsonAsString = - """ - { - "id": "GroundingAttribution", - "type": "object", - "properties": { - "segment": { - "${'$'}ref": "Segment" - }, - "confidenceScore": { - "type": "number" - } - } - } - """ - .trimIndent() - val actualJson = descriptorToJson(GroundingAttribution.Internal.serializer().descriptor) - expectedJsonAsString shouldEqualJson actualJson.toString() - } - @Test fun `test Schema serialization as Json`() { /** diff --git a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/type/GenerativeBackendTest.kt b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/type/GenerativeBackendTest.kt index e8c4ba85165..c2329926236 100644 --- a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/type/GenerativeBackendTest.kt +++ b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/type/GenerativeBackendTest.kt @@ -44,14 +44,6 @@ internal class GenerativeBackendTest { shouldThrow { GenerativeBackend.agentPlatform("us/central1") } } - @Test - @Suppress("DEPRECATION") - fun `vertexAI default location`() { - val backend = GenerativeBackend.vertexAI() - backend.location shouldBe "us-central1" - backend.backend shouldBe GenerativeBackendEnum.VERTEX_AI - } - @Test fun `googleAI properties`() { val backend = GenerativeBackend.googleAI() @@ -60,18 +52,15 @@ internal class GenerativeBackendTest { } @Test - @Suppress("DEPRECATION") fun `GenerativeBackend equality and hashcode`() { val agentPlatformGlobal1 = GenerativeBackend.agentPlatform("global") val agentPlatformGlobal2 = GenerativeBackend.agentPlatform("global") val agentPlatformUsCentral = GenerativeBackend.agentPlatform("us-central1") - val vertexGlobal = GenerativeBackend.vertexAI("global") agentPlatformGlobal1 shouldBe agentPlatformGlobal2 agentPlatformGlobal1.hashCode() shouldBe agentPlatformGlobal2.hashCode() agentPlatformGlobal1 shouldNotBe agentPlatformUsCentral - agentPlatformGlobal1 shouldNotBe vertexGlobal agentPlatformGlobal1 shouldNotBe GenerativeBackend.googleAI() } } diff --git a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/type/RealtimeInputConfigTest.kt b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/type/RealtimeInputConfigTest.kt index 1e04514cf80..3d2669f8927 100644 --- a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/type/RealtimeInputConfigTest.kt +++ b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/type/RealtimeInputConfigTest.kt @@ -118,8 +118,8 @@ internal class RealtimeInputConfigTest { } @Test - fun `BidiGenerateContentRealtimeInputSetup with activityStart serializes correctly`() { - val setup = LiveSession.BidiGenerateContentRealtimeInputSetup(activityStart = true) + fun `LiveRealtimeInput with activityStart serializes correctly`() { + val setup = LiveSession.LiveRealtimeInput(activityStart = true) val expectedJson = """ @@ -135,8 +135,8 @@ internal class RealtimeInputConfigTest { } @Test - fun `BidiGenerateContentRealtimeInputSetup with activityEnd serializes correctly`() { - val setup = LiveSession.BidiGenerateContentRealtimeInputSetup(activityEnd = true) + fun `LiveRealtimeInput with activityEnd serializes correctly`() { + val setup = LiveSession.LiveRealtimeInput(activityEnd = true) val expectedJson = """ diff --git a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/util/tests.kt b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/util/tests.kt index e4a870b1869..b811ba56d04 100644 --- a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/util/tests.kt +++ b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/util/tests.kt @@ -108,7 +108,7 @@ internal typealias CommonTest = suspend CommonTestScope.() -> Unit internal fun commonTest( status: HttpStatusCode = HttpStatusCode.OK, requestOptions: RequestOptions = RequestOptions(), - backend: GenerativeBackend = GenerativeBackend.vertexAI(), + backend: GenerativeBackend = GenerativeBackend.agentPlatform(), tools: List = emptyList(), requestHandler: (HttpRequestData) -> Unit = {}, block: CommonTest, @@ -175,7 +175,7 @@ internal fun commonTest( internal fun commonMultiTurnTest( responses: List, requestOptions: RequestOptions = RequestOptions(), - backend: GenerativeBackend = GenerativeBackend.vertexAI(), + backend: GenerativeBackend = GenerativeBackend.agentPlatform(), tools: List = emptyList(), requestHandler: (HttpRequestData) -> Unit = {}, responseLoader: suspend (String, ByteChannel) -> Unit, @@ -236,7 +236,7 @@ internal fun commonMultiTurnTest( */ internal fun goldenStreamingFile( responses: List, - backend: GenerativeBackend = GenerativeBackend.vertexAI(), + backend: GenerativeBackend = GenerativeBackend.agentPlatform(), tools: List = emptyList(), requestHandler: (HttpRequestData) -> Unit, block: CommonTest, @@ -366,7 +366,7 @@ internal fun goldenDevAPIStreamingFile( */ internal fun goldenUnaryFile( responses: List, - backend: GenerativeBackend = GenerativeBackend.vertexAI(), + backend: GenerativeBackend = GenerativeBackend.agentPlatform(), tools: List = emptyList(), block: CommonTest, ) = doBlocking { @@ -397,7 +397,7 @@ internal fun goldenUnaryFile( internal fun goldenVertexUnaryFiles( responses: List, requestOptions: RequestOptions, - backend: GenerativeBackend = GenerativeBackend.vertexAI(), + backend: GenerativeBackend = GenerativeBackend.agentPlatform(), tools: List = emptyList(), block: CommonTest, ) = doBlocking { diff --git a/ai-logic/firebase-ai/src/testUtil/java/com/google/firebase/ai/JavaCompileTests.java b/ai-logic/firebase-ai/src/testUtil/java/com/google/firebase/ai/JavaCompileTests.java index 423060dd779..90bcec9e3e3 100644 --- a/ai-logic/firebase-ai/src/testUtil/java/com/google/firebase/ai/JavaCompileTests.java +++ b/ai-logic/firebase-ai/src/testUtil/java/com/google/firebase/ai/JavaCompileTests.java @@ -62,7 +62,6 @@ import com.google.firebase.ai.type.LiveServerSetupComplete; import com.google.firebase.ai.type.LiveServerToolCall; import com.google.firebase.ai.type.LiveServerToolCallCancellation; -import com.google.firebase.ai.type.MediaData; import com.google.firebase.ai.type.ModalityTokenCount; import com.google.firebase.ai.type.MultiSpeakerVoiceConfig; import com.google.firebase.ai.type.Part; @@ -314,10 +313,8 @@ public void testMapsGrounding() { public void validateCountTokensResponse(CountTokensResponse response) { int tokens = response.getTotalTokens(); - Integer billable = response.getTotalBillableCharacters(); Assert.assertEquals(tokens, response.component1()); - Assert.assertEquals(billable, response.component2()); - Assert.assertEquals(response.getPromptTokensDetails(), response.component3()); + Assert.assertEquals(response.getPromptTokensDetails(), response.component2()); for (ModalityTokenCount count : response.getPromptTokensDetails()) { ContentModality modality = count.getModality(); int tokenCount = count.getTokenCount(); @@ -461,7 +458,6 @@ public void onComplete() { session.send(new Content.Builder().addText("Fake message").build()); byte[] bytes = new byte[] {(byte) 0xCA, (byte) 0xFE, (byte) 0xBA, (byte) 0xBE}; - session.sendMediaStream(List.of(new MediaData(bytes, "image/jxl"))); session.sendAudioRealtime(new InlineData(bytes, "audio/jxl", null)); session.sendVideoRealtime(new InlineData(bytes, "image/jxl", null)); session.sendTextRealtime("text"); diff --git a/ai-logic/firebase-ai/src/testUtil/java/com/google/firebase/ai/JavaSnippetCompileTests.java b/ai-logic/firebase-ai/src/testUtil/java/com/google/firebase/ai/JavaSnippetCompileTests.java index f4c6e002f5a..7553f4d4c97 100644 --- a/ai-logic/firebase-ai/src/testUtil/java/com/google/firebase/ai/JavaSnippetCompileTests.java +++ b/ai-logic/firebase-ai/src/testUtil/java/com/google/firebase/ai/JavaSnippetCompileTests.java @@ -59,7 +59,7 @@ public void template_chat() { // Initialize the Vertex AI Gemini API backend service. TemplateGenerativeModel templateModel = - FirebaseAI.getInstance(GenerativeBackend.vertexAI("global")).templateGenerativeModel(); + FirebaseAI.getInstance(GenerativeBackend.agentPlatform("global")).templateGenerativeModel(); // Initialize TemplateChat with history and inputs TemplateChat templateChat = templateModel.startChat("my-chat-template-v1-0-0", Map.of(), Collections.emptyList()); @@ -92,7 +92,7 @@ public void template_functionCallingSchemaInTemplate(String userMessage) { // Initialize the Vertex AI Gemini API backend service. // Create a `TemplateGenerativeModel` instance. TemplateGenerativeModel model = - FirebaseAI.getInstance(GenerativeBackend.vertexAI("global")).templateGenerativeModel(); + FirebaseAI.getInstance(GenerativeBackend.agentPlatform("global")).templateGenerativeModel(); // Start a chat session with a template that has functions listed as tools. TemplateChat chatSession = @@ -164,7 +164,7 @@ public void template_functionCallingSchemaInCode() { ))), JsonSchema.string("A description of the current weather.")); TemplateGenerativeModel templateModel = - FirebaseAI.getInstance(GenerativeBackend.vertexAI("global")) + FirebaseAI.getInstance(GenerativeBackend.agentPlatform("global")) .templateGenerativeModel( new RequestOptions(), List.of(TemplateTool.functionDeclarations(List.of(tool), List.of()))); From f8239e8958d8bc2576920c245aeb3e140342f58e Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Mon, 31 Aug 2026 13:23:40 -0400 Subject: [PATCH 2/3] fix tests --- .../src/main/kotlin/com/google/firebase/ai/FirebaseAI.kt | 1 - .../test/java/com/google/firebase/ai/SerializationTests.kt | 3 --- .../com/google/firebase/ai/VertexAIUnarySnapshotTests.kt | 5 +---- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAI.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAI.kt index ea75a51d44b..8e4bd66533d 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAI.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAI.kt @@ -211,7 +211,6 @@ internal constructor( } return LiveGenerativeModel( when (backend.backend) { - GenerativeBackendEnum.VERTEX_AI, GenerativeBackendEnum.AGENT_PLATFORM -> "projects/${firebaseApp.options.projectId}/locations/${backend.location}/publishers/google/models/${modelName}" GenerativeBackendEnum.GOOGLE_AI -> diff --git a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/SerializationTests.kt b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/SerializationTests.kt index d148b653b53..c8ecfba773f 100644 --- a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/SerializationTests.kt +++ b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/SerializationTests.kt @@ -53,9 +53,6 @@ internal class SerializationTests { "totalTokens": { "type": "integer" }, - "totalBillableCharacters": { - "type": "integer" - }, "promptTokensDetails": { "type": "array", "items": { diff --git a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/VertexAIUnarySnapshotTests.kt b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/VertexAIUnarySnapshotTests.kt index 1a885f4e3d6..bb3719f38c2 100644 --- a/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/VertexAIUnarySnapshotTests.kt +++ b/ai-logic/firebase-ai/src/test/java/com/google/firebase/ai/VertexAIUnarySnapshotTests.kt @@ -587,7 +587,6 @@ internal class VertexAIUnarySnapshotTests { val response = model.countTokens("prompt") response.totalTokens shouldBe 6 - response.totalBillableCharacters shouldBe 16 response.promptTokensDetails.isEmpty() shouldBe true } } @@ -599,9 +598,8 @@ internal class VertexAIUnarySnapshotTests { val response = model.countTokens("prompt") response.totalTokens shouldBe 1837 - response.totalBillableCharacters shouldBe 117 response.promptTokensDetails shouldNotBe null - response.promptTokensDetails?.forAtLeastOne { + response.promptTokensDetails.forAtLeastOne { it.modality shouldBe ContentModality.IMAGE it.tokenCount shouldBe 1806 } @@ -615,7 +613,6 @@ internal class VertexAIUnarySnapshotTests { val response = model.countTokens("prompt") response.totalTokens shouldBe 258 - response.totalBillableCharacters shouldBe 0 } } From e5c3e4e35532f1b34fcd1983a1065767c20f8659 Mon Sep 17 00:00:00 2001 From: Vinay Guthal Date: Mon, 31 Aug 2026 13:39:22 -0400 Subject: [PATCH 3/3] update --- .../kotlin/com/google/firebase/ai/GenerateContentTests.kt | 2 +- .../kotlin/com/google/firebase/ai/LiveSessionTests.kt | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/GenerateContentTests.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/GenerateContentTests.kt index 6d4edb1a154..4baa2515d5f 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/GenerateContentTests.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/GenerateContentTests.kt @@ -205,7 +205,7 @@ class GenerateContentTests { ) } catch (e: Exception) { assertThat(e).isInstanceOf(ServerException::class.java) - assertThat(e.message).contains("the number of enabled_voices must equal 2") + assertThat(e.message).contains("the number of speaker_voice_configs must equal 2") } } } diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/LiveSessionTests.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/LiveSessionTests.kt index 8c605a3769a..3904fc42235 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/LiveSessionTests.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/LiveSessionTests.kt @@ -268,6 +268,7 @@ class LiveSessionTests { val session = liveModel.connect(SessionResumptionConfig()) session.send("My favorite color is blue. Remember that.", true) var lastResumptionUpdate: LiveSessionResumptionUpdate? = null + var handle: String? = null var gotTurnComplete = false withTimeout(30.seconds) { session @@ -275,17 +276,19 @@ class LiveSessionTests { .takeWhile { if (it is LiveSessionResumptionUpdate) { lastResumptionUpdate = it + if (it.newHandle != null) { + handle = it.newHandle + } } if (it is LiveServerContent && it.turnComplete) { gotTurnComplete = true } // Stop when we've seen a turn complete and we have a new handle - !(gotTurnComplete && lastResumptionUpdate?.newHandle != null) + !(gotTurnComplete && handle != null) } .collect {} } lastResumptionUpdate shouldNotBe null - val handle = lastResumptionUpdate?.newHandle handle.shouldNotBeNull() session.resumeSession(SessionResumptionConfig(handle)) session.send("What is my favorite color?")