2024-02-20 18:10:20 +08:00
import SimilaritySlider from '@/components/similarity-slider' ;
2024-03-20 18:20:42 +08:00
import { DeleteOutlined , QuestionCircleOutlined } from '@ant-design/icons' ;
2024-02-19 19:16:23 +08:00
import {
Button ,
Col ,
Divider ,
Form ,
Input ,
Row ,
2024-02-20 18:10:20 +08:00
Slider ,
2024-02-19 19:16:23 +08:00
Switch ,
Table ,
TableProps ,
2024-03-20 18:20:42 +08:00
Tooltip ,
2024-02-19 19:16:23 +08:00
} from 'antd' ;
import classNames from 'classnames' ;
2024-02-20 18:10:20 +08:00
import {
ForwardedRef ,
forwardRef ,
useEffect ,
useImperativeHandle ,
useState ,
} from 'react' ;
2024-02-19 19:16:23 +08:00
import { v4 as uuid } from 'uuid' ;
2024-02-22 17:14:25 +08:00
import {
VariableTableDataType as DataType ,
IPromptConfigParameters ,
ISegmentedContentProps ,
} from '../interface' ;
2024-02-19 19:16:23 +08:00
import { EditableCell , EditableRow } from './editable-cell' ;
2024-02-22 17:14:25 +08:00
import { useSelectPromptConfigParameters } from '../hooks' ;
2024-02-19 19:16:23 +08:00
import styles from './index.less' ;
2024-02-20 18:10:20 +08:00
type FieldType = {
similarity_threshold? : number ;
vector_similarity_weight? : number ;
top_n? : number ;
} ;
2024-02-19 19:16:23 +08:00
2024-02-20 18:10:20 +08:00
const PromptEngine = (
2024-02-22 17:14:25 +08:00
{ show } : ISegmentedContentProps ,
ref : ForwardedRef < Array < IPromptConfigParameters > > ,
2024-02-20 18:10:20 +08:00
) = > {
2024-02-19 19:16:23 +08:00
const [ dataSource , setDataSource ] = useState < DataType [ ] > ( [ ] ) ;
2024-02-22 17:14:25 +08:00
const parameters = useSelectPromptConfigParameters ( ) ;
2024-02-19 19:16:23 +08:00
const components = {
body : {
row : EditableRow ,
cell : EditableCell ,
} ,
} ;
const handleRemove = ( key : string ) = > ( ) = > {
const newData = dataSource . filter ( ( item ) = > item . key !== key ) ;
setDataSource ( newData ) ;
} ;
const handleSave = ( row : DataType ) = > {
const newData = [ . . . dataSource ] ;
const index = newData . findIndex ( ( item ) = > row . key === item . key ) ;
const item = newData [ index ] ;
newData . splice ( index , 1 , {
. . . item ,
. . . row ,
} ) ;
setDataSource ( newData ) ;
} ;
2024-02-20 18:10:20 +08:00
const handleAdd = ( ) = > {
setDataSource ( ( state ) = > [
. . . state ,
{
key : uuid ( ) ,
variable : '' ,
optional : true ,
} ,
] ) ;
} ;
const handleOptionalChange = ( row : DataType ) = > ( checked : boolean ) = > {
const newData = [ . . . dataSource ] ;
const index = newData . findIndex ( ( item ) = > row . key === item . key ) ;
const item = newData [ index ] ;
newData . splice ( index , 1 , {
. . . item ,
optional : checked ,
} ) ;
setDataSource ( newData ) ;
} ;
useImperativeHandle (
ref ,
( ) = > {
return dataSource
. filter ( ( x ) = > x . variable . trim ( ) !== '' )
. map ( ( x ) = > ( { key : x.variable , optional : x.optional } ) ) ;
} ,
[ dataSource ] ,
) ;
2024-02-19 19:16:23 +08:00
const columns : TableProps < DataType > [ 'columns' ] = [
{
title : 'key' ,
dataIndex : 'variable' ,
key : 'variable' ,
onCell : ( record : DataType ) = > ( {
record ,
editable : true ,
dataIndex : 'variable' ,
title : 'key' ,
handleSave ,
} ) ,
} ,
{
title : 'optional' ,
dataIndex : 'optional' ,
key : 'optional' ,
width : 40 ,
align : 'center' ,
2024-02-20 18:10:20 +08:00
render ( text , record ) {
return (
< Switch
size = "small"
checked = { text }
onChange = { handleOptionalChange ( record ) }
/ >
) ;
2024-02-19 19:16:23 +08:00
} ,
} ,
{
title : 'operation' ,
dataIndex : 'operation' ,
width : 30 ,
key : 'operation' ,
align : 'center' ,
render ( _ , record ) {
return < DeleteOutlined onClick = { handleRemove ( record . key ) } / > ;
} ,
} ,
] ;
2024-02-22 17:14:25 +08:00
useEffect ( ( ) = > {
setDataSource ( parameters ) ;
} , [ parameters ] ) ;
2024-02-19 19:16:23 +08:00
return (
< section
className = { classNames ( {
[ styles . segmentedHidden ] : ! show ,
} ) }
>
< Form.Item
2024-02-22 17:14:25 +08:00
label = "System"
2024-02-19 19:16:23 +08:00
rules = { [ { required : true , message : 'Please input!' } ] }
2024-03-22 15:35:06 +08:00
tooltip = "Instructions you need LLM to follow when LLM answers questions, like charactor design, answer length and answer language etc."
2024-02-20 18:10:20 +08:00
name = { [ 'prompt_config' , 'system' ] }
initialValue = { ` 你是一个智能助手,请总结知识库的内容来回答问题,请列举知识库中的数据详细回答。当所有知识库内容都与问题无关时,你的回答必须包括“知识库中未找到您要的答案!”这句话。回答需要考虑聊天历史。
以 下 是 知 识 库 :
{ knowledge }
以 上 是 知 识 库 。 ` }
2024-02-19 19:16:23 +08:00
>
2024-02-22 17:14:25 +08:00
< Input.TextArea autoSize = { { maxRows : 8 , minRows : 5 } } / >
2024-02-19 19:16:23 +08:00
< / Form.Item >
< Divider > < / Divider >
2024-03-05 12:01:48 +08:00
< SimilaritySlider isTooltipShown > < / SimilaritySlider >
< Form.Item < FieldType >
2024-03-22 15:35:06 +08:00
label = "Top N"
2024-03-05 12:01:48 +08:00
name = { 'top_n' }
initialValue = { 8 }
2024-03-22 15:35:06 +08:00
tooltip = { ` Not all the chunks whose similarity score is above the 'simialrity threashold' will be feed to LLMs. LLM can only see these 'Top N' chunks. ` }
2024-03-05 12:01:48 +08:00
>
2024-02-20 18:10:20 +08:00
< Slider max = { 30 } / >
< / Form.Item >
2024-02-19 19:16:23 +08:00
< section className = { classNames ( styles . variableContainer ) } >
< Row align = { 'middle' } justify = "end" >
2024-03-20 18:20:42 +08:00
< Col span = { 7 } className = { styles . variableAlign } >
< label className = { styles . variableLabel } >
Variables
2024-03-22 15:35:06 +08:00
< Tooltip title = " If you use dialog APIs , the varialbes might help you chat with your clients with different strategies.
The variables are used to fill - in the 'System' part in prompt in order to give LLM a hint .
The 'knowledge' is a very special variable which will be filled - in with the retrieved chunks .
All the variables in 'System' should be curly bracketed . " >
2024-03-20 18:20:42 +08:00
< QuestionCircleOutlined className = { styles . variableIcon } / >
< / Tooltip >
< / label >
2024-02-19 19:16:23 +08:00
< / Col >
2024-03-20 18:20:42 +08:00
< Col span = { 17 } className = { styles . variableAlign } >
2024-02-19 19:16:23 +08:00
< Button size = "small" onClick = { handleAdd } >
Add
< / Button >
< / Col >
< / Row >
{ dataSource . length > 0 && (
< Row >
2024-03-20 18:20:42 +08:00
< Col span = { 7 } > < / Col >
< Col span = { 17 } >
2024-02-19 19:16:23 +08:00
< Table
dataSource = { dataSource }
columns = { columns }
rowKey = { 'key' }
className = { styles . variableTable }
components = { components }
rowClassName = { ( ) = > styles . editableRow }
/ >
< / Col >
< / Row >
) }
< / section >
< / section >
) ;
} ;
2024-02-20 18:10:20 +08:00
export default forwardRef ( PromptEngine ) ;