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
ee979434
authored
Jun 04, 2026
by
YeYuheng
Committed by
GitHub
Jun 04, 2026
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: stabilize agent sandbox mentions (#7027)
parent
2272899b
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
252 additions
and
21 deletions
+252
-21
packages/global/core/ai/sandbox/tools/common.ts
+2
-0
packages/global/core/ai/sandbox/tools/index.ts
+1
-1
packages/global/core/workflow/node/agent/constants.ts
+12
-1
packages/service/core/chat/HelperBot/dispatch/topAgent/index.ts
+5
-1
packages/service/core/chat/HelperBot/dispatch/topAgent/utils.ts
+2
-2
packages/service/test/core/chat/topAgentDispatch.test.ts
+129
-0
packages/service/test/core/chat/topAgentUtils.test.ts
+54
-0
packages/web/components/common/Textarea/PromptEditor/Editor.tsx
+6
-4
packages/web/components/common/Textarea/PromptEditor/plugins/SkillLabelPlugin/index.tsx
+8
-3
pro
+1
-1
projects/app/src/pageComponents/app/detail/Edit/ChatAgent/EditForm.tsx
+26
-2
projects/app/src/pageComponents/app/detail/Edit/ChatAgent/hooks/useSkillManager.tsx
+6
-6
No files found.
packages/global/core/ai/sandbox/tools/common.ts
View file @
ee979434
...
@@ -7,3 +7,5 @@ export const SANDBOX_NAME: I18nStringType = {
...
@@ -7,3 +7,5 @@ export const SANDBOX_NAME: I18nStringType = {
};
};
export
const
SANDBOX_ICON
=
'core/app/sandbox/sandbox'
as
const
;
export
const
SANDBOX_ICON
=
'core/app/sandbox/sandbox'
as
const
;
export
const
AGENT_SANDBOX_TOOLSET_ID
=
'agent_sandbox'
;
packages/global/core/ai/sandbox/tools/index.ts
View file @
ee979434
...
@@ -24,7 +24,7 @@ import {
...
@@ -24,7 +24,7 @@ import {
SANDBOX_WRITE_FILE_TOOL_NAME
SANDBOX_WRITE_FILE_TOOL_NAME
}
from
'./writeFile'
;
}
from
'./writeFile'
;
export
{
SANDBOX_ICON
,
SANDBOX_NAME
}
from
'./common'
;
export
{
AGENT_SANDBOX_TOOLSET_ID
,
SANDBOX_ICON
,
SANDBOX_NAME
}
from
'./common'
;
export
{
export
{
SANDBOX_EDIT_FILE_NAME
,
SANDBOX_EDIT_FILE_NAME
,
SANDBOX_EDIT_FILE_TOOL
,
SANDBOX_EDIT_FILE_TOOL
,
...
...
packages/global/core/workflow/node/agent/constants.ts
View file @
ee979434
import
type
{
I18nStringType
,
localeType
}
from
'../../../../common/i18n/type'
;
import
type
{
I18nStringType
,
localeType
}
from
'../../../../common/i18n/type'
;
import
{
sandboxToolMap
}
from
'../../../ai/sandbox/tools'
;
import
{
AGENT_SANDBOX_TOOLSET_ID
,
SANDBOX_ICON
,
SANDBOX_NAME
,
sandboxToolMap
}
from
'../../../ai/sandbox/tools'
;
import
{
parseI18nString
}
from
'../../../../common/i18n/utils'
;
import
{
parseI18nString
}
from
'../../../../common/i18n/utils'
;
export
enum
SubAppIds
{
export
enum
SubAppIds
{
...
@@ -50,6 +55,12 @@ export const systemSubInfo: Record<
...
@@ -50,6 +55,12 @@ export const systemSubInfo: Record<
avatar
:
'core/workflow/template/agent'
,
avatar
:
'core/workflow/template/agent'
,
toolDescription
:
'调用 LLM 模型完成一些通用任务。'
toolDescription
:
'调用 LLM 模型完成一些通用任务。'
},
},
[
AGENT_SANDBOX_TOOLSET_ID
]:
{
name
:
SANDBOX_NAME
,
avatar
:
SANDBOX_ICON
,
toolDescription
:
'提供完整虚拟机能力,包括命令执行、文件读写、文件编辑、文件搜索和文件链接生成。'
},
...
sandboxToolMap
...
sandboxToolMap
};
};
export
const
getSystemToolInfo
=
(
id
:
string
,
lang
:
localeType
=
'en'
)
=>
{
export
const
getSystemToolInfo
=
(
id
:
string
,
lang
:
localeType
=
'en'
)
=>
{
...
...
packages/service/core/chat/HelperBot/dispatch/topAgent/index.ts
View file @
ee979434
...
@@ -23,6 +23,7 @@ import { MongoDataset } from '../../../../dataset/schema';
...
@@ -23,6 +23,7 @@ import { MongoDataset } from '../../../../dataset/schema';
import
{
ObjectIdSchema
}
from
'@fastgpt/global/common/type/mongo'
;
import
{
ObjectIdSchema
}
from
'@fastgpt/global/common/type/mongo'
;
import
type
{
SelectedDatasetType
}
from
'@fastgpt/global/core/workflow/type/io'
;
import
type
{
SelectedDatasetType
}
from
'@fastgpt/global/core/workflow/type/io'
;
import
{
getLogger
,
LogCategories
}
from
'../../../../../common/logger'
;
import
{
getLogger
,
LogCategories
}
from
'../../../../../common/logger'
;
import
{
AGENT_SANDBOX_TOOLSET_ID
}
from
'@fastgpt/global/core/ai/sandbox/tools'
;
export
const
dispatchTopAgent
=
async
(
export
const
dispatchTopAgent
=
async
(
props
:
HelperBotDispatchParamsType
<
TopAgentParamsType
>
props
:
HelperBotDispatchParamsType
<
TopAgentParamsType
>
...
@@ -155,12 +156,15 @@ export const dispatchTopAgent = async (
...
@@ -155,12 +156,15 @@ export const dispatchTopAgent = async (
teamId
:
user
.
teamId
,
teamId
:
user
.
teamId
,
datasetIds
:
knowledges
datasetIds
:
knowledges
});
});
const
enableSandboxEnabled
=
responseJson
.
resources
?.
system_features
?.
sandbox
?.
enabled
||
tools
.
includes
(
AGENT_SANDBOX_TOOLSET_ID
);
const
formData
=
TopAgentFormDataSchema
.
parse
({
const
formData
=
TopAgentFormDataSchema
.
parse
({
systemPrompt
:
buildSystemPrompt
(
responseJson
),
// 构建 system prompt
systemPrompt
:
buildSystemPrompt
(
responseJson
),
// 构建 system prompt
tools
,
// 从 execution_plan 提取
tools
,
// 从 execution_plan 提取
datasets
:
filterDatasets
,
datasets
:
filterDatasets
,
fileUploadEnabled
:
responseJson
.
resources
?.
system_features
?.
file_upload
?.
enabled
||
false
,
fileUploadEnabled
:
responseJson
.
resources
?.
system_features
?.
file_upload
?.
enabled
||
false
,
enableSandboxEnabled
:
responseJson
.
resources
?.
system_features
?.
sandbox
?.
enabled
||
false
,
enableSandboxEnabled
,
executionPlan
:
responseJson
.
execution_plan
// 保存原始 execution_plan
executionPlan
:
responseJson
.
execution_plan
// 保存原始 execution_plan
});
});
...
...
packages/service/core/chat/HelperBot/dispatch/topAgent/utils.ts
View file @
ee979434
...
@@ -7,9 +7,9 @@ import { MongoResourcePermission } from '../../../../../support/permission/schem
...
@@ -7,9 +7,9 @@ import { MongoResourcePermission } from '../../../../../support/permission/schem
import
{
PerResourceTypeEnum
}
from
'@fastgpt/global/support/permission/constant'
;
import
{
PerResourceTypeEnum
}
from
'@fastgpt/global/support/permission/constant'
;
import
{
getGroupsByTmbId
}
from
'../../../../../support/permission/memberGroup/controllers'
;
import
{
getGroupsByTmbId
}
from
'../../../../../support/permission/memberGroup/controllers'
;
import
{
getOrgIdSetWithParentByTmbId
}
from
'../../../../../support/permission/org/controllers'
;
import
{
getOrgIdSetWithParentByTmbId
}
from
'../../../../../support/permission/org/controllers'
;
import
{
SANDBOX_SHELL_TOOL_NAME
}
from
'@fastgpt/global/core/ai/sandbox/tools'
;
import
{
getUserAvaliableWorkflowTools
}
from
'../../../../app/tool/workflowTool'
;
import
{
getUserAvaliableWorkflowTools
}
from
'../../../../app/tool/workflowTool'
;
import
{
SystemToolRepo
}
from
'../../../../app/tool/systemTool/systemTool.repo'
;
import
{
SystemToolRepo
}
from
'../../../../app/tool/systemTool/systemTool.repo'
;
import
{
AGENT_SANDBOX_TOOLSET_ID
}
from
'@fastgpt/global/core/ai/sandbox/tools'
;
const
getAccessibleDatasets
=
async
({
teamId
,
tmbId
}:
{
teamId
:
string
;
tmbId
:
string
})
=>
{
const
getAccessibleDatasets
=
async
({
teamId
,
tmbId
}:
{
teamId
:
string
;
tmbId
:
string
})
=>
{
const
[
roleList
,
myGroupMap
,
myOrgSet
]
=
await
Promise
.
all
([
const
[
roleList
,
myGroupMap
,
myOrgSet
]
=
await
Promise
.
all
([
...
@@ -109,7 +109,7 @@ ${dataset}
...
@@ -109,7 +109,7 @@ ${dataset}
})
})
]);
]);
const
builtinTools
=
[
SubAppIds
.
readFiles
,
SANDBOX_SHELL_TOOL_NAME
].
map
((
id
)
=>
{
const
builtinTools
=
[
SubAppIds
.
readFiles
,
AGENT_SANDBOX_TOOLSET_ID
].
map
((
id
)
=>
{
const
info
=
systemSubInfo
[
id
];
const
info
=
systemSubInfo
[
id
];
return
`- **
${
id
}
** [工具]:
${
parseI18nString
(
info
.
name
,
lang
)}
-
${
info
.
toolDescription
}
`
;
return
`- **
${
id
}
** [工具]:
${
parseI18nString
(
info
.
name
,
lang
)}
-
${
info
.
toolDescription
}
`
;
});
});
...
...
packages/service/test/core/chat/topAgentDispatch.test.ts
0 → 100644
View file @
ee979434
import
{
beforeEach
,
describe
,
expect
,
it
,
vi
}
from
'vitest'
;
import
{
AGENT_SANDBOX_TOOLSET_ID
}
from
'@fastgpt/global/core/ai/sandbox/tools'
;
import
{
SseResponseEventEnum
}
from
'@fastgpt/global/core/workflow/runtime/constants'
;
const
{
createLLMResponseMock
}
=
vi
.
hoisted
(()
=>
({
createLLMResponseMock
:
vi
.
fn
()
}));
vi
.
mock
(
'@fastgpt/service/core/ai/llm/request'
,
()
=>
({
createLLMResponse
:
createLLMResponseMock
}));
vi
.
mock
(
'@fastgpt/service/core/ai/model'
,
()
=>
({
getDefaultHelperBotModel
:
vi
.
fn
(()
=>
({
model
:
'helper-model'
}))
}));
vi
.
mock
(
'@fastgpt/service/core/app/tool/controller'
,
()
=>
({
getSystemToolsWithInstalled
:
vi
.
fn
(
async
()
=>
[]),
getMyTools
:
vi
.
fn
(
async
()
=>
[])
}));
vi
.
mock
(
'@fastgpt/service/core/dataset/schema'
,
()
=>
({
MongoDataset
:
{
find
:
vi
.
fn
(()
=>
({
select
:
vi
.
fn
(()
=>
({
sort
:
vi
.
fn
(()
=>
({
lean
:
vi
.
fn
(
async
()
=>
[])
}))
})),
lean
:
vi
.
fn
(
async
()
=>
[])
}))
}
}));
vi
.
mock
(
'@fastgpt/service/support/permission/schema'
,
()
=>
({
MongoResourcePermission
:
{
find
:
vi
.
fn
(()
=>
({
lean
:
vi
.
fn
(
async
()
=>
[])
}))
}
}));
vi
.
mock
(
'@fastgpt/service/support/permission/memberGroup/controllers'
,
()
=>
({
getGroupsByTmbId
:
vi
.
fn
(
async
()
=>
[])
}));
vi
.
mock
(
'@fastgpt/service/support/permission/org/controllers'
,
()
=>
({
getOrgIdSetWithParentByTmbId
:
vi
.
fn
(
async
()
=>
new
Set
())
}));
import
{
dispatchTopAgent
}
from
'@fastgpt/service/core/chat/HelperBot/dispatch/topAgent'
;
describe
(
'dispatchTopAgent'
,
()
=>
{
beforeEach
(()
=>
{
vi
.
clearAllMocks
();
});
it
(
'enables sandbox when generated plan selects the agent sandbox toolset'
,
async
()
=>
{
createLLMResponseMock
.
mockResolvedValue
({
answerText
:
JSON
.
stringify
({
phase
:
'generation'
,
reasoning
:
'need sandbox'
,
task_analysis
:
{
goal
:
'run code'
,
role
:
'coding assistant'
,
key_features
:
'execute shell commands'
},
execution_plan
:
{
total_steps
:
1
,
steps
:
[
{
id
:
'step_1'
,
title
:
'Execute command'
,
description
:
`Use @
${
AGENT_SANDBOX_TOOLSET_ID
}
to inspect files`
,
expectedTools
:
[
{
id
:
AGENT_SANDBOX_TOOLSET_ID
,
type
:
'tool'
}
]
}
]
},
resources
:
{
system_features
:
{
file_upload
:
{
enabled
:
false
},
sandbox
:
{
enabled
:
false
}
}
}
}),
reasoningText
:
''
,
usage
:
{
inputTokens
:
10
,
outputTokens
:
5
}
});
const
workflowResponseWrite
=
vi
.
fn
();
await
dispatchTopAgent
({
query
:
'build an agent that can run commands'
,
files
:
[],
data
:
{},
histories
:
[],
workflowResponseWrite
,
user
:
{
teamId
:
'team_1'
,
tmbId
:
'tmb_1'
,
userId
:
'user_1'
,
isRoot
:
false
,
lang
:
'zh-CN'
}
});
expect
(
workflowResponseWrite
).
toHaveBeenCalledWith
({
event
:
SseResponseEventEnum
.
topAgentConfig
,
data
:
expect
.
objectContaining
({
tools
:
[
AGENT_SANDBOX_TOOLSET_ID
],
enableSandboxEnabled
:
true
})
});
});
});
packages/service/test/core/chat/topAgentUtils.test.ts
0 → 100644
View file @
ee979434
import
{
describe
,
expect
,
it
,
vi
}
from
'vitest'
;
import
{
AGENT_SANDBOX_TOOLSET_ID
,
SANDBOX_SHELL_TOOL_NAME
}
from
'@fastgpt/global/core/ai/sandbox/tools'
;
vi
.
mock
(
'@fastgpt/service/core/app/tool/controller'
,
()
=>
({
getSystemToolsWithInstalled
:
vi
.
fn
(
async
()
=>
[]),
getMyTools
:
vi
.
fn
(
async
()
=>
[])
}));
vi
.
mock
(
'@fastgpt/service/core/dataset/schema'
,
()
=>
({
MongoDataset
:
{
find
:
vi
.
fn
(()
=>
({
select
:
vi
.
fn
(()
=>
({
sort
:
vi
.
fn
(()
=>
({
lean
:
vi
.
fn
(
async
()
=>
[])
}))
}))
}))
}
}));
vi
.
mock
(
'@fastgpt/service/support/permission/schema'
,
()
=>
({
MongoResourcePermission
:
{
find
:
vi
.
fn
(()
=>
({
lean
:
vi
.
fn
(
async
()
=>
[])
}))
}
}));
vi
.
mock
(
'@fastgpt/service/support/permission/memberGroup/controllers'
,
()
=>
({
getGroupsByTmbId
:
vi
.
fn
(
async
()
=>
[])
}));
vi
.
mock
(
'@fastgpt/service/support/permission/org/controllers'
,
()
=>
({
getOrgIdSetWithParentByTmbId
:
vi
.
fn
(
async
()
=>
new
Set
())
}));
import
{
generateResourceList
}
from
'@fastgpt/service/core/chat/HelperBot/dispatch/topAgent/utils'
;
describe
(
'topAgent utils'
,
()
=>
{
it
(
'lists sandbox as an agent sandbox capability group instead of the shell tool'
,
async
()
=>
{
const
{
resourceList
}
=
await
generateResourceList
({
teamId
:
'team_1'
,
tmbId
:
'tmb_1'
,
isRoot
:
false
,
lang
:
'zh-CN'
});
expect
(
resourceList
).
toContain
(
`**
${
AGENT_SANDBOX_TOOLSET_ID
}
**`
);
expect
(
resourceList
).
not
.
toContain
(
`**
${
SANDBOX_SHELL_TOOL_NAME
}
**`
);
});
});
packages/web/components/common/Textarea/PromptEditor/Editor.tsx
View file @
ee979434
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*/
*/
import
type
{
CSSProperties
}
from
'react'
;
import
type
{
CSSProperties
}
from
'react'
;
import
{
use
Effect
,
use
Memo
,
useState
,
useTransition
,
useRef
}
from
'react'
;
import
{
useMemo
,
useState
,
useTransition
,
useRef
}
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
{
RichTextPlugin
}
from
'@lexical/react/LexicalRichTextPlugin'
;
import
{
RichTextPlugin
}
from
'@lexical/react/LexicalRichTextPlugin'
;
...
@@ -27,7 +27,7 @@ import { Box, Flex } from '@chakra-ui/react';
...
@@ -27,7 +27,7 @@ import { Box, Flex } from '@chakra-ui/react';
import
styles
from
'./index.module.scss'
;
import
styles
from
'./index.module.scss'
;
import
VariablePlugin
from
'./plugins/VariablePlugin'
;
import
VariablePlugin
from
'./plugins/VariablePlugin'
;
import
{
VariableNode
}
from
'./plugins/VariablePlugin/node'
;
import
{
VariableNode
}
from
'./plugins/VariablePlugin/node'
;
import
type
{
EditorState
,
LexicalEditor
}
from
'lexical'
;
import
type
{
LexicalEditor
}
from
'lexical'
;
import
OnBlurPlugin
from
'./plugins/OnBlurPlugin'
;
import
OnBlurPlugin
from
'./plugins/OnBlurPlugin'
;
import
type
{
FormPropsType
}
from
'./type'
;
import
type
{
FormPropsType
}
from
'./type'
;
import
{
type
EditorVariableLabelPickerType
,
type
EditorVariablePickerType
}
from
'./type'
;
import
{
type
EditorVariableLabelPickerType
,
type
EditorVariablePickerType
}
from
'./type'
;
...
@@ -142,7 +142,7 @@ export default function Editor({
...
@@ -142,7 +142,7 @@ export default function Editor({
onBlur
?:
(
editor
:
LexicalEditor
)
=>
void
;
onBlur
?:
(
editor
:
LexicalEditor
)
=>
void
;
})
{
})
{
const
[
key
,
setKey
]
=
useState
(
getNanoid
(
6
));
const
[
key
,
setKey
]
=
useState
(
getNanoid
(
6
));
const
[
_
,
startSts
]
=
useTransition
();
const
[,
startSts
]
=
useTransition
();
const
[
focus
,
setFocus
]
=
useState
(
false
);
const
[
focus
,
setFocus
]
=
useState
(
false
);
const
[
scrollHeight
,
setScrollHeight
]
=
useState
(
0
);
const
[
scrollHeight
,
setScrollHeight
]
=
useState
(
0
);
const
editorOutputRef
=
useRef
(
value
);
const
editorOutputRef
=
useRef
(
value
);
...
@@ -164,10 +164,12 @@ export default function Editor({
...
@@ -164,10 +164,12 @@ export default function Editor({
}
}
};
};
// 技能菜单和标签状态由插件内部同步;不能因 selectedSkills 变化重建编辑器,
// 否则 @ 插入瞬间会销毁 SkillNode,并误触发工具移除监听。
useDeepCompareEffect
(()
=>
{
useDeepCompareEffect
(()
=>
{
if
(
focus
&&
value
===
editorOutputRef
.
current
)
return
;
if
(
focus
&&
value
===
editorOutputRef
.
current
)
return
;
setKey
(
getNanoid
(
6
));
setKey
(
getNanoid
(
6
));
},
[
value
,
variables
,
variableLabels
,
skillOption
,
selectedSkills
]);
},
[
value
,
variables
,
variableLabels
]);
const
showFullScreenIcon
=
useMemo
(()
=>
{
const
showFullScreenIcon
=
useMemo
(()
=>
{
return
showOpenModal
&&
scrollHeight
>
maxH
;
return
showOpenModal
&&
scrollHeight
>
maxH
;
...
...
packages/web/components/common/Textarea/PromptEditor/plugins/SkillLabelPlugin/index.tsx
View file @
ee979434
...
@@ -97,8 +97,6 @@ function SkillLabelPlugin({
...
@@ -97,8 +97,6 @@ function SkillLabelPlugin({
// Update existing SkillNode properties when selectedSkills change
// Update existing SkillNode properties when selectedSkills change
// Sync tool name, avatar, status and configure handler for each skill node
// Sync tool name, avatar, status and configure handler for each skill node
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
selectedSkills
.
length
===
0
)
return
;
// Wrapped click handler: delete if invalid, otherwise call original onClickSkill
// Wrapped click handler: delete if invalid, otherwise call original onClickSkill
const
handleClick
=
(
id
:
string
,
status
:
SkillLabelItemType
[
'configStatus'
])
=>
{
const
handleClick
=
(
id
:
string
,
status
:
SkillLabelItemType
[
'configStatus'
])
=>
{
if
(
status
===
'invalid'
)
{
if
(
status
===
'invalid'
)
{
...
@@ -126,14 +124,21 @@ function SkillLabelPlugin({
...
@@ -126,14 +124,21 @@ function SkillLabelPlugin({
if
(
node
instanceof
SkillNode
)
{
if
(
node
instanceof
SkillNode
)
{
const
id
=
node
.
getSkillKey
();
const
id
=
node
.
getSkillKey
();
const
tool
=
selectedSkills
.
find
((
t
)
=>
t
.
id
===
id
);
const
tool
=
selectedSkills
.
find
((
t
)
=>
t
.
id
===
id
);
const
writableNode
=
node
.
getWritable
();
if
(
tool
)
{
if
(
tool
)
{
const
writableNode
=
node
.
getWritable
();
writableNode
.
__id
=
tool
.
id
;
writableNode
.
__id
=
tool
.
id
;
writableNode
.
__name
=
tool
.
name
;
writableNode
.
__name
=
tool
.
name
;
writableNode
.
__icon
=
tool
.
avatar
;
writableNode
.
__icon
=
tool
.
avatar
;
writableNode
.
__skillType
=
tool
.
flowNodeType
;
writableNode
.
__skillType
=
tool
.
flowNodeType
;
writableNode
.
__status
=
tool
.
configStatus
;
writableNode
.
__status
=
tool
.
configStatus
;
writableNode
.
__onClick
=
(
id
)
=>
handleClick
(
id
,
tool
.
configStatus
);
writableNode
.
__onClick
=
(
id
)
=>
handleClick
(
id
,
tool
.
configStatus
);
}
else
{
writableNode
.
__name
=
id
;
writableNode
.
__icon
=
undefined
;
writableNode
.
__skillType
=
FlowNodeTypeEnum
.
tool
;
writableNode
.
__status
=
'invalid'
;
writableNode
.
__onClick
=
(
id
)
=>
handleClick
(
id
,
'invalid'
);
}
}
}
}
});
});
...
...
pro
@
1ebfaac6
Subproject commit
0e3a010511341a538100a3ca7291bb2c6ccb5118
Subproject commit
1ebfaac6a4e6faef2c01d4b6785add3debf7285f
projects/app/src/pageComponents/app/detail/Edit/ChatAgent/EditForm.tsx
View file @
ee979434
...
@@ -28,7 +28,7 @@ import { SmallAddIcon } from '@chakra-ui/icons';
...
@@ -28,7 +28,7 @@ import { SmallAddIcon } from '@chakra-ui/icons';
import
MyIconButton
,
{
MyDeleteIconButton
}
from
'@fastgpt/web/components/common/Icon/button'
;
import
MyIconButton
,
{
MyDeleteIconButton
}
from
'@fastgpt/web/components/common/Icon/button'
;
import
MyTooltip
from
'@fastgpt/web/components/common/MyTooltip'
;
import
MyTooltip
from
'@fastgpt/web/components/common/MyTooltip'
;
import
{
useSkillManager
}
from
'./hooks/useSkillManager'
;
import
{
useSkillManager
}
from
'./hooks/useSkillManager'
;
import
{
SANDBOX_ICON
}
from
'@fastgpt/global/core/ai/sandbox/tools'
;
import
{
AGENT_SANDBOX_TOOLSET_ID
,
SANDBOX_ICON
}
from
'@fastgpt/global/core/ai/sandbox/tools'
;
import
QuestionTip
from
'@fastgpt/web/components/common/MyTooltip/QuestionTip'
;
import
QuestionTip
from
'@fastgpt/web/components/common/MyTooltip/QuestionTip'
;
import
SandboxTipTag
from
'../../components/SandboxTipTag'
;
import
SandboxTipTag
from
'../../components/SandboxTipTag'
;
import
{
useSystemStore
}
from
'@/web/common/system/useSystemStore'
;
import
{
useSystemStore
}
from
'@/web/common/system/useSystemStore'
;
...
@@ -134,6 +134,30 @@ const EditForm = ({
...
@@ -134,6 +134,30 @@ const EditForm = ({
enableSandbox
,
enableSandbox
,
setAppForm
setAppForm
});
});
const
promptSkillOption
=
useMemo
(
()
=>
({
...
skillOption
,
onSelect
:
async
(
id
:
string
)
=>
{
const
option
=
await
skillOption
.
onSelect
?.(
id
);
if
(
!
option
?.
onClick
)
return
option
;
return
{
...
option
,
onClick
:
async
(
toolId
:
string
)
=>
{
const
skillId
=
await
option
.
onClick
?.(
toolId
);
// AgentV2 提示词 @虚拟机 时,同步打开下方虚拟机开关。
if
(
skillId
===
AGENT_SANDBOX_TOOLSET_ID
&&
!
appForm
.
aiSettings
.
useAgentSandbox
)
{
onChangeAgentSandbox
(
true
);
}
return
skillId
;
}
};
}
}),
[
appForm
.
aiSettings
.
useAgentSandbox
,
onChangeAgentSandbox
,
skillOption
]
);
const
tokenLimit
=
useMemo
(()
=>
{
const
tokenLimit
=
useMemo
(()
=>
{
return
selectedModel
.
quoteMaxToken
||
3000
;
return
selectedModel
.
quoteMaxToken
||
3000
;
},
[
selectedModel
.
quoteMaxToken
]);
},
[
selectedModel
.
quoteMaxToken
]);
...
@@ -217,7 +241,7 @@ const EditForm = ({
...
@@ -217,7 +241,7 @@ const EditForm = ({
bg=
{
'myGray.50'
}
bg=
{
'myGray.50'
}
title=
{
t
(
'common:core.ai.Prompt'
)
}
title=
{
t
(
'common:core.ai.Prompt'
)
}
isRichText=
{
true
}
isRichText=
{
true
}
skillOption=
{
s
killOption
}
skillOption=
{
promptS
killOption
}
selectedSkills=
{
selectedSkills
}
selectedSkills=
{
selectedSkills
}
onClickSkill=
{
onClickSkill
}
onClickSkill=
{
onClickSkill
}
onRemoveSkill=
{
onRemoveSkill
}
onRemoveSkill=
{
onRemoveSkill
}
...
...
projects/app/src/pageComponents/app/detail/Edit/ChatAgent/hooks/useSkillManager.tsx
View file @
ee979434
...
@@ -31,7 +31,7 @@ import {
...
@@ -31,7 +31,7 @@ import {
import
{
useLatest
}
from
'ahooks'
;
import
{
useLatest
}
from
'ahooks'
;
import
{
SubAppIds
,
systemSubInfo
}
from
'@fastgpt/global/core/workflow/node/agent/constants'
;
import
{
SubAppIds
,
systemSubInfo
}
from
'@fastgpt/global/core/workflow/node/agent/constants'
;
import
{
parseI18nString
}
from
'@fastgpt/global/common/i18n/utils'
;
import
{
parseI18nString
}
from
'@fastgpt/global/common/i18n/utils'
;
import
{
SANDBOX_SHELL_TOOL_NAME
}
from
'@fastgpt/global/core/ai/sandbox/tools'
;
import
{
AGENT_SANDBOX_TOOLSET_ID
}
from
'@fastgpt/global/core/ai/sandbox/tools'
;
const
ConfigToolModal
=
dynamic
(()
=>
import
(
'../../component/ConfigToolModal'
));
const
ConfigToolModal
=
dynamic
(()
=>
import
(
'../../component/ConfigToolModal'
));
...
@@ -100,10 +100,10 @@ export const useSkillManager = ({
...
@@ -100,10 +100,10 @@ export const useSkillManager = ({
});
});
}
}
const
sandboxToolInfo
=
systemSubInfo
[
SANDBOX_SHELL_TOOL_NAME
];
const
sandboxToolInfo
=
systemSubInfo
[
AGENT_SANDBOX_TOOLSET_ID
];
if
(
sandboxToolInfo
)
{
if
(
sandboxToolInfo
)
{
apiTools
.
unshift
({
apiTools
.
unshift
({
id
:
SANDBOX_SHELL_TOOL_NAME
,
id
:
AGENT_SANDBOX_TOOLSET_ID
,
label
:
parseI18nString
(
sandboxToolInfo
.
name
,
i18n
.
language
),
label
:
parseI18nString
(
sandboxToolInfo
.
name
,
i18n
.
language
),
icon
:
sandboxToolInfo
.
avatar
,
icon
:
sandboxToolInfo
.
avatar
,
description
:
sandboxToolInfo
.
toolDescription
,
description
:
sandboxToolInfo
.
toolDescription
,
...
@@ -306,11 +306,11 @@ export const useSkillManager = ({
...
@@ -306,11 +306,11 @@ export const useSkillManager = ({
}
}
// Merge sandbox tool
// Merge sandbox tool
const
sandboxToolInfo
=
systemSubInfo
[
SANDBOX_SHELL_TOOL_NAME
];
const
sandboxToolInfo
=
systemSubInfo
[
AGENT_SANDBOX_TOOLSET_ID
];
if
(
sandboxToolInfo
)
{
if
(
sandboxToolInfo
)
{
tools
.
push
({
tools
.
push
({
id
:
SANDBOX_SHELL_TOOL_NAME
,
id
:
AGENT_SANDBOX_TOOLSET_ID
,
pluginId
:
SANDBOX_SHELL_TOOL_NAME
,
pluginId
:
AGENT_SANDBOX_TOOLSET_ID
,
name
:
parseI18nString
(
sandboxToolInfo
.
name
,
i18n
.
language
),
name
:
parseI18nString
(
sandboxToolInfo
.
name
,
i18n
.
language
),
avatar
:
sandboxToolInfo
.
avatar
,
avatar
:
sandboxToolInfo
.
avatar
,
intro
:
sandboxToolInfo
.
toolDescription
,
intro
:
sandboxToolInfo
.
toolDescription
,
...
...
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