4.8.12 test (#2936)

* system config tip

* perf: prompt editor code

* perf: cookie tip
This commit is contained in:
Archer
2024-10-18 16:49:35 +08:00
committed by shilin66
parent 7906acd77b
commit d6cf1fa3ea
9 changed files with 162 additions and 174 deletions

View File

@@ -15,6 +15,7 @@ weight: 812
4. 新增 - Debug 模式支持输入全局变量 4. 新增 - Debug 模式支持输入全局变量
5. 新增 - chat openapi 文档 5. 新增 - chat openapi 文档
6. 新增 - wiki 搜索插件 6. 新增 - wiki 搜索插件
7. 修复 - 文件后缀判断,去除 query 影响。 7. 新增 - Cookie 隐私协议提示
8. 修复 - AI 响应为空时,会造成 LLM 历史记录合并 8. 修复 - 文件后缀判断,去除 query 影响
9. 修复 - 用户交互节点未阻塞流程 9. 修复 - AI 响应为空时,会造成 LLM 历史记录合并
10. 修复 - 用户交互节点未阻塞流程。

View File

@@ -1,5 +1,5 @@
{ {
"author": "", "author": "silencezhang7",
"version": "486", "version": "486",
"name": "BI图表功能", "name": "BI图表功能",
"avatar": "core/workflow/template/BI", "avatar": "core/workflow/template/BI",

View File

@@ -243,7 +243,7 @@ const toolChoice = async (props: ActionProps) => {
const arg: Record<string, any> = (() => { const arg: Record<string, any> = (() => {
try { try {
return json5.parse( return json5.parse(
response?.choices?.[0]?.message?.tool_calls?.[0]?.function?.arguments || '{}' response?.choices?.[0]?.message?.tool_calls?.[0]?.function?.arguments || ''
); );
} catch (error) { } catch (error) {
console.log(agentFunction.parameters); console.log(agentFunction.parameters);

View File

@@ -6,7 +6,7 @@
* *
*/ */
import { useState, useRef, useTransition, useCallback } from 'react'; import { useState, useTransition } from 'react';
import { LexicalComposer } from '@lexical/react/LexicalComposer'; import { LexicalComposer } from '@lexical/react/LexicalComposer';
import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin'; import { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin';
import { ContentEditable } from '@lexical/react/LexicalContentEditable'; import { ContentEditable } from '@lexical/react/LexicalContentEditable';

View File

@@ -25,7 +25,7 @@
"usedInExtractFields": true, // 是否用于内容提取务必保证至少有一个为true "usedInExtractFields": true, // 是否用于内容提取务必保证至少有一个为true
"usedInToolCall": true, // 是否用于工具调用务必保证至少有一个为true "usedInToolCall": true, // 是否用于工具调用务必保证至少有一个为true
"usedInQueryExtension": true, // 是否用于问题优化务必保证至少有一个为true "usedInQueryExtension": true, // 是否用于问题优化务必保证至少有一个为true
"toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。目前只有gpt支持 "toolChoice": true, // 是否支持工具选择(分类,内容提取,工具调用会用到。)
"functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice如果为false则使用 functionCall如果仍为 false则使用提示词模式 "functionCall": false, // 是否支持函数调用(分类,内容提取,工具调用会用到。会优先使用 toolChoice如果为false则使用 functionCall如果仍为 false则使用提示词模式
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型 "customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型
"customExtractPrompt": "", // 自定义内容提取提示词 "customExtractPrompt": "", // 自定义内容提取提示词

View File

@@ -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 type { RenderInputProps } from '../type';
import { Box, BoxProps, Button, Flex, ModalFooter, useDisclosure } from '@chakra-ui/react'; import { Box, BoxProps, Button, Flex, ModalFooter, useDisclosure } from '@chakra-ui/react';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
@@ -43,30 +43,22 @@ const selectTemplateBtn: BoxProps = {
cursor: 'pointer' cursor: 'pointer'
}; };
const SettingQuotePrompt = (props: RenderInputProps) => { const EditModal = ({ onClose, ...props }: RenderInputProps & { onClose: () => void }) => {
const { inputs = [], nodeId } = props; const { inputs = [], nodeId } = props;
const { t } = useTranslation(); const { t } = useTranslation();
const { isOpen, onOpen, onClose } = useDisclosure();
const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode); const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode);
const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList); const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
const defaultValues = useMemo(() => { const { watch, setValue, handleSubmit } = useForm({
return { defaultValues: {
quoteTemplate: quoteTemplate:
inputs.find((input) => input.key === NodeInputKeyEnum.aiChatQuoteTemplate)?.value || '', inputs.find((input) => input.key === NodeInputKeyEnum.aiChatQuoteTemplate)?.value || '',
quotePrompt: quotePrompt:
inputs.find((input) => input.key === NodeInputKeyEnum.aiChatQuotePrompt)?.value || '', inputs.find((input) => input.key === NodeInputKeyEnum.aiChatQuotePrompt)?.value || '',
quoteRole: (inputs.find((input) => input.key === NodeInputKeyEnum.aiChatQuoteRole)?.value || quoteRole: (inputs.find((input) => input.key === NodeInputKeyEnum.aiChatQuoteRole)?.value ||
'system') as AiChatQuoteRoleType 'system') as AiChatQuoteRoleType
}; }
}, [inputs]); });
const { watch, setValue, handleSubmit, reset } = useForm({ defaultValues });
useEffect(() => {
reset(defaultValues);
}, [defaultValues, reset]);
const aiChatQuoteTemplate = watch('quoteTemplate'); const aiChatQuoteTemplate = watch('quoteTemplate');
const aiChatQuotePrompt = watch('quotePrompt'); const aiChatQuotePrompt = watch('quotePrompt');
const aiChatQuoteRole = watch('quoteRole'); const aiChatQuoteRole = watch('quoteRole');
@@ -175,34 +167,10 @@ const SettingQuotePrompt = (props: RenderInputProps) => {
const quotePromptTemplates = const quotePromptTemplates =
aiChatQuoteRole === 'user' ? Prompt_userQuotePromptList : Prompt_systemQuotePromptList; aiChatQuoteRole === 'user' ? Prompt_userQuotePromptList : Prompt_systemQuotePromptList;
const Render = useMemo(() => {
return ( return (
<> <>
<Flex className="nodrag" cursor={'default'} alignItems={'center'} position={'relative'}>
<Box position={'relative'} color={'myGray.600'} fontWeight={'medium'}>
{t('common:core.module.Dataset quote.label')}
</Box>
<ValueTypeLabel
valueType={WorkflowIOValueTypeEnum.datasetQuote}
valueDesc={datasetQuoteValueDesc}
/>
<MyTooltip label={t('common:core.module.Setting quote prompt')}>
<MyIcon
ml={1}
name={'common/settingLight'}
w={'14px'}
cursor={'pointer'}
onClick={onOpen}
/>
</MyTooltip>
</Flex>
<Box mt={1}>
<Reference {...props} />
</Box>
<MyModal <MyModal
isOpen={isOpen} isOpen
iconSrc={'modal/edit'} iconSrc={'modal/edit'}
title={t('workflow:Quote_prompt_setting')} title={t('workflow:Quote_prompt_setting')}
w={'100%'} w={'100%'}
@@ -324,23 +292,42 @@ const SettingQuotePrompt = (props: RenderInputProps) => {
)} )}
</> </>
); );
}, [ };
aiChatQuotePrompt,
aiChatQuoteRole, const SettingQuotePrompt = (props: RenderInputProps) => {
aiChatQuoteTemplate, const { t } = useTranslation();
handleSubmit, const { isOpen, onOpen, onClose } = useDisclosure();
isOpen,
onClose, const Render = useMemo(() => {
onOpen, return (
onSubmit, <>
props, <Flex className="nodrag" cursor={'default'} alignItems={'center'} position={'relative'}>
quotePromptTemplates, <Box position={'relative'} color={'myGray.600'} fontWeight={'medium'}>
quotePromptVariables, {t('common:core.module.Dataset quote.label')}
quoteTemplateVariables, </Box>
selectTemplateData, <ValueTypeLabel
setValue, valueType={WorkflowIOValueTypeEnum.datasetQuote}
t valueDesc={datasetQuoteValueDesc}
]); />
<MyTooltip label={t('common:core.module.Setting quote prompt')}>
<MyIcon
ml={1}
name={'common/settingLight'}
w={'14px'}
cursor={'pointer'}
onClick={onOpen}
/>
</MyTooltip>
</Flex>
<Box mt={1}>
<Reference {...props} />
</Box>
{isOpen && <EditModal {...props} onClose={onClose} />}
</>
);
}, [isOpen, onClose, onOpen, t]);
return Render; return Render;
}; };

View File

@@ -123,7 +123,6 @@ export const getEditorVariables = ({
const sourceNodeVariables = !sourceNodes const sourceNodeVariables = !sourceNodes
? [] ? []
: sourceNodes : sourceNodes
.reverse()
.map((node) => { .map((node) => {
return node.outputs return node.outputs
.filter((output) => !!output.label) .filter((output) => !!output.label)

View File

@@ -46,23 +46,15 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => {
const { setLastChatId, setLastChatAppId } = useChatStore(); const { setLastChatId, setLastChatAppId } = useChatStore();
const { isOpen, onOpen, onClose } = useDisclosure(); const { isOpen, onOpen, onClose } = useDisclosure();
const { isPc } = useSystem(); const { isPc } = useSystem();
const {
isOpen: isOpenRedirect,
onOpen: onOpenRedirect,
onClose: onCloseRedirect
} = useDisclosure();
const { const {
isOpen: isOpenCookiesDrawer, isOpen: isOpenCookiesDrawer,
onOpen: onOpenCookiesDrawer, onOpen: onOpenCookiesDrawer,
onClose: onCloseCookiesDrawer onClose: onCloseCookiesDrawer
} = useDisclosure(); } = useDisclosure();
const cookieVersion = '1';
const [showRedirect, setShowRedirect] = useLocalStorageState<boolean>('showRedirect', {
defaultValue: true
});
const cookieVersion = 1;
const [localCookieVersion, setLocalCookieVersion] = const [localCookieVersion, setLocalCookieVersion] =
useLocalStorageState<number>('localCookieVersion'); useLocalStorageState<string>('localCookieVersion');
const loginSuccess = useCallback( const loginSuccess = useCallback(
(res: ResLogin) => { (res: ResLogin) => {
@@ -99,6 +91,14 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => {
); );
}, [feConfigs.oauth]); }, [feConfigs.oauth]);
const {
isOpen: isOpenRedirect,
onOpen: onOpenRedirect,
onClose: onCloseRedirect
} = useDisclosure();
const [showRedirect, setShowRedirect] = useLocalStorageState<boolean>('showRedirect', {
defaultValue: true
});
const checkIpInChina = useCallback(async () => { const checkIpInChina = useCallback(async () => {
try { try {
const res = await GET<any>(ipDetectURL); const res = await GET<any>(ipDetectURL);
@@ -116,9 +116,11 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => {
console.log(error); console.log(error);
} }
}, [onOpenRedirect]); }, [onOpenRedirect]);
useMount(() => { useMount(() => {
clearToken(); clearToken();
router.prefetch('/app/list'); router.prefetch('/app/list');
ChineseRedirectUrl && showRedirect && checkIpInChina(); ChineseRedirectUrl && showRedirect && checkIpInChina();
localCookieVersion !== cookieVersion && onOpenCookiesDrawer(); localCookieVersion !== cookieVersion && onOpenCookiesDrawer();
}); });
@@ -249,7 +251,6 @@ function RedirectDrawer({
function CookiesDrawer({ onClose, onAgree }: { onClose: () => void; onAgree: () => void }) { function CookiesDrawer({ onClose, onAgree }: { onClose: () => void; onAgree: () => void }) {
const { t } = useTranslation(); const { t } = useTranslation();
const router = useRouter();
return ( return (
<Drawer placement="bottom" size={'xs'} isOpen={true} onClose={onClose}> <Drawer placement="bottom" size={'xs'} isOpen={true} onClose={onClose}>
@@ -268,7 +269,7 @@ function CookiesDrawer({ onClose, onAgree }: { onClose: () => void; onAgree: ()
textDecorationLine={'underline'} textDecorationLine={'underline'}
cursor={'pointer'} cursor={'pointer'}
w={'fit-content'} w={'fit-content'}
onClick={() => router.push(getDocPath('/docs/agreement/privacy/'))} onClick={() => window.open(getDocPath('/docs/agreement/privacy/'), '_blank')}
> >
{t('login:privacy_policy')} {t('login:privacy_policy')}
</Box> </Box>

View File

@@ -211,7 +211,7 @@ export const computedNodeInputReference = ({
}; };
findSourceNode(nodeId); findSourceNode(nodeId);
sourceNodes.unshift( sourceNodes.push(
getGlobalVariableNode({ getGlobalVariableNode({
nodes, nodes,
t, t,