Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
40f527a0
authored
Oct 18, 2024
by
Archer
Committed by
GitHub
Oct 18, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
4.8.12 test (#2936)
* system config tip * perf: prompt editor code * perf: cookie tip
parent
4aaf9bfe
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
162 additions
and
174 deletions
+162
-174
docSite/content/zh-cn/docs/development/upgrading/4812.md
+4
-3
packages/plugins/src/drawing/template.json
+1
-1
packages/service/core/workflow/dispatch/agent/extract.ts
+1
-1
packages/web/components/common/Textarea/PromptEditor/Editor.tsx
+1
-1
projects/app/data/config.json
+1
-1
projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SettingQuotePrompt.tsx
+139
-152
projects/app/src/pages/app/detail/components/WorkflowComponents/utils.tsx
+0
-1
projects/app/src/pages/login/index.tsx
+14
-13
projects/app/src/web/core/workflow/utils.ts
+1
-1
No files found.
docSite/content/zh-cn/docs/development/upgrading/4812.md
View file @
40f527a0
...
...
@@ -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.
修复 - 用户交互节点未阻塞流程。
packages/plugins/src/drawing/template.json
View file @
40f527a0
{
"author"
:
""
,
"author"
:
"
silencezhang7
"
,
"version"
:
"486"
,
"name"
:
"BI图表功能"
,
"avatar"
:
"core/workflow/template/BI"
,
...
...
packages/service/core/workflow/dispatch/agent/extract.ts
View file @
40f527a0
...
...
@@ -243,7 +243,7 @@ const toolChoice = async (props: ActionProps) => {
const
arg
:
Record
<
string
,
any
>
=
(()
=>
{
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
);
...
...
packages/web/components/common/Textarea/PromptEditor/Editor.tsx
View file @
40f527a0
...
...
@@ -6,7 +6,7 @@
*
*/
import
{
useState
,
use
Ref
,
useTransition
,
useCallback
}
from
'react'
;
import
{
useState
,
use
Transition
}
from
'react'
;
import
{
LexicalComposer
}
from
'@lexical/react/LexicalComposer'
;
import
{
PlainTextPlugin
}
from
'@lexical/react/LexicalPlainTextPlugin'
;
import
{
ContentEditable
}
from
'@lexical/react/LexicalContentEditable'
;
...
...
projects/app/data/config.json
View file @
40f527a0
...
...
@@ -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"
:
""
,
//
自定义内容提取提示词
...
...
projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SettingQuotePrompt.tsx
View file @
40f527a0
import
React
,
{
useCallback
,
use
Effect
,
use
Memo
,
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
(
<>
<
MyModal
isOpen
iconSrc=
{
'modal/edit'
}
title=
{
t
(
'workflow:Quote_prompt_setting'
)
}
w=
{
'100%'
}
h=
{
[
'90vh'
,
'85vh'
]
}
maxW=
{
[
'90vw'
,
'700px'
]
}
isCentered
>
<
ModalBody
flex=
{
'1 0 0'
}
overflow=
{
'auto'
}
>
<
Flex
{
...
LabelStyles
}
alignItems=
{
'center'
}
>
<
FormLabel
>
{
t
(
'workflow:dataset_quote_role'
)
}
</
FormLabel
>
<
QuestionTip
label=
{
t
(
'workflow:dataset_quote_role_tip'
)
}
ml=
{
1
}
mr=
{
5
}
/>
<
MySelect
<
AiChatQuoteRoleType
>
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
);
}
}
/
>
<
Box
ml=
{
5
}
>
{
aiChatQuoteRole
===
'user'
?
(
<
LightTip
text=
{
t
(
'workflow:quote_role_user_tip'
)
}
/>
)
:
(
<
LightTip
text=
{
t
(
'workflow:quote_role_system_tip'
)
}
/>
)
}
</
Box
>
</
Flex
>
<
Box
mt=
{
4
}
>
<
Flex
{
...
LabelStyles
}
mb=
{
1
}
>
<
FormLabel
>
{
t
(
'common:core.app.Quote templates'
)
}
</
FormLabel
>
<
QuestionTip
ml=
{
1
}
label=
{
t
(
'workflow:quote_content_tip'
,
{
default
:
Prompt_QuoteTemplateList
[
0
].
value
})
}
></
QuestionTip
>
<
Box
flex=
{
1
}
/>
<
Box
{
...
selectTemplateBtn
}
fontSize=
{
'sm'
}
onClick=
{
()
=>
setSelectTemplateData
({
title
:
t
(
'common:core.app.Select quote template'
),
templates
:
Prompt_QuoteTemplateList
})
}
>
{
t
(
'common:common.Select template'
)
}
</
Box
>
</
Flex
>
<
PromptEditor
variables=
{
quoteTemplateVariables
}
minH=
{
160
}
title=
{
t
(
'common:core.app.Quote templates'
)
}
placeholder=
{
t
(
'workflow:quote_content_placeholder'
)
}
value=
{
aiChatQuoteTemplate
}
onChange=
{
(
e
)
=>
{
setValue
(
'quoteTemplate'
,
e
);
}
}
/>
</
Box
>
<
Box
mt=
{
4
}
>
<
Flex
{
...
LabelStyles
}
mb=
{
1
}
>
<
FormLabel
>
{
t
(
'common:core.app.Quote prompt'
)
}
</
FormLabel
>
<
QuestionTip
ml=
{
1
}
label=
{
t
(
'workflow:quote_prompt_tip'
,
{
default
:
quotePromptTemplates
[
0
].
value
})
}
></
QuestionTip
>
</
Flex
>
<
PromptEditor
variables=
{
quotePromptVariables
}
title=
{
t
(
'common:core.app.Quote prompt'
)
}
minH=
{
300
}
placeholder=
{
t
(
'workflow:quote_prompt_tip'
,
{
default
:
quotePromptTemplates
[
0
].
value
})
}
value=
{
aiChatQuotePrompt
}
onChange=
{
(
e
)
=>
{
setValue
(
'quotePrompt'
,
e
);
}
}
/>
</
Box
>
</
ModalBody
>
<
ModalFooter
>
<
Button
variant=
{
'whiteBase'
}
mr=
{
2
}
onClick=
{
onClose
}
>
{
t
(
'common:common.Close'
)
}
</
Button
>
<
Button
onClick=
{
handleSubmit
(
onSubmit
)
}
>
{
t
(
'common:common.Confirm'
)
}
</
Button
>
</
ModalFooter
>
</
MyModal
>
{
/* Prompt template */
}
{
!!
selectTemplateData
&&
(
<
PromptTemplate
title=
{
selectTemplateData
.
title
}
templates=
{
selectTemplateData
.
templates
}
onClose=
{
()
=>
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) => {
<
Reference
{
...
props
}
/>
</
Box
>
<
MyModal
isOpen=
{
isOpen
}
iconSrc=
{
'modal/edit'
}
title=
{
t
(
'workflow:Quote_prompt_setting'
)
}
w=
{
'100%'
}
h=
{
[
'90vh'
,
'85vh'
]
}
maxW=
{
[
'90vw'
,
'700px'
]
}
isCentered
>
<
ModalBody
flex=
{
'1 0 0'
}
overflow=
{
'auto'
}
>
<
Flex
{
...
LabelStyles
}
alignItems=
{
'center'
}
>
<
FormLabel
>
{
t
(
'workflow:dataset_quote_role'
)
}
</
FormLabel
>
<
QuestionTip
label=
{
t
(
'workflow:dataset_quote_role_tip'
)
}
ml=
{
1
}
mr=
{
5
}
/>
<
MySelect
<
AiChatQuoteRoleType
>
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
);
}
}
/
>
<
Box
ml=
{
5
}
>
{
aiChatQuoteRole
===
'user'
?
(
<
LightTip
text=
{
t
(
'workflow:quote_role_user_tip'
)
}
/>
)
:
(
<
LightTip
text=
{
t
(
'workflow:quote_role_system_tip'
)
}
/>
)
}
</
Box
>
</
Flex
>
<
Box
mt=
{
4
}
>
<
Flex
{
...
LabelStyles
}
mb=
{
1
}
>
<
FormLabel
>
{
t
(
'common:core.app.Quote templates'
)
}
</
FormLabel
>
<
QuestionTip
ml=
{
1
}
label=
{
t
(
'workflow:quote_content_tip'
,
{
default
:
Prompt_QuoteTemplateList
[
0
].
value
})
}
></
QuestionTip
>
<
Box
flex=
{
1
}
/>
<
Box
{
...
selectTemplateBtn
}
fontSize=
{
'sm'
}
onClick=
{
()
=>
setSelectTemplateData
({
title
:
t
(
'common:core.app.Select quote template'
),
templates
:
Prompt_QuoteTemplateList
})
}
>
{
t
(
'common:common.Select template'
)
}
</
Box
>
</
Flex
>
<
PromptEditor
variables=
{
quoteTemplateVariables
}
minH=
{
160
}
title=
{
t
(
'common:core.app.Quote templates'
)
}
placeholder=
{
t
(
'workflow:quote_content_placeholder'
)
}
value=
{
aiChatQuoteTemplate
}
onChange=
{
(
e
)
=>
{
setValue
(
'quoteTemplate'
,
e
);
}
}
/>
</
Box
>
<
Box
mt=
{
4
}
>
<
Flex
{
...
LabelStyles
}
mb=
{
1
}
>
<
FormLabel
>
{
t
(
'common:core.app.Quote prompt'
)
}
</
FormLabel
>
<
QuestionTip
ml=
{
1
}
label=
{
t
(
'workflow:quote_prompt_tip'
,
{
default
:
quotePromptTemplates
[
0
].
value
})
}
></
QuestionTip
>
</
Flex
>
<
PromptEditor
variables=
{
quotePromptVariables
}
title=
{
t
(
'common:core.app.Quote prompt'
)
}
minH=
{
300
}
placeholder=
{
t
(
'workflow:quote_prompt_tip'
,
{
default
:
quotePromptTemplates
[
0
].
value
})
}
value=
{
aiChatQuotePrompt
}
onChange=
{
(
e
)
=>
{
setValue
(
'quotePrompt'
,
e
);
}
}
/>
</
Box
>
</
ModalBody
>
<
ModalFooter
>
<
Button
variant=
{
'whiteBase'
}
mr=
{
2
}
onClick=
{
onClose
}
>
{
t
(
'common:common.Close'
)
}
</
Button
>
<
Button
onClick=
{
handleSubmit
(
onSubmit
)
}
>
{
t
(
'common:common.Confirm'
)
}
</
Button
>
</
ModalFooter
>
</
MyModal
>
{
/* Prompt template */
}
{
!!
selectTemplateData
&&
(
<
PromptTemplate
title=
{
selectTemplateData
.
title
}
templates=
{
selectTemplateData
.
templates
}
onClose=
{
()
=>
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
&&
<
EditModal
{
...
props
}
onClose=
{
onClose
}
/>
}
</>
);
}, [
aiChatQuotePrompt,
aiChatQuoteRole,
aiChatQuoteTemplate,
handleSubmit,
isOpen,
onClose,
onOpen,
onSubmit,
props,
quotePromptTemplates,
quotePromptVariables,
quoteTemplateVariables,
selectTemplateData,
setValue,
t
]);
},
[
isOpen
,
onClose
,
onOpen
,
t
]);
return
Render
;
}
;
...
...
projects/app/src/pages/app/detail/components/WorkflowComponents/utils.tsx
View file @
40f527a0
...
...
@@ -123,7 +123,6 @@ export const getEditorVariables = ({
const
sourceNodeVariables
=
!
sourceNodes
?
[]
:
sourceNodes
.
reverse
()
.
map
((
node
)
=>
{
return
node
.
outputs
.
filter
((
output
)
=>
!!
output
.
label
)
...
...
projects/app/src/pages/login/index.tsx
View file @
40f527a0
...
...
@@ -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
<
boolean
>
(
'showRedirect'
,
{
defaultValue
:
true
});
const
cookieVersion
=
1
;
const
cookieVersion
=
'1'
;
const
[
localCookieVersion
,
setLocalCookieVersion
]
=
useLocalStorageState
<
number
>
(
'localCookieVersion'
);
useLocalStorageState
<
string
>
(
'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
<
boolean
>
(
'showRedirect'
,
{
defaultValue
:
true
});
const
checkIpInChina
=
useCallback
(
async
()
=>
{
try
{
const
res
=
await
GET
<
any
>
(
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
(
<
Drawer
placement=
"bottom"
size=
{
'xs'
}
isOpen=
{
true
}
onClose=
{
onClose
}
>
...
...
@@ -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'
)
}
</
Box
>
...
...
projects/app/src/web/core/workflow/utils.ts
View file @
40f527a0
...
...
@@ -211,7 +211,7 @@ export const computedNodeInputReference = ({
};
findSourceNode
(
nodeId
);
sourceNodes
.
unshift
(
sourceNodes
.
push
(
getGlobalVariableNode
({
nodes
,
t
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment