fix: suggestion is not rendered

This commit is contained in:
G.Wood-Sun
2025-05-28 12:39:30 +08:00
parent 7495bf44a2
commit 60a33804cc
5 changed files with 57 additions and 9 deletions

View File

@ -21,6 +21,9 @@ const Button: FC<IButtonProps> = ({
}) => {
let style = 'cursor-pointer'
switch (type) {
case 'link':
style = disabled ? 'border-solid border border-gray-200 bg-gray-200 cursor-not-allowed text-gray-800' : 'border-solid border border-gray-200 cursor-pointer text-blue-600 bg-white hover:shadow-sm hover:border-gray-300'
break
case 'primary':
style = (disabled || loading) ? 'bg-primary-600/75 cursor-not-allowed text-white' : 'bg-primary-600 hover:bg-primary-600/75 hover:shadow-md cursor-pointer text-white hover:shadow-sm'
break

View File

@ -13,6 +13,7 @@ import type { ChatItem, MessageRating, VisionFile } from '@/types/app'
import Tooltip from '@/app/components/base/tooltip'
import WorkflowProcess from '@/app/components/workflow/workflow-process'
import { Markdown } from '@/app/components/base/markdown'
import Button from '@/app/components/base/button'
import type { Emoji } from '@/types/tools'
const OperationBtn = ({ innerContent, onClick, className }: { innerContent: React.ReactNode; onClick?: () => void; className?: string }) => (
@ -60,6 +61,7 @@ type IAnswerProps = {
onFeedback?: FeedbackFunc
isResponding?: boolean
allToolIcons?: Record<string, string | Emoji>
suggestionClick?: (suggestion: string) => void
}
// The component needs to maintain its own state to control whether to display input component
@ -69,8 +71,9 @@ const Answer: FC<IAnswerProps> = ({
onFeedback,
isResponding,
allToolIcons,
suggestionClick = () => { },
}) => {
const { id, content, feedback, agent_thoughts, workflowProcess } = item
const { id, content, feedback, agent_thoughts, workflowProcess, suggestedQuestions = [] } = item
const isAgentMode = !!agent_thoughts && agent_thoughts.length > 0
const { t } = useTranslation()
@ -192,6 +195,17 @@ const Answer: FC<IAnswerProps> = ({
: (
<Markdown content={content} />
))}
{suggestedQuestions.length > 0 && (
<div className='mt-3'>
<div className='flex gap-1 mt-1 flex-wrap'>
{suggestedQuestions.map((suggestion, index) => (
<div key={index} className='flex items-center gap-1'>
<Button className='text-sm' type='link' onClick={() => suggestionClick(suggestion)}>{suggestion}</Button>
</div>
))}
</div>
</div>
)}
</div>
<div className='absolute top-[-14px] right-[-14px] flex flex-row justify-end gap-1'>
{!feedbackDisabled && !item.feedbackDisabled && renderItemOperation()}

View File

@ -52,9 +52,12 @@ const Chat: FC<IChatProps> = ({
const isUseInputMethod = useRef(false)
const [query, setQuery] = React.useState('')
const queryRef = useRef('')
const handleContentChange = (e: any) => {
const value = e.target.value
setQuery(value)
queryRef.current = value
}
const logError = (message: string) => {
@ -62,16 +65,19 @@ const Chat: FC<IChatProps> = ({
}
const valid = () => {
const query = queryRef.current
if (!query || query.trim() === '') {
logError('Message cannot be empty')
logError(t('app.errorMessage.valueOfVarRequired'))
return false
}
return true
}
useEffect(() => {
if (controlClearQuery)
if (controlClearQuery) {
setQuery('')
queryRef.current = ''
}
}, [controlClearQuery])
const {
files,
@ -86,7 +92,7 @@ const Chat: FC<IChatProps> = ({
const handleSend = () => {
if (!valid() || (checkCanSend && !checkCanSend()))
return
onSend(query, files.filter(file => file.progress !== -1).map(fileItem => ({
onSend(queryRef.current, files.filter(file => file.progress !== -1).map(fileItem => ({
type: 'image',
transfer_method: fileItem.type,
url: fileItem.url,
@ -95,8 +101,10 @@ const Chat: FC<IChatProps> = ({
if (!files.find(item => item.type === TransferMethod.local_file && !item.fileId)) {
if (files.length)
onClear()
if (!isResponding)
if (!isResponding) {
setQuery('')
queryRef.current = ''
}
}
}
@ -112,11 +120,19 @@ const Chat: FC<IChatProps> = ({
const handleKeyDown = (e: any) => {
isUseInputMethod.current = e.nativeEvent.isComposing
if (e.code === 'Enter' && !e.shiftKey) {
setQuery(query.replace(/\n$/, ''))
const result = query.replace(/\n$/, '')
setQuery(result)
queryRef.current = result
e.preventDefault()
}
}
const suggestionClick = (suggestion: string) => {
setQuery(suggestion)
queryRef.current = suggestion
handleSend()
}
return (
<div className={cn(!feedbackDisabled && 'px-3.5', 'h-full')}>
{/* Chat List */}
@ -130,6 +146,7 @@ const Chat: FC<IChatProps> = ({
feedbackDisabled={feedbackDisabled}
onFeedback={onFeedback}
isResponding={isResponding && isLast}
suggestionClick={suggestionClick}
/>
}
return (

View File

@ -101,6 +101,7 @@ const Main: FC<IMainProps> = () => {
const conversationName = currConversationInfo?.name || t('app.chat.newChatDefaultName') as string
const conversationIntroduction = currConversationInfo?.introduction || ''
const suggestedQuestions = currConversationInfo?.suggested_questions || []
const handleConversationSwitch = () => {
if (!inited)
@ -117,6 +118,7 @@ const Main: FC<IMainProps> = () => {
setExistConversationInfo({
name: item?.name || '',
introduction: notSyncToStateIntroduction,
suggested_questions: suggestedQuestions,
})
}
else {
@ -192,6 +194,7 @@ const Main: FC<IMainProps> = () => {
name: t('app.chat.newChatDefaultName'),
inputs: newConversationInputs,
introduction: conversationIntroduction,
suggested_questions: suggestedQuestions,
})
}))
}
@ -209,6 +212,7 @@ const Main: FC<IMainProps> = () => {
isAnswer: true,
feedbackDisabled: true,
isOpeningStatement: isShowPrompt,
suggestedQuestions: suggestedQuestions,
}
if (calculatedIntroduction)
return [openStatement]
@ -233,15 +237,24 @@ const Main: FC<IMainProps> = () => {
return
}
const _conversationId = getConversationIdFromStorage(APP_ID)
const isNotNewConversation = conversations.some(item => item.id === _conversationId)
const currentConversation = conversations.find(item => item.id === _conversationId)
const isNotNewConversation = !!currentConversation
// fetch new conversation info
const { user_input_form, opening_statement: introduction, file_upload, system_parameters }: any = appParams
const { user_input_form, opening_statement: introduction, file_upload, system_parameters, suggested_questions = [] }: any = appParams
setLocaleOnClient(APP_INFO.default_language, true)
setNewConversationInfo({
name: t('app.chat.newChatDefaultName'),
introduction,
suggested_questions
})
if (isNotNewConversation) {
setExistConversationInfo({
name: currentConversation.name || t('app.chat.newChatDefaultName'),
introduction,
suggested_questions
})
}
const prompt_variables = userInputsFormToPromptVariables(user_input_form)
setPromptConfig({
prompt_template: promptTemplate,

View File

@ -102,7 +102,8 @@ export type ConversationItem = {
id: string
name: string
inputs: Record<string, any> | null
introduction: string
introduction: string,
suggested_questions?: string[]
}
export type AppInfo = {