### What problem does this PR solve? Feat: Translate the begin operator #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.19.x
| @@ -0,0 +1,28 @@ | |||
| import { | |||
| Collapsible, | |||
| CollapsibleContent, | |||
| CollapsibleTrigger, | |||
| } from '@/components/ui/collapsible'; | |||
| import { ListCollapse } from 'lucide-react'; | |||
| import { PropsWithChildren, ReactNode } from 'react'; | |||
| type CollapseProps = { | |||
| title?: ReactNode; | |||
| rightContent?: ReactNode; | |||
| } & PropsWithChildren; | |||
| export function Collapse({ title, children, rightContent }: CollapseProps) { | |||
| return ( | |||
| <Collapsible defaultOpen> | |||
| <CollapsibleTrigger className="w-full"> | |||
| <section className="flex justify-between items-center pb-2"> | |||
| <div className="flex items-center gap-1"> | |||
| <ListCollapse className="size-4" /> {title} | |||
| </div> | |||
| <div>{rightContent}</div> | |||
| </section> | |||
| </CollapsibleTrigger> | |||
| <CollapsibleContent>{children}</CollapsibleContent> | |||
| </Collapsible> | |||
| ); | |||
| } | |||
| @@ -14,8 +14,7 @@ import { | |||
| import { Label } from '@/components/ui/label'; | |||
| import { cn } from '@/lib/utils'; | |||
| import { Info } from 'lucide-react'; | |||
| import { Tooltip, TooltipContent, TooltipTrigger } from './tooltip'; | |||
| import { FormTooltip } from './tooltip'; | |||
| const Form = FormProvider; | |||
| @@ -104,16 +103,7 @@ const FormLabel = React.forwardRef< | |||
| {...props} | |||
| > | |||
| {props.children} | |||
| {tooltip && ( | |||
| <Tooltip> | |||
| <TooltipTrigger> | |||
| <Info className="size-3 ml-2" /> | |||
| </TooltipTrigger> | |||
| <TooltipContent> | |||
| <p>{tooltip}</p> | |||
| </TooltipContent> | |||
| </Tooltip> | |||
| )} | |||
| {tooltip && <FormTooltip tooltip={tooltip}></FormTooltip>} | |||
| </Label> | |||
| ); | |||
| }); | |||
| @@ -4,6 +4,7 @@ import * as TooltipPrimitive from '@radix-ui/react-tooltip'; | |||
| import * as React from 'react'; | |||
| import { cn } from '@/lib/utils'; | |||
| import { Info } from 'lucide-react'; | |||
| const TooltipProvider = TooltipPrimitive.Provider; | |||
| @@ -28,3 +29,16 @@ const TooltipContent = React.forwardRef< | |||
| TooltipContent.displayName = TooltipPrimitive.Content.displayName; | |||
| export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }; | |||
| export const FormTooltip = ({ tooltip }: { tooltip: React.ReactNode }) => { | |||
| return ( | |||
| <Tooltip> | |||
| <TooltipTrigger> | |||
| <Info className="size-3 ml-2" /> | |||
| </TooltipTrigger> | |||
| <TooltipContent> | |||
| <p>{tooltip}</p> | |||
| </TooltipContent> | |||
| </Tooltip> | |||
| ); | |||
| }; | |||
| @@ -455,7 +455,8 @@ This auto-tagging feature enhances retrieval by adding another layer of domain-s | |||
| modelTip: 'Large language chat model', | |||
| modelMessage: 'Please select!', | |||
| modelEnabledTools: 'Enabled tools', | |||
| modelEnabledToolsTip: 'Please select one or more tools for the chat model to use. It takes no effect for models not supporting tool call.', | |||
| modelEnabledToolsTip: | |||
| 'Please select one or more tools for the chat model to use. It takes no effect for models not supporting tool call.', | |||
| freedom: 'Freedom', | |||
| improvise: 'Improvise', | |||
| precise: 'Precise', | |||
| @@ -1268,14 +1269,22 @@ This delimiter is used to split the input text into several text pieces echo of | |||
| codeDescription: 'It allows developers to write custom Python logic.', | |||
| inputVariables: 'Input variables', | |||
| runningHintText: 'is running...🕞', | |||
| openingSwitch: 'Opening switch', | |||
| openingCopy: 'Opening copy', | |||
| openingSwitchTip: | |||
| 'Your users will see this welcome message at the beginning.', | |||
| modeTip: 'The mode defines how the workflow is initiated.', | |||
| beginInputTip: | |||
| 'By defining input parameters, this content can be accessed by other components in subsequent processes.', | |||
| }, | |||
| llmTools: { | |||
| bad_calculator: { | |||
| name: "Calculator", | |||
| description: "A tool to calculate the sum of two numbers (will give wrong answer)", | |||
| name: 'Calculator', | |||
| description: | |||
| 'A tool to calculate the sum of two numbers (will give wrong answer)', | |||
| params: { | |||
| a: "The first number", | |||
| b: "The second number", | |||
| a: 'The first number', | |||
| b: 'The second number', | |||
| }, | |||
| }, | |||
| }, | |||
| @@ -1162,6 +1162,9 @@ export default { | |||
| codeDescription: '它允許開發人員編寫自訂 Python 邏輯。', | |||
| inputVariables: '輸入變數', | |||
| runningHintText: '正在運行...🕞', | |||
| openingSwitchTip: '您的用戶將在開始時看到此歡迎訊息。', | |||
| modeTip: '模式定義工作流程如何啟動。 ', | |||
| beginInputTip: `透過定義輸入參數,這些內容可以在後續流程中被其他元件存取。`, | |||
| }, | |||
| footer: { | |||
| profile: '“保留所有權利 @ react”', | |||
| @@ -462,7 +462,8 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 | |||
| modelTip: '大语言聊天模型', | |||
| modelMessage: '请选择', | |||
| modelEnabledTools: '可用的工具', | |||
| modelEnabledToolsTip: '请选择一个或多个可供该模型所使用的工具。仅对支持工具调用的模型生效。', | |||
| modelEnabledToolsTip: | |||
| '请选择一个或多个可供该模型所使用的工具。仅对支持工具调用的模型生效。', | |||
| freedom: '自由度', | |||
| improvise: '即兴创作', | |||
| precise: '精确', | |||
| @@ -1224,6 +1225,11 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 | |||
| inputVariables: '输入变量', | |||
| addVariable: '新增变量', | |||
| runningHintText: '正在运行中...🕞', | |||
| openingSwitch: '开场白开关', | |||
| openingCopy: '开场白文案', | |||
| openingSwitchTip: '您的用户将在开始时看到此欢迎消息。', | |||
| modeTip: '模式定义了工作流的启动方式。', | |||
| beginInputTip: '通过定义输入参数,此内容可以被后续流程中的其他组件访问。', | |||
| }, | |||
| footer: { | |||
| profile: 'All rights reserved @ React', | |||
| @@ -1235,11 +1241,11 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 | |||
| }, | |||
| llmTools: { | |||
| bad_calculator: { | |||
| name: "计算器", | |||
| description: "用于计算两个数的和的工具(会给出错误答案)", | |||
| name: '计算器', | |||
| description: '用于计算两个数的和的工具(会给出错误答案)', | |||
| params: { | |||
| a: "第一个数", | |||
| b: "第二个数", | |||
| a: '第一个数', | |||
| b: '第二个数', | |||
| }, | |||
| }, | |||
| }, | |||
| @@ -29,7 +29,10 @@ 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'; | |||
| // 邮件功能 | |||
| export enum AgentDialogueMode { | |||
| Conversational = 'Conversational', | |||
| Task = 'Task', | |||
| } | |||
| import { | |||
| ChatVariableEnabledField, | |||
| @@ -424,6 +427,7 @@ export const initialRetrievalValues = { | |||
| }; | |||
| export const initialBeginValues = { | |||
| mode: AgentDialogueMode.Conversational, | |||
| prologue: `Hi! I'm your assistant, what can I do for you?`, | |||
| }; | |||
| @@ -3006,8 +3010,3 @@ export const NoDebugOperatorsList = [ | |||
| Operator.Switch, | |||
| Operator.Iteration, | |||
| ]; | |||
| export enum AgentDialogueMode { | |||
| Conversational = 'Conversational', | |||
| Task = 'Task', | |||
| } | |||
| @@ -49,24 +49,27 @@ export function useFormConfigMap() { | |||
| mode: AgentDialogueMode.Conversational, | |||
| }, | |||
| schema: z.object({ | |||
| enablePrologue: z.boolean(), | |||
| enablePrologue: z.boolean().optional(), | |||
| prologue: z | |||
| .string() | |||
| .min(1, { | |||
| message: t('common.namePlaceholder'), | |||
| }) | |||
| .trim(), | |||
| .trim() | |||
| .optional(), | |||
| mode: z.string(), | |||
| query: z.array( | |||
| z.object({ | |||
| key: z.string(), | |||
| type: z.string(), | |||
| value: z.string(), | |||
| optional: z.boolean(), | |||
| name: z.string(), | |||
| options: z.array(z.union([z.number(), z.string(), z.boolean()])), | |||
| }), | |||
| ), | |||
| query: z | |||
| .array( | |||
| z.object({ | |||
| key: z.string(), | |||
| type: z.string(), | |||
| value: z.string(), | |||
| optional: z.boolean(), | |||
| name: z.string(), | |||
| options: z.array(z.union([z.number(), z.string(), z.boolean()])), | |||
| }), | |||
| ) | |||
| .optional(), | |||
| }), | |||
| }, | |||
| [Operator.Retrieval]: { | |||
| @@ -1,4 +1,5 @@ | |||
| import { BlockButton } from '@/components/ui/button'; | |||
| import { Collapse } from '@/components/collapse'; | |||
| import { Button } from '@/components/ui/button'; | |||
| import { | |||
| Form, | |||
| FormControl, | |||
| @@ -10,7 +11,9 @@ import { | |||
| import { RAGFlowSelect } from '@/components/ui/select'; | |||
| import { Switch } from '@/components/ui/switch'; | |||
| import { Textarea } from '@/components/ui/textarea'; | |||
| import { FormTooltip } from '@/components/ui/tooltip'; | |||
| import { buildSelectOptions } from '@/utils/common-util'; | |||
| import { Plus } from 'lucide-react'; | |||
| import { useCallback } from 'react'; | |||
| import { useWatch } from 'react-hook-form'; | |||
| import { useTranslation } from 'react-i18next'; | |||
| @@ -21,13 +24,16 @@ import { QueryTable } from './query-table'; | |||
| import { useEditQueryRecord } from './use-edit-query'; | |||
| const ModeOptions = buildSelectOptions([ | |||
| (AgentDialogueMode.Conversational, AgentDialogueMode.Task), | |||
| AgentDialogueMode.Conversational, | |||
| AgentDialogueMode.Task, | |||
| ]); | |||
| const BeginForm = ({ form, node }: INextOperatorForm) => { | |||
| const { t } = useTranslation(); | |||
| const query = useWatch({ control: form.control, name: 'query' }); | |||
| const mode = useWatch({ control: form.control, name: 'mode' }); | |||
| const enablePrologue = useWatch({ | |||
| control: form.control, | |||
| name: 'enablePrologue', | |||
| @@ -61,7 +67,7 @@ const BeginForm = ({ form, node }: INextOperatorForm) => { | |||
| name={'mode'} | |||
| render={({ field }) => ( | |||
| <FormItem> | |||
| <FormLabel tooltip={t('chat.setAnOpenerTip')}>Mode</FormLabel> | |||
| <FormLabel tooltip={t('flow.modeTip')}>Mode</FormLabel> | |||
| <FormControl> | |||
| <RAGFlowSelect | |||
| placeholder={t('common.pleaseSelect')} | |||
| @@ -73,24 +79,26 @@ const BeginForm = ({ form, node }: INextOperatorForm) => { | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| <FormField | |||
| control={form.control} | |||
| name={'enablePrologue'} | |||
| render={({ field }) => ( | |||
| <FormItem> | |||
| <FormLabel tooltip={t('chat.setAnOpenerTip')}> | |||
| Welcome Message | |||
| </FormLabel> | |||
| <FormControl> | |||
| <Switch | |||
| checked={field.value} | |||
| onCheckedChange={field.onChange} | |||
| /> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| {mode === AgentDialogueMode.Conversational && ( | |||
| <FormField | |||
| control={form.control} | |||
| name={'enablePrologue'} | |||
| render={({ field }) => ( | |||
| <FormItem> | |||
| <FormLabel tooltip={t('flow.openingSwitchTip')}> | |||
| {t('flow.openingSwitch')} | |||
| </FormLabel> | |||
| <FormControl> | |||
| <Switch | |||
| checked={field.value} | |||
| onCheckedChange={field.onChange} | |||
| /> | |||
| </FormControl> | |||
| <FormMessage /> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| )} | |||
| {enablePrologue && ( | |||
| <FormField | |||
| control={form.control} | |||
| @@ -98,7 +106,7 @@ const BeginForm = ({ form, node }: INextOperatorForm) => { | |||
| render={({ field }) => ( | |||
| <FormItem> | |||
| <FormLabel tooltip={t('chat.setAnOpenerTip')}> | |||
| {t('chat.setAnOpener')} | |||
| {t('flow.openingCopy')} | |||
| </FormLabel> | |||
| <FormControl> | |||
| <Textarea | |||
| @@ -118,14 +126,32 @@ const BeginForm = ({ form, node }: INextOperatorForm) => { | |||
| name={'query'} | |||
| render={() => <div></div>} | |||
| /> | |||
| <QueryTable | |||
| data={query} | |||
| showModal={showModal} | |||
| deleteRecord={handleDeleteRecord} | |||
| ></QueryTable> | |||
| <BlockButton onClick={() => showModal()}> | |||
| {t('flow.addItem')} | |||
| </BlockButton> | |||
| <Collapse | |||
| title={ | |||
| <div> | |||
| {t('flow.input')} | |||
| <FormTooltip tooltip={t('flow.beginInputTip')}></FormTooltip> | |||
| </div> | |||
| } | |||
| rightContent={ | |||
| <Button | |||
| variant={'ghost'} | |||
| onClick={(e) => { | |||
| e.preventDefault(); | |||
| showModal(); | |||
| }} | |||
| > | |||
| <Plus /> | |||
| </Button> | |||
| } | |||
| > | |||
| <QueryTable | |||
| data={query} | |||
| showModal={showModal} | |||
| deleteRecord={handleDeleteRecord} | |||
| ></QueryTable> | |||
| </Collapse> | |||
| {visible && ( | |||
| <ParameterDialog | |||
| visible={visible} | |||