### What problem does this PR solve? Feat: Migrate the code operator to the new agent. #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.19.x
| import { ReactComponent as TuShareIcon } from '@/assets/svg/tushare.svg'; | import { ReactComponent as TuShareIcon } from '@/assets/svg/tushare.svg'; | ||||
| import { ReactComponent as WenCaiIcon } from '@/assets/svg/wencai.svg'; | import { ReactComponent as WenCaiIcon } from '@/assets/svg/wencai.svg'; | ||||
| import { ReactComponent as YahooFinanceIcon } from '@/assets/svg/yahoo-finance.svg'; | import { ReactComponent as YahooFinanceIcon } from '@/assets/svg/yahoo-finance.svg'; | ||||
| import { CodeTemplateStrMap, ProgrammingLanguage } from '@/constants/agent'; | |||||
| // 邮件功能 | // 邮件功能 | ||||
| import { | import { | ||||
| CirclePower, | CirclePower, | ||||
| CloudUpload, | CloudUpload, | ||||
| CodeXml, | |||||
| IterationCcw, | IterationCcw, | ||||
| ListOrdered, | ListOrdered, | ||||
| OptionIcon, | OptionIcon, | ||||
| Email = 'Email', | Email = 'Email', | ||||
| Iteration = 'Iteration', | Iteration = 'Iteration', | ||||
| IterationStart = 'IterationItem', | IterationStart = 'IterationItem', | ||||
| Code = 'Code', | |||||
| } | } | ||||
| export const CommonOperatorList = Object.values(Operator).filter( | export const CommonOperatorList = Object.values(Operator).filter( | ||||
| [Operator.Email]: EmailIcon, | [Operator.Email]: EmailIcon, | ||||
| [Operator.Iteration]: IterationCcw, | [Operator.Iteration]: IterationCcw, | ||||
| [Operator.IterationStart]: CirclePower, | [Operator.IterationStart]: CirclePower, | ||||
| [Operator.Code]: CodeXml, | |||||
| }; | }; | ||||
| export const operatorMap: Record< | export const operatorMap: Record< | ||||
| [Operator.Email]: { backgroundColor: '#e6f7ff' }, | [Operator.Email]: { backgroundColor: '#e6f7ff' }, | ||||
| [Operator.Iteration]: { backgroundColor: '#e6f7ff' }, | [Operator.Iteration]: { backgroundColor: '#e6f7ff' }, | ||||
| [Operator.IterationStart]: { backgroundColor: '#e6f7ff' }, | [Operator.IterationStart]: { backgroundColor: '#e6f7ff' }, | ||||
| [Operator.Code]: { backgroundColor: '#4c5458' }, | |||||
| }; | }; | ||||
| export const componentMenuList = [ | export const componentMenuList = [ | ||||
| { | { | ||||
| name: Operator.Iteration, | name: Operator.Iteration, | ||||
| }, | }, | ||||
| { | |||||
| name: Operator.Code, | |||||
| }, | |||||
| { | { | ||||
| name: Operator.Note, | name: Operator.Note, | ||||
| }, | }, | ||||
| }; | }; | ||||
| export const initialIterationStartValues = {}; | export const initialIterationStartValues = {}; | ||||
| export const initialCodeValues = { | |||||
| lang: 'python', | |||||
| script: CodeTemplateStrMap[ProgrammingLanguage.Python], | |||||
| arguments: [ | |||||
| { | |||||
| name: 'arg1', | |||||
| }, | |||||
| { | |||||
| name: 'arg2', | |||||
| }, | |||||
| ], | |||||
| }; | |||||
| export const CategorizeAnchorPointPositions = [ | export const CategorizeAnchorPointPositions = [ | ||||
| { top: 1, right: 34 }, | { top: 1, right: 34 }, | ||||
| { top: 8, right: 18 }, | { top: 8, right: 18 }, | ||||
| [Operator.Email]: [Operator.Begin], | [Operator.Email]: [Operator.Begin], | ||||
| [Operator.Iteration]: [Operator.Begin], | [Operator.Iteration]: [Operator.Begin], | ||||
| [Operator.IterationStart]: [Operator.Begin], | [Operator.IterationStart]: [Operator.Begin], | ||||
| [Operator.Code]: [Operator.Begin], | |||||
| }; | }; | ||||
| export const NodeMap = { | export const NodeMap = { | ||||
| [Operator.Email]: 'emailNode', | [Operator.Email]: 'emailNode', | ||||
| [Operator.Iteration]: 'group', | [Operator.Iteration]: 'group', | ||||
| [Operator.IterationStart]: 'iterationStartNode', | [Operator.IterationStart]: 'iterationStartNode', | ||||
| [Operator.Code]: 'ragNode', | |||||
| }; | }; | ||||
| export const LanguageOptions = [ | export const LanguageOptions = [ |
| return ( | return ( | ||||
| <Sheet open={visible} modal={false}> | <Sheet open={visible} modal={false}> | ||||
| <SheetTitle className="hidden"></SheetTitle> | <SheetTitle className="hidden"></SheetTitle> | ||||
| <SheetContent className={cn('bg-white top-20 p-0')} closeIcon={false}> | |||||
| <SheetContent className={cn('top-20 p-0')} closeIcon={false}> | |||||
| <SheetHeader> | <SheetHeader> | ||||
| <section className="flex-col border-b py-2 px-5"> | <section className="flex-col border-b py-2 px-5"> | ||||
| <div className="flex items-center gap-2 pb-3"> | <div className="flex items-center gap-2 pb-3"> |
| import BeginForm from '../form/begin-form'; | import BeginForm from '../form/begin-form'; | ||||
| import BingForm from '../form/bing-form'; | import BingForm from '../form/bing-form'; | ||||
| import CategorizeForm from '../form/categorize-form'; | import CategorizeForm from '../form/categorize-form'; | ||||
| import CodeForm from '../form/code-form'; | |||||
| import CrawlerForm from '../form/crawler-form'; | import CrawlerForm from '../form/crawler-form'; | ||||
| import DeepLForm from '../form/deepl-form'; | import DeepLForm from '../form/deepl-form'; | ||||
| import DuckDuckGoForm from '../form/duckduckgo-form'; | import DuckDuckGoForm from '../form/duckduckgo-form'; | ||||
| language: z.string(), | 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]: { | [Operator.Baidu]: { | ||||
| component: BaiduForm, | component: BaiduForm, | ||||
| defaultValues: { top_n: 10 }, | defaultValues: { top_n: 10 }, |
| 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 ( | |||||
| <FormCollapse title={t('flow.inputVariables')}> | |||||
| <Form.List name={name}> | |||||
| {(fields, { add, remove }) => ( | |||||
| <> | |||||
| {fields.map(({ key, name, ...restField }) => ( | |||||
| <div key={key} className="flex items-center gap-2 pb-4"> | |||||
| <Form.Item | |||||
| {...restField} | |||||
| name={[name, 'name']} | |||||
| className="m-0 flex-1" | |||||
| > | |||||
| <Input /> | |||||
| </Form.Item> | |||||
| <Form.Item | |||||
| {...restField} | |||||
| name={[name, 'component_id']} | |||||
| className="m-0 flex-1" | |||||
| > | |||||
| <Select | |||||
| placeholder={t('common.pleaseSelect')} | |||||
| options={valueOptions} | |||||
| ></Select> | |||||
| </Form.Item> | |||||
| <MinusCircleOutlined onClick={() => remove(name)} /> | |||||
| </div> | |||||
| ))} | |||||
| <Form.Item> | |||||
| <Button | |||||
| type="dashed" | |||||
| onClick={() => add()} | |||||
| block | |||||
| icon={<PlusOutlined />} | |||||
| > | |||||
| {t('flow.addVariable')} | |||||
| </Button> | |||||
| </Form.Item> | |||||
| </> | |||||
| )} | |||||
| </Form.List> | |||||
| </FormCollapse> | |||||
| ); | |||||
| }; |
| 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 ( | |||||
| <Form {...form}> | |||||
| <DynamicInputVariable node={node}></DynamicInputVariable> | |||||
| <FormField | |||||
| control={form.control} | |||||
| name="script" | |||||
| render={({ field }) => ( | |||||
| <FormItem> | |||||
| <FormLabel> | |||||
| <FormField | |||||
| control={form.control} | |||||
| name="channel" | |||||
| render={({ field }) => ( | |||||
| <FormItem> | |||||
| <FormLabel tooltip={t('channelTip')}> | |||||
| {t('channel')} | |||||
| </FormLabel> | |||||
| <FormControl> | |||||
| <RAGFlowSelect {...field} options={options} /> | |||||
| </FormControl> | |||||
| <FormMessage /> | |||||
| </FormItem> | |||||
| )} | |||||
| /> | |||||
| </FormLabel> | |||||
| <FormControl> | |||||
| <Editor | |||||
| height={600} | |||||
| theme="vs-dark" | |||||
| language={formData.lang} | |||||
| options={{ | |||||
| minimap: { enabled: false }, | |||||
| automaticLayout: true, | |||||
| }} | |||||
| {...field} | |||||
| /> | |||||
| </FormControl> | |||||
| <FormMessage /> | |||||
| </FormItem> | |||||
| )} | |||||
| /> | |||||
| </Form> | |||||
| ); | |||||
| }; | |||||
| export default CodeForm; |
| initialBeginValues, | initialBeginValues, | ||||
| initialBingValues, | initialBingValues, | ||||
| initialCategorizeValues, | initialCategorizeValues, | ||||
| initialCodeValues, | |||||
| initialConcentratorValues, | initialConcentratorValues, | ||||
| initialCrawlerValues, | initialCrawlerValues, | ||||
| initialDeepLValues, | initialDeepLValues, | ||||
| [Operator.Email]: initialEmailValues, | [Operator.Email]: initialEmailValues, | ||||
| [Operator.Iteration]: initialIterationValues, | [Operator.Iteration]: initialIterationValues, | ||||
| [Operator.IterationStart]: initialIterationValues, | [Operator.IterationStart]: initialIterationValues, | ||||
| [Operator.Code]: initialCodeValues, | |||||
| }; | }; | ||||
| }, [llmId]); | }, [llmId]); | ||||