diff --git a/web/src/pages/agent/constant.tsx b/web/src/pages/agent/constant.tsx index f308e0727..a52d9892f 100644 --- a/web/src/pages/agent/constant.tsx +++ b/web/src/pages/agent/constant.tsx @@ -27,6 +27,7 @@ import { ReactComponent as TemplateIcon } from '@/assets/svg/template.svg'; import { ReactComponent as TuShareIcon } from '@/assets/svg/tushare.svg'; import { ReactComponent as WenCaiIcon } from '@/assets/svg/wencai.svg'; import { ReactComponent as YahooFinanceIcon } from '@/assets/svg/yahoo-finance.svg'; +import { CodeTemplateStrMap, ProgrammingLanguage } from '@/constants/agent'; // 邮件功能 @@ -56,6 +57,7 @@ import upperFirst from 'lodash/upperFirst'; import { CirclePower, CloudUpload, + CodeXml, IterationCcw, ListOrdered, OptionIcon, @@ -103,6 +105,7 @@ export enum Operator { Email = 'Email', Iteration = 'Iteration', IterationStart = 'IterationItem', + Code = 'Code', } export const CommonOperatorList = Object.values(Operator).filter( @@ -161,6 +164,7 @@ export const operatorIconMap = { [Operator.Email]: EmailIcon, [Operator.Iteration]: IterationCcw, [Operator.IterationStart]: CirclePower, + [Operator.Code]: CodeXml, }; export const operatorMap: Record< @@ -299,6 +303,7 @@ export const operatorMap: Record< [Operator.Email]: { backgroundColor: '#e6f7ff' }, [Operator.Iteration]: { backgroundColor: '#e6f7ff' }, [Operator.IterationStart]: { backgroundColor: '#e6f7ff' }, + [Operator.Code]: { backgroundColor: '#4c5458' }, }; export const componentMenuList = [ @@ -336,6 +341,9 @@ export const componentMenuList = [ { name: Operator.Iteration, }, + { + name: Operator.Code, + }, { name: Operator.Note, }, @@ -645,6 +653,19 @@ export const initialIterationValues = { }; export const initialIterationStartValues = {}; +export const initialCodeValues = { + lang: 'python', + script: CodeTemplateStrMap[ProgrammingLanguage.Python], + arguments: [ + { + name: 'arg1', + }, + { + name: 'arg2', + }, + ], +}; + export const CategorizeAnchorPointPositions = [ { top: 1, right: 34 }, { top: 8, right: 18 }, @@ -726,6 +747,7 @@ export const RestrictedUpstreamMap = { [Operator.Email]: [Operator.Begin], [Operator.Iteration]: [Operator.Begin], [Operator.IterationStart]: [Operator.Begin], + [Operator.Code]: [Operator.Begin], }; export const NodeMap = { @@ -765,6 +787,7 @@ export const NodeMap = { [Operator.Email]: 'emailNode', [Operator.Iteration]: 'group', [Operator.IterationStart]: 'iterationStartNode', + [Operator.Code]: 'ragNode', }; export const LanguageOptions = [ diff --git a/web/src/pages/agent/form-sheet/next.tsx b/web/src/pages/agent/form-sheet/next.tsx index 7335844c2..cecb7a3f0 100644 --- a/web/src/pages/agent/form-sheet/next.tsx +++ b/web/src/pages/agent/form-sheet/next.tsx @@ -98,7 +98,7 @@ const FormSheet = ({ return ( - +
diff --git a/web/src/pages/agent/form-sheet/use-form-config-map.tsx b/web/src/pages/agent/form-sheet/use-form-config-map.tsx index 4371b7471..9cde6628d 100644 --- a/web/src/pages/agent/form-sheet/use-form-config-map.tsx +++ b/web/src/pages/agent/form-sheet/use-form-config-map.tsx @@ -9,6 +9,7 @@ import BaiduForm from '../form/baidu-form'; import BeginForm from '../form/begin-form'; import BingForm from '../form/bing-form'; import CategorizeForm from '../form/categorize-form'; +import CodeForm from '../form/code-form'; import CrawlerForm from '../form/crawler-form'; import DeepLForm from '../form/deepl-form'; import DuckDuckGoForm from '../form/duckduckgo-form'; @@ -130,6 +131,17 @@ export function useFormConfigMap() { language: z.string(), }), }, + [Operator.Code]: { + component: CodeForm, + defaultValues: { + message_history_window_size: 6, + }, + schema: z.object({ + llm_id: z.string(), + message_history_window_size: z.number(), + language: z.string(), + }), + }, [Operator.Baidu]: { component: BaiduForm, defaultValues: { top_n: 10 }, diff --git a/web/src/pages/agent/form/code-form/dynamic-input-variable.tsx b/web/src/pages/agent/form/code-form/dynamic-input-variable.tsx new file mode 100644 index 000000000..8fc55c0be --- /dev/null +++ b/web/src/pages/agent/form/code-form/dynamic-input-variable.tsx @@ -0,0 +1,66 @@ +import { RAGFlowNodeType } from '@/interfaces/database/flow'; +import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; +import { Button, Form, Input, Select } from 'antd'; +import { useTranslation } from 'react-i18next'; +import { useBuildComponentIdSelectOptions } from '../../hooks/use-get-begin-query'; +import { FormCollapse } from '../components/dynamic-input-variable'; + +type DynamicInputVariableProps = { + name?: string; + node?: RAGFlowNodeType; +}; + +export const DynamicInputVariable = ({ + name = 'arguments', + node, +}: DynamicInputVariableProps) => { + const { t } = useTranslation(); + + const valueOptions = useBuildComponentIdSelectOptions( + node?.id, + node?.parentId, + ); + + return ( + + + {(fields, { add, remove }) => ( + <> + {fields.map(({ key, name, ...restField }) => ( +
+ + + + + + + remove(name)} /> +
+ ))} + + + + + )} +
+
+ ); +}; diff --git a/web/src/pages/agent/form/code-form/index.tsx b/web/src/pages/agent/form/code-form/index.tsx new file mode 100644 index 000000000..e081b40c1 --- /dev/null +++ b/web/src/pages/agent/form/code-form/index.tsx @@ -0,0 +1,84 @@ +import Editor, { loader } from '@monaco-editor/react'; +import { INextOperatorForm } from '../../interface'; +import { DynamicInputVariable } from './dynamic-input-variable'; + +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@/components/ui/form'; +import { RAGFlowSelect } from '@/components/ui/select'; +import { ProgrammingLanguage } from '@/constants/agent'; +import { ICodeForm } from '@/interfaces/database/flow'; +import { useTranslation } from 'react-i18next'; + +loader.config({ paths: { vs: '/vs' } }); + +const options = [ + ProgrammingLanguage.Python, + ProgrammingLanguage.Javascript, +].map((x) => ({ value: x, label: x })); + +const CodeForm = ({ form, node }: INextOperatorForm) => { + const formData = node?.data.form as ICodeForm; + const { t } = useTranslation(); + + // useEffect(() => { + // setTimeout(() => { + // // TODO: Direct operation zustand is more elegant + // form?.setFieldValue( + // 'script', + // CodeTemplateStrMap[formData.lang as ProgrammingLanguage], + // ); + // }, 0); + // }, [form, formData.lang]); + + return ( +
+ + ( + + + ( + + + {t('channel')} + + + + + + + )} + /> + + + + + + + )} + /> + + ); +}; + +export default CodeForm; diff --git a/web/src/pages/agent/hooks.tsx b/web/src/pages/agent/hooks.tsx index 969f386b4..5319434e5 100644 --- a/web/src/pages/agent/hooks.tsx +++ b/web/src/pages/agent/hooks.tsx @@ -40,6 +40,7 @@ import { initialBeginValues, initialBingValues, initialCategorizeValues, + initialCodeValues, initialConcentratorValues, initialCrawlerValues, initialDeepLValues, @@ -141,6 +142,7 @@ export const useInitializeOperatorParams = () => { [Operator.Email]: initialEmailValues, [Operator.Iteration]: initialIterationValues, [Operator.IterationStart]: initialIterationValues, + [Operator.Code]: initialCodeValues, }; }, [llmId]);