### What problem does this PR solve? Feat: Downstream operators can get the variables defined by the user input operator #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.20.0
| "rc-tween-one": "^3.0.6", | "rc-tween-one": "^3.0.6", | ||||
| "react": "^18.2.0", | "react": "^18.2.0", | ||||
| "react-copy-to-clipboard": "^5.1.0", | "react-copy-to-clipboard": "^5.1.0", | ||||
| "react-day-picker": "^9.8.0", | |||||
| "react-dom": "^18.2.0", | "react-dom": "^18.2.0", | ||||
| "react-dropzone": "^14.3.5", | "react-dropzone": "^14.3.5", | ||||
| "react-error-boundary": "^4.0.13", | "react-error-boundary": "^4.0.13", | ||||
| "node": ">=10" | "node": ">=10" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/@date-fns/tz": { | |||||
| "version": "1.2.0", | |||||
| "resolved": "https://registry.npmmirror.com/@date-fns/tz/-/tz-1.2.0.tgz", | |||||
| "integrity": "sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==", | |||||
| "license": "MIT" | |||||
| }, | |||||
| "node_modules/@dnd-kit/accessibility": { | "node_modules/@dnd-kit/accessibility": { | ||||
| "version": "3.1.0", | "version": "3.1.0", | ||||
| "resolved": "https://registry.npmmirror.com/@dnd-kit/accessibility/-/accessibility-3.1.0.tgz", | "resolved": "https://registry.npmmirror.com/@dnd-kit/accessibility/-/accessibility-3.1.0.tgz", | ||||
| "node": ">= 0.4" | "node": ">= 0.4" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/date-fns": { | |||||
| "version": "4.1.0", | |||||
| "resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-4.1.0.tgz", | |||||
| "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", | |||||
| "license": "MIT", | |||||
| "funding": { | |||||
| "type": "github", | |||||
| "url": "https://github.com/sponsors/kossnocorp" | |||||
| } | |||||
| }, | |||||
| "node_modules/date-fns-jalali": { | |||||
| "version": "4.1.0-0", | |||||
| "resolved": "https://registry.npmmirror.com/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz", | |||||
| "integrity": "sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==", | |||||
| "license": "MIT" | |||||
| }, | |||||
| "node_modules/dayjs": { | "node_modules/dayjs": { | ||||
| "version": "1.11.10", | "version": "1.11.10", | ||||
| "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz", | "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz", | ||||
| "react": "^15.3.0 || 16 || 17 || 18" | "react": "^15.3.0 || 16 || 17 || 18" | ||||
| } | } | ||||
| }, | }, | ||||
| "node_modules/react-day-picker": { | |||||
| "version": "9.8.0", | |||||
| "resolved": "https://registry.npmmirror.com/react-day-picker/-/react-day-picker-9.8.0.tgz", | |||||
| "integrity": "sha512-E0yhhg7R+pdgbl/2toTb0xBhsEAtmAx1l7qjIWYfcxOy8w4rTSVfbtBoSzVVhPwKP/5E9iL38LivzoE3AQDhCQ==", | |||||
| "license": "MIT", | |||||
| "dependencies": { | |||||
| "@date-fns/tz": "1.2.0", | |||||
| "date-fns": "4.1.0", | |||||
| "date-fns-jalali": "4.1.0-0" | |||||
| }, | |||||
| "engines": { | |||||
| "node": ">=18" | |||||
| }, | |||||
| "funding": { | |||||
| "type": "individual", | |||||
| "url": "https://github.com/sponsors/gpbl" | |||||
| }, | |||||
| "peerDependencies": { | |||||
| "react": ">=16.8.0" | |||||
| } | |||||
| }, | |||||
| "node_modules/react-dev-inspector": { | "node_modules/react-dev-inspector": { | ||||
| "version": "2.0.1", | "version": "2.0.1", | ||||
| "resolved": "https://registry.npmmirror.com/react-dev-inspector/-/react-dev-inspector-2.0.1.tgz", | "resolved": "https://registry.npmmirror.com/react-dev-inspector/-/react-dev-inspector-2.0.1.tgz", |
| </FileUploadDropzone> | </FileUploadDropzone> | ||||
| <form | <form | ||||
| onSubmit={onSubmit} | onSubmit={onSubmit} | ||||
| className="relative flex w-full max-w-md flex-col gap-2.5 rounded-md border border-input px-3 py-2 outline-none focus-within:ring-1 focus-within:ring-ring/50" | |||||
| className="relative flex w-full flex-col gap-2.5 rounded-md border border-input px-3 py-2 outline-none focus-within:ring-1 focus-within:ring-ring/50" | |||||
| > | > | ||||
| <FileUploadList | <FileUploadList | ||||
| orientation="horizontal" | orientation="horizontal" |
| files.forEach((file) => { | files.forEach((file) => { | ||||
| onError(file, error as Error); | onError(file, error as Error); | ||||
| }); | }); | ||||
| message.error('error', error.message); | |||||
| message.error('error', error?.message); | |||||
| } | } | ||||
| }, | }, | ||||
| }); | }); | ||||
| initialData: {}, | initialData: {}, | ||||
| enabled: !!id && !!componentId, | enabled: !!id && !!componentId, | ||||
| queryFn: async () => { | queryFn: async () => { | ||||
| const { data } = await agentService.inputForm({ | |||||
| id, | |||||
| component_id: componentId, | |||||
| }); | |||||
| const { data } = await agentService.inputForm( | |||||
| { | |||||
| params: { | |||||
| id, | |||||
| component_id: componentId, | |||||
| }, | |||||
| }, | |||||
| true, | |||||
| ); | |||||
| return data.data; | return data.data; | ||||
| }, | }, |
| addFishAudioRefID: 'ID de referência do FishAudio', | addFishAudioRefID: 'ID de referência do FishAudio', | ||||
| addFishAudioRefIDMessage: | addFishAudioRefIDMessage: | ||||
| 'Por favor, insira o ID de referência (deixe em branco para usar o modelo padrão).', | 'Por favor, insira o ID de referência (deixe em branco para usar o modelo padrão).', | ||||
| `Por favor, adicione tanto o modelo de incorporação quanto o LLM em <b>Configurações > Provedores de Modelo</b> primeiro. Depois, defina-os nas 'Configurações do modelo do sistema'.`, | |||||
| modelProvidersWarn: `Por favor, adicione tanto o modelo de incorporação quanto o LLM em <b>Configurações > Provedores de Modelo</b> primeiro. Depois, defina-os nas 'Configurações do modelo do sistema'.`, | |||||
| apiVersion: 'Versão da API', | apiVersion: 'Versão da API', | ||||
| apiVersionMessage: 'Por favor, insira a versão da API', | apiVersionMessage: 'Por favor, insira a versão da API', | ||||
| add: 'Adicionar', | add: 'Adicionar', |
| import { NodeProps, Position } from '@xyflow/react'; | import { NodeProps, Position } from '@xyflow/react'; | ||||
| import { memo } from 'react'; | import { memo } from 'react'; | ||||
| import { NodeHandleId } from '../../constant'; | import { NodeHandleId } from '../../constant'; | ||||
| import { needsSingleStepDebugging } from '../../utils'; | |||||
| import { CommonHandle } from './handle'; | import { CommonHandle } from './handle'; | ||||
| import { LeftHandleStyle, RightHandleStyle } from './handle-icon'; | import { LeftHandleStyle, RightHandleStyle } from './handle-icon'; | ||||
| import NodeHeader from './node-header'; | import NodeHeader from './node-header'; | ||||
| selected, | selected, | ||||
| }: NodeProps<IRagNode>) { | }: NodeProps<IRagNode>) { | ||||
| return ( | return ( | ||||
| <ToolBar selected={selected} id={id} label={data.label}> | |||||
| <ToolBar | |||||
| selected={selected} | |||||
| id={id} | |||||
| label={data.label} | |||||
| showRun={needsSingleStepDebugging(data.label)} | |||||
| > | |||||
| <NodeWrapper selected={selected}> | <NodeWrapper selected={selected}> | ||||
| <CommonHandle | <CommonHandle | ||||
| id={NodeHandleId.End} | id={NodeHandleId.End} |
| enable_tips: true, | enable_tips: true, | ||||
| tips: '', | tips: '', | ||||
| inputs: [], | inputs: [], | ||||
| outputs: {}, | |||||
| }; | }; | ||||
| export enum StringTransformMethod { | export enum StringTransformMethod { | ||||
| Operator.RewriteQuestion, | Operator.RewriteQuestion, | ||||
| Operator.Switch, | Operator.Switch, | ||||
| Operator.Iteration, | Operator.Iteration, | ||||
| Operator.UserFillUp, | |||||
| ]; | ]; | ||||
| export enum NodeHandleId { | export enum NodeHandleId { |
| import { useForm, useWatch } from 'react-hook-form'; | import { useForm, useWatch } from 'react-hook-form'; | ||||
| import { useTranslation } from 'react-i18next'; | import { useTranslation } from 'react-i18next'; | ||||
| import { z } from 'zod'; | import { z } from 'zod'; | ||||
| import { INextOperatorForm } from '../../interface'; | |||||
| import { BeginQuery, INextOperatorForm } from '../../interface'; | |||||
| import { ParameterDialog } from '../begin-form/parameter-dialog'; | import { ParameterDialog } from '../begin-form/parameter-dialog'; | ||||
| import { QueryTable } from '../begin-form/query-table'; | import { QueryTable } from '../begin-form/query-table'; | ||||
| import { useEditQueryRecord } from '../begin-form/use-edit-query'; | import { useEditQueryRecord } from '../begin-form/use-edit-query'; | ||||
| import { Output } from '../components/output'; | |||||
| import { useValues } from './use-values'; | import { useValues } from './use-values'; | ||||
| import { useWatchFormChange } from './use-watch-change'; | import { useWatchFormChange } from './use-watch-change'; | ||||
| useWatchFormChange(node?.id, form); | useWatchFormChange(node?.id, form); | ||||
| const inputs = useWatch({ control: form.control, name: 'inputs' }); | |||||
| const inputs: BeginQuery[] = useWatch({ | |||||
| control: form.control, | |||||
| name: 'inputs', | |||||
| }); | |||||
| const outputList = inputs?.map((item) => ({ | |||||
| title: item.name, | |||||
| type: item.type, | |||||
| })); | |||||
| const { | const { | ||||
| ok, | ok, | ||||
| ></ParameterDialog> | ></ParameterDialog> | ||||
| )} | )} | ||||
| </Form> | </Form> | ||||
| <Output list={outputList}></Output> | |||||
| </section> | </section> | ||||
| ); | ); | ||||
| } | } |
| if (id) { | if (id) { | ||||
| values = form?.getValues() || {}; | values = form?.getValues() || {}; | ||||
| const inputs = transferInputsArrayToObject(values.inputs); | |||||
| const nextValues = { | const nextValues = { | ||||
| ...values, | ...values, | ||||
| inputs: transferInputsArrayToObject(values.inputs), | |||||
| inputs, | |||||
| outputs: inputs, | |||||
| }; | }; | ||||
| updateNodeForm(id, nextValues); | updateNodeForm(id, nextValues); |