diff --git a/web/.umirc.ts b/web/.umirc.ts index 35279635d..db0fab9b0 100644 --- a/web/.umirc.ts +++ b/web/.umirc.ts @@ -1,40 +1,40 @@ -import { defineConfig } from 'umi'; -import { appName } from './src/conf.json'; -import routes from './src/routes'; - -export default defineConfig({ - title: appName, - outputPath: 'dist', - // alias: { '@': './src' }, - npmClient: 'npm', - base: '/', - routes, - publicPath: '/', - esbuildMinifyIIFE: true, - icons: {}, - hash: true, - favicons: ['/logo.svg'], - clickToComponent: {}, - history: { - type: 'browser', - }, - plugins: ['@react-dev-inspector/umi4-plugin', '@umijs/plugins/dist/dva'], - dva: {}, - - lessLoader: { - modifyVars: { - hack: `true; @import "~@/less/index.less";`, - }, - }, - devtool: 'source-map', - copy: ['src/conf.json'], - proxy: { - '/v1': { - target: '', - changeOrigin: true, - ws: true, - logger: console, - // pathRewrite: { '^/v1': '/v1' }, - }, - }, -}); +import { defineConfig } from 'umi'; +import { appName } from './src/conf.json'; +import routes from './src/routes'; + +export default defineConfig({ + title: appName, + outputPath: 'dist', + // alias: { '@': './src' }, + npmClient: 'npm', + base: '/', + routes, + publicPath: '/', + esbuildMinifyIIFE: true, + icons: {}, + hash: true, + favicons: ['/logo.svg'], + clickToComponent: {}, + history: { + type: 'browser', + }, + plugins: ['@react-dev-inspector/umi4-plugin', '@umijs/plugins/dist/dva'], + dva: {}, + + lessLoader: { + modifyVars: { + hack: `true; @import "~@/less/index.less";`, + }, + }, + devtool: 'source-map', + copy: ['src/conf.json'], + proxy: { + '/v1': { + target: '', + changeOrigin: true, + ws: true, + logger: console, + // pathRewrite: { '^/v1': '/v1' }, + }, + }, +}); diff --git a/web/src/components/message-item/index.less b/web/src/components/message-item/index.less index 4e6c3b304..cb6090d2e 100644 --- a/web/src/components/message-item/index.less +++ b/web/src/components/message-item/index.less @@ -4,10 +4,10 @@ display: inline-block; } .messageItemSectionLeft { - width: 70%; + width: 80%; } .messageItemSectionRight { - width: 40%; + width: 80%; } .messageItemContent { display: inline-flex; diff --git a/web/src/hooks/logicHooks.ts b/web/src/hooks/logicHooks.ts index 9fa960189..a386d1343 100644 --- a/web/src/hooks/logicHooks.ts +++ b/web/src/hooks/logicHooks.ts @@ -22,8 +22,13 @@ import { useTranslation } from 'react-i18next'; import { useDispatch } from 'umi'; import { useSetModalState, useTranslate } from './commonHooks'; import { useSetDocumentParser } from './documentHooks'; +import { useFetchLlmList } from './llmHooks'; import { useOneNamespaceEffectsLoading } from './storeHooks'; -import { useSaveSetting } from './userSettingHook'; +import { + useFetchTenantInfo, + useSaveSetting, + useSelectTenantInfo, +} from './userSettingHook'; export const useChangeDocumentParser = (documentId: string) => { const setDocumentParser = useSetDocumentParser(); @@ -269,3 +274,26 @@ export const useSelectItem = (defaultId?: string) => { return { selectedId, handleItemClick }; }; + +export const useFetchModelId = (visible: boolean) => { + const fetchTenantInfo = useFetchTenantInfo(false); + const tenantInfo = useSelectTenantInfo(); + + useEffect(() => { + if (visible) { + fetchTenantInfo(); + } + }, [visible, fetchTenantInfo]); + + return tenantInfo?.llm_id ?? ''; +}; + +export const useFetchLlmModelOnVisible = (visible: boolean) => { + const fetchLlmList = useFetchLlmList(); + + useEffect(() => { + if (visible) { + fetchLlmList(); + } + }, [fetchLlmList, visible]); +}; diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 9c009a6e1..9e11b6b3e 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -565,6 +565,17 @@ The above is the content you need to summarize.`, componentId: 'component id', add: 'Add', operation: 'operation', + beginDescription: 'This is where the flow begin', + answerDescription: `This component is used as an interface between bot and human. It receives input of user and display the result of the computation of the bot.`, + retrievalDescription: `This component is for the process of retrieving relevent information from knowledge base. So, knowledgebases should be selected. If there's nothing retrieved, the 'Empty response' will be returned.`, + generateDescription: `This component is used to call LLM to generate text. Be careful about the prompt setting.`, + categorizeDescription: `This component is used to categorize text. Please specify the name, description and examples of the category. Every single category leads to different downstream components.`, + relevantDescription: `This component is used to judge if the retrieved information is relevent to user's question. 'Yes' represents that they're relevant. 'No' represents they're irrelevant.`, + rewriteQuestionDescription: `This component is used to refine user's quesion. Typically, when a user's original question can't retrieve relevant information from knowledge base, this component help you change the question into a proper one which might be more consistant with the expressions in knowledge base. Only 'Retrieval' can be its downstreams.`, + messageDescription: + 'This component is used to send user static information.', + keywordDescription: + 'This component is used to send user static information.', }, footer: { profile: 'All rights reserved @ React', diff --git a/web/src/pages/chat/chat-configuration-modal/hooks.ts b/web/src/pages/chat/chat-configuration-modal/hooks.ts deleted file mode 100644 index 28db2b52b..000000000 --- a/web/src/pages/chat/chat-configuration-modal/hooks.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { useFetchLlmList } from '@/hooks/llmHooks'; -import { - useFetchTenantInfo, - useSelectTenantInfo, -} from '@/hooks/userSettingHook'; -import { useEffect } from 'react'; - -export const useFetchModelId = (visible: boolean) => { - const fetchTenantInfo = useFetchTenantInfo(false); - const tenantInfo = useSelectTenantInfo(); - - useEffect(() => { - if (visible) { - fetchTenantInfo(); - } - }, [visible, fetchTenantInfo]); - - return tenantInfo?.llm_id ?? ''; -}; - -export const useFetchLlmModelOnVisible = (visible: boolean) => { - const fetchLlmList = useFetchLlmList(); - - useEffect(() => { - if (visible) { - fetchLlmList(); - } - }, [fetchLlmList, visible]); -}; diff --git a/web/src/pages/chat/chat-configuration-modal/index.tsx b/web/src/pages/chat/chat-configuration-modal/index.tsx index d468c2bfd..580113a46 100644 --- a/web/src/pages/chat/chat-configuration-modal/index.tsx +++ b/web/src/pages/chat/chat-configuration-modal/index.tsx @@ -11,11 +11,11 @@ import camelCase from 'lodash/camelCase'; import { useEffect, useRef, useState } from 'react'; import { IPromptConfigParameters } from '../interface'; import AssistantSetting from './assistant-setting'; -import { useFetchLlmModelOnVisible, useFetchModelId } from './hooks'; import ModelSetting from './model-setting'; import PromptEngine from './prompt-engine'; import { useTranslate } from '@/hooks/commonHooks'; +import { useFetchLlmModelOnVisible, useFetchModelId } from '@/hooks/logicHooks'; import { getBase64FromUploadFileList } from '@/utils/fileUtil'; import { removeUselessFieldsFromValues } from '@/utils/form'; import styles from './index.less'; diff --git a/web/src/pages/flow/chat/drawer.tsx b/web/src/pages/flow/chat/drawer.tsx index 44c0078c8..baeec8a6f 100644 --- a/web/src/pages/flow/chat/drawer.tsx +++ b/web/src/pages/flow/chat/drawer.tsx @@ -1,16 +1,19 @@ +import { useFetchFlow } from '@/hooks/flow-hooks'; import { IModalProps } from '@/interfaces/common'; import { Drawer } from 'antd'; import FlowChatBox from './box'; const ChatDrawer = ({ visible, hideModal }: IModalProps) => { + const { data } = useFetchFlow(); + return ( 1278 ? '30%' : 470} + width={window.innerWidth > 1278 ? '40%' : 470} mask={false} // zIndex={10000} > diff --git a/web/src/pages/flow/constant.tsx b/web/src/pages/flow/constant.tsx index 60725de15..a266db7ae 100644 --- a/web/src/pages/flow/constant.tsx +++ b/web/src/pages/flow/constant.tsx @@ -1,3 +1,4 @@ +import { variableEnabledFieldMap } from '@/constants/chat'; import { BranchesOutlined, DatabaseOutlined, @@ -33,7 +34,7 @@ export const operatorIconMap = { export const operatorMap = { [Operator.Retrieval]: { - description: 'Retrieval description drjlftglrthjftl', + description: 'This is where the flow begin', backgroundColor: '#cad6e0', color: '#385974', }, @@ -47,7 +48,8 @@ export const operatorMap = { color: '#996464', }, [Operator.Answer]: { - description: 'Answer description', + description: + 'This component is used as an interface between bot and human. It receives input of user and display the result of the computation of the bot.', backgroundColor: '#f4816d', color: 'white', }, @@ -126,7 +128,15 @@ export const initialBeginValues = { prologue: `Hi! I'm your assistant, what can I do for you?`, }; +export const variableCheckBoxFieldMap = Object.keys( + variableEnabledFieldMap, +).reduce>((pre, cur) => { + pre[cur] = true; + return pre; +}, {}); + const initialLlmBaseValues = { + ...variableCheckBoxFieldMap, temperature: 0.1, top_p: 0.3, frequency_penalty: 0.7, @@ -196,7 +206,14 @@ export const RestrictedUpstreamMap = { [Operator.Answer]: [], [Operator.Retrieval]: [], [Operator.Generate]: [], - [Operator.Message]: [], + [Operator.Message]: [ + Operator.Begin, + Operator.Message, + Operator.Generate, + Operator.Retrieval, + Operator.RewriteQuestion, + Operator.Categorize, + ], [Operator.Relevant]: [], [Operator.RewriteQuestion]: [], }; diff --git a/web/src/pages/flow/flow-sider/index.tsx b/web/src/pages/flow/flow-sider/index.tsx index b5428abf5..80731f8d3 100644 --- a/web/src/pages/flow/flow-sider/index.tsx +++ b/web/src/pages/flow/flow-sider/index.tsx @@ -1,6 +1,7 @@ -import { Card, Flex, Layout, Space, Typography } from 'antd'; +import { useTranslate } from '@/hooks/commonHooks'; +import { Card, Flex, Layout, Space, Tooltip } from 'antd'; import classNames from 'classnames'; - +import lowerFirst from 'lodash/lowerFirst'; import { componentMenuList } from '../constant'; import { useHandleDrag } from '../hooks'; import OperatorIcon from '../operator-icon'; @@ -8,8 +9,6 @@ import styles from './index.less'; const { Sider } = Layout; -const { Text } = Typography; - interface IProps { setCollapsed: (width: boolean) => void; collapsed: boolean; @@ -17,6 +16,7 @@ interface IProps { const FlowSide = ({ setCollapsed, collapsed }: IProps) => { const { handleDragStart } = useHandleDrag(); + const { t } = useTranslate('flow'); return ( {
- {x.name} - - {x.description} - + + {x.name} +
diff --git a/web/src/pages/flow/hooks.ts b/web/src/pages/flow/hooks.ts index 6581da68c..d0776b9d8 100644 --- a/web/src/pages/flow/hooks.ts +++ b/web/src/pages/flow/hooks.ts @@ -17,13 +17,25 @@ import { ModelVariableType, settledModelVariableMap, } from '@/constants/knowledge'; +import { useFetchModelId } from '@/hooks/logicHooks'; import { Variable } from '@/interfaces/database/chat'; import { useDebounceEffect } from 'ahooks'; import { FormInstance, message } from 'antd'; import { humanId } from 'human-id'; import trim from 'lodash/trim'; import { useParams } from 'umi'; -import { NodeMap, Operator, RestrictedUpstreamMap } from './constant'; +import { + NodeMap, + Operator, + RestrictedUpstreamMap, + initialBeginValues, + initialCategorizeValues, + initialGenerateValues, + initialMessageValues, + initialRelevantValues, + initialRetrievalValues, + initialRewriteQuestionValues, +} from './constant'; import useGraphStore, { RFState } from './store'; import { buildDslComponentsByGraph } from './utils'; @@ -43,6 +55,32 @@ export const useSelectCanvasData = () => { return useGraphStore(selector); }; +export const useInitializeOperatorParams = () => { + const llmId = useFetchModelId(true); + + const initializeOperatorParams = useCallback( + (operatorName: Operator) => { + const initialFormValuesMap = { + [Operator.Begin]: initialBeginValues, + [Operator.Retrieval]: initialRetrievalValues, + [Operator.Generate]: { ...initialGenerateValues, llm_id: llmId }, + [Operator.Answer]: {}, + [Operator.Categorize]: { ...initialCategorizeValues, llm_id: llmId }, + [Operator.Relevant]: { ...initialRelevantValues, llm_id: llmId }, + [Operator.RewriteQuestion]: { + ...initialRewriteQuestionValues, + llm_id: llmId, + }, + [Operator.Message]: initialMessageValues, + }; + return initialFormValuesMap[operatorName]; + }, + [llmId], + ); + + return initializeOperatorParams; +}; + export const useHandleDrag = () => { const handleDragStart = useCallback( (operatorId: string) => (ev: React.DragEvent) => { @@ -59,6 +97,7 @@ export const useHandleDrop = () => { const addNode = useGraphStore((state) => state.addNode); const [reactFlowInstance, setReactFlowInstance] = useState>(); + const initializeOperatorParams = useInitializeOperatorParams(); const onDragOver = useCallback((event: React.DragEvent) => { event.preventDefault(); @@ -93,6 +132,7 @@ export const useHandleDrop = () => { data: { label: `${type}`, name: humanId(), + form: initializeOperatorParams(type as Operator), }, sourcePosition: Position.Right, targetPosition: Position.Left, @@ -100,7 +140,7 @@ export const useHandleDrop = () => { addNode(newNode); }, - [reactFlowInstance, addNode], + [reactFlowInstance, addNode, initializeOperatorParams], ); return { onDrop, onDragOver, setReactFlowInstance }; @@ -244,7 +284,10 @@ export const useSetLlmSetting = (form?: FormInstance) => { return pre; }, {}); const otherValues = settledModelVariableMap[ModelVariableType.Precise]; - form?.setFieldsValue({ ...switchBoxValues, ...otherValues }); + form?.setFieldsValue({ + ...switchBoxValues, + ...otherValues, + }); }, [form, initialLlmSetting]); }; diff --git a/web/src/pages/flow/list/index.less b/web/src/pages/flow/list/index.less index 00f7e26ac..17f646dab 100644 --- a/web/src/pages/flow/list/index.less +++ b/web/src/pages/flow/list/index.less @@ -56,6 +56,6 @@ } .templatesBox { - max-height: 500px; + // max-height: 500px; overflow: auto; } diff --git a/web/src/pages/flow/utils.ts b/web/src/pages/flow/utils.ts index 7fae2729b..fff2cf38e 100644 --- a/web/src/pages/flow/utils.ts +++ b/web/src/pages/flow/utils.ts @@ -2,11 +2,11 @@ import { DSLComponents } from '@/interfaces/database/flow'; import { removeUselessFieldsFromValues } from '@/utils/form'; import dagre from 'dagre'; import { humanId } from 'human-id'; -import { curry, isEmpty } from 'lodash'; +import { curry } from 'lodash'; import pipe from 'lodash/fp/pipe'; import { Edge, Node, Position } from 'reactflow'; import { v4 as uuidv4 } from 'uuid'; -import { NodeMap, Operator, initialFormValuesMap } from './constant'; +import { NodeMap, Operator } from './constant'; import { ICategorizeItemResult, NodeData } from './interface'; const buildEdges = ( @@ -143,17 +143,17 @@ const removeUselessDataInTheOperator = curry( }, ); // initialize data for operators without parameters -const initializeOperatorParams = curry((operatorName: string, values: any) => { - if (isEmpty(values)) { - return initialFormValuesMap[operatorName as Operator]; - } - return values; -}); +// const initializeOperatorParams = curry((operatorName: string, values: any) => { +// if (isEmpty(values)) { +// return initialFormValuesMap[operatorName as Operator]; +// } +// return values; +// }); const buildOperatorParams = (operatorName: string) => pipe( removeUselessDataInTheOperator(operatorName), - initializeOperatorParams(operatorName), // Final processing, for guarantee + // initializeOperatorParams(operatorName), // Final processing, for guarantee ); // construct a dsl based on the node information of the graph