Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.8.10 test #2568

Merged
merged 6 commits into from
Aug 29, 2024
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
27 changes: 15 additions & 12 deletions docSite/content/zh-cn/docs/development/upgrading/4810.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,18 @@ curl --location --request POST 'https://{{host}}/api/admin/initv4810' \
16. 优化 - 节点选择,避免切换 tab 时候,path 加载报错。
17. 优化 - 最新 React Markdown 组件,支持 Base64 图片。
18. 优化 - 知识库列表 UI。
19. 优化 - 支持无网络配置情况下运行。
20. 优化 - 部分全局变量,增加数据类型约束。
21. 修复 - 全局变量 key 可能重复。
22. 修复 - Prompt 模式调用工具,stream=false 模式下,会携带 0: 开头标记。
23. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
24. 修复 - 选择 Milvus 部署时,无法导出知识库。
25. 修复 - 创建 APP 副本,无法复制系统配置。
26. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
27. 修复 - 内容提取的数据类型与输出数据类型未一致。
28. 修复 - 工作流运行时间统计错误。
29. 修复 - stream 模式下,工具调用有可能出现 undefined
30. 修复 - 全局变量在 API 中无法持久化。
19. 优化 - 知识库详情页 UI。
20. 优化 - 支持无网络配置情况下运行。
21. 优化 - 部分全局变量,增加数据类型约束。
22. 修复 - 全局变量 key 可能重复。
23. 修复 - Prompt 模式调用工具,stream=false 模式下,会携带 0: 开头标记。
24. 修复 - 对话日志鉴权问题:仅为 APP 管理员的用户,无法查看对话日志详情。
25. 修复 - 选择 Milvus 部署时,无法导出知识库。
26. 修复 - 创建 APP 副本,无法复制系统配置。
27. 修复 - 图片识别模式下,自动解析图片链接正则不够严谨问题。
28. 修复 - 内容提取的数据类型与输出数据类型未一致。
29. 修复 - 工作流运行时间统计错误。
30. 修复 - stream 模式下,工具调用有可能出现 undefined
31. 修复 - 全局变量在 API 中无法持久化。
32. 修复 - OpenAPI,detail=false模式下,不应该返回 tool 调用结果,仅返回文字。(可解决 cow 不适配问题)
33. 修复 - 知识库标签重复加载。
5 changes: 3 additions & 2 deletions packages/global/core/workflow/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,15 +333,16 @@ export const removePluginInputVariables = (
);
};

