Developer Guides
Customizing schema

Customizing Schema

Flowformer utilizes a schema language to define the structure and behavior of your app. The schema language is designed to be simple and easy to understand, allowing you to quickly build and customize your applications.

If you're using VSCode, you can install the Flowformer extension to get syntax highlighting and autocompletion for the schema language.

Install the Flowformer extension for VSCode (opens in a new tab)

Creating Your Schema

When you create a new app in Flowformer using the @flowformer/create-app CLI, a default schema file is generated in src/schema.flowform. This file contains the schema for a sample presentation deck builder app, which you can modify to create any app you want. Below is the default example schema and an explanation of its components.

A screenshot of the Flowformer studio's schema tab

Example Schema

/**
 * This is a demo of a presentation app that allows users to create a PowerPoint presentation
 * You can modify this file to create any app you want
 */
model Presentation
    @entry
    @systemPrompt("This app will help users create a PowerPoint presentation. Use any appropriate slide type to create a presentation. Try to use a variety of slide types to make your presentation more engaging.")
{
    title String? @description("The title of the presentation")
    slides PresentationSlide[]
        @description("The slides in the presentation.")
        @itemRenderer("PresentationSlide")
}
 
/**
 * PresentationSlide is a union type that can be one of the following types
 */
union PresentationSlide =
    SingleImageSlide |
    BulletPointSlide |
    TitleOnlySlide
 
/**
 * This is a slide that has a title and narration
 */
model TitleOnlySlide {
    title String @description("The title of the slide")
    narration String @description("The narration for the slide")
}
 
/**
 * This is a slide that has a title, narration, and bullet points
 */
model BulletPointSlide {
    title String @description("The title of the slide")
    narration String @description("The narration for the slide")
    bulletPoints String[] @description("The bullet points on the slide")
}
 
/**
 * This is a slide that has a single image on it
 */
model SingleImageSlide {
    title String @description("The title of the slide")
    narration String @description("The narration for the slide. Write 2 paragraphs of text.")
    queryForImage String
        @description("The prompt for the image that I will send to DALLE to generate an image")
        -> DALLE3 as generatedImage @description("The image generated by DALLE")
}

Output JSON

Here is an example of an output JSON generated by the AI according to the schema above. The user asked the AI to create a presentation on martial arts.

{
  "$type": "Presentation",
  "title": "The Art of Martial Arts",
  "slides": [
    {
      "$type": "SingleImageSlide",
      "title": "Introduction to Martial Arts",
      "narration": "Martial arts have a rich history dating back centuries. They encompass a variety of combat and self-defense techniques practiced for physical, mental, and spiritual development.",
      "queryForImage": "Very serious-looking male martial artist",
      "generatedImage": "https://flowformer.app/assets/generated/generated-image-dall-e.jpg"
    },
    {
      "$type": "BulletPointSlide",
      "title": "Popular Martial Arts Styles",
      "narration": "There are numerous martial arts styles practiced worldwide, each with its unique techniques and philosophies. Some popular styles include Karate, Taekwondo, Judo, and Kung Fu.",
      "bulletPoints": [
        "Karate emphasizes striking techniques",
        "Taekwondo focuses on high kicks and fast movements",
        "Judo is known for throws and grappling techniques",
        "Kung Fu incorporates a wide range of fighting styles"
      ]
    },
    {
      "$type": "TitleOnlySlide",
      "title": "Benefits of Practicing Martial Arts",
      "narration": "Engaging in martial arts training offers a wide range of benefits, including improved physical fitness, enhanced self-discipline, increased self-confidence, and stress relief."
    }
  ]
}

Generated Types

As shown in the screenshot above, Flowformer generates TypeScript types and JSON schema for your Flowform schema. You can download these files from the "Schema" tab in the studio.

TypeScript types for the schema
export type PresentationSlide =
  | SingleImageSlide
  | BulletPointSlide
  | TitleOnlySlide;
