### What problem does this PR solve? feat: run flow #918 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.8.0
| @@ -90,3 +90,22 @@ export const useDeleteFlow = () => { | |||
| return { data, loading, deleteFlow: mutateAsync }; | |||
| }; | |||
| export const useRunFlow = () => { | |||
| const { | |||
| data, | |||
| isPending: loading, | |||
| mutateAsync, | |||
| } = useMutation({ | |||
| mutationKey: ['runFlow'], | |||
| mutationFn: async (params: { id: string; dsl: DSL }) => { | |||
| const { data } = await flowService.runCanvas(params); | |||
| if (data.retcode === 0) { | |||
| message.success(i18n.t(`message.modified`)); | |||
| } | |||
| return data?.data ?? {}; | |||
| }, | |||
| }); | |||
| return { data, loading, runFlow: mutateAsync }; | |||
| }; | |||
| @@ -1,5 +1,3 @@ | |||
| import { ModelVariableType } from '@/constants/knowledge'; | |||
| export enum Operator { | |||
| Begin = 'Begin', | |||
| Retrieval = 'Retrieval', | |||
| @@ -18,8 +16,8 @@ export const initialBeginValues = { | |||
| }; | |||
| export const initialGenerateValues = { | |||
| parameters: ModelVariableType.Precise, | |||
| temperatureEnabled: false, | |||
| // parameters: ModelVariableType.Precise, | |||
| // temperatureEnabled: true, | |||
| temperature: 0.1, | |||
| top_p: 0.3, | |||
| frequency_penalty: 0.7, | |||
| @@ -30,3 +28,10 @@ export const initialGenerateValues = { | |||
| The above is the content you need to summarize.`, | |||
| cite: true, | |||
| }; | |||
| export const initialFormValuesMap = { | |||
| [Operator.Begin]: initialBeginValues, | |||
| [Operator.Retrieval]: initialRetrievalValues, | |||
| [Operator.Generate]: initialGenerateValues, | |||
| [Operator.Answer]: {}, | |||
| }; | |||
| @@ -1,10 +1,11 @@ | |||
| import { Button, Flex } from 'antd'; | |||
| import { useSaveGraph } from '../hooks'; | |||
| import { useRunGraph, useSaveGraph } from '../hooks'; | |||
| import styles from './index.less'; | |||
| const FlowHeader = () => { | |||
| const { saveGraph } = useSaveGraph(); | |||
| const { runGraph } = useRunGraph(); | |||
| return ( | |||
| <Flex | |||
| @@ -13,7 +14,7 @@ const FlowHeader = () => { | |||
| gap={'large'} | |||
| className={styles.flowHeader} | |||
| > | |||
| <Button> | |||
| <Button onClick={runGraph}> | |||
| <b>Debug</b> | |||
| </Button> | |||
| <Button type="primary" onClick={saveGraph}> | |||
| @@ -2,6 +2,7 @@ import { useSetModalState } from '@/hooks/commonHooks'; | |||
| import { | |||
| useFetchFlow, | |||
| useFetchFlowTemplates, | |||
| useRunFlow, | |||
| useSetFlow, | |||
| } from '@/hooks/flow-hooks'; | |||
| import { useFetchLlmList } from '@/hooks/llmHooks'; | |||
| @@ -83,7 +84,9 @@ export const useHandleDrop = () => { | |||
| x: 0, | |||
| y: 0, | |||
| }, | |||
| data: { label: `${type}` }, | |||
| data: { | |||
| label: `${type}`, | |||
| }, | |||
| sourcePosition: Position.Right, | |||
| targetPosition: Position.Left, | |||
| }; | |||
| @@ -141,7 +144,6 @@ export const useSaveGraph = () => { | |||
| const { nodes, edges } = useStore((state) => state); | |||
| const saveGraph = useCallback(() => { | |||
| const dslComponents = buildDslComponentsByGraph(nodes, edges); | |||
| console.info('components:', dslComponents); | |||
| setFlow({ | |||
| id, | |||
| title: data.title, | |||
| @@ -198,3 +200,19 @@ export const useFetchDataOnMount = () => { | |||
| export const useFlowIsFetching = () => { | |||
| return useIsFetching({ queryKey: ['flowDetail'] }) > 0; | |||
| }; | |||
| export const useRunGraph = () => { | |||
| const { data } = useFetchFlow(); | |||
| const { runFlow } = useRunFlow(); | |||
| const { id } = useParams(); | |||
| const { nodes, edges } = useStore((state) => state); | |||
| const runGraph = useCallback(() => { | |||
| const dslComponents = buildDslComponentsByGraph(nodes, edges); | |||
| runFlow({ | |||
| id: id!!, | |||
| dsl: { ...data.dsl, components: dslComponents }, | |||
| }); | |||
| }, [nodes, edges, runFlow, id, data]); | |||
| return { runGraph }; | |||
| }; | |||
| @@ -181,6 +181,6 @@ export const dsl = { | |||
| }, | |||
| }, | |||
| history: [], | |||
| path: ['begin'], | |||
| path: [], | |||
| answer: [], | |||
| }; | |||
| @@ -1,8 +1,11 @@ | |||
| import { DSLComponents } from '@/interfaces/database/flow'; | |||
| import { removeUselessFieldsFromValues } from '@/utils/form'; | |||
| import dagre from 'dagre'; | |||
| import { curry, isEmpty } from 'lodash'; | |||
| import pipe from 'lodash/fp/pipe'; | |||
| import { Edge, MarkerType, Node, Position } from 'reactflow'; | |||
| import { v4 as uuidv4 } from 'uuid'; | |||
| import { Operator, initialFormValuesMap } from './constant'; | |||
| import { NodeData } from './interface'; | |||
| const buildEdges = ( | |||
| @@ -109,15 +112,27 @@ const buildComponentDownstreamOrUpstream = ( | |||
| .map((y) => y[isBuildDownstream ? 'target' : 'source']); | |||
| }; | |||
| const removeUselessDataInTheOperator = ( | |||
| operatorName: string, | |||
| params: Record<string, unknown>, | |||
| ) => { | |||
| if (operatorName === 'Generate') { | |||
| return removeUselessFieldsFromValues(params, ''); | |||
| const removeUselessDataInTheOperator = curry( | |||
| (operatorName: string, params: Record<string, unknown>) => { | |||
| if (operatorName === Operator.Generate) { | |||
| return removeUselessFieldsFromValues(params, ''); | |||
| } | |||
| return params; | |||
| }, | |||
| ); | |||
| // initialize data for operators without parameters | |||
| const initializeOperatorParams = curry((operatorName: string, values: any) => { | |||
| if (isEmpty(values)) { | |||
| return initialFormValuesMap[operatorName as Operator]; | |||
| } | |||
| return params; | |||
| }; | |||
| return values; | |||
| }); | |||
| const buildOperatorParams = (operatorName: string) => | |||
| pipe( | |||
| removeUselessDataInTheOperator(operatorName), | |||
| initializeOperatorParams(operatorName), // Final processing, for guarantee | |||
| ); | |||
| // construct a dsl based on the node information of the graph | |||
| export const buildDslComponentsByGraph = ( | |||
| @@ -132,9 +147,13 @@ export const buildDslComponentsByGraph = ( | |||
| components[id] = { | |||
| obj: { | |||
| component_name: operatorName, | |||
| // params: | |||
| // removeUselessDataInTheOperator( | |||
| // operatorName, | |||
| // x.data.form as Record<string, unknown>, | |||
| // ) ?? {}, | |||
| params: | |||
| removeUselessDataInTheOperator( | |||
| operatorName, | |||
| buildOperatorParams(operatorName)( | |||
| x.data.form as Record<string, unknown>, | |||
| ) ?? {}, | |||
| }, | |||
| @@ -8,6 +8,7 @@ const { | |||
| listCanvas, | |||
| resetCanvas, | |||
| removeCanvas, | |||
| runCanvas, | |||
| listTemplates, | |||
| } = api; | |||
| @@ -32,6 +33,10 @@ const methods = { | |||
| url: removeCanvas, | |||
| method: 'post', | |||
| }, | |||
| runCanvas: { | |||
| url: runCanvas, | |||
| method: 'post', | |||
| }, | |||
| listTemplates: { | |||
| url: listTemplates, | |||
| method: 'get', | |||
| @@ -89,4 +89,5 @@ export default { | |||
| removeCanvas: `${api_host}/canvas/rm`, | |||
| setCanvas: `${api_host}/canvas/set`, | |||
| resetCanvas: `${api_host}/canvas/reset`, | |||
| runCanvas: `${api_host}/canvas/run`, | |||
| }; | |||
| @@ -3,7 +3,7 @@ import omit from 'lodash/omit'; | |||
| // chat model setting and generate operator | |||
| export const excludeUnEnabledVariables = ( | |||
| values: any, | |||
| values: any = {}, | |||
| prefix = 'llm_setting.', | |||
| ) => { | |||
| const unEnabledFields: Array<keyof typeof variableEnabledFieldMap> = | |||