| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  | import React, { useState } from 'react' | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  | import { useTranslation } from 'react-i18next' | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   RiEqualizer2Line, | 
					
						
							|  |  |  | } from '@remixicon/react' | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  | import Image from 'next/image' | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  | import Button from '../../base/button' | 
					
						
							|  |  |  | import { getIcon } from '../common/retrieval-method-info' | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  | import ModifyExternalRetrievalModal from './modify-external-retrieval-modal' | 
					
						
							| 
									
										
										
										
											2024-08-26 13:00:02 +08:00
										 |  |  | import Tooltip from '@/app/components/base/tooltip' | 
					
						
							| 
									
										
										
										
											2024-07-09 15:05:40 +08:00
										 |  |  | import cn from '@/utils/classnames' | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  | import type { ExternalKnowledgeBaseHitTestingResponse, HitTestingResponse } from '@/models/datasets' | 
					
						
							|  |  |  | import { externalKnowledgeBaseHitTesting, hitTesting } from '@/service/datasets' | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  | import { asyncRunSafe } from '@/utils' | 
					
						
							|  |  |  | import { RETRIEVE_METHOD, type RetrievalConfig } from '@/types/app' | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  | import promptS from '@/app/components/app/configuration/config-prompt/style.module.css' | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 11:19:57 +08:00
										 |  |  | type TextAreaWithButtonIProps = { | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |   datasetId: string | 
					
						
							|  |  |  |   onUpdateList: () => void | 
					
						
							|  |  |  |   setHitResult: (res: HitTestingResponse) => void | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |   setExternalHitResult: (res: ExternalKnowledgeBaseHitTestingResponse) => void | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |   loading: boolean | 
					
						
							|  |  |  |   setLoading: (v: boolean) => void | 
					
						
							|  |  |  |   text: string | 
					
						
							|  |  |  |   setText: (v: string) => void | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |   isExternal?: boolean | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |   onClickRetrievalMethod: () => void | 
					
						
							|  |  |  |   retrievalConfig: RetrievalConfig | 
					
						
							|  |  |  |   isEconomy: boolean | 
					
						
							| 
									
										
										
										
											2023-11-27 11:47:48 +08:00
										 |  |  |   onSubmit?: () => void | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-27 11:47:48 +08:00
										 |  |  | const TextAreaWithButton = ({ | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |   datasetId, | 
					
						
							|  |  |  |   onUpdateList, | 
					
						
							|  |  |  |   setHitResult, | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |   setExternalHitResult, | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |   setLoading, | 
					
						
							|  |  |  |   loading, | 
					
						
							|  |  |  |   text, | 
					
						
							|  |  |  |   setText, | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |   isExternal = false, | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |   onClickRetrievalMethod, | 
					
						
							|  |  |  |   retrievalConfig, | 
					
						
							|  |  |  |   isEconomy, | 
					
						
							| 
									
										
										
										
											2023-11-27 11:47:48 +08:00
										 |  |  |   onSubmit: _onSubmit, | 
					
						
							|  |  |  | }: TextAreaWithButtonIProps) => { | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |   const { t } = useTranslation() | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |   const [isSettingsOpen, setIsSettingsOpen] = useState(false) | 
					
						
							|  |  |  |   const [externalRetrievalSettings, setExternalRetrievalSettings] = useState({ | 
					
						
							|  |  |  |     top_k: 2, | 
					
						
							|  |  |  |     score_threshold: 0.5, | 
					
						
							|  |  |  |     score_threshold_enabled: false, | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const handleSaveExternalRetrievalSettings = (data: { top_k: number; score_threshold: number; score_threshold_enabled: boolean }) => { | 
					
						
							|  |  |  |     setExternalRetrievalSettings(data) | 
					
						
							|  |  |  |     setIsSettingsOpen(false) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   function handleTextChange(event: any) { | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |     setText(event.target.value) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const onSubmit = async () => { | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |     setLoading(true) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     const [e, res] = await asyncRunSafe<HitTestingResponse>( | 
					
						
							| 
									
										
										
										
											2024-04-17 17:40:28 +08:00
										 |  |  |       hitTesting({ | 
					
						
							|  |  |  |         datasetId, | 
					
						
							|  |  |  |         queryText: text, | 
					
						
							|  |  |  |         retrieval_model: { | 
					
						
							|  |  |  |           ...retrievalConfig, | 
					
						
							|  |  |  |           search_method: isEconomy ? RETRIEVE_METHOD.keywordSearch : retrievalConfig.search_method, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }) as Promise<HitTestingResponse>, | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     if (!e) { | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |       setHitResult(res) | 
					
						
							|  |  |  |       onUpdateList?.() | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |     setLoading(false) | 
					
						
							| 
									
										
										
										
											2023-11-27 11:47:48 +08:00
										 |  |  |     _onSubmit && _onSubmit() | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |   const externalRetrievalTestingOnSubmit = async () => { | 
					
						
							| 
									
										
										
										
											2025-01-21 14:31:45 +08:00
										 |  |  |     setLoading(true) | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |     const [e, res] = await asyncRunSafe<ExternalKnowledgeBaseHitTestingResponse>( | 
					
						
							|  |  |  |       externalKnowledgeBaseHitTesting({ | 
					
						
							|  |  |  |         datasetId, | 
					
						
							|  |  |  |         query: text, | 
					
						
							|  |  |  |         external_retrieval_model: { | 
					
						
							|  |  |  |           top_k: externalRetrievalSettings.top_k, | 
					
						
							|  |  |  |           score_threshold: externalRetrievalSettings.score_threshold, | 
					
						
							|  |  |  |           score_threshold_enabled: externalRetrievalSettings.score_threshold_enabled, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }) as Promise<ExternalKnowledgeBaseHitTestingResponse>, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     if (!e) { | 
					
						
							|  |  |  |       setExternalHitResult(res) | 
					
						
							|  |  |  |       onUpdateList?.() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     setLoading(false) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |   const retrievalMethod = isEconomy ? RETRIEVE_METHOD.invertedIndex : retrievalConfig.search_method | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |   const icon = <Image className='size-3.5 text-util-colors-purple-purple-600' src={getIcon(retrievalMethod)} alt='' /> | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |   return ( | 
					
						
							|  |  |  |     <> | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |       <div className={cn('relative rounded-xl', promptS.gradientBorder)}> | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |         <div className='relative rounded-t-xl bg-background-section-burn pt-1.5'> | 
					
						
							|  |  |  |           <div className="flex h-8 items-center justify-between pb-1 pl-4 pr-1.5"> | 
					
						
							|  |  |  |             <span className="text-[13px] font-semibold uppercase leading-4 text-text-secondary"> | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |               {t('datasetHitTesting.input.title')} | 
					
						
							|  |  |  |             </span> | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |             {isExternal | 
					
						
							|  |  |  |               ? <Button | 
					
						
							|  |  |  |                 variant='secondary' | 
					
						
							|  |  |  |                 size='small' | 
					
						
							|  |  |  |                 onClick={() => setIsSettingsOpen(!isSettingsOpen)} | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |               > | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 <RiEqualizer2Line className='h-3.5 w-3.5 text-components-button-secondary-text' /> | 
					
						
							|  |  |  |                 <div className='flex items-center justify-center gap-1 px-[3px]'> | 
					
						
							|  |  |  |                   <span className='system-xs-medium text-components-button-secondary-text'>{t('datasetHitTesting.settingTitle')}</span> | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |                 </div> | 
					
						
							|  |  |  |               </Button> | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |               : <div | 
					
						
							|  |  |  |                 onClick={onClickRetrievalMethod} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 className='flex h-7 cursor-pointer items-center space-x-0.5 rounded-lg border-[0.5px] border-components-button-secondary-bg bg-components-button-secondary-bg px-1.5 shadow-xs backdrop-blur-[5px] hover:bg-components-button-secondary-bg-hover' | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |               > | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |                 {icon} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 <div className='text-xs font-medium uppercase text-text-secondary'>{t(`dataset.retrieval.${retrievalMethod}.title`)}</div> | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |                 <RiEqualizer2Line className='size-4 text-components-menu-item-text'></RiEqualizer2Line> | 
					
						
							|  |  |  |               </div> | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |           </div> | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |           { | 
					
						
							|  |  |  |             isSettingsOpen && ( | 
					
						
							|  |  |  |               <ModifyExternalRetrievalModal | 
					
						
							|  |  |  |                 onClose={() => setIsSettingsOpen(false)} | 
					
						
							|  |  |  |                 onSave={handleSaveExternalRetrievalSettings} | 
					
						
							|  |  |  |                 initialTopK={externalRetrievalSettings.top_k} | 
					
						
							|  |  |  |                 initialScoreThreshold={externalRetrievalSettings.score_threshold} | 
					
						
							|  |  |  |                 initialScoreThresholdEnabled={externalRetrievalSettings.score_threshold_enabled} | 
					
						
							|  |  |  |               /> | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2025-03-19 11:19:57 +08:00
										 |  |  |           <div className='h-2 rounded-t-xl bg-background-default'></div> | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |         </div> | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |         <div className='rounded-b-xl bg-background-default px-4 pb-11'> | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |           <textarea | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |             className='h-[220px] w-full resize-none border-none bg-transparent text-sm font-normal text-text-secondary caret-[#295EFF]  placeholder:text-sm placeholder:font-normal placeholder:text-components-input-text-placeholder focus-visible:outline-none' | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |             value={text} | 
					
						
							|  |  |  |             onChange={handleTextChange} | 
					
						
							|  |  |  |             placeholder={t('datasetHitTesting.input.placeholder') as string} | 
					
						
							|  |  |  |           /> | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |           <div className="absolute inset-x-0 bottom-0 mx-4 mb-2 mt-2 flex items-center justify-between"> | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |             {text?.length > 200 | 
					
						
							|  |  |  |               ? ( | 
					
						
							|  |  |  |                 <Tooltip | 
					
						
							| 
									
										
										
										
											2024-08-26 13:00:02 +08:00
										 |  |  |                   popupContent={t('datasetHitTesting.input.countWarning')} | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |                 > | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |                   <div | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                     className={cn('flex h-5 items-center rounded-md bg-background-section-burn px-1 text-xs font-medium text-red-600', !text?.length && 'opacity-50')} | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |                   > | 
					
						
							|  |  |  |                     {text?.length} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                     <span className="mx-0.5 text-red-300">/</span> | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |                     200 | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |                   </div> | 
					
						
							|  |  |  |                 </Tooltip> | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  |               : ( | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |                 <div | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                   className={cn('flex h-5 items-center rounded-md bg-background-section-burn px-1 text-xs font-medium text-text-tertiary', !text?.length && 'opacity-50')} | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |                 > | 
					
						
							|  |  |  |                   {text?.length} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                   <span className="mx-0.5 text-divider-deep">/</span> | 
					
						
							| 
									
										
										
										
											2024-04-17 17:40:28 +08:00
										 |  |  |                   200 | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |                 </div> | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |               )} | 
					
						
							| 
									
										
										
										
											2024-04-17 17:40:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             <div> | 
					
						
							|  |  |  |               <Button | 
					
						
							| 
									
										
										
										
											2024-09-30 15:38:43 +08:00
										 |  |  |                 onClick={isExternal ? externalRetrievalTestingOnSubmit : onSubmit} | 
					
						
							| 
									
										
										
										
											2024-06-19 14:13:16 +08:00
										 |  |  |                 variant="primary" | 
					
						
							| 
									
										
										
										
											2024-04-17 17:40:28 +08:00
										 |  |  |                 loading={loading} | 
					
						
							|  |  |  |                 disabled={(!text?.length || text?.length > 200)} | 
					
						
							| 
									
										
										
										
											2024-12-26 12:01:51 +08:00
										 |  |  |                 className='w-[88px]' | 
					
						
							| 
									
										
										
										
											2024-04-17 17:40:28 +08:00
										 |  |  |               > | 
					
						
							|  |  |  |                 {t('datasetHitTesting.input.testing')} | 
					
						
							|  |  |  |               </Button> | 
					
						
							|  |  |  |             </div> | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |           </div> | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |         </div> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     </> | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-18 11:53:35 +08:00
										 |  |  | export default TextAreaWithButton |