Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/service/core/app/tool/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ export const refreshSystemTools = async (): Promise<AppToolTemplateItemType[]> =
author: item.author,
courseUrl: item.courseUrl,
instructions: dbPluginConfig?.customConfig?.userGuide,
tags: item.tags,
tags: dbPluginConfig?.customConfig?.tags || item.tags,
workflow: {
nodes: [],
edges: []
Expand Down
171 changes: 132 additions & 39 deletions projects/app/src/pageComponents/config/tool/SystemToolConfigModal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useMemo } from 'react';
import {
Box,
Button,
Expand Down Expand Up @@ -32,9 +32,14 @@ import MyDivider from '@fastgpt/web/components/common/MyDivider';
import { PluginStatusEnum } from '@fastgpt/global/core/plugin/type';
import MySelect from '@fastgpt/web/components/common/MySelect';
import { useTranslation } from 'next-i18next';
import MultipleSelect from '@fastgpt/web/components/common/MySelect/MultipleSelect';
import MultipleSelect, {
useMultipleSelect
} from '@fastgpt/web/components/common/MySelect/MultipleSelect';
import { UserTagsEnum } from '@fastgpt/global/support/user/type';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { getPluginToolTags } from '@/web/core/plugin/toolTag/api';
import { useToast } from '@fastgpt/web/hooks/useToast';
import type { UpdateToolBodyType } from '@fastgpt/global/openapi/core/plugin/admin/tool/api';

const COST_LIMITS = { max: 1000, min: 0, step: 0.1 };

Expand All @@ -47,28 +52,55 @@ const SystemToolConfigModal = ({
onSuccess: () => void;
onClose: () => void;
}) => {
const { t } = useTranslation();
const { t, i18n } = useTranslation();
const { feConfigs } = useSystemStore();
const { register, reset, handleSubmit, setValue, watch, control } =
useForm<AdminSystemToolDetailType>();
const { toast } = useToast();
const { register, reset, handleSubmit, setValue, watch, control } = useForm<UpdateToolBodyType>();

const { data: tool, loading } = useRequest2(() => getAdminSystemToolDetail({ toolId }), {
onSuccess(res) {
reset(res);
// 转换 AdminSystemToolDetailType 到 UpdateToolBodyType
const formData: Partial<UpdateToolBodyType> = {
status: res.status,
defaultInstalled: res.defaultInstalled,
inputListVal: res.inputListVal,
systemKeyCost: res.systemKeyCost,
childTools: res.childTools?.map((t) => ({
pluginId: t.pluginId,
systemKeyCost: t.systemKeyCost
})),
promoteTags: res.promoteTags,
hideTags: res.hideTags,
tagIds: res.tags || []
};
reset(formData);
setSelectedTags(res.tags || []);
},
manual: false
});

const [inputList, status, defaultInstalled, inputListVal, childTools, promoteTags, hideTags] =
watch([
'inputList',
'status',
'defaultInstalled',
'inputListVal',
'childTools',
'promoteTags',
'hideTags'
]);
// 从表单 watch 可变数据
const [status, defaultInstalled, inputListVal, childTools, promoteTags, hideTags] = watch([
'status',
'defaultInstalled',
'inputListVal',
'childTools',
'promoteTags',
'hideTags'
]);

// 从 tool 读取只读数据
const inputList = tool?.inputList;
const isFolder = tool?.isFolder;

const { value: selectedTags, setValue: setSelectedTags } = useMultipleSelect<string>(
tool?.tags ?? [],
false
);

useEffect(() => {
setValue('tagIds', selectedTags);
}, [selectedTags, setValue]);

// 是否显示系统密钥配置
const showSystemSecretInput = !!inputList && inputList.length > 0;
Expand All @@ -79,17 +111,24 @@ const SystemToolConfigModal = ({
value: tag
}));

const { data: toolTags = [], loading: loadingTags } = useRequest2(getPluginToolTags, {
manual: false
});

const pluginTypeSelectList = useMemo(
() =>
toolTags?.map((tag) => ({
label: parseI18nString(tag.tagName, i18n.language),
value: tag.tagId
})) || [],
[i18n.language, toolTags]
);

const { runAsync: onSubmit, loading: submitting } = useRequest2(
(formData: AdminSystemToolDetailType) =>
(formData: UpdateToolBodyType) =>
putAdminUpdateTool({
...formData,
pluginId: toolId,
childTools: formData.childTools?.map((tool) => {
return {
pluginId: tool.pluginId,
systemKeyCost: tool.systemKeyCost
};
})
pluginId: toolId
}),
{
successToast: t('common:Config') + t('common:Success'),
Expand Down Expand Up @@ -156,7 +195,7 @@ const SystemToolConfigModal = ({
<>
<MyDivider my={2} />

{!tool?.isFolder && (
{!isFolder && (
<HStack>
<Box flex={1} fontSize={'sm'} fontWeight={'medium'}>
{t('app:toolkit_system_key_cost')}
Expand All @@ -170,24 +209,24 @@ const SystemToolConfigModal = ({
/>
</HStack>
)}
{tool?.inputList?.map(renderInputField)}
{inputList?.map(renderInputField)}
</>
);

return (
<MyModal
isOpen
isLoading={loading}
isLoading={loading || loadingTags}
title={t('app:toolkit_tool_config', { name: tool?.name })}
iconSrc={tool?.avatar}
onClose={onClose}
width={tool?.isFolder ? '900px' : '450px'}
height={tool?.isFolder ? '500px' : 'auto'}
maxW={tool?.isFolder ? '900px' : '600px'}
width={isFolder ? '900px' : '450px'}
height={isFolder ? '500px' : 'auto'}
maxW={isFolder ? '900px' : '600px'}
bg={'white'}
>
<ModalBody>
{tool?.isFolder ? (
{isFolder ? (
<Flex gap={5}>
<Flex flexDirection={'column'} gap={5} flex={'0 0 300px'}>
<Box fontWeight={'medium'} color={'myGray.900'}>
Expand Down Expand Up @@ -234,6 +273,28 @@ const SystemToolConfigModal = ({
/>
</HStack>

<Box>
<Box color={'myGray.900'} fontSize={'sm'} fontWeight={'medium'} mb={2}>
{t('app:custom_plugin_tags_label')}
</Box>
<MultipleSelect
list={pluginTypeSelectList}
value={selectedTags}
onSelect={(newTags) => {
if (newTags.length > 3) {
toast({
title: t('app:custom_plugin_tags_max_limit'),
status: 'warning'
});
return;
}
setSelectedTags(newTags);
}}
placeholder={t('app:custom_plugin_tags_label')}
w={'100%'}
/>
</Box>

{showSystemSecretInput && (
<>
<HStack>
Expand Down Expand Up @@ -304,21 +365,18 @@ const SystemToolConfigModal = ({
<Th fontSize="xs" py={2} px={2} width="50px">
{t('app:toolkit_tool_name')}
</Th>
{/* <Th fontSize="xs" py={2} px={2} width="50px">
{t('common:Status')}
</Th> */}
<Th fontSize="xs" py={2} px={2} width="50px">
{t('app:toolkit_key_price')}
</Th>
</Tr>
</Thead>
<Tbody>
{childTools?.map((tool, index) => {
{tool?.childTools?.map((childTool, index) => {
return (
<Tr key={tool.pluginId}>
<Tr key={childTool.pluginId}>
<Td fontSize="xs">
<Text fontSize="xs" fontWeight="medium">
{parseI18nString(tool.name)}
{childTool.name}
</Text>
</Td>
<Td fontSize="xs">
Expand All @@ -329,6 +387,11 @@ const SystemToolConfigModal = ({
name={`childTools.${index}.systemKeyCost`}
{...COST_LIMITS}
/>
<Input
type="hidden"
{...register(`childTools.${index}.pluginId`)}
value={childTool.pluginId}
/>
</Td>
</Tr>
);
Expand Down Expand Up @@ -391,10 +454,9 @@ const SystemToolConfigModal = ({
onChange={(e) => {
const val = e.target.checked;
if (val) {
// @ts-ignore
setValue('inputListVal', {});
} else {
setValue('inputListVal', undefined);
setValue('inputListVal', null);
}
}}
/>
Expand All @@ -403,6 +465,37 @@ const SystemToolConfigModal = ({
</>
)}

<HStack>
<Box
flex={'0 0 160px'}
color={'myGray.900'}
fontWeight={'medium'}
fontSize={'sm'}
mb={2}
>
{t('app:custom_plugin_tags_label')}
</Box>
<MultipleSelect
list={pluginTypeSelectList}
value={selectedTags}
onSelect={(newTags) => {
if (newTags.length > 3) {
toast({
title: t('app:custom_plugin_tags_max_limit'),
status: 'warning'
});
return;
}
setSelectedTags(newTags);
}}
placeholder={t('app:custom_plugin_tags_label')}
maxW={270}
h={9}
borderRadius={'sm'}
bg={'myGray.50'}
/>
</HStack>

{feConfigs?.showWecomConfig && (
<>
<Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ async function handler(
systemKeyCost: tool.systemKeyCost
});
}),
tags: systemTool.tags || []
tags: systemDbTool?.customConfig?.tags || systemTool.tags || []
});
}

Expand Down
18 changes: 16 additions & 2 deletions projects/app/src/pages/api/core/plugin/admin/tool/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,24 @@ async function handler(
}
);
} else {
// 系统插件只更新基础字段, 如果有 child,需要更新 child
// 系统插件只更新基础字段和 tags(存储在 customConfig 中)
await mongoSessionRun(async (session) => {
await MongoSystemTool.updateOne({ pluginId }, baseUpdateFields, { upsert: true, session });
// 构建 customConfig,保留现有配置并添加/更新 tags
const existingCustomConfig = plugin?.customConfig || {};
const newCustomConfig = updateFields.tagIds
? { ...existingCustomConfig, tags: updateFields.tagIds }
: existingCustomConfig;

await MongoSystemTool.updateOne(
{ pluginId },
{
...baseUpdateFields,
...(Object.keys(newCustomConfig).length > 0 ? { customConfig: newCustomConfig } : {})
},
{ upsert: true, session }
);

// 如果有子工具,更新子工具
for await (const tool of updateFields.childTools || []) {
await MongoSystemTool.updateOne(
{ pluginId: tool.pluginId },
Expand Down
Loading