Skip to content

Commit cf37e62

Browse files
authored
Merge 80deba1 into 4e027a9
2 parents 4e027a9 + 80deba1 commit cf37e62

File tree

6 files changed

+138
-4
lines changed

6 files changed

+138
-4
lines changed

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+
* [feat] Added support for setting thinking budget for the Gemini models that support it. (#6990)
34
* [fixed] Fixed `FirebaseAI.getInstance` StackOverflowException (#6971)
45
* [fixed] Fixed an issue that was causing the SDK to send empty `FunctionDeclaration` descriptions to the API.
56

firebase-ai/api.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ package com.google.firebase.ai.type {
362362
method public com.google.firebase.ai.type.GenerationConfig.Builder setResponseSchema(com.google.firebase.ai.type.Schema? responseSchema);
363363
method public com.google.firebase.ai.type.GenerationConfig.Builder setStopSequences(java.util.List<java.lang.String>? stopSequences);
364364
method public com.google.firebase.ai.type.GenerationConfig.Builder setTemperature(Float? temperature);
365+
method public com.google.firebase.ai.type.GenerationConfig.Builder setThinkingConfig(com.google.firebase.ai.type.ThinkingConfig? thinkingConfig);
365366
method public com.google.firebase.ai.type.GenerationConfig.Builder setTopK(Integer? topK);
366367
method public com.google.firebase.ai.type.GenerationConfig.Builder setTopP(Float? topP);
367368
field public Integer? candidateCount;
@@ -373,6 +374,7 @@ package com.google.firebase.ai.type {
373374
field public com.google.firebase.ai.type.Schema? responseSchema;
374375
field public java.util.List<java.lang.String>? stopSequences;
375376
field public Float? temperature;
377+
field public com.google.firebase.ai.type.ThinkingConfig? thinkingConfig;
376378
field public Integer? topK;
377379
field public Float? topP;
378380
}
@@ -881,6 +883,23 @@ package com.google.firebase.ai.type {
881883
property public final String text;
882884
}
883885

886+
public final class ThinkingConfig {
887+
ctor public ThinkingConfig(Integer? thinkingBudget);
888+
method public Integer? getThinkingBudget();
889+
property public final Integer? thinkingBudget;
890+
}
891+
892+
public static final class ThinkingConfig.Builder {
893+
ctor public ThinkingConfig.Builder();
894+
method public com.google.firebase.ai.type.ThinkingConfig build();
895+
method public com.google.firebase.ai.type.ThinkingConfig.Builder setThinkingBudget(Integer? thinkingBudget);
896+
field public Integer? thinkingBudget;
897+
}
898+
899+
public final class ThinkingConfigKt {
900+
method public static com.google.firebase.ai.type.ThinkingConfig thinkingConfig(kotlin.jvm.functions.Function1<? super com.google.firebase.ai.type.ThinkingConfig.Builder,kotlin.Unit> init);
901+
}
902+
884903
public final class Tool {
885904
method public static com.google.firebase.ai.type.Tool functionDeclarations(java.util.List<com.google.firebase.ai.type.FunctionDeclaration> functionDeclarations);
886905
field public static final com.google.firebase.ai.type.Tool.Companion Companion;

firebase-ai/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
version=16.0.1
15+
version=16.1.0
1616
latestReleasedVersion=16.0.0

firebase-ai/src/main/kotlin/com/google/firebase/ai/type/GenerationConfig.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ private constructor(
9191
internal val responseMimeType: String?,
9292
internal val responseSchema: Schema?,
9393
internal val responseModalities: List<ResponseModality>?,
94+
internal val thinkingConfig: ThinkingConfig?,
9495
) {
9596

9697
/**
@@ -135,6 +136,7 @@ private constructor(
135136
@JvmField public var responseMimeType: String? = null
136137
@JvmField public var responseSchema: Schema? = null
137138
@JvmField public var responseModalities: List<ResponseModality>? = null
139+
@JvmField public var thinkingConfig: ThinkingConfig? = null
138140

139141
public fun setTemperature(temperature: Float?): Builder = apply {
140142
this.temperature = temperature
@@ -165,6 +167,9 @@ private constructor(
165167
public fun setResponseModalities(responseModalities: List<ResponseModality>?): Builder = apply {
166168
this.responseModalities = responseModalities
167169
}
170+
public fun setThinkingConfig(thinkingConfig: ThinkingConfig?): Builder = apply {
171+
this.thinkingConfig = thinkingConfig
172+
}
168173

169174
/** Create a new [GenerationConfig] with the attached arguments. */
170175
public fun build(): GenerationConfig =
@@ -179,7 +184,8 @@ private constructor(
179184
frequencyPenalty = frequencyPenalty,
180185
responseMimeType = responseMimeType,
181186
responseSchema = responseSchema,
182-
responseModalities = responseModalities
187+
responseModalities = responseModalities,
188+
thinkingConfig = thinkingConfig
183189
)
184190
}
185191

@@ -195,7 +201,8 @@ private constructor(
195201
presencePenalty = presencePenalty,
196202
responseMimeType = responseMimeType,
197203
responseSchema = responseSchema?.toInternal(),
198-
responseModalities = responseModalities?.map { it.toInternal() }
204+
responseModalities = responseModalities?.map { it.toInternal() },
205+
thinkingConfig = thinkingConfig?.toInternal()
199206
)
200207

201208
@Serializable
@@ -210,7 +217,8 @@ private constructor(
210217
@SerialName("presence_penalty") val presencePenalty: Float? = null,
211218
@SerialName("frequency_penalty") val frequencyPenalty: Float? = null,
212219
@SerialName("response_schema") val responseSchema: Schema.Internal? = null,
213-
@SerialName("response_modalities") val responseModalities: List<String>? = null
220+
@SerialName("response_modalities") val responseModalities: List<String>? = null,
221+
@SerialName("thinking_config") val thinkingConfig: ThinkingConfig.Internal? = null
214222
)
215223

216224
public companion object {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.ai.type
18+
19+
import kotlinx.serialization.SerialName
20+
import kotlinx.serialization.Serializable
21+
22+
/** Configuration parameters for thinking features. */
23+
public class ThinkingConfig(public val thinkingBudget: Int?) {
24+
25+
public class Builder() {
26+
@JvmField public var thinkingBudget: Int? = null
27+
28+
/** The number of thoughts tokens that the model should generate. */
29+
public fun setThinkingBudget(thinkingBudget: Int?): Builder = apply {
30+
this.thinkingBudget = thinkingBudget
31+
}
32+
33+
public fun build(): ThinkingConfig = ThinkingConfig(thinkingBudget = thinkingBudget)
34+
}
35+
36+
internal fun toInternal() = Internal(thinkingBudget)
37+
38+
@Serializable
39+
internal data class Internal(@SerialName("thinking_budget") val thinkingBudget: Int?)
40+
}
41+
42+
/**
43+
* Helper method to construct a [ThinkingConfig] in a DSL-like manner.
44+
*
45+
* Example Usage:
46+
* ```
47+
* thinkingConfig {
48+
* thinkingBudget = 0 // disable thinking
49+
* }
50+
* ```
51+
*/
52+
public fun thinkingConfig(init: ThinkingConfig.Builder.() -> Unit): ThinkingConfig {
53+
val builder = ThinkingConfig.Builder()
54+
builder.init()
55+
return builder.build()
56+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.firebase.ai.type
18+
19+
import io.kotest.assertions.json.shouldEqualJson
20+
import io.kotest.matchers.equals.shouldBeEqual
21+
import kotlinx.serialization.encodeToString
22+
import kotlinx.serialization.json.Json
23+
import org.junit.Test
24+
25+
internal class ThinkingConfigTest {
26+
27+
@Test
28+
fun `Basic ThinkingConfig`() {
29+
val thinkingConfig = ThinkingConfig.Builder().setThinkingBudget(1024).build()
30+
31+
val expectedJson =
32+
"""
33+
{
34+
"thinking_budget": 1024
35+
}
36+
"""
37+
.trimIndent()
38+
39+
Json.encodeToString(thinkingConfig.toInternal()).shouldEqualJson(expectedJson)
40+
}
41+
42+
@Test
43+
fun `thinkingConfig DSL correctly delegates to ThinkingConfig#Builder`() {
44+
val thinkingConfig = ThinkingConfig.Builder().setThinkingBudget(1024).build()
45+
46+
val thinkingConfigDsl = thinkingConfig { thinkingBudget = 1024 }
47+
48+
thinkingConfig.thinkingBudget?.shouldBeEqual(thinkingConfigDsl.thinkingBudget as Int)
49+
}
50+
}

0 commit comments

Comments
 (0)