> ## Documentation Index
> Fetch the complete documentation index at: https://liquidai-alay2shah-sync-notebook-snippets.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Constrained Generation

> Generate structured JSON output with compile-time validation using constrained generation

Setting the `jsonSchemaConstraint` field in [`GenerationOptions`](./conversation-generation#generationoptions) will enable constrained generation. While it is possible to
directly set the constraint with raw JSON Schema strings, we recommend to create the constraints with the `Generatable` annotation.

## `Generatable` annotation

```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}}
package ai.liquid.leap.structuredoutput

annotation class Generatable(val description: String)
annotation class Guide(val description: String)
```

Only Kotlin data classes can be annotated with `Generatable`, and all the fields of the data class should be declared in the parameter of the constructor. `Guide` annotation can be used to add further descriptions to the fields.

For example, here is a generatable data class for holding information of a city:

```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}}
@Generatable(description="Facts about a city")
data class CityFact(
  @Guide(description="Name of the city")
  val name: String,

  @Guide(description="State/province of the city")
  val state: String,

  @Guide(description="Country name")
  val country: String,

  @Guide(description="Place of interests in the city")
  val placeOfInterests: List<String>,
)
```

## Apply Generatable data class in GenerationOptions

Then we can use `setResponseFormatType()` in `GenerationOptions` to set up the constraint.

```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}}
val options = GenerationOptions.build {
  // Set the response format to follow `CityFact`
  setResponseFormatType(CityFact::class)
  // Example of other parameters
  minP = 0.0f
  temperature = 0.7f
}

conversation.generateResponse("Show the city facts about Tokyo", options)
```

If you want to add the JSON Schema into the prompt to help the generation, you can get the raw JSONSchema with `JSONSchemaGenerator`:

```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}}
val jsonSchema = JSONSchemaGenerator.getJSONSchema(CityFact::class)
conversation.generateResponse(
  "Show the city facts about Tokyo following this JSON Schema: $jsonSchema",
  options
)
```

With these settings, the model will generate a JSON string following the schema as its output.

If the JSON Schema cannot be created from the provided data class, a `LeapGeneratableSchematizationException` will be thrown.

## Deserialize Generatable data class

Finally, you can use `GeneratableFactory.createFromJSONObject()` to deserialize the JSON string generated by the model into the generatable data class:

```kotlin theme={"theme":{"light":"github-light","dark":"github-dark"}}
import ai.liquid.leap.structuredoutput.GeneratableFactory

conversation.generateResponse(
  "Show the city facts about Tokyo.",
  options
).onEach {
  if (it is MessageResponse.Complete) {
    val message = it.fullMessage
    val jsonContent = (message.content.first() as ChatMessageContent.Text).text

    // Deserialize the content as a `CityFact` object.
    val cityFact: CityFact = GeneratableFactory.createFromJSONObject(
      JSONObject(jsonContent),
    )
  }
}.collect()
```

If the JSON string generated by the model is not valid for creating instances of the generatable data class, a `LeapGeneratableDeserializationException` will be thrown.

## Supported data types

Not all Kotlin data types are supported in Leap Android SDK constrained generation. Here is the list of supported JSON Schema types:

* String (`String` in Kotlin)
* Integer (`Int` and `Long` in Kotlin)
* Number (`Float` and `Double` in Kotlin)
* Boolean (`Boolean` in Kotlin)
* Enum (Enum class in Kotlin. The plain name string will be used as values)
* Object (Any data classes annotated with \[Generatable])
* Array (`List` and `MutableList` of any other supported data types, and arrays of integer, float numbers and boolean in Kotlin)

Only if the data types of the fields of object types and the items of array types are supported, these composition data types can be supported.
