Field Types
Every field in a form config has a type that determines how the LLM interacts with it, what validation rules apply, and what value format is expected.
Overview
| Type | Input? | Purpose | Submitted Value Format |
|---|---|---|---|
text | Yes | Short free-form text | String |
email | Yes | Email address | String (validated format) |
number | Yes | Numeric value | Integer or decimal |
date | Yes | Calendar date | YYYY-MM-DD |
time | Yes | Time of day | HH:mm (24-hour) |
select | Yes | Choice from visible options | Option key (string) |
smartSelect | Yes | Choice from hidden options (LLM matches) | Option key (string) |
boolean | Yes | Yes/No | true or false |
textarea | Yes | Long free-form text | String |
info | No | Display-only context | (no value) |
Detailed Reference
text
Short to medium free-form text. The user types a response and it's stored as-is.
name:
type: text
promptKey: fields.name.ask
labelKey: fields.name.label
descriptionKey: fields.name.description
validation:
required: true
minLength: 2
maxLength: 100
Allowed validation: required, minLength, maxLength, pattern
email
Email address with automatic format validation.
email:
type: email
promptKey: fields.email.ask
labelKey: fields.email.label
descriptionKey: fields.email.description
validation:
required: true
Allowed validation: required, minLength, maxLength, pattern
Email format validation is built-in. You don't need a pattern rule for basic email validation.
number
Numeric value. The LLM accepts both words ("five") and digits ("5") and submits as a number.
windowCount:
type: number
promptKey: fields.windowCount.ask
labelKey: fields.windowCount.label
descriptionKey: fields.windowCount.description
validation:
min: 1
max: 100
Allowed validation: required, min, max
date
Calendar date. The LLM accepts natural expressions ("next Friday", "in two weeks") and submits in YYYY-MM-DD format. Today's date and day of week are provided to the LLM automatically.
preferredDate:
type: date
dtoField: date
promptKey: fields.date.ask
labelKey: fields.date.label
descriptionKey: fields.date.description
validation:
required: true
minAdvanceHours: 24
maxAdvanceDays: 365
Allowed validation: required, minAdvanceHours, maxAdvanceDays
For ambiguous expressions like "easter weekend" or "sometime in summer", the LLM will suggest specific dates and ask the user to confirm before submitting.
time
Time of day. The LLM accepts natural expressions ("morning", "around 2pm") and submits in HH:mm (24-hour) format.
preferredTime:
type: time
dtoField: timeslot
promptKey: fields.timeslot.ask
labelKey: fields.timeslot.label
descriptionKey: fields.timeslot.description
Allowed validation: required
select
Choice from a fixed list of options. Options are shown to the user conversationally (not as a numbered list). The LLM matches the user's natural language response to the closest option.
cleaningType:
type: select
promptKey: fields.cleaningType.ask
labelKey: fields.cleaningType.label
descriptionKey: fields.cleaningType.description
options: [deep, regular, move-out]
Allowed validation: required
Options can come from two sources:
- Explicit
optionslist in the field definition - Derived from formFlow — keys under the field name in the formFlow tree
See FormFlow & Branching for details.
smartSelect
Like select, but options are NOT shown to the user. The user responds in their own words, and the LLM interprets and matches to the closest option. If uncertain, the LLM asks a clarifying question.
areaSize:
type: smartSelect
promptKey: fields.areaSize.ask
labelKey: fields.areaSize.label
descriptionKey: fields.areaSize.description
options: ["0-49", "50-59", "60-69", "70-79", "80-89", "90-99", "100+"]
Allowed validation: required
Use smartSelect when showing raw option values would feel unnatural (e.g., area size ranges, internal codes). Use select when the user should see and choose from the options directly.
boolean
Yes/No question. The LLM asks conversationally and submits true or false.
balconyCleaning:
type: boolean
promptKey: fields.balconyCleaning.ask
labelKey: fields.balconyCleaning.label
descriptionKey: fields.balconyCleaning.description
Allowed validation: required
Boolean fields cannot have an explicit options list. Yes/No choices are provided automatically.
textarea
Long free-form text for comments, special instructions, or detailed descriptions.
otherInfo:
type: textarea
promptKey: fields.otherInfo.ask
labelKey: fields.otherInfo.label
descriptionKey: fields.otherInfo.description
validation:
maxLength: 500
Allowed validation: required, minLength, maxLength, pattern
info
Display-only node. No user input is collected. Used as descriptions for branch options (e.g., explaining what "Home Cleaning" includes).
homeCleaning:
type: info
promptKey: services.homeCleaning.prompt
labelKey: services.homeCleaning.label
descriptionKey: services.homeCleaning.description
Allowed validation: required only (though rarely needed)
info nodes are typically used as option descriptions in branching fields. They appear in the form schema as INFO: annotations after the first child field of a branch.
Node Types
Fields in the formFlow tree are classified as either question nodes or answer nodes based on their depth:
Question Node (FIELD)
A question that the user answers. Appears at odd depths (1, 3, 5, ...) in the formFlow tree.
| Property | Required? |
|---|---|
type | Yes |
promptKey | Yes |
labelKey | Yes |
descriptionKey | Yes |
dtoField | No (auto-derived from field name) |
validation | No |
options | No |
Answer Node (OPTION)
A branch option selected by the user's choice on a parent field. Appears at even depths (2, 4, 6, ...).
| Property | Required? |
|---|---|
type | Yes (must be info) |
promptKey | Yes |
labelKey | Yes |
dtoField | Forbidden |
See FormFlow & Branching for how node types are determined by depth.