From 5906daff9fc0c30f5705b6f86af4090fb6ba8159 Mon Sep 17 00:00:00 2001 From: heheer <71265218+newfish-cmyk@users.noreply.github.com> Date: Thu, 25 Jul 2024 18:01:43 +0800 Subject: [PATCH] fix: plugin run & setting quote variables (#2150) * fix * fix * change variables & variablelabels show condition * fix type * fix --- packages/global/core/workflow/utils.ts | 18 ++++++++++ .../workflow/dispatch/tools/textEditor.ts | 7 +--- .../common/Textarea/JsonEditor/index.tsx | 1 - .../common/Textarea/PromptEditor/Editor.tsx | 10 ++++-- .../common/Textarea/PromptEditor/index.tsx | 6 +++- .../VariableLabelPickerPlugin/index.tsx | 34 +++++++++---------- .../plugins/VariableLabelPlugin/index.tsx | 6 ++-- .../common/Textarea/PromptEditor/type.d.ts | 10 +++++- .../app/src/pages/api/core/chat/chatTest.ts | 6 +++- .../app/src/pages/api/v1/chat/completions.ts | 12 +++++-- .../detail/components/SimpleApp/EditForm.tsx | 3 +- .../render/RenderInput/templates/Textarea.tsx | 27 +++++++-------- 12 files changed, 89 insertions(+), 51 deletions(-) diff --git a/packages/global/core/workflow/utils.ts b/packages/global/core/workflow/utils.ts index 460b73d1f..9058a52cf 100644 --- a/packages/global/core/workflow/utils.ts +++ b/packages/global/core/workflow/utils.ts @@ -229,6 +229,24 @@ export const updatePluginInputByVariables = ( ); }; +export const filterPluginInputVariables = ( + variables: Record, + nodes: RuntimeNodeItemType[] +) => { + const pluginInputNode = nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput); + + if (!pluginInputNode) return variables; + return Object.keys(variables).reduce( + (acc, key) => { + if (!pluginInputNode.inputs.find((input) => input.key === key)) { + acc[key] = variables[key]; + } + return acc; + }, + {} as Record + ); +}; + export function replaceVariableLabel({ text, nodes, diff --git a/packages/service/core/workflow/dispatch/tools/textEditor.ts b/packages/service/core/workflow/dispatch/tools/textEditor.ts index fa412b7f4..20e723b33 100644 --- a/packages/service/core/workflow/dispatch/tools/textEditor.ts +++ b/packages/service/core/workflow/dispatch/tools/textEditor.ts @@ -1,9 +1,4 @@ -import { - DispatchNodeResponseKeyEnum, - SseResponseEventEnum -} from '@fastgpt/global/core/workflow/runtime/constants'; -import { responseWrite } from '../../../../common/response'; -import { textAdaptGptResponse } from '@fastgpt/global/core/workflow/runtime/utils'; +import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type'; import { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type'; diff --git a/packages/web/components/common/Textarea/JsonEditor/index.tsx b/packages/web/components/common/Textarea/JsonEditor/index.tsx index ad72fc9ff..18c70163c 100644 --- a/packages/web/components/common/Textarea/JsonEditor/index.tsx +++ b/packages/web/components/common/Textarea/JsonEditor/index.tsx @@ -80,7 +80,6 @@ const JSONEditor = ({ const lineContent = model.getLineContent(position.lineNumber); if (context.triggerCharacter) { - console.log(context.triggerCharacter); triggerChar.current = context.triggerCharacter; } const word = model.getWordUntilPosition(position); diff --git a/packages/web/components/common/Textarea/PromptEditor/Editor.tsx b/packages/web/components/common/Textarea/PromptEditor/Editor.tsx index 6396e84fa..46ffe3ff7 100644 --- a/packages/web/components/common/Textarea/PromptEditor/Editor.tsx +++ b/packages/web/components/common/Textarea/PromptEditor/Editor.tsx @@ -13,7 +13,7 @@ import { VariableNode } from './plugins/VariablePlugin/node'; import { EditorState, LexicalEditor } from 'lexical'; import OnBlurPlugin from './plugins/OnBlurPlugin'; import MyIcon from '../../Icon'; -import { EditorVariablePickerType } from './type.d'; +import { EditorVariableLabelPickerType, EditorVariablePickerType } from './type.d'; import { getNanoid } from '@fastgpt/global/common/string/tools'; import FocusPlugin from './plugins/FocusPlugin'; import { textToEditorState } from './utils'; @@ -21,6 +21,7 @@ import { MaxLengthPlugin } from './plugins/MaxLengthPlugin'; import { VariableLabelNode } from './plugins/VariableLabelPlugin/node'; import VariableLabelPlugin from './plugins/VariableLabelPlugin'; import { useDeepCompareEffect } from 'ahooks'; +import VariablePickerPlugin from './plugins/VariablePickerPlugin'; export default function Editor({ h = 200, @@ -29,6 +30,7 @@ export default function Editor({ showOpenModal = true, onOpenModal, variables, + variableLabels, onChange, onBlur, value, @@ -41,6 +43,7 @@ export default function Editor({ showOpenModal?: boolean; onOpenModal?: () => void; variables: EditorVariablePickerType[]; + variableLabels: EditorVariableLabelPickerType[]; onChange?: (editorState: EditorState, editor: LexicalEditor) => void; onBlur?: (editor: LexicalEditor) => void; value?: string; @@ -130,9 +133,10 @@ export default function Editor({ }); }} /> - + + - + 0 ? [] : variables} /> {showResize && ( diff --git a/packages/web/components/common/Textarea/PromptEditor/index.tsx b/packages/web/components/common/Textarea/PromptEditor/index.tsx index c0ba8b766..84318b077 100644 --- a/packages/web/components/common/Textarea/PromptEditor/index.tsx +++ b/packages/web/components/common/Textarea/PromptEditor/index.tsx @@ -5,13 +5,14 @@ import Editor from './Editor'; import MyModal from '../../MyModal'; import { useTranslation } from 'next-i18next'; import { EditorState, type LexicalEditor } from 'lexical'; -import { EditorVariablePickerType } from './type.d'; +import { EditorVariableLabelPickerType, EditorVariablePickerType } from './type.d'; import { useCallback, useTransition } from 'react'; const PromptEditor = ({ showOpenModal = true, showResize = true, variables = [], + variableLabels = [], value, onChange, onBlur, @@ -24,6 +25,7 @@ const PromptEditor = ({ showOpenModal?: boolean; showResize?: boolean; variables?: EditorVariablePickerType[]; + variableLabels?: EditorVariableLabelPickerType[]; value?: string; onChange?: (text: string) => void; onBlur?: (text: string) => void; @@ -55,6 +57,7 @@ const PromptEditor = ({ showOpenModal={showOpenModal} onOpenModal={onOpen} variables={variables} + variableLabels={variableLabels} h={h} maxLength={maxLength} value={value} @@ -71,6 +74,7 @@ const PromptEditor = ({ showResize showOpenModal={false} variables={variables} + variableLabels={variableLabels} value={value} onChange={onChangeInput} onBlur={onBlurInput} diff --git a/packages/web/components/common/Textarea/PromptEditor/plugins/VariableLabelPickerPlugin/index.tsx b/packages/web/components/common/Textarea/PromptEditor/plugins/VariableLabelPickerPlugin/index.tsx index 98da771d7..a3640052f 100644 --- a/packages/web/components/common/Textarea/PromptEditor/plugins/VariableLabelPickerPlugin/index.tsx +++ b/packages/web/components/common/Textarea/PromptEditor/plugins/VariableLabelPickerPlugin/index.tsx @@ -6,31 +6,31 @@ import { useCallback, useState } from 'react'; import * as ReactDOM from 'react-dom'; import { Box, Flex } from '@chakra-ui/react'; import { useBasicTypeaheadTriggerMatch } from '../../utils'; -import { EditorVariablePickerType } from '../../type'; +import { EditorVariableLabelPickerType } from '../../type'; import { WorkflowIOValueTypeEnum } from '@fastgpt/global/core/workflow/constants'; import { useTranslation } from 'react-i18next'; import Avatar from '../../../../Avatar'; -type EditorVariablePickerType1 = { +interface EditorVariableItemType { key: string; label: string; required?: boolean; icon?: string; valueType?: WorkflowIOValueTypeEnum; index: number; -}; +} interface TransformedParent { id: string; label: string; avatar: string; - children: EditorVariablePickerType1[]; + children: EditorVariableItemType[]; } export default function VariableLabelPickerPlugin({ variables, isFocus }: { - variables: EditorVariablePickerType[]; + variables: EditorVariableLabelPickerType[]; isFocus: boolean; }) { const { t } = useTranslation(); @@ -110,7 +110,7 @@ export default function VariableLabelPickerPlugin({ )} {variableFilter(variables, queryString || '').length > 0 ? ( - transformData(variableFilter(variables, queryString || '')).map((item) => { + transformVariables(variableFilter(variables, queryString || '')).map((item) => { return ( { - const parentId = item.parent!.id; - const parentLabel = item.parent!.label; - const parentAvatar = item.parent!.avatar; + variables.forEach((item, index) => { + const parentId = item.parent.id; + const parentLabel = item.parent.label; + const parentAvatar = item.parent.avatar; if (!parentMap[parentId]) { parentMap[parentId] = { @@ -218,8 +218,8 @@ function transformData(data: EditorVariablePickerType[]): TransformedParent[] { }); const addedParents = new Set(); - data.forEach((item) => { - const parentId = item.parent!.id; + variables.forEach((item) => { + const parentId = item.parent.id; if (!addedParents.has(parentId)) { transformedData.push(parentMap[parentId]); addedParents.add(parentId); @@ -230,15 +230,15 @@ function transformData(data: EditorVariablePickerType[]): TransformedParent[] { } function variableFilter( - data: EditorVariablePickerType[], + variables: EditorVariableLabelPickerType[], queryString: string -): EditorVariablePickerType[] { +): EditorVariableLabelPickerType[] { const lowerCaseQuery = queryString.toLowerCase(); - return data.filter((item) => { + return variables.filter((item) => { const labelMatch = item.label.toLowerCase().includes(lowerCaseQuery); const keyMatch = item.key.toLowerCase().includes(lowerCaseQuery); - const parentLabelMatch = item.parent!.label.toLowerCase().includes(lowerCaseQuery); + const parentLabelMatch = item.parent.label.toLowerCase().includes(lowerCaseQuery); return labelMatch || keyMatch || parentLabelMatch; }); diff --git a/packages/web/components/common/Textarea/PromptEditor/plugins/VariableLabelPlugin/index.tsx b/packages/web/components/common/Textarea/PromptEditor/plugins/VariableLabelPlugin/index.tsx index 1281e9bfb..5d2f3448e 100644 --- a/packages/web/components/common/Textarea/PromptEditor/plugins/VariableLabelPlugin/index.tsx +++ b/packages/web/components/common/Textarea/PromptEditor/plugins/VariableLabelPlugin/index.tsx @@ -1,6 +1,6 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; -import { EditorVariablePickerType } from '../../type'; -import { useCallback, useEffect, useMemo } from 'react'; +import { EditorVariableLabelPickerType } from '../../type'; +import { useCallback, useEffect } from 'react'; import { $createVariableLabelNode, VariableLabelNode } from './node'; import { TextNode } from 'lexical'; import { getHashtagRegexString } from './utils'; @@ -12,7 +12,7 @@ const REGEX = new RegExp(getHashtagRegexString(), 'i'); export default function VariableLabelPlugin({ variables }: { - variables: EditorVariablePickerType[]; + variables: EditorVariableLabelPickerType[]; }) { const [editor] = useLexicalComposerContext(); useEffect(() => { diff --git a/packages/web/components/common/Textarea/PromptEditor/type.d.ts b/packages/web/components/common/Textarea/PromptEditor/type.d.ts index a502907dd..6453bde7b 100644 --- a/packages/web/components/common/Textarea/PromptEditor/type.d.ts +++ b/packages/web/components/common/Textarea/PromptEditor/type.d.ts @@ -6,7 +6,15 @@ export type EditorVariablePickerType = { required?: boolean; icon?: string; valueType?: WorkflowIOValueTypeEnum; - parent?: { +}; + +export type EditorVariableLabelPickerType = { + key: string; + label: string; + required?: boolean; + icon?: string; + valueType?: WorkflowIOValueTypeEnum; + parent: { id: string; label: string; avatar?: string; diff --git a/projects/app/src/pages/api/core/chat/chatTest.ts b/projects/app/src/pages/api/core/chat/chatTest.ts index 9df3f03bd..b7ecd2dd8 100644 --- a/projects/app/src/pages/api/core/chat/chatTest.ts +++ b/projects/app/src/pages/api/core/chat/chatTest.ts @@ -14,7 +14,10 @@ import { RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type' import { removeEmptyUserInput } from '@fastgpt/global/core/chat/utils'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; -import { updatePluginInputByVariables } from '@fastgpt/global/core/workflow/utils'; +import { + filterPluginInputVariables, + updatePluginInputByVariables +} from '@fastgpt/global/core/workflow/utils'; import { NextAPI } from '@/service/middleware/entry'; import { GPTMessages2Chats } from '@fastgpt/global/core/chat/adapt'; import { ChatCompletionMessageParam } from '@fastgpt/global/core/ai/type'; @@ -63,6 +66,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { // Plugin need to replace inputs if (isPlugin) { nodes = updatePluginInputByVariables(nodes, variables); + variables = filterPluginInputVariables(variables, nodes); } else { if (!userInput) { throw new Error('Params Error'); diff --git a/projects/app/src/pages/api/v1/chat/completions.ts b/projects/app/src/pages/api/v1/chat/completions.ts index 3e63fe688..a510d1336 100644 --- a/projects/app/src/pages/api/v1/chat/completions.ts +++ b/projects/app/src/pages/api/v1/chat/completions.ts @@ -54,7 +54,10 @@ import { NextAPI } from '@/service/middleware/entry'; import { getAppLatestVersion } from '@fastgpt/service/core/app/controller'; import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant'; import { AppTypeEnum } from '@fastgpt/global/core/app/constants'; -import { updatePluginInputByVariables } from '@fastgpt/global/core/workflow/utils'; +import { + filterPluginInputVariables, + updatePluginInputByVariables +} from '@fastgpt/global/core/workflow/utils'; import { getNanoid } from '@fastgpt/global/common/string/tools'; import { getPluginInputsFromStoreNodes, @@ -235,6 +238,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { ) : storeNodes2RuntimeNodes(nodes, getDefaultEntryNodeIds(nodes)); + const runtimeVariables = filterPluginInputVariables( + variables, + storeNodes2RuntimeNodes(nodes, getDefaultEntryNodeIds(nodes)) + ); + /* start flow controller */ const { flowResponses, flowUsages, assistantResponses, newVariables } = await (async () => { if (app.version === 'v2') { @@ -249,7 +257,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { responseChatItemId, runtimeNodes, runtimeEdges: initWorkflowEdgeStatus(edges), - variables, + variables: runtimeVariables, query: removeEmptyUserInput(userQuestion.value), histories: newHistories, stream, diff --git a/projects/app/src/pages/app/detail/components/SimpleApp/EditForm.tsx b/projects/app/src/pages/app/detail/components/SimpleApp/EditForm.tsx index 9b719fd50..1145b1193 100644 --- a/projects/app/src/pages/app/detail/components/SimpleApp/EditForm.tsx +++ b/projects/app/src/pages/app/detail/components/SimpleApp/EditForm.tsx @@ -104,7 +104,7 @@ const EditForm = ({ onClose: onCloseToolsSelect } = useDisclosure(); - const formatVariables: any = useMemo( + const formatVariables = useMemo( () => formatEditorVariablePickerIcon([ ...getSystemVariables(t), @@ -186,6 +186,7 @@ const EditForm = ({ })); }); }} + variableLabels={formatVariables} variables={formatVariables} placeholder={t('common:core.app.tip.chatNodeSystemPromptTip')} title={t('common:core.ai.Prompt')} diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/Textarea.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/Textarea.tsx index 97cf3f7c9..71913b141 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/Textarea.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/Textarea.tsx @@ -20,18 +20,16 @@ const TextareaRender = ({ inputs = [], item, nodeId }: RenderInputProps) => { // get variable const variables = useCreation(() => { - const currentNode = nodeList.find((node) => node.nodeId === nodeId); - const nodeVariables = formatEditorVariablePickerIcon( - getNodeDynamicInputs(nodeId).map((item) => ({ - key: item.key, - label: item.label, - parent: { - id: currentNode?.nodeId, - label: currentNode?.name, - avatar: currentNode?.avatar - } - })) - ); + const currentNode = nodeList.find((node) => node.nodeId === nodeId)!; + const nodeVariables = getNodeDynamicInputs(nodeId).map((item) => ({ + key: item.key, + label: item.label, + parent: { + id: currentNode.nodeId, + label: currentNode.name, + avatar: currentNode.avatar + } + })); const sourceNodes = computedNodeInputReference({ nodeId, @@ -61,9 +59,7 @@ const TextareaRender = ({ inputs = [], item, nodeId }: RenderInputProps) => { }) .flat(); - const formatSourceNodeVariables = formatEditorVariablePickerIcon(sourceNodeVariables); - - return [...nodeVariables, ...formatSourceNodeVariables]; + return [...nodeVariables, ...sourceNodeVariables]; }, [nodeList, edges, inputs, t]); const onChange = useCallback( @@ -84,6 +80,7 @@ const TextareaRender = ({ inputs = [], item, nodeId }: RenderInputProps) => { const Render = useMemo(() => { return (