Skip to content

Davidmotson.extra schema #7013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
Expand Up @@ -6,6 +6,8 @@
* [changed] **Breaking Change**: Updated `SpeechConfig` to take in `Voice` class instead of `Voices` class.
* **Action Required:** Update all references of `SpeechConfig` initialization to use `Voice` class.
* [fixed] Fix incorrect model name in count token requests to the developer API backend
* [feature] Added support for extra schema properties like `title`, `minItems`, `maxItems`, `minimum`
and `maximum`. As well as support for the `anyOf` schema.


# 16.0.0
Expand Down
131 changes: 113 additions & 18 deletions firebase-ai/src/main/kotlin/com/google/firebase/ai/type/Schema.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,20 @@ public abstract class StringFormat private constructor(internal val value: Strin
*/
public class Schema
internal constructor(
public val type: String,
public val type: String? = null,
public val description: String? = null,
public val format: String? = null,
public val nullable: Boolean? = null,
public val enum: List<String>? = null,
public val properties: Map<String, Schema>? = null,
public val required: List<String>? = null,
public val items: Schema? = null,
public val title: String? = null,
public val minItems: Int? = null,
public val maxItems: Int? = null,
public val minimum: Double? = null,
public val maximum: Double? = null,
public val anyOf: List<Schema>? = null
) {

public companion object {
Expand All @@ -53,12 +59,12 @@ internal constructor(
*/
@JvmStatic
@JvmOverloads
public fun boolean(description: String? = null, nullable: Boolean = false): Schema =
Schema(
description = description,
nullable = nullable,
type = "BOOLEAN",
)
public fun boolean(
description: String? = null,
nullable: Boolean = false,
title: String? = null
): Schema =
Schema(description = description, nullable = nullable, type = "BOOLEAN", title = title)

/**
* Returns a [Schema] for a 32-bit signed integer number.
Expand All @@ -73,12 +79,21 @@ internal constructor(
@JvmStatic
@JvmName("numInt")
@JvmOverloads
public fun integer(description: String? = null, nullable: Boolean = false): Schema =
public fun integer(
description: String? = null,
nullable: Boolean = false,
title: String? = null,
minimum: Double? = null,
maximum: Double? = null
): Schema =
Schema(
description = description,
format = "int32",
nullable = nullable,
type = "INTEGER",
title = title,
minimum = minimum,
maximum = maximum,
)

/**
Expand All @@ -90,11 +105,20 @@ internal constructor(
@JvmStatic
@JvmName("numLong")
@JvmOverloads
public fun long(description: String? = null, nullable: Boolean = false): Schema =
public fun long(
description: String? = null,
nullable: Boolean = false,
title: String? = null,
minimum: Double? = null,
maximum: Double? = null
): Schema =
Schema(
description = description,
nullable = nullable,
type = "INTEGER",
title = title,
minimum = minimum,
maximum = maximum,
)

/**
Expand All @@ -106,8 +130,21 @@ internal constructor(
@JvmStatic
@JvmName("numDouble")
@JvmOverloads
public fun double(description: String? = null, nullable: Boolean = false): Schema =
Schema(description = description, nullable = nullable, type = "NUMBER")
public fun double(
description: String? = null,
nullable: Boolean = false,
title: String? = null,
minimum: Double? = null,
maximum: Double? = null
): Schema =
Schema(
description = description,
nullable = nullable,
type = "NUMBER",
title = title,
minimum = minimum,
maximum = maximum,
)

/**
* Returns a [Schema] for a single-precision floating-point number.
Expand All @@ -123,8 +160,22 @@ internal constructor(
@JvmStatic
@JvmName("numFloat")
@JvmOverloads
public fun float(description: String? = null, nullable: Boolean = false): Schema =
Schema(description = description, nullable = nullable, type = "NUMBER", format = "float")
public fun float(
description: String? = null,
nullable: Boolean = false,
title: String? = null,
minimum: Double? = null,
maximum: Double? = null
): Schema =
Schema(
description = description,
nullable = nullable,
type = "NUMBER",
format = "float",
title = title,
minimum = minimum,
maximum = maximum,
)

/**
* Returns a [Schema] for a string.
Expand All @@ -139,13 +190,15 @@ internal constructor(
public fun string(
description: String? = null,
nullable: Boolean = false,
format: StringFormat? = null
format: StringFormat? = null,
title: String? = null,
): Schema =
Schema(
description = description,
format = format?.value,
nullable = nullable,
type = "STRING"
type = "STRING",
title = title
)

/**
Expand Down Expand Up @@ -176,6 +229,7 @@ internal constructor(
optionalProperties: List<String> = emptyList(),
description: String? = null,
nullable: Boolean = false,
title: String? = null
): Schema {
if (!properties.keys.containsAll(optionalProperties)) {
throw IllegalArgumentException(
Expand All @@ -188,6 +242,7 @@ internal constructor(
properties = properties,
required = properties.keys.minus(optionalProperties.toSet()).toList(),
type = "OBJECT",
title = title
)
}

Expand All @@ -203,13 +258,19 @@ internal constructor(
public fun array(
items: Schema,
description: String? = null,
nullable: Boolean = false
nullable: Boolean = false,
title: String? = null,
minItems: Int? = null,
maxItems: Int? = null
): Schema =
Schema(
description = description,
nullable = nullable,
items = items,
type = "ARRAY",
title = title,
minItems = minItems,
maxItems = maxItems
)

/**
Expand All @@ -230,15 +291,37 @@ internal constructor(
public fun enumeration(
values: List<String>,
description: String? = null,
nullable: Boolean = false
nullable: Boolean = false,
title: String? = null,
): Schema =
Schema(
description = description,
format = "enum",
nullable = nullable,
enum = values,
type = "STRING",
title = title
)

/**
* Returns a [Schema] representing a value that must conform to *any* (one of) the provided
* sub-schema.
*
* Example: A field that can hold either a simple userID or a more detailed user object.
*
* Schema.anyOf( listOf( Schema.integer(description = "User ID"), Schema.obj(mapOf(
* ```
* "userID" to Schema.integer(description = "User ID"),
* "username" to Schema.string(description = "Username")
* ```
* )) )
*
* @param schemas The list of valid schemas which could be here
*/
@JvmStatic
public fun anyOf(
schemas: List<Schema>,
): Schema = Schema(anyOf = schemas)
}

internal fun toInternal(): Internal =
Expand All @@ -251,16 +334,28 @@ internal constructor(
properties?.mapValues { it.value.toInternal() },
required,
items?.toInternal(),
title,
minItems,
maxItems,
minimum,
maximum,
anyOf?.map { it.toInternal() },
)
@Serializable
internal data class Internal(
val type: String,
val type: String? = null,
val description: String? = null,
val format: String? = null,
val nullable: Boolean? = false,
val enum: List<String>? = null,
val properties: Map<String, Internal>? = null,
val required: List<String>? = null,
val items: Internal? = null,
val title: String? = null,
val minItems: Int? = null,
val maxItems: Int? = null,
val minimum: Double? = null,
val maximum: Double? = null,
val anyOf: List<Internal>? = null
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,18 +175,15 @@ internal class SerializationTests {
"type": {
"type": "string"
},
"format": {
"description": {
"type": "string"
},
"description": {
"format": {
"type": "string"
},
"nullable": {
"type": "boolean"
},
"items": {
"${'$'}ref": "Schema"
},
"enum": {
"type": "array",
"items": {
Expand All @@ -204,7 +201,31 @@ internal class SerializationTests {
"items": {
"type": "string"
}
}
},
"items": {
"${'$'}ref": "Schema"
},
"title": {
"type": "string"
},
"minItems": {
"type": "integer"
},
"maxItems": {
"type": "integer"
},
"minimum": {
"type": "number"
},
"maximum": {
"type": "number"
},
"anyOf": {
"type": "array",
"items": {
"${'$'}ref": "Schema"
}
}
}
}
"""
Expand Down
Loading