Feat/chat add origin (#1130)

This commit is contained in:
zxhlyh
2023-09-09 19:17:12 +08:00
committed by GitHub
parent 6effcd3755
commit 84c76bc04a
74 changed files with 2454 additions and 28 deletions

View File

@@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { UserCircleIcon } from '@heroicons/react/24/solid'
import cn from 'classnames'
import type { DisplayScene, FeedbackFunc, Feedbacktype, IChatItem, SubmitAnnotationFunc, ThoughtItem } from '../type'
import type { CitationItem, DisplayScene, FeedbackFunc, Feedbacktype, IChatItem, SubmitAnnotationFunc, ThoughtItem } from '../type'
import OperationBtn from '../operation'
import LoadingAnim from '../loading-anim'
import { EditIcon, EditIconSolid, OpeningStatementIcon, RatingIcon } from '../icon-component'
@@ -13,6 +13,7 @@ import s from '../style.module.css'
import MoreInfo from '../more-info'
import CopyBtn from '../copy-btn'
import Thought from '../thought'
import Citation from '../citation'
import { randomString } from '@/utils'
import type { Annotation, MessageRating } from '@/models/log'
import AppContext from '@/context/app-context'
@@ -45,11 +46,14 @@ export type IAnswerProps = {
isResponsing?: boolean
answerIconClassName?: string
thoughts?: ThoughtItem[]
citation?: CitationItem[]
isThinking?: boolean
dataSets?: DataSet[]
isShowCitation?: boolean
isShowCitationHitInfo?: boolean
}
// The component needs to maintain its own state to control whether to display input component
const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedbackEdit = false, onFeedback, onSubmitAnnotation, displayScene = 'web', isResponsing, answerIconClassName, thoughts, isThinking, dataSets }) => {
const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedbackEdit = false, onFeedback, onSubmitAnnotation, displayScene = 'web', isResponsing, answerIconClassName, thoughts, citation, isThinking, dataSets, isShowCitation, isShowCitationHitInfo = false }) => {
const { id, content, more, feedback, adminFeedback, annotation: initAnnotation } = item
const [showEdit, setShowEdit] = useState(false)
const [loading, setLoading] = useState(false)
@@ -171,7 +175,7 @@ const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedba
</div>
}
</div>
<div className={s.answerWrapWrap}>
<div className={cn(s.answerWrapWrap, 'chat-answer-container')}>
<div className={`${s.answerWrap} ${showEdit ? 'w-full' : ''}`}>
<div className={`${s.answer} relative text-sm text-gray-900`}>
<div className={'ml-2 py-3 px-4 bg-gray-100 rounded-tr-2xl rounded-b-2xl'}>
@@ -237,6 +241,11 @@ const Answer: FC<IAnswerProps> = ({ item, feedbackDisabled = false, isHideFeedba
</div>
</>
}
{
!!citation?.length && !isThinking && isShowCitation && !isResponsing && (
<Citation data={citation} showHitInfo={isShowCitationHitInfo} />
)
}
</div>
<div className='absolute top-[-14px] right-[-14px] flex flex-row justify-end gap-1'>
{!item.isOpeningStatement && (

View File

@@ -0,0 +1,123 @@
import { useEffect, useMemo, useRef, useState } from 'react'
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import type { CitationItem } from '../type'
import Popup from './popup'
import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows'
export type Resources = {
documentId: string
documentName: string
dataSourceType: string
sources: CitationItem[]
}
type CitationProps = {
data: CitationItem[]
showHitInfo?: boolean
}
const Citation: FC<CitationProps> = ({
data,
showHitInfo,
}) => {
const { t } = useTranslation()
const elesRef = useRef<HTMLDivElement[]>([])
const [limitNumberInOneLine, setlimitNumberInOneLine] = useState(0)
const [showMore, setShowMore] = useState(false)
const resources = useMemo(() => data.reduce((prev: Resources[], next) => {
const documentId = next.document_id
const documentName = next.document_name
const dataSourceType = next.data_source_type
const documentIndex = prev.findIndex(i => i.documentId === documentId)
if (documentIndex > -1) {
prev[documentIndex].sources.push(next)
}
else {
prev.push({
documentId,
documentName,
dataSourceType,
sources: [next],
})
}
return prev
}, []), [data])
const handleAdjustResourcesLayout = () => {
const containerWidth = document.querySelector('.chat-answer-container')!.clientWidth - 40
let totalWidth = 0
for (let i = 0; i < resources.length; i++) {
totalWidth += elesRef.current[i].clientWidth
if (totalWidth + i * 4 > containerWidth!) {
totalWidth -= elesRef.current[i].clientWidth
if (totalWidth + 34 > containerWidth!)
setlimitNumberInOneLine(i - 1)
else
setlimitNumberInOneLine(i)
break
}
else {
setlimitNumberInOneLine(i + 1)
}
}
}
useEffect(() => {
handleAdjustResourcesLayout()
}, [])
const resourcesLength = resources.length
return (
<div className='mt-3 -mb-1'>
<div className='flex items-center mb-2 text-xs font-medium text-gray-500'>
{t('common.chat.citation.title')}
<div className='grow ml-2 h-[1px] bg-black/5' />
</div>
<div className='relative flex flex-wrap'>
{
resources.map((res, index) => (
<div
key={index}
className='absolute top-0 left-0 w-auto mr-1 mb-1 pl-7 pr-2 max-w-[240px] h-7 text-xs whitespace-nowrap opacity-0 -z-10'
ref={ele => (elesRef.current[index] = ele!)}
>
{res.documentName}
</div>
))
}
{
resources.slice(0, showMore ? resourcesLength : limitNumberInOneLine).map((res, index) => (
<div key={index} className='mr-1 mb-1 cursor-pointer'>
<Popup
data={res}
showHitInfo={showHitInfo}
/>
</div>
))
}
{
limitNumberInOneLine < resourcesLength && (
<div
className='flex items-center px-2 h-7 bg-white rounded-lg text-xs font-medium text-gray-500 cursor-pointer'
onClick={() => setShowMore(v => !v)}
>
{
!showMore
? `+ ${resourcesLength - limitNumberInOneLine}`
: <ChevronDown className='w-4 h-4 text-gray-600 rotate-180' />
}
</div>
)
}
</div>
</div>
)
}
export default Citation

View File

@@ -0,0 +1,123 @@
import { Fragment, useState } from 'react'
import type { FC } from 'react'
import Link from 'next/link'
import { useTranslation } from 'react-i18next'
import Tooltip from './tooltip'
import ProgressTooltip from './progress-tooltip'
import type { Resources } from './index'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import FileIcon from '@/app/components/base/file-icon'
import {
Hash02,
Target04,
} from '@/app/components/base/icons/src/vender/line/general'
import { ArrowUpRight } from '@/app/components/base/icons/src/vender/line/arrows'
import {
BezierCurve03,
TypeSquare,
} from '@/app/components/base/icons/src/vender/line/editor'
type PopupProps = {
data: Resources
showHitInfo?: boolean
}
const Popup: FC<PopupProps> = ({
data,
showHitInfo = false,
}) => {
const { t } = useTranslation()
const [open, setOpen] = useState(false)
const fileType = data.dataSourceType === 'upload_file'
? (/\.([^.]*)$/g.exec(data.documentName)?.[1] || '')
: 'notion'
return (
<PortalToFollowElem
open={open}
onOpenChange={setOpen}
placement='top-start'
offset={{
mainAxis: 8,
crossAxis: -2,
}}
>
<PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
<div className='flex items-center px-2 max-w-[240px] h-7 bg-white rounded-lg'>
<FileIcon type={fileType} className='mr-1 w-4 h-4' />
<div className='text-xs text-gray-600 truncate'>{data.documentName}</div>
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent style={{ zIndex: 1000 }}>
<div className='w-[360px] bg-gray-50 rounded-xl shadow-lg'>
<div className='px-4 pt-3 pb-2'>
<div className='flex items-center h-[18px]'>
<FileIcon type={fileType} className='mr-1 w-4 h-4' />
<div className='text-xs font-medium text-gray-600 truncate'>{data.documentName}</div>
</div>
</div>
<div className='px-4 py-0.5 max-h-[450px] bg-white rounded-lg overflow-auto'>
{
data.sources.map((source, index) => (
<Fragment key={index}>
<div className='group py-3'>
{
showHitInfo && (
<div className='flex items-center justify-between mb-2'>
<div className='flex items-center px-1.5 h-5 border border-gray-200 rounded-md'>
<Hash02 className='mr-0.5 w-3 h-3 text-gray-400' />
<div className='text-[11px] font-medium text-gray-500'>{source.segment_position}</div>
</div>
<Link
href={`/datasets/${source.dataset_id}/documents/${source.document_id}`}
className='hidden items-center h-[18px] text-xs text-primary-600 group-hover:flex'>
Link to dataset
<ArrowUpRight className='ml-1 w-3 h-3' />
</Link>
</div>
)
}
<div className='text-[13px] text-gray-800'>{source.content}</div>
{
showHitInfo && (
<div className='flex items-center mt-2 text-xs font-medium text-gray-500'>
<Tooltip
text={t('common.chat.citation.characters')}
data={source.word_count}
icon={<TypeSquare className='mr-1 w-3 h-3' />}
/>
<Tooltip
text={t('common.chat.citation.hitCount')}
data={source.hit_count}
icon={<Target04 className='mr-1 w-3 h-3' />}
/>
<Tooltip
text={t('common.chat.citation.vectorHash')}
data={source.index_node_hash.substring(0, 7)}
icon={<BezierCurve03 className='mr-1 w-3 h-3' />}
/>
<ProgressTooltip data={Number(source.score.toFixed(2))} />
</div>
)
}
</div>
{
index !== data.sources.length - 1 && (
<div className='my-1 h-[1px] bg-black/5' />
)
}
</Fragment>
))
}
</div>
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)
}
export default Popup

View File

@@ -0,0 +1,46 @@
import { useState } from 'react'
import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
type ProgressTooltipProps = {
data: number
}
const ProgressTooltip: FC<ProgressTooltipProps> = ({
data,
}) => {
const { t } = useTranslation()
const [open, setOpen] = useState(false)
return (
<PortalToFollowElem
open={open}
onOpenChange={setOpen}
placement='top-start'
>
<PortalToFollowElemTrigger
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
>
<div className='grow flex items-center'>
<div className='mr-1 w-16 h-1.5 rounded-[3px] border border-gray-400 overflow-hidden'>
<div className='bg-gray-400 h-full' style={{ width: `${data * 100}%` }}></div>
</div>
{data}
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent style={{ zIndex: 1001 }}>
<div className='p-3 bg-white text-xs font-medium text-gray-500 rounded-lg shadow-lg'>
{t('common.chat.citation.hitScore')} {data}
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)
}
export default ProgressTooltip

View File

@@ -0,0 +1,46 @@
import React, { useState } from 'react'
import type { FC } from 'react'
import {
PortalToFollowElem,
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
type TooltipProps = {
data: number | string
text: string
icon: React.ReactNode
}
const Tooltip: FC<TooltipProps> = ({
data,
text,
icon,
}) => {
const [open, setOpen] = useState(false)
return (
<PortalToFollowElem
open={open}
onOpenChange={setOpen}
placement='top-start'
>
<PortalToFollowElemTrigger
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
>
<div className='flex items-center mr-6'>
{icon}
{data}
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent style={{ zIndex: 1001 }}>
<div className='p-3 bg-white text-xs font-medium text-gray-500 rounded-lg shadow-lg'>
{text} {data}
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)
}
export default Tooltip

View File

@@ -48,9 +48,11 @@ export type IChatProps = {
isShowSuggestion?: boolean
suggestionList?: string[]
isShowSpeechToText?: boolean
isShowCitation?: boolean
answerIconClassName?: string
isShowConfigElem?: boolean
dataSets?: DataSet[]
isShowCitationHitInfo?: boolean
}
const Chat: FC<IChatProps> = ({
@@ -74,9 +76,11 @@ const Chat: FC<IChatProps> = ({
isShowSuggestion,
suggestionList,
isShowSpeechToText,
isShowCitation,
answerIconClassName,
isShowConfigElem,
dataSets,
isShowCitationHitInfo,
}) => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
@@ -162,6 +166,7 @@ const Chat: FC<IChatProps> = ({
if (item.isAnswer) {
const isLast = item.id === chatList[chatList.length - 1].id
const thoughts = item.agent_thoughts?.filter(item => item.thought !== '[DONE]')
const citation = item.citation
const isThinking = !item.content && item.agent_thoughts && item.agent_thoughts?.length > 0 && !item.agent_thoughts.some(item => item.thought === '[DONE]')
return <Answer
key={item.id}
@@ -174,8 +179,11 @@ const Chat: FC<IChatProps> = ({
isResponsing={isResponsing && isLast}
answerIconClassName={answerIconClassName}
thoughts={thoughts}
citation={citation}
isThinking={isThinking}
dataSets={dataSets}
isShowCitation={isShowCitation}
isShowCitationHitInfo={isShowCitationHitInfo}
/>
}
return <Question key={item.id} id={item.id} content={item.content} more={item.more} useCurrentUserAvatar={useCurrentUserAvatar} />

View File

@@ -23,10 +23,26 @@ export type ThoughtItem = {
tool_input: string
message_id: string
}
export type CitationItem = {
content: string
data_source_type: string
dataset_name: string
dataset_id: string
document_id: string
document_name: string
hit_count: number
index_node_hash: string
segment_id: string
segment_position: number
score: number
word_count: number
}
export type IChatItem = {
id: string
content: string
agent_thoughts?: ThoughtItem[]
citation?: CitationItem[]
/**
* Specific message type
*/
@@ -51,3 +67,8 @@ export type IChatItem = {
useCurrentUserAvatar?: boolean
isOpeningStatement?: boolean
}
export type MessageEnd = {
id: string
retriever_resources?: CitationItem[]
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 175 KiB

View File

@@ -26,4 +26,8 @@
.speechToTextPreview {
background-image: url(./preview-imgs/speech-to-text.svg);
}
.citationPreview {
background-image: url(./preview-imgs/citation.svg);
}

View File

@@ -8,11 +8,13 @@ import FeatureItem from './feature-item'
import Modal from '@/app/components/base/modal'
import SuggestedQuestionsAfterAnswerIcon from '@/app/components/app/configuration/base/icons/suggested-questions-after-answer-icon'
import { Microphone01 } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices'
import { Citations } from '@/app/components/base/icons/src/vender/solid/editor'
type IConfig = {
openingStatement: boolean
moreLikeThis: boolean
suggestedQuestionsAfterAnswer: boolean
speechToText: boolean
citation: boolean
}
export type IChooseFeatureProps = {
@@ -85,6 +87,14 @@ const ChooseFeature: FC<IChooseFeatureProps> = ({
/>
)
}
<FeatureItem
icon={<Citations className='w-4 h-4 text-[#FD853A]' />}
previewImgClassName='citationPreview'
title={t('appDebug.feature.citation.title')}
description={t('appDebug.feature.citation.description')}
value={config.citation}
onChange={value => onChange('citation', value)}
/>
</>
</FeatureGroup>
)}

View File

@@ -9,6 +9,8 @@ function useFeature({
setSuggestedQuestionsAfterAnswer,
speechToText,
setSpeechToText,
citation,
setCitation,
}: {
introduction: string
setIntroduction: (introduction: string) => void
@@ -18,6 +20,8 @@ function useFeature({
setSuggestedQuestionsAfterAnswer: (suggestedQuestionsAfterAnswer: boolean) => void
speechToText: boolean
setSpeechToText: (speechToText: boolean) => void
citation: boolean
setCitation: (citation: boolean) => void
}) {
const [tempshowOpeningStatement, setTempShowOpeningStatement] = React.useState(!!introduction)
useEffect(() => {
@@ -36,6 +40,7 @@ function useFeature({
moreLikeThis,
suggestedQuestionsAfterAnswer,
speechToText,
citation,
}
const handleFeatureChange = (key: string, value: boolean) => {
switch (key) {
@@ -53,6 +58,9 @@ function useFeature({
break
case 'speechToText':
setSpeechToText(value)
break
case 'citation':
setCitation(value)
}
}
return {

View File

@@ -36,6 +36,8 @@ const Config: FC = () => {
setSuggestedQuestionsAfterAnswerConfig,
speechToTextConfig,
setSpeechToTextConfig,
citationConfig,
setCitationConfig,
} = useContext(ConfigContext)
const isChatApp = mode === AppType.chat
const { speech2textDefaultModel } = useProviderContext()
@@ -88,9 +90,15 @@ const Config: FC = () => {
draft.enabled = value
}))
},
citation: citationConfig.enabled,
setCitation: (value) => {
setCitationConfig(produce(citationConfig, (draft) => {
draft.enabled = value
}))
},
})
const hasChatConfig = isChatApp && (featureConfig.openingStatement || featureConfig.suggestedQuestionsAfterAnswer || (featureConfig.speechToText && !!speech2textDefaultModel))
const hasChatConfig = isChatApp && (featureConfig.openingStatement || featureConfig.suggestedQuestionsAfterAnswer || (featureConfig.speechToText && !!speech2textDefaultModel) || featureConfig.citation)
const hasToolbox = false
const [showAutomatic, { setTrue: showAutomaticTrue, setFalse: showAutomaticFalse }] = useBoolean(false)
@@ -161,6 +169,7 @@ const Config: FC = () => {
}
isShowSuggestedQuestionsAfterAnswer={featureConfig.suggestedQuestionsAfterAnswer}
isShowSpeechText={featureConfig.speechToText && !!speech2textDefaultModel}
isShowCitation={featureConfig.citation}
/>
)
}

View File

@@ -40,6 +40,7 @@ const Debug: FC<IDebug> = ({
introduction,
suggestedQuestionsAfterAnswerConfig,
speechToTextConfig,
citationConfig,
moreLikeThisConfig,
inputs,
// setInputs,
@@ -162,6 +163,7 @@ const Debug: FC<IDebug> = ({
},
suggested_questions_after_answer: suggestedQuestionsAfterAnswerConfig,
speech_to_text: speechToTextConfig,
retriever_resource: citationConfig,
agent_mode: {
enabled: true,
tools: [...postDatasets],
@@ -199,7 +201,7 @@ const Debug: FC<IDebug> = ({
setChatList(newList)
// answer
const responseItem = {
const responseItem: IChatItem = {
id: `${Date.now()}`,
content: '',
isAnswer: true,
@@ -266,6 +268,19 @@ const Debug: FC<IDebug> = ({
setIsShowSuggestion(true)
}
},
onMessageEnd: (messageEnd) => {
responseItem.citation = messageEnd.retriever_resources
const newListWithAnswer = produce(
getChatList().filter(item => item.id !== responseItem.id && item.id !== placeholderAnswerId),
(draft) => {
if (!draft.find(item => item.id === questionId))
draft.push({ ...questionItem })
draft.push({ ...responseItem })
})
setChatList(newListWithAnswer)
},
onError() {
setResponsingFalse()
// role back placeholder answer
@@ -312,6 +327,7 @@ const Debug: FC<IDebug> = ({
opening_statement: introduction,
suggested_questions_after_answer: suggestedQuestionsAfterAnswerConfig,
speech_to_text: speechToTextConfig,
retriever_resource: citationConfig,
more_like_this: moreLikeThisConfig,
agent_mode: {
enabled: true,
@@ -391,6 +407,8 @@ const Debug: FC<IDebug> = ({
isShowSuggestion={doShowSuggestion}
suggestionList={suggestQuestions}
isShowSpeechToText={speechToTextConfig.enabled && !!speech2textDefaultModel}
isShowCitation={citationConfig.enabled}
isShowCitationHitInfo
/>
</div>
</div>

View File

@@ -0,0 +1,25 @@
'use client'
import React, { type FC } from 'react'
import { useTranslation } from 'react-i18next'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import { Citations } from '@/app/components/base/icons/src/vender/solid/editor'
const Citation: FC = () => {
const { t } = useTranslation()
return (
<Panel
title={
<div className='flex items-center gap-2'>
<div>{t('appDebug.feature.citation.title')}</div>
</div>
}
headerIcon={<Citations className='w-4 h-4 text-[#FD853A]' />}
headerRight={
<div className='text-xs text-gray-500'>{t('appDebug.feature.citation.resDes')}</div>
}
noBodySpacing
/>
)
}
export default React.memo(Citation)

View File

@@ -7,6 +7,7 @@ import type { IOpeningStatementProps } from './opening-statement'
import OpeningStatement from './opening-statement'
import SuggestedQuestionsAfterAnswer from './suggested-questions-after-answer'
import SpeechToText from './speech-to-text'
import Citation from './citation'
/*
* Include
@@ -19,12 +20,14 @@ type ChatGroupProps = {
openingStatementConfig: IOpeningStatementProps
isShowSuggestedQuestionsAfterAnswer: boolean
isShowSpeechText: boolean
isShowCitation: boolean
}
const ChatGroup: FC<ChatGroupProps> = ({
isShowOpeningStatement,
openingStatementConfig,
isShowSuggestedQuestionsAfterAnswer,
isShowSpeechText,
isShowCitation,
}) => {
const { t } = useTranslation()
@@ -43,6 +46,11 @@ const ChatGroup: FC<ChatGroupProps> = ({
<SpeechToText />
)
}
{
isShowCitation && (
<Citation />
)
}
</div>
</div>
)

View File

@@ -56,6 +56,9 @@ const Configuration: FC = () => {
const [speechToTextConfig, setSpeechToTextConfig] = useState<MoreLikeThisConfig>({
enabled: false,
})
const [citationConfig, setCitationConfig] = useState<MoreLikeThisConfig>({
enabled: false,
})
const [formattingChanged, setFormattingChanged] = useState(false)
const [inputs, setInputs] = useState<Inputs>({})
const [query, setQuery] = useState('')
@@ -77,6 +80,7 @@ const Configuration: FC = () => {
more_like_this: null,
suggested_questions_after_answer: null,
speech_to_text: null,
retriever_resource: null,
dataSets: [],
})
@@ -110,6 +114,9 @@ const Configuration: FC = () => {
setSpeechToTextConfig(modelConfig.speech_to_text || {
enabled: false,
})
setCitationConfig(modelConfig.retriever_resource || {
enabled: false,
})
}
const { textGenerationModelList } = useProviderContext()
@@ -159,6 +166,9 @@ const Configuration: FC = () => {
if (modelConfig.speech_to_text)
setSpeechToTextConfig(modelConfig.speech_to_text)
if (modelConfig.retriever_resource)
setCitationConfig(modelConfig.retriever_resource)
const config = {
modelConfig: {
provider: model.provider,
@@ -171,6 +181,7 @@ const Configuration: FC = () => {
more_like_this: modelConfig.more_like_this,
suggested_questions_after_answer: modelConfig.suggested_questions_after_answer,
speech_to_text: modelConfig.speech_to_text,
retriever_resource: modelConfig.retriever_resource,
dataSets: datasets || [],
},
completionParams: model.completion_params,
@@ -202,6 +213,7 @@ const Configuration: FC = () => {
more_like_this: moreLikeThisConfig,
suggested_questions_after_answer: suggestedQuestionsAfterAnswerConfig,
speech_to_text: speechToTextConfig,
retriever_resource: citationConfig,
agent_mode: {
enabled: true,
tools: [...postDatasets],
@@ -219,6 +231,7 @@ const Configuration: FC = () => {
draft.more_like_this = moreLikeThisConfig
draft.suggested_questions_after_answer = suggestedQuestionsAfterAnswerConfig
draft.speech_to_text = speechToTextConfig
draft.retriever_resource = citationConfig
draft.dataSets = dataSets
})
setPublishedConfig({
@@ -263,6 +276,8 @@ const Configuration: FC = () => {
setSuggestedQuestionsAfterAnswerConfig,
speechToTextConfig,
setSpeechToTextConfig,
citationConfig,
setCitationConfig,
formattingChanged,
setFormattingChanged,
inputs,