mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-27 16:33:49 +00:00
4.8.12 test (#2936)
* system config tip * perf: prompt editor code * perf: cookie tip
This commit is contained in:
@@ -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. 修复 - 用户交互节点未阻塞流程。
|
||||||
|
@@ -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",
|
||||||
|
@@ -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);
|
||||||
|
@@ -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';
|
||||||
|
@@ -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": "", // 自定义内容提取提示词
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
|
@@ -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)
|
||||||
|
@@ -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>
|
||||||
|
@@ -211,7 +211,7 @@ export const computedNodeInputReference = ({
|
|||||||
};
|
};
|
||||||
findSourceNode(nodeId);
|
findSourceNode(nodeId);
|
||||||
|
|
||||||
sourceNodes.unshift(
|
sourceNodes.push(
|
||||||
getGlobalVariableNode({
|
getGlobalVariableNode({
|
||||||
nodes,
|
nodes,
|
||||||
t,
|
t,
|
||||||
|
Reference in New Issue
Block a user