export function replaceVariableLabel({
// replace {{$xx.xx$}} variables for text
export function replaceEditorVariable({
text,
nodes,
variables,
runningNode
}: {
text: any;
nodes: RuntimeNodeItemType[];
variables: Record<string, string | number>;
variables: Record<string, any>; // global variables
runningNode: RuntimeNodeItemType;
}) {
if (typeof text !== 'string') return text;
Expand Down
4 changes: 3 additions & 1 deletion packages/service/common/file/read/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const readRawContentByFileBuffer = async ({
)
return;

addLog.info('Use custom read file service');
const start = Date.now();

const data = new FormData();
data.append('file', buffer, {
Expand All @@ -101,6 +101,8 @@ export const readRawContentByFileBuffer = async ({
}
});

addLog.info(`Use custom read file service, time: ${Date.now() - start}ms`);

const rawText = response.data.markdown;

return {
Expand Down
4 changes: 2 additions & 2 deletions packages/service/core/workflow/dispatch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from '@fastgpt/global/core/workflow/node/constant';
import { replaceVariable } from '@fastgpt/global/common/string/tools';
import { getSystemTime } from '@fastgpt/global/common/time/timezone';
import { replaceVariableLabel } from '@fastgpt/global/core/workflow/utils';
import { replaceEditorVariable } from '@fastgpt/global/core/workflow/utils';

import { dispatchWorkflowStart } from './init/workflowStart';
import { dispatchChatCompletion } from './chat/oneapi';
Expand Down Expand Up @@ -368,7 +368,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
let value = replaceVariable(input.value, variables);

// replace {{$xx.xx$}} variables
value = replaceVariableLabel({
value = replaceEditorVariable({
text: value,
nodes: runtimeNodes,
variables,
Expand Down
40 changes: 25 additions & 15 deletions packages/service/core/workflow/dispatch/tools/readFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,25 +73,35 @@ export const dispatchReadFiles = async (props: Props): Promise<Response> => {
// Concat fileUrlList and filesFromHistories; remove not supported files
const parseUrlList = [...fileUrlList, ...filesFromHistories]
.map((url) => {
// System file
if (url.startsWith('/') || (requestOrigin && url.startsWith(requestOrigin))) {
// Parse url, get filename query. Keep only documents that can be parsed
const parseUrl = new URL(url);
const filenameQuery = parseUrl.searchParams.get('filename');
if (filenameQuery) {
const extensionQuery = filenameQuery.split('.').pop()?.toLowerCase() || '';
if (!documentFileType.includes(extensionQuery)) {
return '';
try {
// Avoid "/api/xxx" file error.
const origin = requestOrigin ?? 'http://localhost:3000';

// Check is system upload file
if (url.startsWith('/') || (requestOrigin && url.startsWith(requestOrigin))) {
// Parse url, get filename query. Keep only documents that can be parsed
const parseUrl = new URL(url, origin);
const filenameQuery = parseUrl.searchParams.get('filename');

// Not document
if (filenameQuery) {
const extensionQuery = filenameQuery.split('.').pop()?.toLowerCase() || '';
if (!documentFileType.includes(extensionQuery)) {
return '';
}
}
}

// Remove the origin(Make intranet requests directly)
if (requestOrigin && url.startsWith(requestOrigin)) {
url = url.replace(requestOrigin, '');
// Remove the origin(Make intranet requests directly)
if (requestOrigin && url.startsWith(requestOrigin)) {
url = url.replace(requestOrigin, '');
}
}
}

return url;
return url;
} catch (error) {
console.log(error);
return '';
}
})
.filter(Boolean)
.slice(0, maxFiles);
Expand Down
4 changes: 2 additions & 2 deletions packages/service/core/workflow/dispatch/tools/runUpdateVar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getReferenceVariableValue } from '@fastgpt/global/core/workflow/runtime
import { TUpdateListItem } from '@fastgpt/global/core/workflow/template/system/variableUpdate/type';
import { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
import { removeSystemVariable, valueTypeFormat } from '../utils';
import { replaceVariableLabel } from '@fastgpt/global/core/workflow/utils';
import { replaceEditorVariable } from '@fastgpt/global/core/workflow/utils';

type Props = ModuleDispatchProps<{
[NodeInputKeyEnum.updateList]: TUpdateListItem[];
Expand All @@ -32,7 +32,7 @@ export const dispatchUpdateVariable = async (props: Props): Promise<Response> =>
const formatValue = valueTypeFormat(item.value?.[1], item.valueType);

return typeof formatValue === 'string'
? replaceVariableLabel({
? replaceEditorVariable({
text: formatValue,
nodes: runtimeNodes,
variables,
Expand Down
4 changes: 4 additions & 0 deletions packages/web/i18n/en/user.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
"you_can_convert": "You can redeem",
"yuan": "Yuan"
},
"promotion": {
"register": "Register",
"pay": "Pay"
},
"bind_inform_account_error": "Abnormal binding notification account",
"bind_inform_account_success": "Binding notification account successful",
"code_error": {
Expand Down
4 changes: 4 additions & 0 deletions packages/web/i18n/zh/user.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
"current_token_price": "当前积分价格",
"yuan": "元"
},
"promotion": {
"register": "好友注册",
"pay": "好友充值"
},
"bind_inform_account_error": "绑定通知账号异常",
"bind_inform_account_success": "绑定通知账号成功",
"delete": {
Expand Down
4 changes: 1 addition & 3 deletions projects/app/src/pages/account/components/Promotion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ import { useQuery } from '@tanstack/react-query';
import { getPromotionInitData, getPromotionRecords } from '@/web/support/activity/promotion/api';
import { useUserStore } from '@/web/support/user/useUserStore';

import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useCopyData } from '@/web/common/hooks/useCopyData';
import type { PromotionRecordType } from '@/global/support/api/userRes.d';
import MyIcon from '@fastgpt/web/components/common/Icon';
import dayjs from 'dayjs';
import { usePagination } from '@fastgpt/web/hooks/usePagination';
import { useLoading } from '@fastgpt/web/hooks/useLoading';
Expand Down Expand Up @@ -116,7 +114,7 @@ const Promotion = () => {
<Td>
{item.createTime ? dayjs(item.createTime).format('YYYY/MM/DD HH:mm:ss') : '-'}
</Td>
<Td>{t(`user.promotion.${item.type}` as any)}</Td>
<Td>{t(`user:promotion.${item.type}` as any)}</Td>
<Td>{item.amount}</Td>
</Tr>
))}
Expand Down
4 changes: 1 addition & 3 deletions projects/app/src/pages/api/admin/initv4810.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { connectToDatabase } from '@/service/mongo';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { MongoDataset } from '@fastgpt/service/core/dataset/schema';
import { DatasetDefaultPermissionVal } from '@fastgpt/global/support/permission/dataset/constant';
import { MongoAppVersion } from '@fastgpt/service/core/app/version/schema';
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
import { POST } from '@fastgpt/service/common/api/plusRequest';

/* pg 中的数据搬到 mongo dataset.datas 中,并做映射 */
/* 初始化发布的版本 */
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
await connectToDatabase();
Expand Down
6 changes: 5 additions & 1 deletion projects/app/src/pages/api/common/file/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
});
const { file, bucketName, metadata } = await upload.doUpload(req, res);
filePaths.push(file.path);
const { teamId, tmbId, outLinkUid } = await authChatCert({ req, authToken: true });
const { teamId, tmbId, outLinkUid } = await authChatCert({
req,
authToken: true,
authApiKey: true
});

await authUploadLimit(outLinkUid || tmbId);

Expand Down
8 changes: 8 additions & 0 deletions projects/app/src/pages/api/v1/chat/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,14 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
if (assistantResponses.length === 0) return '';
if (assistantResponses.length === 1 && assistantResponses[0].text?.content)
return assistantResponses[0].text?.content;

if (!detail) {
return assistantResponses
.map((item) => item?.text?.content)
.filter(Boolean)
.join('\n');
}

return assistantResponses;
})();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ const Header = ({}: {}) => {
return (
<Box display={['block', 'flex']} alignItems={'center'} gap={2}>
<HStack flex={1}>
<Box flex={1} fontWeight={'500'} color={'myGray.900'}>
<Box flex={1} fontWeight={'500'} color={'myGray.900'} whiteSpace={'nowrap'}>
<ParentPath
paths={paths.map((path, i) => ({
parentId: path.parentId,
Expand Down Expand Up @@ -173,7 +173,8 @@ const Header = ({}: {}) => {
{/* search input */}
{isPc && (
<MyInput
w={['100%', '250px']}
maxW={'250px'}
flex={1}
size={'sm'}
h={'36px'}
placeholder={t('common:common.Search') || ''}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,28 @@ import { Box, Button, Checkbox, Flex, Input, useDisclosure } from '@chakra-ui/re
import MyPopover from '@fastgpt/web/components/common/MyPopover';
import MyIcon from '@fastgpt/web/components/common/Icon';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { postCreateDatasetCollectionTag } from '@/web/core/dataset/api';
import { useContextSelector } from 'use-context-selector';
import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext';
import { useTranslation } from 'next-i18next';
import { useCallback, useEffect, useState } from 'react';
import { useRequest } from '@fastgpt/web/hooks/useRequest';
import { useCallback, useState } from 'react';
import { CollectionPageContext } from './Context';
import { debounce, isEqual } from 'lodash';
import TagManageModal from './TagManageModal';
import { DatasetTagType } from '@fastgpt/global/core/dataset/type';

const HeaderTagPopOver = () => {
const { t } = useTranslation();
const [searchTag, setSearchTag] = useState('');
const [checkedTags, setCheckedTags] = useState<string[]>([]);

const { datasetDetail, datasetTags, loadDatasetTags, checkedDatasetTag, setCheckedDatasetTag } =
useContextSelector(DatasetPageContext, (v) => v);

const { mutate: onCreateCollectionTag, isLoading: isCreateCollectionTagLoading } = useRequest({
mutationFn: async (tag: string) => {
const id = await postCreateDatasetCollectionTag({
datasetId: datasetDetail._id,
tag
});
return id;
},

onSuccess() {
setSearchTag('');
},
successToast: t('common:common.Create Success'),
errorToast: t('common:common.Create Failed')
});
const {
searchDatasetTagsResult,
searchTagKey,
setSearchTagKey,
checkedDatasetTag,
setCheckedDatasetTag,
onCreateCollectionTag,
isCreateCollectionTagLoading
} = useContextSelector(DatasetPageContext, (v) => v);

const { filterTags, setFilterTags, getData } = useContextSelector(
CollectionPageContext,
Expand All @@ -48,10 +36,6 @@ const HeaderTagPopOver = () => {
[]
);

useEffect(() => {
loadDatasetTags({ id: datasetDetail._id, searchKey: searchTag });
}, [searchTag]);

const {
isOpen: isTagManageModalOpen,
onOpen: onOpenTagManageModal,
Expand Down Expand Up @@ -122,35 +106,34 @@ const HeaderTagPopOver = () => {
pl={2}
h={8}
borderRadius={'xs'}
value={searchTag}
value={searchTagKey}
placeholder={t('dataset:tag.searchOrAddTag')}
onChange={(e) => setSearchTag(e.target.value)}
onChange={(e) => setSearchTagKey(e.target.value)}
/>
</Box>

<Box my={1} px={1.5} maxH={'240px'} overflow={'auto'}>
{searchTag && !datasetTags.map((item) => item.tag).includes(searchTag) && (
<Flex
alignItems={'center'}
fontSize={'sm'}
px={1}
cursor={'pointer'}
_hover={{ bg: '#1118240D', color: 'primary.700' }}
borderRadius={'xs'}
onClick={() => {
onCreateCollectionTag(searchTag);
}}
>
<MyIcon name={'common/addLight'} w={'16px'} />
<Box ml={2} py={2}>
{t('dataset:tag.add') + ` "${searchTag}"`}
</Box>
</Flex>
)}
{searchTagKey &&
!searchDatasetTagsResult.map((item) => item.tag).includes(searchTagKey) && (
<Flex
alignItems={'center'}
fontSize={'sm'}
px={1}
cursor={'pointer'}
_hover={{ bg: '#1118240D', color: 'primary.700' }}
borderRadius={'xs'}
onClick={() => onCreateCollectionTag(searchTagKey)}
>
<MyIcon name={'common/addLight'} w={'16px'} />
<Box ml={2} py={2}>
{t('dataset:tag.add') + ` "${searchTagKey}"`}
</Box>
</Flex>
)}

{[
...new Map(
[...checkedDatasetTag, ...datasetTags].map((item) => [item._id, item])
[...checkedDatasetTag, ...searchDatasetTagsResult].map((item) => [item._id, item])
).values()
].map((item) => {
const checked = checkedTags.includes(item._id);
Expand Down Expand Up @@ -197,6 +180,7 @@ const HeaderTagPopOver = () => {
borderBottomLeftRadius={'md'}
variant={'unstyled'}
onClick={() => {
setSearchTagKey('');
setCheckedTags([]);
setFilterTags([]);
debounceRefetch();
Expand Down
Loading
Loading