From db1e7c0d4c351711a021c7ef6aeebe6e0abe4860 Mon Sep 17 00:00:00 2001 From: Mila <107142260+milaGGL@users.noreply.github.com> Date: Wed, 2 Sep 2026 16:56:30 -0400 Subject: [PATCH 1/2] [AI] extend request header --- .../kotlin/com/google/firebase/ai/FirebaseAI.kt | 16 ++++++++++++++++ .../ai/FirebaseAIMultiResourceComponent.kt | 5 ++++- .../google/firebase/ai/FirebaseAIRegistrar.kt | 6 +++++- .../google/firebase/ai/LiveGenerativeModel.kt | 3 ++- .../firebase/ai/TemplateGenerativeModel.kt | 5 +++-- 5 files changed, 30 insertions(+), 5 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 9b348d32f8a..650dffc7670 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 @@ -37,6 +37,7 @@ import com.google.firebase.app import com.google.firebase.appcheck.interop.InteropAppCheckTokenProvider import com.google.firebase.auth.internal.InternalAuthProvider import com.google.firebase.inject.Provider +import com.google.firebase.platforminfo.UserAgentPublisher import kotlin.coroutines.CoroutineContext /** Entry point for all _Firebase AI_ functionality. */ @@ -48,6 +49,7 @@ internal constructor( private val appCheckProvider: Provider, private val internalAuthProvider: Provider, private val onDeviceFactoryProvider: Provider, + private val userAgentPublisher: Provider, private val useLimitedUseAppCheckTokens: Boolean ) { @@ -148,6 +150,10 @@ internal constructor( this.onDeviceFactoryProvider = this@FirebaseAI.onDeviceFactoryProvider.get() this.internalAuthProvider = this@FirebaseAI.internalAuthProvider.get() this.appCheckTokenProvider = appCheckProvider.get() + val userAgent = userAgentPublisher.get()?.userAgent ?: "" + if (userAgent.isNotEmpty()) { + this.apiClient = "${this.apiClient} $userAgent" + } } .build() } @@ -166,6 +172,10 @@ internal constructor( toolConfig: TemplateToolConfig? = null, ): TemplateGenerativeModel { val templateUri = getTemplateUri(backend) + val baseApiClient = "gl-kotlin/${KotlinVersion.CURRENT}-ai fire/${BuildConfig.VERSION_NAME}" + val userAgent = userAgentPublisher.get()?.userAgent ?: "" + val apiClient = if (userAgent.isNotEmpty()) "$baseApiClient $userAgent" else baseApiClient + return TemplateGenerativeModel( templateUri, firebaseApp.options.apiKey, @@ -176,6 +186,7 @@ internal constructor( toolConfig, appCheckProvider.get(), internalAuthProvider.get(), + apiClient ) } @@ -210,6 +221,10 @@ internal constructor( .trimIndent(), ) } + val baseApiClient = "gl-kotlin/${KotlinVersion.CURRENT}-ai fire/${BuildConfig.VERSION_NAME}" + val userAgent = userAgentPublisher.get()?.userAgent ?: "" + val apiClient = if (userAgent.isNotEmpty()) "$baseApiClient $userAgent" else baseApiClient + return LiveGenerativeModel( when (backend.backend) { GenerativeBackendEnum.VERTEX_AI, @@ -230,6 +245,7 @@ internal constructor( internalAuthProvider.get(), backend, useLimitedUseAppCheckTokens, + apiClient ) } diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAIMultiResourceComponent.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAIMultiResourceComponent.kt index 076c7d64df3..043b99831f4 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAIMultiResourceComponent.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAIMultiResourceComponent.kt @@ -24,6 +24,7 @@ import com.google.firebase.annotations.concurrent.Blocking import com.google.firebase.appcheck.interop.InteropAppCheckTokenProvider import com.google.firebase.auth.internal.InternalAuthProvider import com.google.firebase.inject.Provider +import com.google.firebase.platforminfo.UserAgentPublisher import kotlin.coroutines.CoroutineContext /** @@ -36,7 +37,8 @@ internal class FirebaseAIMultiResourceComponent( @Blocking val blockingDispatcher: CoroutineContext, private val appCheckProvider: Provider, private val internalAuthProvider: Provider, - private val onDeviceFactoryProvider: Provider + private val onDeviceFactoryProvider: Provider, + private val userAgentPublisher: Provider ) { @GuardedBy("this") private val instances: MutableMap = mutableMapOf() @@ -51,6 +53,7 @@ internal class FirebaseAIMultiResourceComponent( appCheckProvider, internalAuthProvider, onDeviceFactoryProvider, + userAgentPublisher, key.useLimitedUseAppCheckTokens ) } diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAIRegistrar.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAIRegistrar.kt index 5ef82684269..b312c6f96d4 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAIRegistrar.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/FirebaseAIRegistrar.kt @@ -28,6 +28,7 @@ import com.google.firebase.components.Dependency import com.google.firebase.components.Qualified import com.google.firebase.components.Qualified.unqualified import com.google.firebase.platforminfo.LibraryVersionComponent +import com.google.firebase.platforminfo.UserAgentPublisher import kotlinx.coroutines.CoroutineDispatcher /** @@ -46,13 +47,15 @@ internal class FirebaseAIRegistrar : ComponentRegistrar { .add(Dependency.optionalProvider(appCheckInterop)) .add(Dependency.optionalProvider(internalAuthProvider)) .add(Dependency.optionalProvider(ondeviceInterop)) + .add(Dependency.optionalProvider(userAgentPublisher)) .factory { container -> FirebaseAIMultiResourceComponent( container[firebaseApp], container.get(blockingDispatcher), container.getProvider(appCheckInterop), container.getProvider(internalAuthProvider), - container.getProvider(ondeviceInterop) + container.getProvider(ondeviceInterop), + container.getProvider(userAgentPublisher) ) } .build(), @@ -66,6 +69,7 @@ internal class FirebaseAIRegistrar : ComponentRegistrar { private val appCheckInterop = unqualified(InteropAppCheckTokenProvider::class.java) private val internalAuthProvider = unqualified(InternalAuthProvider::class.java) private val ondeviceInterop = unqualified(FirebaseAIOnDeviceGenerativeModelFactory::class.java) + private val userAgentPublisher = unqualified(UserAgentPublisher::class.java) private val blockingDispatcher = Qualified.qualified(Blocking::class.java, CoroutineDispatcher::class.java) } diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/LiveGenerativeModel.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/LiveGenerativeModel.kt index 55e2008382a..3154d14d5ad 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/LiveGenerativeModel.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/LiveGenerativeModel.kt @@ -80,6 +80,7 @@ internal constructor( internalAuthProvider: InternalAuthProvider? = null, generativeBackend: GenerativeBackend, useLimitedUseAppCheckTokens: Boolean, + apiClient: String = "gl-kotlin/${KotlinVersion.CURRENT}-ai fire/${BuildConfig.VERSION_NAME}", ) : this( modelName, blockingDispatcher, @@ -92,7 +93,7 @@ internal constructor( apiKey, modelName, requestOptions, - "gl-kotlin/${KotlinVersion.CURRENT}-ai fire/${BuildConfig.VERSION_NAME}", + apiClient, firebaseApp, AppCheckHeaderProvider( TAG, diff --git a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/TemplateGenerativeModel.kt b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/TemplateGenerativeModel.kt index 5882902d0a2..fc41de5f434 100644 --- a/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/TemplateGenerativeModel.kt +++ b/ai-logic/firebase-ai/src/main/kotlin/com/google/firebase/ai/TemplateGenerativeModel.kt @@ -71,14 +71,15 @@ internal constructor( tools: List? = null, toolConfig: TemplateToolConfig? = null, appCheckTokenProvider: InteropAppCheckTokenProvider? = null, - internalAuthProvider: InternalAuthProvider? = null + internalAuthProvider: InternalAuthProvider? = null, + apiClient: String = "gl-kotlin/${KotlinVersion.CURRENT}-ai fire/${BuildConfig.VERSION_NAME}" ) : this( templateUri, APIController( apiKey, "", requestOptions, - "gl-kotlin/${KotlinVersion.CURRENT}-ai fire/${BuildConfig.VERSION_NAME}", + apiClient, firebaseApp, AppCheckHeaderProvider( TAG, From 3e11ba52b5ef514a61f952afef93d207208b1ec4 Mon Sep 17 00:00:00 2001 From: Mila <107142260+milaGGL@users.noreply.github.com> Date: Thu, 3 Sep 2026 11:40:09 -0400 Subject: [PATCH 2/2] Update FirebaseAI.kt --- .../kotlin/com/google/firebase/ai/FirebaseAI.kt | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 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 650dffc7670..a7d409158d2 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 @@ -150,9 +150,11 @@ internal constructor( this.onDeviceFactoryProvider = this@FirebaseAI.onDeviceFactoryProvider.get() this.internalAuthProvider = this@FirebaseAI.internalAuthProvider.get() this.appCheckTokenProvider = appCheckProvider.get() - val userAgent = userAgentPublisher.get()?.userAgent ?: "" - if (userAgent.isNotEmpty()) { - this.apiClient = "${this.apiClient} $userAgent" + val customUserAgents = userAgentPublisher.get()?.userAgent ?: "" + val adkUserAgent = + customUserAgents.split(' ').firstOrNull { it.startsWith("google-adk/") } ?: "" + if (adkUserAgent.isNotEmpty()) { + this.apiClient = "${this.apiClient} $adkUserAgent" } } .build() @@ -173,8 +175,10 @@ internal constructor( ): TemplateGenerativeModel { val templateUri = getTemplateUri(backend) val baseApiClient = "gl-kotlin/${KotlinVersion.CURRENT}-ai fire/${BuildConfig.VERSION_NAME}" - val userAgent = userAgentPublisher.get()?.userAgent ?: "" - val apiClient = if (userAgent.isNotEmpty()) "$baseApiClient $userAgent" else baseApiClient + val customUserAgents = userAgentPublisher.get()?.userAgent ?: "" + val adkUserAgent = + customUserAgents.split(' ').firstOrNull { it.startsWith("google-adk/") } ?: "" + val apiClient = if (adkUserAgent.isNotEmpty()) "$baseApiClient $adkUserAgent" else baseApiClient return TemplateGenerativeModel( templateUri,