@@ -27,12 +27,13 @@ import { Popup, DisclaimerPopup } from '@/features/popup';
2727import { Avatar } from '@/components/avatars/Avatar' ;
2828import { DeleteButton , SendButton } from '@/components/buttons/SendButton' ;
2929import { FilePreview } from '@/components/inputs/textInput/components/FilePreview' ;
30- import { CircleDotIcon , TrashIcon } from './icons' ;
30+ import { CircleDotIcon , SparklesIcon , TrashIcon } from './icons' ;
3131import { CancelButton } from './buttons/CancelButton' ;
3232import { cancelAudioRecording , startAudioRecording , stopAudioRecording } from '@/utils/audioRecording' ;
3333import { LeadCaptureBubble } from '@/components/bubbles/LeadCaptureBubble' ;
3434import { removeLocalStorageChatHistory , getLocalStorageChatflow , setLocalStorageChatflow , setCookie , getCookie } from '@/utils' ;
3535import { cloneDeep } from 'lodash' ;
36+ import { FollowUpPromptBubble } from '@/components/bubbles/FollowUpPromptBubble' ;
3637import { fetchEventSource , EventStreamContentType } from '@microsoft/fetch-event-source' ;
3738
3839export type FileEvent < T = EventTarget > = {
@@ -107,6 +108,7 @@ export type MessageType = {
107108 action ?: IAction | null ;
108109 rating ?: FeedbackRatingType ;
109110 id ?: string ;
111+ followUpPrompts ?: string ;
110112 dateTime ?: string ;
111113} ;
112114
@@ -279,6 +281,10 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
279281 const [ recordingNotSupported , setRecordingNotSupported ] = createSignal ( false ) ;
280282 const [ isLoadingRecording , setIsLoadingRecording ] = createSignal ( false ) ;
281283
284+ // follow-up prompts
285+ const [ followUpPromptsStatus , setFollowUpPromptsStatus ] = createSignal < boolean > ( false ) ;
286+ const [ followUpPrompts , setFollowUpPrompts ] = createSignal < string [ ] > ( [ ] ) ;
287+
282288 // drag & drop
283289 const [ isDragActive , setIsDragActive ] = createSignal ( false ) ;
284290 const [ uploadedFiles , setUploadedFiles ] = createSignal < File [ ] > ( [ ] ) ;
@@ -473,6 +479,11 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
473479 handleSubmit ( prompt ) ;
474480 } ;
475481
482+ const followUpPromptClick = ( prompt : string ) => {
483+ setFollowUpPrompts ( [ ] ) ;
484+ handleSubmit ( prompt ) ;
485+ } ;
486+
476487 const updateMetadata = ( data : any , input : string ) => {
477488 if ( data . chatId ) {
478489 setChatId ( data . chatId ) ;
@@ -501,6 +512,17 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
501512 return allMessages ;
502513 } ) ;
503514 }
515+
516+ if ( data . followUpPrompts ) {
517+ setMessages ( ( prevMessages ) => {
518+ const allMessages = [ ...cloneDeep ( prevMessages ) ] ;
519+ if ( allMessages [ allMessages . length - 1 ] . type === 'userMessage' ) return allMessages ;
520+ allMessages [ allMessages . length - 1 ] . followUpPrompts = data . followUpPrompts ;
521+ addChatMessage ( allMessages ) ;
522+ return allMessages ;
523+ } ) ;
524+ setFollowUpPrompts ( JSON . parse ( data . followUpPrompts ) ) ;
525+ }
504526 } ;
505527
506528 const fetchResponseFromEventStream = async ( chatflowid : string , params : any ) => {
@@ -861,6 +883,7 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
861883 if ( message . agentReasoning ) chatHistory . agentReasoning = message . agentReasoning ;
862884 if ( message . action ) chatHistory . action = message . action ;
863885 if ( message . artifacts ) chatHistory . artifacts = message . artifacts ;
886+ if ( message . followUpPrompts ) chatHistory . followUpPrompts = message . followUpPrompts ;
864887 return chatHistory ;
865888 } )
866889 : [ { message : props . welcomeMessage ?? defaultWelcomeMessage , type : 'apiMessage' } ] ;
@@ -909,6 +932,9 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
909932 setMessages ( ( prevMessages ) => [ ...prevMessages , { message : '' , type : 'leadCaptureMessage' } ] ) ;
910933 }
911934 }
935+ if ( chatbotConfig . followUpPrompts ) {
936+ setFollowUpPromptsStatus ( chatbotConfig . followUpPrompts . status ) ;
937+ }
912938 }
913939
914940 // eslint-disable-next-line solid/reactivity
@@ -925,6 +951,17 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
925951 } ;
926952 } ) ;
927953
954+ createEffect ( ( ) => {
955+ if ( followUpPromptsStatus ( ) && messages ( ) . length > 0 ) {
956+ const lastMessage = messages ( ) [ messages ( ) . length - 1 ] ;
957+ if ( lastMessage . type === 'apiMessage' && lastMessage . followUpPrompts ) {
958+ setFollowUpPrompts ( JSON . parse ( lastMessage . followUpPrompts ) ) ;
959+ } else if ( lastMessage . type === 'userMessage' ) {
960+ setFollowUpPrompts ( [ ] ) ;
961+ }
962+ }
963+ } ) ;
964+
928965 const addRecordingToPreviews = ( blob : Blob ) => {
929966 let mimeType = '' ;
930967 const pos = blob . type . indexOf ( ';' ) ;
@@ -1366,6 +1403,27 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
13661403 </ div >
13671404 </ Show >
13681405 </ Show >
1406+ < Show when = { messages ( ) . length > 2 && followUpPromptsStatus ( ) } >
1407+ < Show when = { followUpPrompts ( ) . length > 0 } >
1408+ < >
1409+ < div class = "flex items-center gap-1 px-5" >
1410+ < SparklesIcon class = "w-4 h-4" />
1411+ < span class = "text-sm text-gray-700" > Try these prompts</ span >
1412+ </ div >
1413+ < div class = "w-full flex flex-row flex-wrap px-5 py-[10px] gap-2" >
1414+ < For each = { [ ...followUpPrompts ( ) ] } >
1415+ { ( prompt , index ) => (
1416+ < FollowUpPromptBubble
1417+ prompt = { prompt }
1418+ onPromptClick = { ( ) => followUpPromptClick ( prompt ) }
1419+ starterPromptFontSize = { botProps . starterPromptFontSize } // Pass it here as a number
1420+ />
1421+ ) }
1422+ </ For >
1423+ </ div >
1424+ </ >
1425+ </ Show >
1426+ </ Show >
13691427 < Show when = { previews ( ) . length > 0 } >
13701428 < div class = "w-full flex items-center justify-start gap-2 px-5 pt-2 border-t border-[#eeeeee]" >
13711429 < For each = { [ ...previews ( ) ] } > { ( item ) => < > { previewDisplay ( item ) } </ > } </ For >
0 commit comments