Skip to content

Commit

Permalink
feat: add validation that fields from mfb are iterable
Browse files Browse the repository at this point in the history
  • Loading branch information
kathleenkhy committed May 5, 2024
1 parent 63b5db8 commit a6ef373
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ export enum Roles {
USER = 'user',
}

export const MODEL_TYPE = 'gpt-4-32K-0613'

export const sampleFormFields = `[{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"section"},{"ValidationOptions":{"selectedValidation":null,"customVal":null},"allowPrefill":"<boolean>","lockPrefill":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"textfield"},{"ValidationOptions":{"selectedValidation":null,"customVal":null},"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"textarea"},{"fieldOptions":["<string>"],"othersRadioButton":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"radiobutton"},{"ValidationOptions":{"customMax":null,"customMin":null},"fieldOptions":["<string>"],"othersRadioButton":"<boolean>","validateByValue":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"checkbox"},{"fieldOptions":["<string>"],"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"dropdown"},{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"yes_no"},{"ratingOptions":{"steps":5,"shape":"Star"},"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"rating"},{"autoReplyOptions":{"hasAutoReply":"<boolean>","autoReplySubject":"<string>","autoReplySender":"<string>","autoReplyMessage":"<string>","includeFormSummary":"<boolean>"},"isVerifiable":"<boolean>","hasAllowedEmailDomains":false,"allowedEmailDomains":[],"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"email"},{"allowIntlNumbers":"<boolean>","isVerifiable":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"mobile"},{"allowIntlNumbers":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"homeno"},{"dateValidation":{"customMinDate":null,"customMaxDate":null,"selectedDateValidation":null},"invalidDays":[],"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"date"},{"addMoreRows":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"table","columns":[{"ValidationOptions":{"customVal":null,"selectedValidation":null},"allowPrefill":"<boolean>","lockPrefill":"<boolean>","columnType":"textfield","required":"<boolean>","title":"<string>"}],"minimumRows":2,"maximumRows":null},{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"attachment","attachmentSize":"1"},{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"number","ValidationOptions":{"LengthValidationOptions":{"customVal":null,"selectedLengthValidation":null},"RangeValidationOptions":{"customMin":null,"customMax":null},"selectedValidation":null}},{"ValidationOptions":{"customMax":null,"customMin":null},"validateByValue":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"decimal"},{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"nric"},{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"uen"}]`
export const sampleFormFields = `[{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"section"},{"ValidationOptions":{"selectedValidation":null,"customVal":null},"allowPrefill":"<boolean>","lockPrefill":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"textfield"},{"ValidationOptions":{"selectedValidation":null,"customVal":null},"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"textarea"},{"fieldOptions":["<string>"],"othersRadioButton":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"radiobutton"},{"ValidationOptions":{"customMax":null,"customMin":null},"fieldOptions":["<string>"],"othersRadioButton":"<boolean>","validateByValue":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"checkbox"},{"fieldOptions":["<string>"],"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"dropdown"},{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"yes_no"},{"ratingOptions":{"steps":5,"shape":"Star"},"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"rating"},{"autoReplyOptions":{"hasAutoReply":"<boolean>","autoReplySubject":"<string>","autoReplySender":"<string>","autoReplyMessage":"<string>","includeFormSummary":"<boolean>"},"isVerifiable":"<boolean>","hasAllowedEmailDomains":false,"allowedEmailDomains":[],"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"email"},{"allowIntlNumbers":"<boolean>","isVerifiable":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"mobile"},{"allowIntlNumbers":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"homeno"},{"dateValidation":{"customMinDate":null,"customMaxDate":null,"selectedDateValidation":null},"invalidDays":[],"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"date"},{"addMoreRows":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"table","columns":[{"ValidationOptions":{"customVal":null,"selectedValidation":null},"allowPrefill":"<boolean>","lockPrefill":"<boolean>","columnType":"textfield","required":"<boolean>","title":"<string>"}],"minimumRows":2,"maximumRows":null},{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"attachment","attachmentSize":"<string ranging from 1 to 4>"},{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"number","ValidationOptions":{"LengthValidationOptions":{"customVal":null,"selectedLengthValidation":null},"RangeValidationOptions":{"customMin":null,"customMax":null},"selectedValidation":null}},{"ValidationOptions":{"customMax":null,"customMin":null},"validateByValue":"<boolean>","title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"decimal"},{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"nric"},{"title":"<string>","description":"<string>","required":"<boolean>","disabled":"<boolean>","fieldType":"uen"}].`

export const fieldTypes = [
'section',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export const generateFormFields = (
function: getFormFieldsTool,
},
],
temperature: 0.1,
} as GetChatCompletionsOptions

return ResultAsync.fromPromise(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const formFieldsPromptBuilder = (questions: string, schema: string) => {

export const getFormFieldsTool = {
name: 'getFormFields',
description: `Gets form fields to build a form with the specified field types based on the example of sample form fields. Do not create fields which do not belong to any of the specified field types. For example, do not create a signature field type because 'signature' is not found in the list of fieldTypes, it should either be 'textarea' or 'textfield' instead. Enum values should follow the specified sample form fields provided. Do not create enum values which do not exist or are not valid. For example, the enum value for path dateValidation.selectedDateValidation should be null as described in the sampleFormFields. Replace values in "<>" with actual primitive values. Do not build the fieldType if a path required is not available.`,
description: `Gets form fields to build a form with the specified field types based on the example of sample form fields. Do not create fields which do not belong to any of the specified field types. Replace values in "<>" with actual primitive values.`,
parameters: {
type: 'object',
properties: {
Expand Down
36 changes: 34 additions & 2 deletions src/app/modules/form/admin-form/admin-form.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1988,9 +1988,8 @@ export const _handleCreateFormField: ControllerHandler<
* @returns 422 when an invalid form field creation is attempted on the form
* @returns 422 when user in session cannot be retrieved from the database
* @returns 500 when database error occurs
* todo: add validation
*/
export const handleCreateFormFields: ControllerHandler<
export const _handleCreateFormFields: ControllerHandler<
{ formId: string },
FormFieldDto[] | ErrorDto,
FieldCreateDto[]
Expand Down Expand Up @@ -2218,6 +2217,39 @@ export const handleCreateFormField = [
_handleCreateFormField,
]

/**
* Handler for POST /forms/:formId/fields
*/

//to validate that new fields generated from magic form builder is iterable
export const handleCreateFormFields = [
celebrate({
[Segments.BODY]: Joi.array().items(
Joi.object({
// Ensures id is not provided.
_id: Joi.any().forbidden(),
globalId: Joi.any().forbidden(),
fieldType: Joi.string()
.valid(...Object.values(BasicField))
.required(),
title: Joi.string().trim().required(),
description: Joi.string().allow(''),
required: Joi.boolean(),
disabled: Joi.boolean(),
// Allow other field related key-values to be provided and let the model
// layer handle the validation.
})
.unknown(true)
.custom((value, helpers) => verifyValidUnicodeString(value, helpers)),
),
[Segments.QUERY]: {
// Optional index to insert the field at.
to: Joi.number().min(0),
},
}),
_handleCreateFormFields,
]

/**
* NOTE: Exported for testing.
* Private handler for POST /forms/:formId/fields/:fieldId/reorder
Expand Down

0 comments on commit a6ef373

Please sign in to comment.