Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions firebase-ai/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- [feature] Added support for configuring thinking levels with Gemini 3 series
mdels and onwards. (#7599)
- [changed] Added `LiveAudioConversationConfig` to control different aspects of the conversation
while using the `startAudioConversation` function.
- [fixed] Fixed an issue causing streaming chat interactions to drop thought signatures. (#7562)
Expand Down
12 changes: 12 additions & 0 deletions firebase-ai/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1289,12 +1289,24 @@ package com.google.firebase.ai.type {
method public com.google.firebase.ai.type.ThinkingConfig build();
method public com.google.firebase.ai.type.ThinkingConfig.Builder setIncludeThoughts(boolean includeThoughts);
method public com.google.firebase.ai.type.ThinkingConfig.Builder setThinkingBudget(int thinkingBudget);
method public com.google.firebase.ai.type.ThinkingConfig.Builder setThinkingLevel(com.google.firebase.ai.type.ThinkingLevel thinkingLevel);
}

public final class ThinkingConfigKt {
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);
}

public final class ThinkingLevel {
method public int getOrdinal();
property public final int ordinal;
field public static final com.google.firebase.ai.type.ThinkingLevel.Companion Companion;
field public static final com.google.firebase.ai.type.ThinkingLevel HIGH;
field public static final com.google.firebase.ai.type.ThinkingLevel LOW;
}

public static final class ThinkingLevel.Companion {
}

public final class Tool {
method public static com.google.firebase.ai.type.Tool codeExecution();
method public static com.google.firebase.ai.type.Tool functionDeclarations(java.util.List<com.google.firebase.ai.type.FunctionDeclaration> functionDeclarations);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ package com.google.firebase.ai.type
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/** Configuration parameters for thinking features. */
/**
* Gemini 2.5 series models and newer utilize a thinking process before generating a response. This
* allows them to reason through complex problems and plan a more coherent and accurate answer. See
* the [thinking documentation](https://firebase.google.com/docs/ai-logic/thinking) for more
* details.
*/
public class ThinkingConfig
private constructor(
internal val thinkingBudget: Int? = null,
internal val includeThoughts: Boolean? = null
internal val includeThoughts: Boolean? = null,
internal val thinkingLevel: ThinkingLevel? = null
) {

public class Builder() {
Expand All @@ -35,11 +41,20 @@ private constructor(
@set:JvmSynthetic // hide void setter from Java
public var includeThoughts: Boolean? = null

@JvmField
@set:JvmSynthetic // hide void setter from Java
public var thinkingLevel: ThinkingLevel? = null

/**
* Indicates the thinking budget in tokens. `0` is disabled. `-1` is dynamic. The default values
* and allowed ranges are model dependent.
* Indicates the thinking budget in tokens.
*
* Use `0` for disabled, and `-1` for dynamic. The range of
* [supported thinking budget values](https://firebase.google.com/docs/ai-logic/thinking#supported-thinking-budget-values)
* depends on the model.
*/
public fun setThinkingBudget(thinkingBudget: Int): Builder = apply {
if (thinkingLevel != null)
throw IllegalArgumentException("Cannot set both `thinkingBudget` and `thinkingLevel`")
this.thinkingBudget = thinkingBudget
}

Expand All @@ -55,16 +70,28 @@ private constructor(
this.includeThoughts = includeThoughts
}

/** Indicates the thinking budget based in Levels. */
public fun setThinkingLevel(thinkingLevel: ThinkingLevel): Builder = apply {
if (thinkingBudget != null)
throw IllegalArgumentException("Cannot set both `thinkingBudget` and `thinkingLevel`")
this.thinkingLevel = thinkingLevel
}

public fun build(): ThinkingConfig =
ThinkingConfig(thinkingBudget = thinkingBudget, includeThoughts = includeThoughts)
ThinkingConfig(
thinkingBudget = thinkingBudget,
includeThoughts = includeThoughts,
thinkingLevel = thinkingLevel
)
}

internal fun toInternal() = Internal(thinkingBudget, includeThoughts)
internal fun toInternal() = Internal(thinkingBudget, includeThoughts, thinkingLevel?.toInternal())

@Serializable
internal data class Internal(
@SerialName("thinking_budget") val thinkingBudget: Int? = null,
val includeThoughts: Boolean? = null
val includeThoughts: Boolean? = null,
@SerialName("thinking_level") val thinkingLevel: ThinkingLevel.Internal? = null,
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.SerialName
import kotlinx.serialization.Serializable

/** Specifies the quality of the thinking response. */
public class ThinkingLevel private constructor(public val ordinal: Int) {
internal fun toInternal() =
when (this) {
LOW -> Internal.LOW
HIGH -> Internal.HIGH
else -> throw makeMissingCaseException("ThinkingLevel", ordinal)
}

@Serializable
internal enum class Internal {
@SerialName("THINKING_LEVEL_UNSPECIFIED") UNSPECIFIED,
LOW,
HIGH,
}
public companion object {
/** A lower quality thinking response, which provides low latency. */
@JvmField public val LOW: ThinkingLevel = ThinkingLevel(0)

/** A higher quality thinking response, which may increase latency. */
@JvmField public val HIGH: ThinkingLevel = ThinkingLevel(1)
}
}
Loading