From 40f527a0215aaff016f7b3495d59dff417d3d48c Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Fri, 18 Oct 2024 16:49:35 +0800 Subject: [PATCH] 4.8.12 test (#2936) * system config tip * perf: prompt editor code * perf: cookie tip --- .../zh-cn/docs/development/upgrading/4812.md | 7 +- packages/plugins/src/drawing/template.json | 2 +- .../core/workflow/dispatch/agent/extract.ts | 2 +- .../common/Textarea/PromptEditor/Editor.tsx | 2 +- projects/app/data/config.json | 2 +- .../templates/SettingQuotePrompt.tsx | 291 +++++++++--------- .../components/WorkflowComponents/utils.tsx | 1 - projects/app/src/pages/login/index.tsx | 27 +- projects/app/src/web/core/workflow/utils.ts | 2 +- 9 files changed, 162 insertions(+), 174 deletions(-) diff --git a/docSite/content/zh-cn/docs/development/upgrading/4812.md b/docSite/content/zh-cn/docs/development/upgrading/4812.md index 226c51a20..d56ee1229 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4812.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4812.md @@ -15,6 +15,7 @@ weight: 812 4. 新增 - Debug 模式支持输入全局变量 5. 新增 - chat openapi 文档 6. 新增 - wiki 搜索插件 -7. 修复 - 文件后缀判断,去除 query 影响。 -8. 修复 - AI 响应为空时,会造成 LLM 历史记录合并。 -9. 修复 - 用户交互节点未阻塞流程。 +7. 新增 - Cookie 隐私协议提示 +8. 修复 - 文件后缀判断,去除 query 影响。 +9. 修复 - AI 响应为空时,会造成 LLM 历史记录合并。 +10. 修复 - 用户交互节点未阻塞流程。 diff --git a/packages/plugins/src/drawing/template.json b/packages/plugins/src/drawing/template.json index c1a36e98f..d7ec486b3 100644 --- a/packages/plugins/src/drawing/template.json +++ b/packages/plugins/src/drawing/template.json @@ -1,5 +1,5 @@ { - "author": "", + "author": "silencezhang7", "version": "486", "name": "BI图表功能", "avatar": "core/workflow/template/BI", diff --git a/packages/service/core/workflow/dispatch/agent/extract.ts b/packages/service/core/workflow/dispatch/agent/extract.ts index 436787665..5c0f999c6 100644 --- a/packages/service/core/workflow/dispatch/agent/extract.ts +++ b/packages/service/core/workflow/dispatch/agent/extract.ts @@ -243,7 +243,7 @@ const toolChoice = async (props: ActionProps) => { const arg: Record = (() => { try { return json5.parse( - response?.choices?.[0]?.message?.tool_calls?.[0]?.function?.arguments || '{}' + response?.choices?.[0]?.message?.tool_calls?.[0]?.function?.arguments || '' ); } catch (error) { console.log(agentFunction.parameters); diff --git a/packages/web/components/common/Textarea/PromptEditor/Editor.tsx b/packages/web/components/common/Textarea/PromptEditor/Editor.tsx index c04bd11e0..c8923d681 100644 --- a/packages/web/components/common/Textarea/PromptEditor/Editor.tsx +++ b/packages/web/components/common/Textarea/PromptEditor/Editor.tsx @@ -6,7 +6,7 @@ * */ -import { useState, useRef, useTransition, useCallback } from 'react'; +import { useState, useTransition } from 'react'; import { LexicalComposer } from '@lexical/react/LexicalComposer'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { ContentEditable } from '@lexical/react/LexicalContentEditable'; diff --git a/projects/app/data/config.json b/projects/app/data/config.json index e8bbd7624..1b97164aa 100644 --- a/projects/app/data/config.json +++ b/projects/app/data/config.json @@ -25,7 +25,7 @@ "usedInExtractFields": true, // 是否用于内容提取(务必保证至少有一个为true) "usedInToolCall": true, // 是否用于工具调用(务必保证至少有一个为true) "usedInQueryExtension": true, // 是否用于问题优化(务必保证至少有一个为true) - "toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。目前只有gpt支持) + "toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。) "functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice,如果为false,则使用 functionCall,如果仍为 false,则使用提示词模式) "customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型 "customExtractPrompt": "", // 自定义内容提取提示词 diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SettingQuotePrompt.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SettingQuotePrompt.tsx index 227c6e09e..0f29701c6 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SettingQuotePrompt.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SettingQuotePrompt.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import type { RenderInputProps } from '../type'; import { Box, BoxProps, Button, Flex, ModalFooter, useDisclosure } from '@chakra-ui/react'; import MyModal from '@fastgpt/web/components/common/MyModal'; @@ -43,30 +43,22 @@ const selectTemplateBtn: BoxProps = { cursor: 'pointer' }; -const SettingQuotePrompt = (props: RenderInputProps) => { +const EditModal = ({ onClose, ...props }: RenderInputProps & { onClose: () => void }) => { const { inputs = [], nodeId } = props; const { t } = useTranslation(); - const { isOpen, onOpen, onClose } = useDisclosure(); const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode); const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList); - const defaultValues = useMemo(() => { - return { + const { watch, setValue, handleSubmit } = useForm({ + defaultValues: { quoteTemplate: inputs.find((input) => input.key === NodeInputKeyEnum.aiChatQuoteTemplate)?.value || '', quotePrompt: inputs.find((input) => input.key === NodeInputKeyEnum.aiChatQuotePrompt)?.value || '', quoteRole: (inputs.find((input) => input.key === NodeInputKeyEnum.aiChatQuoteRole)?.value || 'system') as AiChatQuoteRoleType - }; - }, [inputs]); - - const { watch, setValue, handleSubmit, reset } = useForm({ defaultValues }); - - useEffect(() => { - reset(defaultValues); - }, [defaultValues, reset]); - + } + }); const aiChatQuoteTemplate = watch('quoteTemplate'); const aiChatQuotePrompt = watch('quotePrompt'); const aiChatQuoteRole = watch('quoteRole'); @@ -175,6 +167,137 @@ const SettingQuotePrompt = (props: RenderInputProps) => { const quotePromptTemplates = aiChatQuoteRole === 'user' ? Prompt_userQuotePromptList : Prompt_systemQuotePromptList; + return ( + <> + + + + {t('workflow:dataset_quote_role')} + + + value={aiChatQuoteRole} + list={[ + { + label: 'System', + value: 'system', + description: t('workflow:dataset_quote_role_system_option_desc') + }, + { + label: 'User', + value: 'user', + description: t('workflow:dataset_quote_role_user_option_desc') + } + ]} + onchange={(e) => { + setValue('quoteRole', e); + }} + /> + + {aiChatQuoteRole === 'user' ? ( + + ) : ( + + )} + + + + + {t('common:core.app.Quote templates')} + + + + setSelectTemplateData({ + title: t('common:core.app.Select quote template'), + templates: Prompt_QuoteTemplateList + }) + } + > + {t('common:common.Select template')} + + + + { + setValue('quoteTemplate', e); + }} + /> + + + + {t('common:core.app.Quote prompt')} + + + { + setValue('quotePrompt', e); + }} + /> + + + + + + + + {/* Prompt template */} + {!!selectTemplateData && ( + setSelectTemplateData(undefined)} + onSuccess={(e) => { + const quoteVal = e.value; + + const promptVal = quotePromptTemplates.find((item) => item.title === e.title)?.value; + + setValue('quoteTemplate', quoteVal); + setValue('quotePrompt', promptVal); + }} + /> + )} + + ); +}; + +const SettingQuotePrompt = (props: RenderInputProps) => { + const { t } = useTranslation(); + const { isOpen, onOpen, onClose } = useDisclosure(); + const Render = useMemo(() => { return ( <> @@ -201,146 +324,10 @@ const SettingQuotePrompt = (props: RenderInputProps) => { - - - - {t('workflow:dataset_quote_role')} - - - value={aiChatQuoteRole} - list={[ - { - label: 'System', - value: 'system', - description: t('workflow:dataset_quote_role_system_option_desc') - }, - { - label: 'User', - value: 'user', - description: t('workflow:dataset_quote_role_user_option_desc') - } - ]} - onchange={(e) => { - setValue('quoteRole', e); - }} - /> - - {aiChatQuoteRole === 'user' ? ( - - ) : ( - - )} - - - - - {t('common:core.app.Quote templates')} - - - - setSelectTemplateData({ - title: t('common:core.app.Select quote template'), - templates: Prompt_QuoteTemplateList - }) - } - > - {t('common:common.Select template')} - - - - { - setValue('quoteTemplate', e); - }} - /> - - - - {t('common:core.app.Quote prompt')} - - - { - setValue('quotePrompt', e); - }} - /> - - - - - - - - {/* Prompt template */} - {!!selectTemplateData && ( - setSelectTemplateData(undefined)} - onSuccess={(e) => { - const quoteVal = e.value; - - const promptVal = quotePromptTemplates.find((item) => item.title === e.title)?.value; - - setValue('quoteTemplate', quoteVal); - setValue('quotePrompt', promptVal); - }} - /> - )} + {isOpen && } ); - }, [ - aiChatQuotePrompt, - aiChatQuoteRole, - aiChatQuoteTemplate, - handleSubmit, - isOpen, - onClose, - onOpen, - onSubmit, - props, - quotePromptTemplates, - quotePromptVariables, - quoteTemplateVariables, - selectTemplateData, - setValue, - t - ]); + }, [isOpen, onClose, onOpen, t]); return Render; }; diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/utils.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/utils.tsx index 941674cf9..78adddbd9 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/utils.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/utils.tsx @@ -123,7 +123,6 @@ export const getEditorVariables = ({ const sourceNodeVariables = !sourceNodes ? [] : sourceNodes - .reverse() .map((node) => { return node.outputs .filter((output) => !!output.label) diff --git a/projects/app/src/pages/login/index.tsx b/projects/app/src/pages/login/index.tsx index 0dfd01e1e..b4916cc39 100644 --- a/projects/app/src/pages/login/index.tsx +++ b/projects/app/src/pages/login/index.tsx @@ -46,23 +46,15 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => { const { setLastChatId, setLastChatAppId } = useChatStore(); const { isOpen, onOpen, onClose } = useDisclosure(); const { isPc } = useSystem(); - const { - isOpen: isOpenRedirect, - onOpen: onOpenRedirect, - onClose: onCloseRedirect - } = useDisclosure(); + const { isOpen: isOpenCookiesDrawer, onOpen: onOpenCookiesDrawer, onClose: onCloseCookiesDrawer } = useDisclosure(); - - const [showRedirect, setShowRedirect] = useLocalStorageState('showRedirect', { - defaultValue: true - }); - const cookieVersion = 1; + const cookieVersion = '1'; const [localCookieVersion, setLocalCookieVersion] = - useLocalStorageState('localCookieVersion'); + useLocalStorageState('localCookieVersion'); const loginSuccess = useCallback( (res: ResLogin) => { @@ -99,6 +91,14 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => { ); }, [feConfigs.oauth]); + const { + isOpen: isOpenRedirect, + onOpen: onOpenRedirect, + onClose: onCloseRedirect + } = useDisclosure(); + const [showRedirect, setShowRedirect] = useLocalStorageState('showRedirect', { + defaultValue: true + }); const checkIpInChina = useCallback(async () => { try { const res = await GET(ipDetectURL); @@ -116,9 +116,11 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => { console.log(error); } }, [onOpenRedirect]); + useMount(() => { clearToken(); router.prefetch('/app/list'); + ChineseRedirectUrl && showRedirect && checkIpInChina(); localCookieVersion !== cookieVersion && onOpenCookiesDrawer(); }); @@ -249,7 +251,6 @@ function RedirectDrawer({ function CookiesDrawer({ onClose, onAgree }: { onClose: () => void; onAgree: () => void }) { const { t } = useTranslation(); - const router = useRouter(); return ( @@ -268,7 +269,7 @@ function CookiesDrawer({ onClose, onAgree }: { onClose: () => void; onAgree: () textDecorationLine={'underline'} cursor={'pointer'} w={'fit-content'} - onClick={() => router.push(getDocPath('/docs/agreement/privacy/'))} + onClick={() => window.open(getDocPath('/docs/agreement/privacy/'), '_blank')} > {t('login:privacy_policy')} diff --git a/projects/app/src/web/core/workflow/utils.ts b/projects/app/src/web/core/workflow/utils.ts index 4ab93ee97..864b1cc65 100644 --- a/projects/app/src/web/core/workflow/utils.ts +++ b/projects/app/src/web/core/workflow/utils.ts @@ -211,7 +211,7 @@ export const computedNodeInputReference = ({ }; findSourceNode(nodeId); - sourceNodes.unshift( + sourceNodes.push( getGlobalVariableNode({ nodes, t,