Skip to content
4 changes: 4 additions & 0 deletions firebase-ai/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
- [changed] Added support for input and output transcription. (#7482)
- [feature] Added support for sending realtime audio and video in a `LiveSession`.
- [changed] Removed redundant internal exception types. (#7475)
- [feature] Added support for configuring the aspect ratio when generating images with the Gemini
2.5 Flash Image model.
- [feature] Added `FinishReason.IMAGE_PROHIBITED_CONTENT` and `FinishReason.NO_IMAGE`, which can be
returned from Gemini image generation.

# 17.4.0

Expand Down
35 changes: 35 additions & 0 deletions firebase-ai/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,23 @@ package com.google.firebase.ai.type {
public final class APINotConfiguredException extends com.google.firebase.ai.type.FirebaseAIException {
}

public final class AspectRatio {
field public static final com.google.firebase.ai.type.AspectRatio.Companion Companion;
field public static final com.google.firebase.ai.type.AspectRatio LANDSCAPE_16x9;
field public static final com.google.firebase.ai.type.AspectRatio LANDSCAPE_21x9;
field public static final com.google.firebase.ai.type.AspectRatio LANDSCAPE_3x2;
field public static final com.google.firebase.ai.type.AspectRatio LANDSCAPE_4x3;
field public static final com.google.firebase.ai.type.AspectRatio LANDSCAPE_5x4;
field public static final com.google.firebase.ai.type.AspectRatio PORTRAIT_2x3;
field public static final com.google.firebase.ai.type.AspectRatio PORTRAIT_3x4;
field public static final com.google.firebase.ai.type.AspectRatio PORTRAIT_4x5;
field public static final com.google.firebase.ai.type.AspectRatio PORTRAIT_9x16;
field public static final com.google.firebase.ai.type.AspectRatio SQUARE_1x1;
}

public static final class AspectRatio.Companion {
}

public final class AudioRecordInitializationFailedException extends com.google.firebase.ai.type.FirebaseAIException {
ctor public AudioRecordInitializationFailedException(String message);
}
Expand Down Expand Up @@ -337,8 +354,11 @@ package com.google.firebase.ai.type {
property public final int ordinal;
field public static final com.google.firebase.ai.type.FinishReason BLOCKLIST;
field public static final com.google.firebase.ai.type.FinishReason.Companion Companion;
field public static final com.google.firebase.ai.type.FinishReason IMAGE_PROHIBITED_CONTENT;
field public static final com.google.firebase.ai.type.FinishReason IMAGE_SAFETY;
field public static final com.google.firebase.ai.type.FinishReason MALFORMED_FUNCTION_CALL;
field public static final com.google.firebase.ai.type.FinishReason MAX_TOKENS;
field public static final com.google.firebase.ai.type.FinishReason NO_IMAGE;
field public static final com.google.firebase.ai.type.FinishReason OTHER;
field public static final com.google.firebase.ai.type.FinishReason PROHIBITED_CONTENT;
field public static final com.google.firebase.ai.type.FinishReason RECITATION;
Expand Down Expand Up @@ -426,6 +446,7 @@ package com.google.firebase.ai.type {
method public com.google.firebase.ai.type.GenerationConfig build();
method public com.google.firebase.ai.type.GenerationConfig.Builder setCandidateCount(Integer? candidateCount);
method public com.google.firebase.ai.type.GenerationConfig.Builder setFrequencyPenalty(Float? frequencyPenalty);
method public com.google.firebase.ai.type.GenerationConfig.Builder setImageConfig(com.google.firebase.ai.type.ImageConfig? imageConfig);
method public com.google.firebase.ai.type.GenerationConfig.Builder setMaxOutputTokens(Integer? maxOutputTokens);
method public com.google.firebase.ai.type.GenerationConfig.Builder setPresencePenalty(Float? presencePenalty);
method public com.google.firebase.ai.type.GenerationConfig.Builder setResponseMimeType(String? responseMimeType);
Expand All @@ -438,6 +459,7 @@ package com.google.firebase.ai.type {
method public com.google.firebase.ai.type.GenerationConfig.Builder setTopP(Float? topP);
field public Integer? candidateCount;
field public Float? frequencyPenalty;
field public com.google.firebase.ai.type.ImageConfig? imageConfig;
field public Integer? maxOutputTokens;
field public Float? presencePenalty;
field public String? responseMimeType;
Expand Down Expand Up @@ -585,6 +607,19 @@ package com.google.firebase.ai.type {
public static final class HarmSeverity.Companion {
}

public final class ImageConfig {
}

public static final class ImageConfig.Builder {
ctor public ImageConfig.Builder();
method public com.google.firebase.ai.type.ImageConfig build();
method public com.google.firebase.ai.type.ImageConfig.Builder setAspectRatio(com.google.firebase.ai.type.AspectRatio? aspectRatio);
}

public final class ImageConfigKt {
method public static com.google.firebase.ai.type.ImageConfig imageConfig(kotlin.jvm.functions.Function1<? super com.google.firebase.ai.type.ImageConfig.Builder,kotlin.Unit> init);
}

public final class ImagePart implements com.google.firebase.ai.type.Part {
ctor public ImagePart(android.graphics.Bitmap image);
method public android.graphics.Bitmap getImage();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2024 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

/** Represents the aspect ratio that the generated image should conform to. */
public class AspectRatio private constructor(internal val internalVal: String) {
public companion object {
/** A square image, useful for icons, profile pictures, etc. */
@JvmField public val SQUARE_1x1: AspectRatio = AspectRatio("1:1")
/** A portrait image in 3:4, the aspect ratio of older TVs. */
@JvmField public val PORTRAIT_3x4: AspectRatio = AspectRatio("3:4")
/** A landscape image in 4:3, the aspect ratio of older TVs. */
@JvmField public val LANDSCAPE_4x3: AspectRatio = AspectRatio("4:3")
/** A portrait image in 9:16, the aspect ratio of modern monitors and phone screens. */
@JvmField public val PORTRAIT_9x16: AspectRatio = AspectRatio("9:16")
/** A landscape image in 16:9, the aspect ratio of modern monitors and phone screens. */
@JvmField public val LANDSCAPE_16x9: AspectRatio = AspectRatio("16:9")
/** A portrait image in 4:5, the aspect ratio for prints from digital cameras. */
@JvmField public val PORTRAIT_4x5: AspectRatio = AspectRatio("4:5")
/** A landscape image in 5:4, the aspect ratio for prints from digital cameras. */
@JvmField public val LANDSCAPE_5x4: AspectRatio = AspectRatio("5:4")
/** A portrait image in 4:5, the aspect ratio for prints from 35mm film cameras. */
@JvmField public val PORTRAIT_2x3: AspectRatio = AspectRatio("2:3")
/** A landscape image in 4:5, the aspect ratio for prints from 35mm film cameras. */
@JvmField public val LANDSCAPE_3x2: AspectRatio = AspectRatio("3:2")
/** A ultrawide image in 21:9, an aspect ratio commonly used in modern movies. */
@JvmField public val LANDSCAPE_21x9: AspectRatio = AspectRatio("21:9")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,10 @@ public class FinishReason private constructor(public val name: String, public va
BLOCKLIST,
PROHIBITED_CONTENT,
SPII,
MALFORMED_FUNCTION_CALL;
MALFORMED_FUNCTION_CALL,
IMAGE_SAFETY,
IMAGE_PROHIBITED_CONTENT,
NO_IMAGE;

internal object Serializer : KSerializer<Internal> by FirstOrdinalSerializer(Internal::class)

Expand All @@ -262,6 +265,9 @@ public class FinishReason private constructor(public val name: String, public va
PROHIBITED_CONTENT -> FinishReason.PROHIBITED_CONTENT
SPII -> FinishReason.SPII
MALFORMED_FUNCTION_CALL -> FinishReason.MALFORMED_FUNCTION_CALL
IMAGE_SAFETY -> FinishReason.IMAGE_SAFETY
IMAGE_PROHIBITED_CONTENT -> FinishReason.IMAGE_PROHIBITED_CONTENT
NO_IMAGE -> FinishReason.NO_IMAGE
else -> FinishReason.UNKNOWN
}
}
Expand Down Expand Up @@ -301,6 +307,16 @@ public class FinishReason private constructor(public val name: String, public va
/** The function call generated by the model is invalid. */
@JvmField
public val MALFORMED_FUNCTION_CALL: FinishReason = FinishReason("MALFORMED_FUNCTION_CALL", 9)

/** Token generation stopped because generated images has safety violations. */
@JvmField public val IMAGE_SAFETY: FinishReason = FinishReason("IMAGE_SAFETY", 10)

/** Image generation stopped because generated images has other prohibited content. */
@JvmField
public val IMAGE_PROHIBITED_CONTENT: FinishReason = FinishReason("IMAGE_PROHIBITED_CONTENT", 11)

/** The model was expected to generate an image, but none was generated. */
@JvmField public val NO_IMAGE: FinishReason = FinishReason("NO_IMAGE", 12)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ private constructor(
internal val responseSchema: Schema?,
internal val responseModalities: List<ResponseModality>?,
internal val thinkingConfig: ThinkingConfig?,
internal val imageConfig: ImageConfig?,
) {

/**
Expand Down Expand Up @@ -137,6 +138,7 @@ private constructor(
@JvmField public var responseSchema: Schema? = null
@JvmField public var responseModalities: List<ResponseModality>? = null
@JvmField public var thinkingConfig: ThinkingConfig? = null
@JvmField public var imageConfig: ImageConfig? = null

public fun setTemperature(temperature: Float?): Builder = apply {
this.temperature = temperature
Expand Down Expand Up @@ -170,6 +172,9 @@ private constructor(
public fun setThinkingConfig(thinkingConfig: ThinkingConfig?): Builder = apply {
this.thinkingConfig = thinkingConfig
}
public fun setImageConfig(imageConfig: ImageConfig?): Builder = apply {
this.imageConfig = imageConfig
}

/** Create a new [GenerationConfig] with the attached arguments. */
public fun build(): GenerationConfig =
Expand All @@ -185,7 +190,8 @@ private constructor(
responseMimeType = responseMimeType,
responseSchema = responseSchema,
responseModalities = responseModalities,
thinkingConfig = thinkingConfig
thinkingConfig = thinkingConfig,
imageConfig = imageConfig
)
}

Expand All @@ -202,7 +208,8 @@ private constructor(
responseMimeType = responseMimeType,
responseSchema = responseSchema?.toInternalOpenApi(),
responseModalities = responseModalities?.map { it.toInternal() },
thinkingConfig = thinkingConfig?.toInternal()
thinkingConfig = thinkingConfig?.toInternal(),
imageConfig = imageConfig?.toInternal()
)

@Serializable
Expand All @@ -218,7 +225,8 @@ private constructor(
@SerialName("frequency_penalty") val frequencyPenalty: Float? = null,
@SerialName("response_schema") val responseSchema: Schema.InternalOpenAPI? = null,
@SerialName("response_modalities") val responseModalities: List<String>? = null,
@SerialName("thinking_config") val thinkingConfig: ThinkingConfig.Internal? = null
@SerialName("thinking_config") val thinkingConfig: ThinkingConfig.Internal? = null,
@SerialName("image_config") val imageConfig: ImageConfig.Internal? = null
)

public companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2024 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

/**
* Configuration parameters to use for image generation.
*
* @property aspectRatio The aspect ratio of the generated image.
*/
public class ImageConfig internal constructor(internal val aspectRatio: AspectRatio?) {

/**
* Builder for creating an [ImageConfig].
*
* Mainly intended for Java interop. Kotlin consumers should use [imageConfig] for a more
* idiomatic experience.
*
* @property aspectRatio See [ImageConfig.aspectRatio].
* @see [imageConfig]
*/
public class Builder {
@JvmField
@set:JvmSynthetic // hide void setter from Java
public var aspectRatio: AspectRatio? = null

public fun setAspectRatio(aspectRatio: AspectRatio?): Builder = apply {
this.aspectRatio = aspectRatio
}

/** Create a new [ImageConfig] with the attached arguments. */
public fun build(): ImageConfig = ImageConfig(aspectRatio = aspectRatio)
}

internal fun toInternal() = Internal(aspectRatio = aspectRatio?.internalVal)

@Serializable internal data class Internal(val aspectRatio: String?)
}

/**
* Helper method to construct an [ImageConfig] in a DSL-like manner.
*
* Example Usage:
* ```
* imageConfig {
* aspectRatio = AspectRatio.LANDSCAPE_16x9
* }
* ```
*/
public fun imageConfig(init: ImageConfig.Builder.() -> Unit): ImageConfig {
val builder = ImageConfig.Builder()
builder.init()
return builder.build()
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,12 @@ internal class SerializationTests {
"BLOCKLIST",
"PROHIBITED_CONTENT",
"SPII",
"MALFORMED_FUNCTION_CALL"
"MALFORMED_FUNCTION_CALL",
"IMAGE_SAFETY",
"IMAGE_PROHIBITED_CONTENT",
"IMAGE_RECITATION",
"IMAGE_OTHER",
"NO_IMAGE"
]
},
"safetyRatings": {
Expand Down
Loading