diff --git a/src/main/java/com/google/genai/interactions/models/interactions/Usage.kt b/src/main/java/com/google/genai/interactions/models/interactions/Usage.kt index 84255fd42c8..0cc13a41d3d 100644 --- a/src/main/java/com/google/genai/interactions/models/interactions/Usage.kt +++ b/src/main/java/com/google/genai/interactions/models/interactions/Usage.kt @@ -40,6 +40,7 @@ class Usage @JsonCreator(mode = JsonCreator.Mode.DISABLED) private constructor( private val cachedTokensByModality: JsonField>, + private val groundingToolCountByCategory: JsonField>, private val inputTokensByModality: JsonField>, private val outputTokensByModality: JsonField>, private val toolUseTokensByModality: JsonField>, @@ -57,6 +58,10 @@ private constructor( @JsonProperty("cached_tokens_by_modality") @ExcludeMissing cachedTokensByModality: JsonField> = JsonMissing.of(), + @JsonProperty("grounding_tool_count_by_category") + @ExcludeMissing + groundingToolCountByCategory: JsonField> = + JsonMissing.of(), @JsonProperty("input_tokens_by_modality") @ExcludeMissing inputTokensByModality: JsonField> = JsonMissing.of(), @@ -86,6 +91,7 @@ private constructor( totalToolUseTokens: JsonField = JsonMissing.of(), ) : this( cachedTokensByModality, + groundingToolCountByCategory, inputTokensByModality, outputTokensByModality, toolUseTokensByModality, @@ -107,6 +113,15 @@ private constructor( fun cachedTokensByModality(): Optional> = cachedTokensByModality.getOptional("cached_tokens_by_modality") + /** + * A breakdown of tool usage count by category. + * + * @throws GeminiNextGenApiInvalidDataException if the JSON field has an unexpected type (e.g. + * if the server responded with an unexpected value). + */ + fun groundingToolCountByCategory(): Optional> = + groundingToolCountByCategory.getOptional("grounding_tool_count_by_category") + /** * A breakdown of input token usage by modality. * @@ -193,6 +208,17 @@ private constructor( @ExcludeMissing fun _cachedTokensByModality(): JsonField> = cachedTokensByModality + /** + * Returns the raw JSON value of [groundingToolCountByCategory]. + * + * Unlike [groundingToolCountByCategory], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("grounding_tool_count_by_category") + @ExcludeMissing + fun _groundingToolCountByCategory(): JsonField> = + groundingToolCountByCategory + /** * Returns the raw JSON value of [inputTokensByModality]. * @@ -303,6 +329,9 @@ private constructor( class Builder internal constructor() { private var cachedTokensByModality: JsonField>? = null + private var groundingToolCountByCategory: + JsonField>? = + null private var inputTokensByModality: JsonField>? = null private var outputTokensByModality: JsonField>? = null private var toolUseTokensByModality: JsonField>? = null @@ -317,6 +346,8 @@ private constructor( @JvmSynthetic internal fun from(usage: Usage) = apply { cachedTokensByModality = usage.cachedTokensByModality.map { it.toMutableList() } + groundingToolCountByCategory = + usage.groundingToolCountByCategory.map { it.toMutableList() } inputTokensByModality = usage.inputTokensByModality.map { it.toMutableList() } outputTokensByModality = usage.outputTokensByModality.map { it.toMutableList() } toolUseTokensByModality = usage.toolUseTokensByModality.map { it.toMutableList() } @@ -358,6 +389,39 @@ private constructor( } } + /** A breakdown of tool usage count by category. */ + fun groundingToolCountByCategory( + groundingToolCountByCategory: List + ) = groundingToolCountByCategory(JsonField.of(groundingToolCountByCategory)) + + /** + * Sets [Builder.groundingToolCountByCategory] to an arbitrary JSON value. + * + * You should usually call [Builder.groundingToolCountByCategory] with a well-typed + * `List` value instead. This method is primarily for setting + * the field to an undocumented or not yet supported value. + */ + fun groundingToolCountByCategory( + groundingToolCountByCategory: JsonField> + ) = apply { + this.groundingToolCountByCategory = + groundingToolCountByCategory.map { it.toMutableList() } + } + + /** + * Adds a single [GroundingToolCountByCategory] to [Builder.groundingToolCountByCategory]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addGroundingToolCountByCategory( + groundingToolCountByCategory: GroundingToolCountByCategory + ) = apply { + this.groundingToolCountByCategory = + (this.groundingToolCountByCategory ?: JsonField.of(mutableListOf())).also { + checkKnown("groundingToolCountByCategory", it).add(groundingToolCountByCategory) + } + } + /** A breakdown of input token usage by modality. */ fun inputTokensByModality(inputTokensByModality: List) = inputTokensByModality(JsonField.of(inputTokensByModality)) @@ -560,6 +624,7 @@ private constructor( fun build(): Usage = Usage( (cachedTokensByModality ?: JsonMissing.of()).map { it.toImmutable() }, + (groundingToolCountByCategory ?: JsonMissing.of()).map { it.toImmutable() }, (inputTokensByModality ?: JsonMissing.of()).map { it.toImmutable() }, (outputTokensByModality ?: JsonMissing.of()).map { it.toImmutable() }, (toolUseTokensByModality ?: JsonMissing.of()).map { it.toImmutable() }, @@ -581,6 +646,7 @@ private constructor( } cachedTokensByModality().ifPresent { it.forEach { it.validate() } } + groundingToolCountByCategory().ifPresent { it.forEach { it.validate() } } inputTokensByModality().ifPresent { it.forEach { it.validate() } } outputTokensByModality().ifPresent { it.forEach { it.validate() } } toolUseTokensByModality().ifPresent { it.forEach { it.validate() } } @@ -609,6 +675,8 @@ private constructor( @JvmSynthetic internal fun validity(): Int = (cachedTokensByModality.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (groundingToolCountByCategory.asKnown().getOrNull()?.sumOf { it.validity().toInt() } + ?: 0) + (inputTokensByModality.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (outputTokensByModality.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + (toolUseTokensByModality.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + @@ -951,6 +1019,341 @@ private constructor( "CachedTokensByModality{modality=$modality, tokens=$tokens, additionalProperties=$additionalProperties}" } + /** The number of calls by a single tool category. */ + class GroundingToolCountByCategory + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val count: JsonField, + private val toolCategory: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("count") @ExcludeMissing count: JsonField = JsonMissing.of(), + @JsonProperty("toolCategory") + @ExcludeMissing + toolCategory: JsonField = JsonMissing.of(), + ) : this(count, toolCategory, mutableMapOf()) + + /** + * The number of calls by the tool category. + * + * @throws GeminiNextGenApiInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun count(): Optional = count.getOptional("count") + + /** + * The tool category associated with the count. + * + * @throws GeminiNextGenApiInvalidDataException if the JSON field has an unexpected type + * (e.g. if the server responded with an unexpected value). + */ + fun toolCategory(): Optional = toolCategory.getOptional("toolCategory") + + /** + * Returns the raw JSON value of [count]. + * + * Unlike [count], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("count") @ExcludeMissing fun _count(): JsonField = count + + /** + * Returns the raw JSON value of [toolCategory]. + * + * Unlike [toolCategory], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("toolCategory") + @ExcludeMissing + fun _toolCategory(): JsonField = toolCategory + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [GroundingToolCountByCategory]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [GroundingToolCountByCategory]. */ + class Builder internal constructor() { + + private var count: JsonField = JsonMissing.of() + private var toolCategory: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(groundingToolCountByCategory: GroundingToolCountByCategory) = apply { + count = groundingToolCountByCategory.count + toolCategory = groundingToolCountByCategory.toolCategory + additionalProperties = + groundingToolCountByCategory.additionalProperties.toMutableMap() + } + + /** The number of calls by the tool category. */ + fun count(count: Int) = count(JsonField.of(count)) + + /** + * Sets [Builder.count] to an arbitrary JSON value. + * + * You should usually call [Builder.count] with a well-typed [Int] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun count(count: JsonField) = apply { this.count = count } + + /** The tool category associated with the count. */ + fun toolCategory(toolCategory: ToolCategory) = toolCategory(JsonField.of(toolCategory)) + + /** + * Sets [Builder.toolCategory] to an arbitrary JSON value. + * + * You should usually call [Builder.toolCategory] with a well-typed [ToolCategory] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun toolCategory(toolCategory: JsonField) = apply { + this.toolCategory = toolCategory + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [GroundingToolCountByCategory]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): GroundingToolCountByCategory = + GroundingToolCountByCategory( + count, + toolCategory, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): GroundingToolCountByCategory = apply { + if (validated) { + return@apply + } + + count() + toolCategory().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: GeminiNextGenApiInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (count.asKnown().isPresent) 1 else 0) + + (toolCategory.asKnown().getOrNull()?.validity() ?: 0) + + /** The tool category associated with the count. */ + class ToolCategory @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is + * on an older version than the API, then the API may respond with new members that the + * SDK is unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val SEARCH = of("search") + + @JvmField val MAP = of("map") + + @JvmField val RETRIEVAL = of("retrieval") + + @JvmStatic fun of(value: String) = ToolCategory(JsonField.of(value)) + } + + /** An enum containing [ToolCategory]'s known values. */ + enum class Known { + SEARCH, + MAP, + RETRIEVAL, + } + + /** + * An enum containing [ToolCategory]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [ToolCategory] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if + * the SDK is on an older version than the API, then the API may respond with new + * members that the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + SEARCH, + MAP, + RETRIEVAL, + /** + * An enum member indicating that [ToolCategory] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or + * [Value._UNKNOWN] if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you + * want to throw for the unknown case. + */ + fun value(): Value = + when (this) { + SEARCH -> Value.SEARCH + MAP -> Value.MAP + RETRIEVAL -> Value.RETRIEVAL + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and + * don't want to throw for the unknown case. + * + * @throws GeminiNextGenApiInvalidDataException if this class instance's value is a not + * a known member. + */ + fun known(): Known = + when (this) { + SEARCH -> Known.SEARCH + MAP -> Known.MAP + RETRIEVAL -> Known.RETRIEVAL + else -> + throw GeminiNextGenApiInvalidDataException("Unknown ToolCategory: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for + * debugging and generally doesn't throw. + * + * @throws GeminiNextGenApiInvalidDataException if this class instance's value does not + * have the expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + GeminiNextGenApiInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): ToolCategory = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: GeminiNextGenApiInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is ToolCategory && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is GroundingToolCountByCategory && + count == other.count && + toolCategory == other.toolCategory && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(count, toolCategory, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "GroundingToolCountByCategory{count=$count, toolCategory=$toolCategory, additionalProperties=$additionalProperties}" + } + /** The token count for a single response modality. */ class InputTokensByModality @JsonCreator(mode = JsonCreator.Mode.DISABLED) @@ -1954,6 +2357,7 @@ private constructor( return other is Usage && cachedTokensByModality == other.cachedTokensByModality && + groundingToolCountByCategory == other.groundingToolCountByCategory && inputTokensByModality == other.inputTokensByModality && outputTokensByModality == other.outputTokensByModality && toolUseTokensByModality == other.toolUseTokensByModality && @@ -1969,6 +2373,7 @@ private constructor( private val hashCode: Int by lazy { Objects.hash( cachedTokensByModality, + groundingToolCountByCategory, inputTokensByModality, outputTokensByModality, toolUseTokensByModality, @@ -1985,5 +2390,5 @@ private constructor( override fun hashCode(): Int = hashCode override fun toString() = - "Usage{cachedTokensByModality=$cachedTokensByModality, inputTokensByModality=$inputTokensByModality, outputTokensByModality=$outputTokensByModality, toolUseTokensByModality=$toolUseTokensByModality, totalCachedTokens=$totalCachedTokens, totalInputTokens=$totalInputTokens, totalOutputTokens=$totalOutputTokens, totalThoughtTokens=$totalThoughtTokens, totalTokens=$totalTokens, totalToolUseTokens=$totalToolUseTokens, additionalProperties=$additionalProperties}" + "Usage{cachedTokensByModality=$cachedTokensByModality, groundingToolCountByCategory=$groundingToolCountByCategory, inputTokensByModality=$inputTokensByModality, outputTokensByModality=$outputTokensByModality, toolUseTokensByModality=$toolUseTokensByModality, totalCachedTokens=$totalCachedTokens, totalInputTokens=$totalInputTokens, totalOutputTokens=$totalOutputTokens, totalThoughtTokens=$totalThoughtTokens, totalTokens=$totalTokens, totalToolUseTokens=$totalToolUseTokens, additionalProperties=$additionalProperties}" }