Skip to content

Commit 21831fd

Browse files
authored
Add model version to GenerateContent Output (#8227)
This PR adds to the Firebase Android SDK's `GenerateContentResponse` object the output-only `modelVersion` string field, which enables developers to identify the exact version of the model that performed the inference. This pr also updated the script to take in a branch name argument to get the test data in.
1 parent 36b3e5b commit 21831fd

18 files changed

Lines changed: 64 additions & 15 deletions

File tree

ai-logic/firebase-ai-ondevice-interop/api.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,11 @@ package com.google.firebase.ai.ondevice.interop {
9898

9999
public final class GenerateContentResponse {
100100
ctor public GenerateContentResponse(java.util.List<com.google.firebase.ai.ondevice.interop.Candidate> candidates);
101+
ctor public GenerateContentResponse(java.util.List<com.google.firebase.ai.ondevice.interop.Candidate> candidates, String? modelVersion = null);
101102
method public java.util.List<com.google.firebase.ai.ondevice.interop.Candidate> getCandidates();
103+
method public String? getModelVersion();
102104
property public final java.util.List<com.google.firebase.ai.ondevice.interop.Candidate> candidates;
105+
property public final String? modelVersion;
103106
}
104107

105108
public final class GenerationConfig {

ai-logic/firebase-ai-ondevice-interop/src/main/kotlin/com/google/firebase/ai/ondevice/interop/GenerateContentResponse.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,8 @@ package com.google.firebase.ai.ondevice.interop
2020
* Represents a content generation response from the model.
2121
*
2222
* @property candidates The individual responses from the model.
23+
* @property modelVersion The version of the model that generated the response.
2324
*/
24-
public class GenerateContentResponse(public val candidates: List<Candidate>) {}
25+
public class GenerateContentResponse
26+
@JvmOverloads
27+
constructor(public val candidates: List<Candidate>, public val modelVersion: String? = null) {}

ai-logic/firebase-ai-ondevice/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Unreleased
22

3+
- [feature] Added `modelVersion` property to `GenerateContentResponse` (#8227)
4+
35
# 16.0.0-beta02
46

57
- [feature] Added support for model selection, required for nano-v4. (#8043)

ai-logic/firebase-ai-ondevice/firebase-ai-ondevice.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ kotlin {
6868

6969
dependencies {
7070
implementation(libs.genai.prompt)
71-
implementation("com.google.firebase:firebase-ai-ondevice-interop:16.0.0-beta02")
71+
implementation(project(":ai-logic:firebase-ai-ondevice-interop"))
7272

7373
implementation(libs.firebase.common)
7474
implementation(libs.firebase.components)

ai-logic/firebase-ai-ondevice/src/main/kotlin/com/google/firebase/ai/ondevice/Converters.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ internal fun com.google.firebase.ai.ondevice.interop.GenerateContentRequest.toMl
8080
}
8181
}
8282

83-
internal fun com.google.mlkit.genai.prompt.GenerateContentResponse.toInterop():
84-
GenerateContentResponse = GenerateContentResponse(candidates.map { it.toInterop() })
83+
internal fun com.google.mlkit.genai.prompt.GenerateContentResponse.toInterop(
84+
modelName: String
85+
): GenerateContentResponse = GenerateContentResponse(candidates.map { it.toInterop() }, modelName)
8586

8687
// ================================================
8788
// `GenerationConfig` converter extension functions

ai-logic/firebase-ai-ondevice/src/main/kotlin/com/google/firebase/ai/ondevice/GenerativeModelImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ internal class GenerativeModelImpl(
4848
override suspend fun generateContent(request: GenerateContentRequest): GenerateContentResponse =
4949
try {
5050
val response = mlkitModel.generateContent(request.toMlKit())
51-
response.toInterop()
51+
response.toInterop(mlkitModel.getBaseModelName())
5252
} catch (e: GenAiException) {
5353
throw getMappingException(e)
5454
}
@@ -67,7 +67,7 @@ internal class GenerativeModelImpl(
6767
return mlkitModel
6868
.generateContentStream(request.toMlKit())
6969
.catch { throw getMappingException(it) }
70-
.map { it.toInterop() }
70+
.map { it.toInterop(mlkitModel.getBaseModelName()) }
7171
}
7272

7373
override suspend fun getBaseModelName(): String = mlkitModel.getBaseModelName()

ai-logic/firebase-ai-ondevice/src/test/kotlin/com/google/firebase/ai/ondevice/ConvertersTest.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,22 @@ internal class ConvertersTest {
103103
assertThat(mlKitRequest.candidateCount).isEqualTo(1)
104104
assertThat(mlKitRequest.maxOutputTokens).isEqualTo(256)
105105
}
106+
107+
@Test
108+
fun `GenerateContentResponse toInterop should convert correctly and populate modelVersion`() {
109+
val mlKitCandidate =
110+
mock(Candidate::class.java).apply {
111+
`when`(text).thenReturn("hello")
112+
`when`(finishReason).thenReturn(Candidate.FinishReason.STOP)
113+
}
114+
val mlKitResponse =
115+
mock(com.google.mlkit.genai.prompt.GenerateContentResponse::class.java).apply {
116+
`when`(candidates).thenReturn(listOf(mlKitCandidate))
117+
}
118+
val interopResponse = mlKitResponse.toInterop("gemini-3.1-flash-lite")
119+
120+
assertThat(interopResponse.candidates.size).isEqualTo(1)
121+
assertThat(interopResponse.candidates[0].text).isEqualTo("hello")
122+
assertThat(interopResponse.modelVersion).isEqualTo("gemini-3.1-flash-lite")
123+
}
106124
}

ai-logic/firebase-ai-ondevice/src/test/kotlin/com/google/firebase/ai/ondevice/GenerativeModelImplTest.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class GenerativeModelImplTest {
6868
fun `generateContent should return converted response`() = runTest {
6969
val mlkitModel =
7070
mockk<MlKitGenerativeModel> {
71+
coEvery { getBaseModelName() } returns "gemini-3.1-flash-lite"
7172
coEvery { generateContent(any<MlKitGenerateContentRequest>()) } returns
7273
mockk {
7374
every { candidates } returns
@@ -111,6 +112,7 @@ class GenerativeModelImplTest {
111112
fun `generateContentStream should emit converted responses`() = runTest {
112113
val mlkitModel =
113114
mockk<MlKitGenerativeModel> {
115+
coEvery { getBaseModelName() } returns "gemini-3.1-flash-lite"
114116
coEvery { generateContentStream(any<MlKitGenerateContentRequest>()) } returns
115117
flowOf(
116118
mockk {

ai-logic/firebase-ai/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Unreleased
22

3+
- [feature] Added `modelVersion` property to `GenerateContentResponse` (#8227)
34
- [feature] Added [firebase_app_check] as a dependency of the SDK (#8225)
45

56
# 17.12.1

ai-logic/firebase-ai/api.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,7 @@ package com.google.firebase.ai.type {
679679
method public java.util.List<com.google.firebase.ai.type.FunctionCallPart> getFunctionCalls();
680680
method public com.google.firebase.ai.InferenceSource getInferenceSource();
681681
method public java.util.List<com.google.firebase.ai.type.InlineDataPart> getInlineDataParts();
682+
method public String? getModelVersion();
682683
method public com.google.firebase.ai.type.PromptFeedback? getPromptFeedback();
683684
method public String? getText();
684685
method public String? getThoughtSummary();
@@ -687,6 +688,7 @@ package com.google.firebase.ai.type {
687688
property public final java.util.List<com.google.firebase.ai.type.FunctionCallPart> functionCalls;
688689
property public final com.google.firebase.ai.InferenceSource inferenceSource;
689690
property public final java.util.List<com.google.firebase.ai.type.InlineDataPart> inlineDataParts;
691+
property public final String? modelVersion;
690692
property public final com.google.firebase.ai.type.PromptFeedback? promptFeedback;
691693
property public final String? text;
692694
property public final String? thoughtSummary;

0 commit comments

Comments
 (0)