mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-05-17 09:26:57 +08:00
94 lines
3.4 KiB
TypeScript
94 lines
3.4 KiB
TypeScript
'use client'
|
|
import type { FC } from 'react'
|
|
import React from 'react'
|
|
import cn from 'classnames'
|
|
import { useTranslation } from 'react-i18next'
|
|
import type { ThoughtItem } from '../type'
|
|
import s from './style.module.css'
|
|
import { DataSet as DataSetIcon, Loading as LodingIcon, Search, ThoughtList, WebReader } from '@/app/components/base/icons/src/public/thought'
|
|
import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows'
|
|
import type { DataSet } from '@/models/datasets'
|
|
|
|
export type IThoughtProps = {
|
|
list: ThoughtItem[]
|
|
isThinking?: boolean
|
|
dataSets?: DataSet[]
|
|
}
|
|
|
|
const getIcon = (toolId: string) => {
|
|
switch (toolId) {
|
|
case 'dataset':
|
|
return <DataSetIcon />
|
|
case 'web_reader':
|
|
return <WebReader />
|
|
default:
|
|
return <Search />
|
|
}
|
|
}
|
|
|
|
const Thought: FC<IThoughtProps> = ({
|
|
list,
|
|
isThinking,
|
|
dataSets,
|
|
}) => {
|
|
const { t } = useTranslation()
|
|
const [isShowDetail, setIsShowDetail] = React.useState(false)
|
|
|
|
const getThoughtText = (item: ThoughtItem) => {
|
|
try {
|
|
const input = JSON.parse(item.tool_input)
|
|
// dataset
|
|
if (item.tool.startsWith('dataset-')) {
|
|
const dataSetId = item.tool.replace('dataset-', '')
|
|
const datasetName = dataSets?.find(item => item.id === dataSetId)?.name || 'unknown dataset'
|
|
return t('explore.universalChat.thought.res.dataset').replace('{datasetName}', `<span class="text-gray-700">${datasetName}</span>`)
|
|
}
|
|
switch (item.tool) {
|
|
case 'web_reader':
|
|
return t(`explore.universalChat.thought.res.webReader.${!input.cursor ? 'normal' : 'hasPageInfo'}`).replace('{url}', `<a href="${input.url}" class="text-[#155EEF]">${input.url}</a>`)
|
|
case 'google_search':
|
|
return t('explore.universalChat.thought.res.google', { query: input.query })
|
|
case 'wikipedia':
|
|
return t('explore.universalChat.thought.res.wikipedia', { query: input.query })
|
|
case 'current_datetime':
|
|
return t('explore.universalChat.thought.res.date')
|
|
default:
|
|
return `Unknown tool: ${item.tool}`
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.error(error)
|
|
return item
|
|
}
|
|
}
|
|
const renderItem = (item: ThoughtItem) => (
|
|
<div className='flex space-x-1 py-[3px] leading-[18px]' key={item.id}>
|
|
<div className='flex items-center h-[18px] shrink-0'>{getIcon(item.tool)}</div>
|
|
<div dangerouslySetInnerHTML={{
|
|
__html: getThoughtText(item),
|
|
// item.thought.replace(urlRegex, (url) => {
|
|
// return `<a href="${url}" class="text-[#155EEF]">${url}</a>`
|
|
// }),
|
|
}}></div>
|
|
</div>
|
|
)
|
|
return (
|
|
<div className={cn(s.wrap, !isShowDetail && s.wrapHoverEffect, 'inline-block mb-2 px-2 py-0.5 rounded-md text-xs text-gray-500 font-medium')} >
|
|
<div className='flex items-center h-6 space-x-1 cursor-pointer' onClick={() => setIsShowDetail(!isShowDetail)} >
|
|
{!isThinking ? <ThoughtList /> : <div className='animate-spin'><LodingIcon /></div>}
|
|
<div dangerouslySetInnerHTML= {{
|
|
__html: isThinking ? getThoughtText(list[list.length - 1]) : (t(`explore.universalChat.thought.${isShowDetail ? 'hide' : 'show'}`) + t('explore.universalChat.thought.processOfThought')),
|
|
}}
|
|
></div>
|
|
<ChevronDown className={isShowDetail ? 'rotate-180' : '' } />
|
|
</div>
|
|
{isShowDetail && (
|
|
<div>
|
|
{list.map(item => renderItem(item))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|
|
export default React.memo(Thought)
|