export type Presentation = {
  $type: "Presentation";
  /** The title of the presentation */
  title?: string | undefined;
  /** The slides in the presentation. */
  slides: PresentationSlide[];
};
export type TitleOnlySlide = {
  $type: "TitleOnlySlide";
  /** The title of the slide */
  title: string;
  /** The narration for the slide */
  narration: string;
};
export type BulletPointSlide = {
  $type: "BulletPointSlide";
  /** The title of the slide */
  title: string;
  /** The narration for the slide */
  narration: string;
  /** The bullet points on the slide */
  bulletPoints: string[];
};
export type SingleImageSlide = {
  $type: "SingleImageSlide";
  /** The title of the slide */
  title: string;
  /** The narration for the slide. Write 2 paragraphs of text. */
  narration: string;
  /** The prompt for the image that I will send to google images to get an image */
  queryForImage: string;
  /** The original image that I fetched from google */
  generatedImage: string;
};
JSON schema for the schema
{
  "type": "object",
  "properties": {
    "title": {
      "type": "string",
      "description": "The title of the presentation"
    },
    "slides": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "title": {
                "type": "string",
                "description": "The title of the slide"
              },
              "narration": {
                "type": "string",
                "description": "The narration for the slide. Write 2 paragraphs of text."
              },
              "queryForImage": {
                "type": "string",
                "description": "The prompt for the image that I will send to google images to get an image"
              }
            },
            "required": ["title", "narration", "queryForImage"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "title": {
                "type": "string",
                "description": "The title of the slide"
              },
              "narration": {
                "type": "string",
                "description": "The narration for the slide"
              },
              "bulletPoints": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "The bullet points on the slide"
              }
            },
            "required": ["title", "narration", "bulletPoints"],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "title": {
                "type": "string",
                "description": "The title of the slide"
              },
              "narration": {
                "type": "string",
                "description": "The narration for the slide"
              }
            },
            "required": ["title", "narration"],
            "additionalProperties": false
          }
        ]
      },
      "description": "The slides in the presentation."
    }
  },
  "required": ["slides"],
  "additionalProperties": false,
  "$schema": "http://json-schema.org/draft-07/schema#"
}

Understanding the Schema

Model Definition

  • The model keyword defines a structure with fields that represent the data of your app.
  • Presentation is the main model, marked with @entry to indicate it's the entry point.
  • @systemPrompt provides a system-wide instruction for generating content.

Each schema must have exactly one entry model marked with @entry. The entry model serves as the starting point for generating content in your app.

The @systemPrompt directive provides a system-wide instruction for generating content. This instruction is used by the AI to understand the context and generate content accordingly.

Fields

  • Fields within a model represent the properties of the structure.
  • title is a string field with an optional value (indicated by String?) and a description.
  • slides is an array of PresentationSlide union types, each with its own renderer.

Using the @description directive, you can provide a hint for each field to help AI understand the context and generate content accordingly.

Union Types

  • union defines a type that can be one of several specified models.
  • PresentationSlide can be SingleImageSlide, BulletPointSlide, or TitleOnlySlide.

Custom UI Renderer

The @itemRenderer directive specifies a custom renderer named PresentationSlide for the items of the field slides.

  • The slides field uses a custom renderer called PresentationSlide.
  • In the created flowformer app, you can see PresentationSlide as a custom React component. It is used to render the different types of slides.

Transformation with functions

Flowformer allows you to pipe data through custom functions to transfoor generate content. In the example schema, the queryForImage field uses a custom function to fetch an image from Google Images.

  • The LLM first generates a query based on the prompt provided in the queryForImage field.
  • The query is then sent to DALLE 3 to generate an image.

Modifying Your Schema

To create your own app, modify the default schema to fit your requirements. Add or remove fields, create new models, and define custom behavior using the schema language's simple and intuitive syntax.

For more advanced customizations and integrations, refer to the Flowformer documentation on schema extensions and external API integrations. Happy building with Flowformer!