fix :Get application bound knowledge base information logical rewrite (#4057)
* fix :Get application bound knowledge base information logical rewrite * fix :Get application bound knowledge base information logical rewrite * fix :Get application bound knowledge base information logical rewrite * fix :Get application bound knowledge base information logical rewrite
This commit is contained in:
parent
f9dd170895
commit
4dbe41db0e
7
packages/global/core/workflow/api.d.ts
vendored
7
packages/global/core/workflow/api.d.ts
vendored
@ -1,7 +1,12 @@
|
|||||||
import { EmbeddingModelItemType } from '../ai/model.d';
|
import { EmbeddingModelItemType } from '../ai/model.d';
|
||||||
import { NodeInputKeyEnum } from './constants';
|
import { NodeInputKeyEnum } from './constants';
|
||||||
|
|
||||||
export type SelectedDatasetType = { datasetId: string }[];
|
export type SelectedDatasetType = {
|
||||||
|
datasetId: string;
|
||||||
|
avatar: string;
|
||||||
|
name: string;
|
||||||
|
vectorModel: EmbeddingModelItemType;
|
||||||
|
}[];
|
||||||
|
|
||||||
export type HttpBodyType<T = Record<string, any>> = {
|
export type HttpBodyType<T = Record<string, any>> = {
|
||||||
// [NodeInputKeyEnum.addInputParam]: Record<string, any>;
|
// [NodeInputKeyEnum.addInputParam]: Record<string, any>;
|
||||||
|
|||||||
123
packages/service/core/app/utils.ts
Normal file
123
packages/service/core/app/utils.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
import { MongoDataset } from '../dataset/schema';
|
||||||
|
import { getEmbeddingModel } from '../ai/model';
|
||||||
|
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||||
|
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||||
|
import type { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
|
||||||
|
|
||||||
|
export type ListByAppIdAndDatasetIdsBody = {
|
||||||
|
teamId: string;
|
||||||
|
datasetIdList: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Dataset {
|
||||||
|
datasetId: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listAppDatasetDataByTeamIdAndDatasetIds({
|
||||||
|
teamId,
|
||||||
|
datasetIdList
|
||||||
|
}: ListByAppIdAndDatasetIdsBody) {
|
||||||
|
const myDatasets = await MongoDataset.find({
|
||||||
|
teamId,
|
||||||
|
_id: { $in: datasetIdList }
|
||||||
|
}).lean();
|
||||||
|
|
||||||
|
return myDatasets.map((item) => ({
|
||||||
|
datasetId: item._id,
|
||||||
|
avatar: item.avatar,
|
||||||
|
name: item.name,
|
||||||
|
vectorModel: getEmbeddingModel(item.vectorModel)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function rewriteAppWorkflowToDetail(nodes: StoreNodeItemType[], teamId: string) {
|
||||||
|
const datasetIdSet = new Set<string>();
|
||||||
|
|
||||||
|
nodes.forEach((node) => {
|
||||||
|
if (node.flowNodeType !== FlowNodeTypeEnum.datasetSearchNode) return;
|
||||||
|
|
||||||
|
const input = node.inputs.find((item) => item.key === NodeInputKeyEnum.datasetSelectList);
|
||||||
|
if (!input) return;
|
||||||
|
|
||||||
|
const rawValue = input.value as undefined | { datasetId: string }[] | { datasetId: string };
|
||||||
|
|
||||||
|
const datasetIds = Array.isArray(rawValue)
|
||||||
|
? rawValue
|
||||||
|
.map((v) => v?.datasetId)
|
||||||
|
.filter((id): id is string => !!id && typeof id === 'string')
|
||||||
|
: rawValue?.datasetId
|
||||||
|
? [String(rawValue.datasetId)]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
if (datasetIds.length === 0) return;
|
||||||
|
|
||||||
|
datasetIds.forEach((id) => datasetIdSet.add(id));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (datasetIdSet.size === 0) return;
|
||||||
|
|
||||||
|
const uniqueDatasetIds = Array.from(datasetIdSet);
|
||||||
|
const datasetList = await listAppDatasetDataByTeamIdAndDatasetIds({
|
||||||
|
teamId,
|
||||||
|
datasetIdList: uniqueDatasetIds
|
||||||
|
});
|
||||||
|
|
||||||
|
const datasetMap = new Map(
|
||||||
|
datasetList.map((ds) => [
|
||||||
|
String(ds.datasetId),
|
||||||
|
{
|
||||||
|
...ds,
|
||||||
|
vectorModel: getEmbeddingModel(ds.vectorModel.model)
|
||||||
|
}
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
nodes.forEach((node) => {
|
||||||
|
if (node.flowNodeType !== FlowNodeTypeEnum.datasetSearchNode) return;
|
||||||
|
|
||||||
|
const input = node.inputs.find((item) => item.key === NodeInputKeyEnum.datasetSelectList);
|
||||||
|
if (!input) return;
|
||||||
|
|
||||||
|
const rawValue = input.value as undefined | { datasetId: string }[] | { datasetId: string };
|
||||||
|
|
||||||
|
const datasetIds = Array.isArray(rawValue)
|
||||||
|
? rawValue
|
||||||
|
.map((v) => v?.datasetId)
|
||||||
|
.filter((id): id is string => !!id && typeof id === 'string')
|
||||||
|
: rawValue?.datasetId
|
||||||
|
? [String(rawValue.datasetId)]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
if (datasetIds.length === 0) return;
|
||||||
|
|
||||||
|
input.value = datasetIds
|
||||||
|
.map((id) => {
|
||||||
|
const data = datasetMap.get(String(id));
|
||||||
|
return data
|
||||||
|
? {
|
||||||
|
datasetId: data.datasetId,
|
||||||
|
avatar: data.avatar,
|
||||||
|
name: data.name,
|
||||||
|
vectorModel: data.vectorModel
|
||||||
|
}
|
||||||
|
: undefined;
|
||||||
|
})
|
||||||
|
.filter((item): item is NonNullable<typeof item> => !!item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function rewriteAppWorkflowToSimple(formatNodes: StoreNodeItemType[]) {
|
||||||
|
formatNodes.forEach((node) => {
|
||||||
|
if (node.flowNodeType !== FlowNodeTypeEnum.datasetSearchNode) return;
|
||||||
|
|
||||||
|
const datasetsInput = node.inputs.find(
|
||||||
|
(input) => input.key === NodeInputKeyEnum.datasetSelectList
|
||||||
|
);
|
||||||
|
if (datasetsInput?.value) {
|
||||||
|
datasetsInput.value = datasetsInput.value.map((dataset: Dataset) => ({
|
||||||
|
datasetId: dataset.datasetId
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -17,7 +17,6 @@ import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
|||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
|
||||||
import DatasetSelectContainer, { useDatasetSelect } from '@/components/core/dataset/SelectModal';
|
import DatasetSelectContainer, { useDatasetSelect } from '@/components/core/dataset/SelectModal';
|
||||||
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
import { useLoading } from '@fastgpt/web/hooks/useLoading';
|
||||||
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
import EmptyTip from '@fastgpt/web/components/common/EmptyTip';
|
||||||
@ -35,29 +34,24 @@ export const DatasetSelectModal = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { allDatasets } = useDatasetStore();
|
const [selectedDatasets, setSelectedDatasets] =
|
||||||
const [selectedDatasets, setSelectedDatasets] = useState<SelectedDatasetType>(
|
useState<SelectedDatasetType>(defaultSelectedDatasets);
|
||||||
defaultSelectedDatasets.filter((dataset) => {
|
|
||||||
return allDatasets.find((item) => item._id === dataset.datasetId);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { paths, setParentId, datasets, isFetching } = useDatasetSelect();
|
const { paths, setParentId, datasets, isFetching } = useDatasetSelect();
|
||||||
const { Loading } = useLoading();
|
const { Loading } = useLoading();
|
||||||
|
|
||||||
const filterDatasets = useMemo(() => {
|
const filterDatasets = useMemo(() => {
|
||||||
return {
|
const filtered = {
|
||||||
selected: allDatasets.filter((item) =>
|
selected: datasets.filter((item) =>
|
||||||
selectedDatasets.find((dataset) => dataset.datasetId === item._id)
|
selectedDatasets.find((dataset) => dataset.datasetId === item._id)
|
||||||
),
|
),
|
||||||
unSelected: datasets.filter(
|
unSelected: datasets.filter(
|
||||||
(item) => !selectedDatasets.find((dataset) => dataset.datasetId === item._id)
|
(item) => !selectedDatasets.find((dataset) => dataset.datasetId === item._id)
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}, [datasets, allDatasets, selectedDatasets]);
|
return filtered;
|
||||||
const activeVectorModel = allDatasets.find(
|
}, [datasets, selectedDatasets]);
|
||||||
(dataset) => dataset._id === selectedDatasets[0]?.datasetId
|
const activeVectorModel = defaultSelectedDatasets[0]?.vectorModel?.model;
|
||||||
)?.vectorModel?.model;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DatasetSelectContainer
|
<DatasetSelectContainer
|
||||||
@ -150,7 +144,15 @@ export const DatasetSelectModal = ({
|
|||||||
title: t('common:dataset.Select Dataset Tips')
|
title: t('common:dataset.Select Dataset Tips')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setSelectedDatasets((state) => [...state, { datasetId: item._id }]);
|
setSelectedDatasets((state) => [
|
||||||
|
...state,
|
||||||
|
{
|
||||||
|
datasetId: item._id,
|
||||||
|
avatar: item.avatar,
|
||||||
|
name: item.name,
|
||||||
|
vectorModel: item.vectorModel
|
||||||
|
}
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -200,7 +202,7 @@ export const DatasetSelectModal = ({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
// filter out the dataset that is not in the kList
|
// filter out the dataset that is not in the kList
|
||||||
const filterDatasets = selectedDatasets.filter((dataset) => {
|
const filterDatasets = selectedDatasets.filter((dataset) => {
|
||||||
return allDatasets.find((item) => item._id === dataset.datasetId);
|
return datasets.find((item) => item._id === dataset.datasetId);
|
||||||
});
|
});
|
||||||
|
|
||||||
onClose();
|
onClose();
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { useI18n } from '@/web/context/I18n';
|
|||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import { AppContext } from '../context';
|
import { AppContext } from '../context';
|
||||||
import { useChatTest } from '../useChatTest';
|
import { useChatTest } from '../useChatTest';
|
||||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
|
||||||
import ChatItemContextProvider from '@/web/core/chat/context/chatItemContext';
|
import ChatItemContextProvider from '@/web/core/chat/context/chatItemContext';
|
||||||
import ChatRecordContextProvider from '@/web/core/chat/context/chatRecordContext';
|
import ChatRecordContextProvider from '@/web/core/chat/context/chatRecordContext';
|
||||||
import { useChatStore } from '@/web/core/chat/context/useChatStore';
|
import { useChatStore } from '@/web/core/chat/context/useChatStore';
|
||||||
@ -23,8 +22,6 @@ const ChatTest = ({ appForm }: Props) => {
|
|||||||
const { appT } = useI18n();
|
const { appT } = useI18n();
|
||||||
|
|
||||||
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
||||||
// form2AppWorkflow dependent allDatasets
|
|
||||||
const { allDatasets } = useDatasetStore();
|
|
||||||
|
|
||||||
const [workflowData, setWorkflowData] = useSafeState({
|
const [workflowData, setWorkflowData] = useSafeState({
|
||||||
nodes: appDetail.modules || [],
|
nodes: appDetail.modules || [],
|
||||||
@ -33,10 +30,8 @@ const ChatTest = ({ appForm }: Props) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const { nodes, edges } = form2AppWorkflow(appForm, t);
|
const { nodes, edges } = form2AppWorkflow(appForm, t);
|
||||||
// console.log(form2AppWorkflow(appForm, t));
|
|
||||||
setWorkflowData({ nodes, edges });
|
setWorkflowData({ nodes, edges });
|
||||||
}, [appForm, setWorkflowData, allDatasets, t]);
|
}, [appForm, setWorkflowData, t]);
|
||||||
|
|
||||||
const { ChatContainer, restartChat, loading } = useChatTest({
|
const { ChatContainer, restartChat, loading } = useChatTest({
|
||||||
...workflowData,
|
...workflowData,
|
||||||
chatConfig: appForm.chatConfig,
|
chatConfig: appForm.chatConfig,
|
||||||
|
|||||||
@ -10,9 +10,9 @@ import {
|
|||||||
HStack
|
HStack
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type.d';
|
import type { AppSimpleEditFormType } from '@fastgpt/global/core/app/type.d';
|
||||||
|
import type { DatasetSimpleItemType } from '@fastgpt/global/core/dataset/type.d';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
|
||||||
|
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
|
||||||
@ -68,18 +68,9 @@ const EditForm = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
const { appDetail } = useContextSelector(AppContext, (v) => v);
|
||||||
|
const selectDatasets = useMemo(() => appForm?.dataset?.datasets, [appForm]);
|
||||||
const { allDatasets } = useDatasetStore();
|
|
||||||
const [, startTst] = useTransition();
|
const [, startTst] = useTransition();
|
||||||
|
|
||||||
const selectDatasets = useMemo(
|
|
||||||
() =>
|
|
||||||
allDatasets.filter((item) =>
|
|
||||||
appForm.dataset?.datasets.find((dataset) => dataset.datasetId === item._id)
|
|
||||||
),
|
|
||||||
[allDatasets, appForm?.dataset?.datasets]
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isOpen: isOpenDatasetSelect,
|
isOpen: isOpenDatasetSelect,
|
||||||
onOpen: onOpenKbSelect,
|
onOpen: onOpenKbSelect,
|
||||||
@ -252,7 +243,7 @@ const EditForm = ({
|
|||||||
)}
|
)}
|
||||||
<Grid gridTemplateColumns={'repeat(2, minmax(0, 1fr))'} gridGap={[2, 4]}>
|
<Grid gridTemplateColumns={'repeat(2, minmax(0, 1fr))'} gridGap={[2, 4]}>
|
||||||
{selectDatasets.map((item) => (
|
{selectDatasets.map((item) => (
|
||||||
<MyTooltip key={item._id} label={t('common:core.dataset.Read Dataset')}>
|
<MyTooltip key={item.datasetId} label={t('common:core.dataset.Read Dataset')}>
|
||||||
<Flex
|
<Flex
|
||||||
overflow={'hidden'}
|
overflow={'hidden'}
|
||||||
alignItems={'center'}
|
alignItems={'center'}
|
||||||
@ -266,7 +257,7 @@ const EditForm = ({
|
|||||||
router.push({
|
router.push({
|
||||||
pathname: '/dataset/detail',
|
pathname: '/dataset/detail',
|
||||||
query: {
|
query: {
|
||||||
datasetId: item._id
|
datasetId: item.datasetId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -413,8 +404,10 @@ const EditForm = ({
|
|||||||
<DatasetSelectModal
|
<DatasetSelectModal
|
||||||
isOpen={isOpenDatasetSelect}
|
isOpen={isOpenDatasetSelect}
|
||||||
defaultSelectedDatasets={selectDatasets.map((item) => ({
|
defaultSelectedDatasets={selectDatasets.map((item) => ({
|
||||||
datasetId: item._id,
|
datasetId: item.datasetId,
|
||||||
vectorModel: item.vectorModel
|
vectorModel: item.vectorModel,
|
||||||
|
name: item.name,
|
||||||
|
avatar: item.avatar
|
||||||
}))}
|
}))}
|
||||||
onClose={onCloseKbSelect}
|
onClose={onCloseKbSelect}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import { publishStatusStyle } from '../constants';
|
|||||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||||
import { formatTime2YMDHMS } from '@fastgpt/global/common/string/time';
|
import { formatTime2YMDHMS } from '@fastgpt/global/common/string/time';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
|
||||||
import SaveButton from '../Workflow/components/SaveButton';
|
import SaveButton from '../Workflow/components/SaveButton';
|
||||||
import { useBoolean, useDebounceEffect, useLockFn } from 'ahooks';
|
import { useBoolean, useDebounceEffect, useLockFn } from 'ahooks';
|
||||||
import { appWorkflow2Form } from '@fastgpt/global/core/app/utils';
|
import { appWorkflow2Form } from '@fastgpt/global/core/app/utils';
|
||||||
@ -61,7 +60,6 @@ const Header = ({
|
|||||||
const currentTab = useContextSelector(AppContext, (v) => v.currentTab);
|
const currentTab = useContextSelector(AppContext, (v) => v.currentTab);
|
||||||
|
|
||||||
const { lastAppListRouteType } = useSystemStore();
|
const { lastAppListRouteType } = useSystemStore();
|
||||||
const { allDatasets } = useDatasetStore();
|
|
||||||
|
|
||||||
const { data: paths = [] } = useRequest2(() => getAppFolderPath(appId), {
|
const { data: paths = [] } = useRequest2(() => getAppFolderPath(appId), {
|
||||||
manual: false,
|
manual: false,
|
||||||
@ -159,7 +157,7 @@ const Header = ({
|
|||||||
const val = compareSimpleAppSnapshot(savedSnapshot?.appForm, appForm);
|
const val = compareSimpleAppSnapshot(savedSnapshot?.appForm, appForm);
|
||||||
setIsSaved(val);
|
setIsSaved(val);
|
||||||
},
|
},
|
||||||
[past, allDatasets],
|
[past],
|
||||||
{ wait: 500 }
|
{ wait: 500 }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { Box, Flex } from '@chakra-ui/react';
|
|||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { SimpleAppSnapshotType, useSimpleAppSnapshots } from './useSnapshots';
|
import { SimpleAppSnapshotType, useSimpleAppSnapshots } from './useSnapshots';
|
||||||
import { useDebounceEffect, useMount } from 'ahooks';
|
import { useDebounceEffect, useMount } from 'ahooks';
|
||||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
|
||||||
import { v1Workflow2V2 } from '@/web/core/workflow/adapt';
|
import { v1Workflow2V2 } from '@/web/core/workflow/adapt';
|
||||||
import { getAppConfigByDiff } from '@/web/core/app/diff';
|
import { getAppConfigByDiff } from '@/web/core/app/diff';
|
||||||
|
|
||||||
@ -19,7 +18,6 @@ const PublishChannel = dynamic(() => import('../Publish'));
|
|||||||
|
|
||||||
const SimpleEdit = () => {
|
const SimpleEdit = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { loadAllDatasets } = useDatasetStore();
|
|
||||||
|
|
||||||
const { currentTab, appDetail } = useContextSelector(AppContext, (v) => v);
|
const { currentTab, appDetail } = useContextSelector(AppContext, (v) => v);
|
||||||
const { forbiddenSaveSnapshot, past, setPast, saveSnapshot } = useSimpleAppSnapshots(
|
const { forbiddenSaveSnapshot, past, setPast, saveSnapshot } = useSimpleAppSnapshots(
|
||||||
@ -31,7 +29,6 @@ const SimpleEdit = () => {
|
|||||||
// Init app form
|
// Init app form
|
||||||
useMount(() => {
|
useMount(() => {
|
||||||
// show selected dataset
|
// show selected dataset
|
||||||
loadAllDatasets();
|
|
||||||
|
|
||||||
if (appDetail.version !== 'v2') {
|
if (appDetail.version !== 'v2') {
|
||||||
return setAppForm(
|
return setAppForm(
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import type { RenderInputProps } from '../type';
|
import type { RenderInputProps } from '../type';
|
||||||
import { Box, Button, Flex, Grid, Switch, useDisclosure, useTheme } from '@chakra-ui/react';
|
import { Box, Button, Flex, Grid, Switch, useDisclosure, useTheme } from '@chakra-ui/react';
|
||||||
import { useDatasetStore } from '@/web/core/dataset/store/dataset';
|
|
||||||
import { SelectedDatasetType } from '@fastgpt/global/core/workflow/api';
|
import { SelectedDatasetType } from '@fastgpt/global/core/workflow/api';
|
||||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { DatasetSearchModeEnum } from '@fastgpt/global/core/dataset/constants';
|
import { DatasetSearchModeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||||
|
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
@ -32,26 +29,17 @@ export const SelectDatasetRender = React.memo(function SelectDatasetRender({
|
|||||||
usingReRank: false
|
usingReRank: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const { allDatasets, loadAllDatasets } = useDatasetStore();
|
|
||||||
const {
|
const {
|
||||||
isOpen: isOpenDatasetSelect,
|
isOpen: isOpenDatasetSelect,
|
||||||
onOpen: onOpenDatasetSelect,
|
onOpen: onOpenDatasetSelect,
|
||||||
onClose: onCloseDatasetSelect
|
onClose: onCloseDatasetSelect
|
||||||
} = useDisclosure();
|
} = useDisclosure();
|
||||||
|
|
||||||
const selectedDatasetsValue = useMemo(() => {
|
const selectedDatasets = useMemo(() => {
|
||||||
if (Array.isArray(item.value)) return item.value as SelectedDatasetType;
|
if (Array.isArray(item.value)) return item.value as SelectedDatasetType;
|
||||||
return [] as SelectedDatasetType;
|
return [] as SelectedDatasetType;
|
||||||
}, [item.value]);
|
}, [item.value]);
|
||||||
|
|
||||||
const selectedDatasets = useMemo(() => {
|
|
||||||
return allDatasets.filter((dataset) =>
|
|
||||||
selectedDatasetsValue?.find((item) => item.datasetId === dataset._id)
|
|
||||||
);
|
|
||||||
}, [allDatasets, selectedDatasetsValue]);
|
|
||||||
|
|
||||||
useQuery(['loadAllDatasets'], loadAllDatasets);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
inputs.forEach((input) => {
|
inputs.forEach((input) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -82,7 +70,7 @@ export const SelectDatasetRender = React.memo(function SelectDatasetRender({
|
|||||||
</Button>
|
</Button>
|
||||||
{selectedDatasets.map((item) => (
|
{selectedDatasets.map((item) => (
|
||||||
<Flex
|
<Flex
|
||||||
key={item._id}
|
key={item.datasetId}
|
||||||
alignItems={'center'}
|
alignItems={'center'}
|
||||||
h={10}
|
h={10}
|
||||||
boxShadow={'sm'}
|
boxShadow={'sm'}
|
||||||
@ -108,7 +96,12 @@ export const SelectDatasetRender = React.memo(function SelectDatasetRender({
|
|||||||
{isOpenDatasetSelect && (
|
{isOpenDatasetSelect && (
|
||||||
<DatasetSelectModal
|
<DatasetSelectModal
|
||||||
isOpen={isOpenDatasetSelect}
|
isOpen={isOpenDatasetSelect}
|
||||||
defaultSelectedDatasets={selectedDatasetsValue}
|
defaultSelectedDatasets={selectedDatasets.map((item) => ({
|
||||||
|
datasetId: item.datasetId,
|
||||||
|
vectorModel: item.vectorModel,
|
||||||
|
name: item.name,
|
||||||
|
avatar: item.avatar
|
||||||
|
}))}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
onChangeNode({
|
onChangeNode({
|
||||||
nodeId,
|
nodeId,
|
||||||
@ -133,7 +126,6 @@ export const SelectDatasetRender = React.memo(function SelectDatasetRender({
|
|||||||
onCloseDatasetSelect,
|
onCloseDatasetSelect,
|
||||||
onOpenDatasetSelect,
|
onOpenDatasetSelect,
|
||||||
selectedDatasets,
|
selectedDatasets,
|
||||||
selectedDatasetsValue,
|
|
||||||
t
|
t
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { NextAPI } from '@/service/middleware/entry';
|
|||||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||||
import { checkNode } from '@/service/core/app/utils';
|
import { checkNode } from '@/service/core/app/utils';
|
||||||
|
import { rewriteAppWorkflowToDetail } from '@fastgpt/service/core/app/utils';
|
||||||
/* 获取应用详情 */
|
/* 获取应用详情 */
|
||||||
async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||||
const { appId } = req.query as { appId: string };
|
const { appId } = req.query as { appId: string };
|
||||||
@ -14,6 +14,9 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||||||
}
|
}
|
||||||
// 凭证校验
|
// 凭证校验
|
||||||
const { app } = await authApp({ req, authToken: true, appId, per: ReadPermissionVal });
|
const { app } = await authApp({ req, authToken: true, appId, per: ReadPermissionVal });
|
||||||
|
const teamId = app.teamId;
|
||||||
|
|
||||||
|
await rewriteAppWorkflowToDetail(app.modules, teamId);
|
||||||
|
|
||||||
if (!app.permission.hasWritePer) {
|
if (!app.permission.hasWritePer) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controlle
|
|||||||
import { AppChatConfigType } from '@fastgpt/global/core/app/type';
|
import { AppChatConfigType } from '@fastgpt/global/core/app/type';
|
||||||
import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
|
import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
|
||||||
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
|
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
|
||||||
|
import { rewriteAppWorkflowToDetail } from '@fastgpt/service/core/app/utils';
|
||||||
|
|
||||||
export type getLatestVersionQuery = {
|
export type getLatestVersionQuery = {
|
||||||
appId: string;
|
appId: string;
|
||||||
@ -30,6 +31,10 @@ async function handler(
|
|||||||
per: WritePermissionVal
|
per: WritePermissionVal
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const teamId = app.teamId;
|
||||||
|
|
||||||
|
await rewriteAppWorkflowToDetail(app.modules, teamId);
|
||||||
|
|
||||||
return getAppLatestVersion(req.query.appId, app);
|
return getAppLatestVersion(req.query.appId, app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import { PostPublishAppProps } from '@/global/core/app/api';
|
|||||||
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
import { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||||
|
import { rewriteAppWorkflowToSimple } from '@fastgpt/service/core/app/utils';
|
||||||
|
|
||||||
async function handler(req: ApiRequestProps<PostPublishAppProps>, res: NextApiResponse<any>) {
|
async function handler(req: ApiRequestProps<PostPublishAppProps>, res: NextApiResponse<any>) {
|
||||||
const { appId } = req.query as { appId: string };
|
const { appId } = req.query as { appId: string };
|
||||||
@ -22,6 +23,8 @@ async function handler(req: ApiRequestProps<PostPublishAppProps>, res: NextApiRe
|
|||||||
isPlugin: app.type === AppTypeEnum.plugin
|
isPlugin: app.type === AppTypeEnum.plugin
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await rewriteAppWorkflowToSimple(formatNodes);
|
||||||
|
|
||||||
if (autoSave) {
|
if (autoSave) {
|
||||||
return MongoApp.findByIdAndUpdate(appId, {
|
return MongoApp.findByIdAndUpdate(appId, {
|
||||||
modules: formatNodes,
|
modules: formatNodes,
|
||||||
|
|||||||
@ -1,38 +0,0 @@
|
|||||||
import type { NextApiRequest } from 'next';
|
|
||||||
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
|
|
||||||
import { getEmbeddingModel } from '@fastgpt/service/core/ai/model';
|
|
||||||
import type { DatasetSimpleItemType } from '@fastgpt/global/core/dataset/type.d';
|
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
|
||||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
|
||||||
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
|
||||||
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
|
||||||
|
|
||||||
/* get all dataset by teamId or tmbId */
|
|
||||||
async function handler(req: NextApiRequest): Promise<DatasetSimpleItemType[]> {
|
|
||||||
const { teamId } = await authUserPer({
|
|
||||||
req,
|
|
||||||
authToken: true,
|
|
||||||
authApiKey: true,
|
|
||||||
per: ReadPermissionVal
|
|
||||||
});
|
|
||||||
|
|
||||||
const myDatasets = await MongoDataset.find({
|
|
||||||
teamId,
|
|
||||||
type: {
|
|
||||||
$ne: DatasetTypeEnum.folder
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.sort({
|
|
||||||
updateTime: -1
|
|
||||||
})
|
|
||||||
.lean();
|
|
||||||
|
|
||||||
return myDatasets.map((item) => ({
|
|
||||||
_id: item._id,
|
|
||||||
avatar: item.avatar,
|
|
||||||
name: item.name,
|
|
||||||
vectorModel: getEmbeddingModel(item.vectorModel)
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
export default NextAPI(handler);
|
|
||||||
@ -21,7 +21,6 @@ import { getNanoid } from '@fastgpt/global/common/string/tools';
|
|||||||
import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
|
import { StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
|
||||||
import { EditorVariablePickerType } from '@fastgpt/web/components/common/Textarea/PromptEditor/type';
|
import { EditorVariablePickerType } from '@fastgpt/web/components/common/Textarea/PromptEditor/type';
|
||||||
import { ToolModule } from '@fastgpt/global/core/workflow/template/system/tools';
|
import { ToolModule } from '@fastgpt/global/core/workflow/template/system/tools';
|
||||||
import { useDatasetStore } from '../dataset/store/dataset';
|
|
||||||
import {
|
import {
|
||||||
WorkflowStart,
|
WorkflowStart,
|
||||||
userFilesInput
|
userFilesInput
|
||||||
@ -54,12 +53,7 @@ export function form2AppWorkflow(
|
|||||||
} {
|
} {
|
||||||
const datasetNodeId = 'iKBoX2vIzETU';
|
const datasetNodeId = 'iKBoX2vIzETU';
|
||||||
const aiChatNodeId = '7BdojPlukIQw';
|
const aiChatNodeId = '7BdojPlukIQw';
|
||||||
|
const selectedDatasets = data.dataset.datasets;
|
||||||
const allDatasets = useDatasetStore.getState().allDatasets;
|
|
||||||
const selectedDatasets = data.dataset.datasets.filter((item) =>
|
|
||||||
allDatasets.some((ds) => ds._id === item.datasetId)
|
|
||||||
);
|
|
||||||
|
|
||||||
function systemConfigTemplate(): StoreNodeItemType {
|
function systemConfigTemplate(): StoreNodeItemType {
|
||||||
return {
|
return {
|
||||||
nodeId: SystemConfigNode.id,
|
nodeId: SystemConfigNode.id,
|
||||||
|
|||||||
@ -70,10 +70,11 @@ import { GetQuoteDataResponse } from '@/pages/api/core/dataset/data/getQuoteData
|
|||||||
export const getDatasets = (data: GetDatasetListBody) =>
|
export const getDatasets = (data: GetDatasetListBody) =>
|
||||||
POST<DatasetListItemType[]>(`/core/dataset/list`, data);
|
POST<DatasetListItemType[]>(`/core/dataset/list`, data);
|
||||||
|
|
||||||
|
export const getDatasetsByAppIdAndDatasetIds = (data: { appId: string; datasetIdList: string[] }) =>
|
||||||
|
POST<DatasetSimpleItemType[]>(`/core/dataset/listByAppIdAndDatasetIds`, data);
|
||||||
/**
|
/**
|
||||||
* get type=dataset list
|
* get type=dataset list
|
||||||
*/
|
*/
|
||||||
export const getAllDataset = () => GET<DatasetSimpleItemType[]>(`/core/dataset/allDataset`);
|
|
||||||
|
|
||||||
export const getDatasetPaths = (parentId: ParentIdType) =>
|
export const getDatasetPaths = (parentId: ParentIdType) =>
|
||||||
GET<ParentTreePathItemType[]>('/core/dataset/paths', { parentId });
|
GET<ParentTreePathItemType[]>('/core/dataset/paths', { parentId });
|
||||||
|
|||||||
@ -1,15 +1,10 @@
|
|||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
import { devtools, persist } from 'zustand/middleware';
|
import { devtools, persist } from 'zustand/middleware';
|
||||||
import { immer } from 'zustand/middleware/immer';
|
import { immer } from 'zustand/middleware/immer';
|
||||||
import type {
|
import type { DatasetListItemType } from '@fastgpt/global/core/dataset/type.d';
|
||||||
DatasetListItemType,
|
import { getDatasets } from '@/web/core/dataset/api';
|
||||||
DatasetSimpleItemType
|
|
||||||
} from '@fastgpt/global/core/dataset/type.d';
|
|
||||||
import { getAllDataset, getDatasets } from '@/web/core/dataset/api';
|
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
allDatasets: DatasetSimpleItemType[];
|
|
||||||
loadAllDatasets: () => Promise<DatasetSimpleItemType[]>;
|
|
||||||
myDatasets: DatasetListItemType[];
|
myDatasets: DatasetListItemType[];
|
||||||
loadMyDatasets: (parentId?: string) => Promise<DatasetListItemType[]>;
|
loadMyDatasets: (parentId?: string) => Promise<DatasetListItemType[]>;
|
||||||
};
|
};
|
||||||
@ -18,14 +13,6 @@ export const useDatasetStore = create<State>()(
|
|||||||
devtools(
|
devtools(
|
||||||
persist(
|
persist(
|
||||||
immer((set, get) => ({
|
immer((set, get) => ({
|
||||||
allDatasets: [],
|
|
||||||
async loadAllDatasets() {
|
|
||||||
const res = await getAllDataset();
|
|
||||||
set((state) => {
|
|
||||||
state.allDatasets = res;
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
myDatasets: [],
|
myDatasets: [],
|
||||||
async loadMyDatasets(parentId = '') {
|
async loadMyDatasets(parentId = '') {
|
||||||
const res = await getDatasets({ parentId });
|
const res = await getDatasets({ parentId });
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user