Skip to content

Commit

Permalink
chore: WIP improving prompt to OpenAI for PDF uploads
Browse files Browse the repository at this point in the history
  • Loading branch information
kathleenkhy committed Apr 17, 2024
1 parent 1982bb4 commit 81e4856
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ export const MagicFormBuilderPdfDetailsScreen = (): JSX.Element => {
return combinedText.trim()
}

const isError = pdfFileText.length > 3000

return (
<>
<ModalHeader color="secondary.700">
Expand All @@ -97,15 +95,15 @@ export const MagicFormBuilderPdfDetailsScreen = (): JSX.Element => {
</ModalHeader>
<ModalBody whiteSpace="pre-wrap">
<Container maxW={'42.5rem'} p={0}>
<FormControl isInvalid={isError || !!errors.pdfFileText}>
<FormControl isInvalid={!!errors.pdfFileText}>
<FormLabel>
Upload a PDF - The PDF should not be a scanned copy and should not
contain any restricted or sensitive information.
</FormLabel>
<Controller
rules={{
validate: (pdfFileText) => {
if (pdfFileText && pdfFileText.length < 3001) return true
if (pdfFileText) return true
return 'This PDF file cannot be processed. Please ensure that the PDF uploaded contains selectable text and is not a scanned copy.'
},
}}
Expand All @@ -127,15 +125,11 @@ export const MagicFormBuilderPdfDetailsScreen = (): JSX.Element => {
/>

<FormErrorMessage alignItems="top">
{(isError || !pdfFileText) && (
<FormErrorIcon h="1.5rem" as={BxsErrorCircle} />
)}
{!pdfFileText && <FormErrorIcon h="1.5rem" as={BxsErrorCircle} />}
{!pdfFileText &&
(pdfFile
? `${errors.pdfFileText?.message}`
: 'Please upload a PDF.')}
{isError &&
`The PDF uploaded exceeds the character limit acceptable (${pdfFileText.length}/3000). Please try another form.`}
</FormErrorMessage>
</FormControl>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export enum Roles {
export const MODEL_TYPE = 'gpt-3.5-turbo'

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 fieldTypes = `'section','textfield','textarea','radiobutton','checkbox','dropdown','yes_no','rating','email','mobile','homeno','date','table','attachment','number','decimal','nric','uen'`
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ const generateQuestionsSchema = Joi.object({
type: Joi.string()
.valid(...Object.values(ContentTypes))
.required(),
content: Joi.alternatives().conditional('type', {
content: Joi.string().when('type', {
is: ContentTypes.PROMPT,
then: Joi.string().max(300).required(),
otherwise: Joi.string().max(3000).required(), // max character of 3000 to cater for PDF uploads
}),
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ export const generateFormFields = (
> => {
const messages: ChatRequestMessage[] = [
{ role: Roles.SYSTEM, content: schemaPromptBuilder(sampleFormFields) },
{ role: Roles.USER, content: formFieldsPromptBuilder(questions) },
{
role: Roles.USER,
content: formFieldsPromptBuilder(questions, sampleFormFields),
},
]
return ResultAsync.fromPromise(
azureOpenAi.getChatCompletions(deploymentId, messages),
Expand All @@ -132,6 +135,7 @@ export const generateFormFields = (
},
).andThen((chatCompletions) => {
const { message } = chatCompletions.choices[0]
// const {tokenUsage} = chatCompletions.usage?.totalTokens?
if (!message) {
return errAsync(new AssistanceConnectionError())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// type guard for OpenAIError
import { fieldTypes } from './admin-form.assistance.constants'
import { OpenAIError } from './admin-form.assistance.types'

export function isOpenAIError(error: unknown): error is OpenAIError {
Expand All @@ -24,12 +25,12 @@ export const schemaPromptBuilder = (schema: string) => {

export const questionListPromptBuilder = (purpose: string) => {
return `I am a public officer who wants to create a form that collects ${purpose}.
Give me a list of content / questions I should have in my form built with this form builder, in the form of "${expectedQuestionsListFormat}".`
Give me a list of content / questions I should have in my form built with this form builder, in the form of "${expectedQuestionsListFormat}", where <answer type> must follow the category of types within ${fieldTypes}. Do not create the question if the <answer type> does not exist in ${fieldTypes}.`
}

export const formFieldsPromptBuilder = (questions: string) => {
export const formFieldsPromptBuilder = (questions: string, schema: string) => {
return `Help me generate a form with the following list of questions: ${questions}
Present the questions as FormSG form fields in JSON (list of form field schemas), in the form of "${expectedFormFieldSchemaFormat}" as defined by the system, without any code blocks. Format the JSON as a single line.`
Provide the questions as FormSG form fields in JSON format (with the following keys: ${schema}), in the form of "${expectedFormFieldSchemaFormat}" as defined by the system, without any code blocks. Format the JSON as a single line. Ensure the JSON generated only contain fieldTypes of types ${fieldTypes}. Do not create any fieldTypes which are not ${fieldTypes}. Replace values in <> with actual primitive values. Do not build the fieldType if a path required is not available.`
}
export const migratePromptBuilder = (parsedContent: string) => {
return `Help me generate the corresponding JSON form fields from content parsed from a PDF document.
Expand Down

0 comments on commit 81e4856

Please sign in to comment.