From 09205e4666c4c00b327516ca2f25894e264e4f03 Mon Sep 17 00:00:00 2001 From: Archer <545436317@qq.com> Date: Tue, 18 Feb 2025 20:50:25 +0800 Subject: [PATCH] fix: price page init data;perf: usage code;fix: reasoning tokens;fix: workflow basic node cannot upgrade (#3816) * fix: img read * fix: price page init data * perf: ai model avatar * perf: refresh in change team * perf: null checker * perf: usage code * fix: reasoning tokens * fix: workflow basic node cannot upgrade * perf: model refresh * perf: icon refresh --- .../zh-cn/docs/development/upgrading/4822.md | 14 ++- packages/global/common/file/constants.ts | 2 +- packages/global/core/ai/type.d.ts | 1 + packages/global/core/chat/adapt.ts | 20 +-- .../service/common/file/image/controller.ts | 11 +- .../service/common/string/tiktoken/index.ts | 2 +- .../core/workflow/dispatch/chat/oneapi.ts | 3 +- .../service/core/workflow/dispatch/index.ts | 9 +- .../support/wallet/usage/controller.ts | 116 +++++++++++++++++- .../service/support/wallet/usage/type.d.ts | 12 ++ .../service/support/wallet/usage/utils.ts | 18 +++ .../worker/countGptMessagesTokens/index.ts | 10 +- packages/web/components/common/Icon/index.tsx | 12 +- projects/app/data/config.json | 2 +- projects/app/data/model.json | 2 +- projects/app/next-i18next.config.js | 4 +- projects/app/src/components/Layout/index.tsx | 40 +++--- .../src/components/Select/AIModelSelector.tsx | 101 +++++++-------- .../pageComponents/account/TeamSelector.tsx | 8 +- .../Flow/nodes/render/NodeCard.tsx | 29 +++-- .../detail/Import/components/FileSelector.tsx | 93 +++++++------- projects/app/src/pages/account/info/index.tsx | 2 +- projects/app/src/pages/account/team/index.tsx | 2 +- .../pages/api/common/system/getInitData.ts | 10 ++ .../app/src/pages/api/core/chat/chatTest.ts | 4 +- .../app/src/pages/api/core/workflow/debug.ts | 6 +- .../app/src/pages/api/v1/chat/completions.ts | 4 +- projects/app/src/pages/login/index.tsx | 4 +- projects/app/src/service/core/app/utils.ts | 4 +- .../support/wallet/usage/controller.ts | 27 ---- .../src/service/support/wallet/usage/push.ts | 47 +------ .../app/src/web/common/file/controller.ts | 2 +- 32 files changed, 373 insertions(+), 248 deletions(-) create mode 100644 packages/service/support/wallet/usage/type.d.ts delete mode 100644 projects/app/src/service/support/wallet/usage/controller.ts diff --git a/docSite/content/zh-cn/docs/development/upgrading/4822.md b/docSite/content/zh-cn/docs/development/upgrading/4822.md index 6f747c344..386cc0f18 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4822.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4822.md @@ -11,7 +11,13 @@ weight: 802 ## 完整更新内容 1. 新增 - AI 对话节点解析 标签内容,便于各类模型进行思考链输出。 -2. 修复 - 思考链流输出时,有时与正文顺序偏差。 -3. 修复 - API 调用工作流,如果传递的图片不支持 Head 检测时,图片会被过滤。已增加该类错误检测,避免被错误过滤。 -4. 修复 - 模板市场部分模板错误。 -5. 修复 - 免登录窗口无法正常判断语言识别是否开启。 \ No newline at end of file +2. 优化 - 模型未配置时提示,减少冲突提示。 +3. 优化 - 使用记录代码。 +4. 修复 - 思考内容未进入到输出 Tokens. +5. 修复 - 思考链流输出时,有时与正文顺序偏差。 +6. 修复 - API 调用工作流,如果传递的图片不支持 Head 检测时,图片会被过滤。已增加该类错误检测,避免被错误过滤。 +7. 修复 - 模板市场部分模板错误。 +8. 修复 - 免登录窗口无法正常判断语言识别是否开启。 +9. 修复 - 对话日志导出,未兼容 sub path。 +10. 修复 - list 接口在联查 member 时,存在空指针可能性。 +11. 修复 - 工作流基础节点无法升级。 diff --git a/packages/global/common/file/constants.ts b/packages/global/common/file/constants.ts index 5e1886c89..d98793b0b 100644 --- a/packages/global/common/file/constants.ts +++ b/packages/global/common/file/constants.ts @@ -20,4 +20,4 @@ export const ReadFileBaseUrl = `${process.env.FILE_DOMAIN || process.env.FE_DOMA export const documentFileType = '.txt, .docx, .csv, .xlsx, .pdf, .md, .html, .pptx'; export const imageFileType = - '.jpg, .jpeg, .png, .gif, .bmp, .webp, .svg, .tiff, .tif, .ico, .heic, .heif, .avif'; + '.jpg, .jpeg, .png, .gif, .bmp, .webp, .svg, .tiff, .tif, .ico, .heic, .heif, .avif, .raw, .cr2, .nef, .arw, .dng, .psd, .ai, .eps, .emf, .wmf, .jfif, .exif, .pgm, .ppm, .pbm, .jp2, .j2k, .jpf, .jpx, .jpm, .mj2, .xbm, .pcx'; diff --git a/packages/global/core/ai/type.d.ts b/packages/global/core/ai/type.d.ts index 1d288ec98..bb7f87c38 100644 --- a/packages/global/core/ai/type.d.ts +++ b/packages/global/core/ai/type.d.ts @@ -46,6 +46,7 @@ export type ChatCompletionMessageParam = ( | CustomChatCompletionToolMessageParam | CustomChatCompletionAssistantMessageParam ) & { + reasoning_text?: string; dataId?: string; hideInUI?: boolean; }; diff --git a/packages/global/core/chat/adapt.ts b/packages/global/core/chat/adapt.ts index d5bc6d80a..4c4d65101 100644 --- a/packages/global/core/chat/adapt.ts +++ b/packages/global/core/chat/adapt.ts @@ -46,7 +46,16 @@ export const chats2GPTMessages = ({ messages.forEach((item) => { const dataId = reserveId ? item.dataId : undefined; - if (item.obj === ChatRoleEnum.Human) { + if (item.obj === ChatRoleEnum.System) { + const content = item.value?.[0]?.text?.content; + if (content) { + results.push({ + dataId, + role: ChatCompletionRequestMessageRoleEnum.System, + content + }); + } + } else if (item.obj === ChatRoleEnum.Human) { const value = item.value .map((item) => { if (item.type === ChatItemValueTypeEnum.text) { @@ -80,15 +89,6 @@ export const chats2GPTMessages = ({ role: ChatCompletionRequestMessageRoleEnum.User, content: simpleUserContentPart(value) }); - } else if (item.obj === ChatRoleEnum.System) { - const content = item.value?.[0]?.text?.content; - if (content) { - results.push({ - dataId, - role: ChatCompletionRequestMessageRoleEnum.System, - content - }); - } } else { const aiResults: ChatCompletionMessageParam[] = []; diff --git a/packages/service/common/file/image/controller.ts b/packages/service/common/file/image/controller.ts index 6ab13cd0f..f368e45e0 100644 --- a/packages/service/common/file/image/controller.ts +++ b/packages/service/common/file/image/controller.ts @@ -26,15 +26,18 @@ export async function uploadMongoImg({ const [base64Mime, base64Data] = base64Img.split(','); // Check if mime type is valid if (!base64MimeRegex.test(base64Mime)) { - return Promise.reject('Invalid image mime type'); + return Promise.reject('Invalid image base64'); } const mime = `image/${base64Mime.match(base64MimeRegex)?.[1] ?? 'image/jpeg'}`; const binary = Buffer.from(base64Data, 'base64'); - const extension = mime.split('/')[1]; + let extension = mime.split('/')[1]; + if (extension.startsWith('x-')) { + extension = extension.substring(2); // Remove 'x-' prefix + } - if (!imageFileType.includes(`.${extension}`)) { - return Promise.reject('Invalid image file type'); + if (!extension || !imageFileType.includes(`.${extension}`)) { + return Promise.reject(`Invalid image file type: ${mime}`); } const { _id } = await MongoImage.create({ diff --git a/packages/service/common/string/tiktoken/index.ts b/packages/service/common/string/tiktoken/index.ts index a53d11b64..388f81ed8 100644 --- a/packages/service/common/string/tiktoken/index.ts +++ b/packages/service/common/string/tiktoken/index.ts @@ -25,7 +25,7 @@ export const countGptMessagesTokens = async ( number >({ name: WorkerNameEnum.countGptMessagesTokens, - maxReservedThreads: global.systemEnv?.tokenWorkers || 50 + maxReservedThreads: global.systemEnv?.tokenWorkers || 30 }); const total = await workerController.run({ messages, tools, functionCall }); diff --git a/packages/service/core/workflow/dispatch/chat/oneapi.ts b/packages/service/core/workflow/dispatch/chat/oneapi.ts index 8dff023b2..a634e6e98 100644 --- a/packages/service/core/workflow/dispatch/chat/oneapi.ts +++ b/packages/service/core/workflow/dispatch/chat/oneapi.ts @@ -270,7 +270,8 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise { + const totalPoints = flowUsages.reduce((sum, item) => sum + (item.totalPoints || 0), 0); + + createUsage({ + teamId, + tmbId, + appName, + appId, + pluginId, + totalPoints, + source, + list: flowUsages.map((item) => ({ + moduleName: item.moduleName, + amount: item.totalPoints || 0, + model: item.model, + inputTokens: item.inputTokens, + outputTokens: item.outputTokens + })) + }); + addLog.debug(`Create chat usage`, { + source, + teamId, + totalPoints + }); + return { totalPoints }; +}; export const createTrainingUsage = async ({ teamId, @@ -29,21 +137,21 @@ export const createTrainingUsage = async ({ totalPoints: 0, list: [ { - moduleName: 'support.wallet.moduleName.index', + moduleName: i18nT('common:support.wallet.moduleName.index'), model: vectorModel, amount: 0, inputTokens: 0, outputTokens: 0 }, { - moduleName: 'support.wallet.moduleName.qa', + moduleName: i18nT('common:support.wallet.moduleName.qa'), model: agentModel, amount: 0, inputTokens: 0, outputTokens: 0 }, { - moduleName: 'core.dataset.training.Auto mode', + moduleName: i18nT('common:core.dataset.training.Auto mode'), model: agentModel, amount: 0, inputTokens: 0, diff --git a/packages/service/support/wallet/usage/type.d.ts b/packages/service/support/wallet/usage/type.d.ts new file mode 100644 index 000000000..930d6723e --- /dev/null +++ b/packages/service/support/wallet/usage/type.d.ts @@ -0,0 +1,12 @@ +export type ConcatBillQueueItemType = { + billId: string; + listIndex?: number; + totalPoints: number; + inputTokens: number; + outputTokens: number; +}; + +declare global { + var reduceAiPointsQueue: { teamId: string; totalPoints: number }[]; + var concatBillQueue: ConcatBillQueueItemType[]; +} diff --git a/packages/service/support/wallet/usage/utils.ts b/packages/service/support/wallet/usage/utils.ts index fef3ce934..c9154c695 100644 --- a/packages/service/support/wallet/usage/utils.ts +++ b/packages/service/support/wallet/usage/utils.ts @@ -1,5 +1,6 @@ import { findAIModel } from '../../../core/ai/model'; import { ModelTypeEnum } from '@fastgpt/global/core/ai/model'; +import { ConcatBillQueueItemType } from './type'; export const formatModelChars2Points = ({ model, @@ -34,3 +35,20 @@ export const formatModelChars2Points = ({ totalPoints }; }; + +export const pushReduceTeamAiPointsTask = ({ + teamId, + totalPoints +}: { + teamId: string; + totalPoints: number; +}) => { + global.reduceAiPointsQueue.push({ + teamId: String(teamId), + totalPoints + }); +}; + +export const pushConcatBillTask = (data: ConcatBillQueueItemType[]) => { + global.concatBillQueue.push(...data); +}; diff --git a/packages/service/worker/countGptMessagesTokens/index.ts b/packages/service/worker/countGptMessagesTokens/index.ts index 7cd836a36..5db9084b6 100644 --- a/packages/service/worker/countGptMessagesTokens/index.ts +++ b/packages/service/worker/countGptMessagesTokens/index.ts @@ -72,7 +72,7 @@ parentPort?.on( }; const total = - messages.reduce((sum, item) => { + messages.reduce((sum, item, index) => { // Evaluates the text of toolcall and functioncall const functionCallPrompt = (() => { let prompt = ''; @@ -100,7 +100,13 @@ parentPort?.on( .join(''); })(); - return sum + countPromptTokens(`${contentPrompt}${functionCallPrompt}`, item.role); + // Only the last message computed reasoning_text + const reasoningText = index === messages.length - 1 ? item.reasoning_text || '' : ''; + + return ( + sum + + countPromptTokens(`${reasoningText}${contentPrompt}${functionCallPrompt}`, item.role) + ); }, 0) + countToolsTokens(tools) + countToolsTokens(functionCall); diff --git a/packages/web/components/common/Icon/index.tsx b/packages/web/components/common/Icon/index.tsx index 3256298c5..aedc7ef14 100644 --- a/packages/web/components/common/Icon/index.tsx +++ b/packages/web/components/common/Icon/index.tsx @@ -1,17 +1,17 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; import type { IconProps } from '@chakra-ui/react'; import { Box, Icon } from '@chakra-ui/react'; import { iconPaths } from './constants'; import type { IconNameType } from './type.d'; +import { useRefresh } from '../../../hooks/useRefresh'; const iconCache: Record = {}; const MyIcon = ({ name, w = 'auto', h = 'auto', ...props }: { name: IconNameType } & IconProps) => { - const [IconComponent, setIconComponent] = useState(null); + const { refresh } = useRefresh(); useEffect(() => { if (iconCache[name]) { - setIconComponent(iconCache[name]); return; } @@ -20,11 +20,13 @@ const MyIcon = ({ name, w = 'auto', h = 'auto', ...props }: { name: IconNameType const component = { as: icon.default }; // Store in cache iconCache[name] = component; - setIconComponent(component); + refresh(); }) .catch((error) => console.log(error)); }, [name]); + const IconComponent = iconCache[name]; + return !!IconComponent ? ( { }); // Check model invalid - useEffect(() => { - if (userInfo?.username === 'root') { - if (llmModelList.length === 0) { - toast({ - status: 'warning', - title: t('common:llm_model_not_config') - }); - router.push('/account/model'); - } else if (embeddingModelList.length === 0) { - toast({ - status: 'warning', - title: t('common:embedding_model_not_config') - }); - router.push('/account/model'); + useDebounceEffect( + () => { + if (userInfo?.username === 'root') { + if (llmModelList.length === 0) { + toast({ + status: 'warning', + title: t('common:llm_model_not_config') + }); + router.push('/account/model'); + } else if (embeddingModelList.length === 0) { + toast({ + status: 'warning', + title: t('common:embedding_model_not_config') + }); + router.push('/account/model'); + } } + }, + [embeddingModelList.length, llmModelList.length, userInfo?.username], + { + wait: 2000 } - }, [embeddingModelList.length, llmModelList.length, userInfo?.username]); + ); return ( <> diff --git a/projects/app/src/components/Select/AIModelSelector.tsx b/projects/app/src/components/Select/AIModelSelector.tsx index 852c25d58..2a0881e9f 100644 --- a/projects/app/src/components/Select/AIModelSelector.tsx +++ b/projects/app/src/components/Select/AIModelSelector.tsx @@ -35,34 +35,46 @@ const OneRowSelector = ({ list, onchange, disableTip, ...props }: Props) => { return props.size ? size[props.size] : size['md']; }, [props.size]); - const avatarList = list.map((item) => { - const modelData = getModelFromList( - [ - ...llmModelList, - ...embeddingModelList, - ...ttsModelList, - ...sttModelList, - ...reRankModelList - ], - item.value - ); + const avatarList = useMemo( + () => + list.map((item) => { + const modelData = getModelFromList( + [ + ...llmModelList, + ...embeddingModelList, + ...ttsModelList, + ...sttModelList, + ...reRankModelList + ], + item.value + ); - return { - value: item.value, - label: ( - - - {modelData.name} - - ) - }; - }); + return { + value: item.value, + label: ( + + + {modelData.name} + + ) + }; + }), + [ + list, + llmModelList, + embeddingModelList, + ttsModelList, + sttModelList, + reRankModelList, + avatarSize + ] + ); return ( const { t } = useTranslation(); const { llmModelList, embeddingModelList, ttsModelList, sttModelList, reRankModelList } = useSystemStore(); + const modelList = useMemo(() => { + return [ + ...llmModelList, + ...embeddingModelList, + ...ttsModelList, + ...sttModelList, + ...reRankModelList + ]; + }, [llmModelList, embeddingModelList, ttsModelList, sttModelList, reRankModelList]); + const [value, setValue] = useState([]); const avatarSize = useMemo(() => { @@ -134,7 +156,7 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) => })); for (const item of list) { - const modelData = getModelFromList([...llmModelList, ...embeddingModelList], item.value); + const modelData = getModelFromList(modelList, item.value); const provider = renderList.find((item) => item.value === (modelData?.provider || 'Other')) ?? renderList[renderList.length - 1]; @@ -146,7 +168,7 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) => } return renderList.filter((item) => item.children.length > 0); - }, [avatarSize, list, llmModelList, t, embeddingModelList]); + }, [avatarSize, list, modelList]); const onSelect = useCallback( (e: string[]) => { @@ -156,16 +178,7 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) => ); const SelectedModel = useMemo(() => { - const modelData = getModelFromList( - [ - ...llmModelList, - ...embeddingModelList, - ...ttsModelList, - ...sttModelList, - ...reRankModelList - ], - props.value - ); + const modelData = getModelFromList(modelList, props.value); setValue([modelData.provider, props.value]); @@ -181,15 +194,7 @@ const MultipleRowSelector = ({ list, onchange, disableTip, ...props }: Props) => {modelData?.name} ); - }, [ - llmModelList, - embeddingModelList, - ttsModelList, - sttModelList, - reRankModelList, - props.value, - avatarSize - ]); + }, [modelList, props.value, avatarSize]); return ( & { showManage?: boolean; - afterSwitchTeam?: () => void; + onChange?: () => void; }) => { const { t } = useTranslation(); const router = useRouter(); @@ -38,7 +38,7 @@ const TeamSelector = ({ { onFinally: () => { setLoading(false); - afterSwitchTeam?.(); + onChange?.(); }, errorToast: t('common:user.team.Switch Team Failed') } diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx index deb2d56d8..b7feff68f 100644 --- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx +++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx @@ -142,19 +142,36 @@ const NodeCard = (props: Props) => { const { runAsync: onClickSyncVersion } = useRequest2( async () => { - if (!node?.pluginId) return; - const template = await getPreviewPluginNode({ appId: node.pluginId }); + if (!node) return; - if (!!template) { + if (node.pluginId) { + const template = await getPreviewPluginNode({ appId: node.pluginId }); + + if (!!template) { + onResetNode({ + id: nodeId, + node: template + }); + } + } else { + const template = moduleTemplatesFlat.find( + (item) => item.flowNodeType === node.flowNodeType + ); + if (!template) { + return toast({ + title: t('app:app.modules.not_found_tips'), + status: 'warning' + }); + } onResetNode({ id: nodeId, node: template }); } - onCloseConfirmSync(); }, { - refreshDeps: [node, nodeId, onResetNode] + refreshDeps: [node, nodeId, onResetNode], + onFinally() {} } ); @@ -311,7 +328,6 @@ const NodeCard = (props: Props) => { )} - ); }, [ @@ -335,7 +351,6 @@ const NodeCard = (props: Props) => { intro, menuForbid, nodeList, - ConfirmSyncModal, onChangeNode, onOpenCustomTitleModal, toast diff --git a/projects/app/src/pageComponents/dataset/detail/Import/components/FileSelector.tsx b/projects/app/src/pageComponents/dataset/detail/Import/components/FileSelector.tsx index 7ea6c823b..f758e63e7 100644 --- a/projects/app/src/pageComponents/dataset/detail/Import/components/FileSelector.tsx +++ b/projects/app/src/pageComponents/dataset/detail/Import/components/FileSelector.tsx @@ -7,7 +7,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon'; import { useTranslation } from 'next-i18next'; import React, { DragEvent, useCallback, useMemo, useState } from 'react'; import { getNanoid } from '@fastgpt/global/common/string/tools'; -import { useRequest } from '@fastgpt/web/hooks/useRequest'; +import { useRequest2 } from '@fastgpt/web/hooks/useRequest'; import { getFileIcon } from '@fastgpt/global/common/file/icon'; import { useSystemStore } from '@/web/common/system/useSystemStore'; import { uploadFile2DB } from '@/web/common/file/controller'; @@ -66,9 +66,50 @@ const FileSelector = ({ 'i' ); - const { mutate: onSelectFile, isLoading } = useRequest({ - mutationFn: async (files: SelectFileItemType[]) => { + const { runAsync: onSelectFile, loading: isLoading } = useRequest2( + async (files: SelectFileItemType[]) => { { + await Promise.all( + files.map(async ({ fileId, file }) => { + const { fileId: uploadFileId } = await uploadFile2DB({ + file, + bucketName: BucketNameEnum.dataset, + data: { + datasetId + }, + percentListen: (e) => { + setSelectFiles((state) => + state.map((item) => + item.id === fileId + ? { + ...item, + uploadedFileRate: item.uploadedFileRate + ? Math.max(e, item.uploadedFileRate) + : e + } + : item + ) + ); + } + }); + setSelectFiles((state) => + state.map((item) => + item.id === fileId + ? { + ...item, + dbFileId: uploadFileId, + isUploading: false, + uploadedFileRate: 100 + } + : item + ) + ); + }) + ); + } + }, + { + onBefore([files]) { onStartSelect(); setSelectFiles((state) => { const formatFiles = files.map((selectFile) => { @@ -88,52 +129,12 @@ const FileSelector = ({ const results = formatFiles.concat(state).slice(0, maxCount); return results; }); - try { - // upload file - await Promise.all( - files.map(async ({ fileId, file }) => { - const { fileId: uploadFileId } = await uploadFile2DB({ - file, - bucketName: BucketNameEnum.dataset, - data: { - datasetId - }, - percentListen: (e) => { - setSelectFiles((state) => - state.map((item) => - item.id === fileId - ? { - ...item, - uploadedFileRate: item.uploadedFileRate - ? Math.max(e, item.uploadedFileRate) - : e - } - : item - ) - ); - } - }); - setSelectFiles((state) => - state.map((item) => - item.id === fileId - ? { - ...item, - dbFileId: uploadFileId, - isUploading: false, - uploadedFileRate: 100 - } - : item - ) - ); - }) - ); - } catch (error) { - console.log(error); - } + }, + onFinally() { onFinishSelect(); } } - }); + ); const selectFileCallback = useCallback( (files: SelectFileItemType[]) => { diff --git a/projects/app/src/pages/account/info/index.tsx b/projects/app/src/pages/account/info/index.tsx index 3f0fc6f26..768dac4f7 100644 --- a/projects/app/src/pages/account/info/index.tsx +++ b/projects/app/src/pages/account/info/index.tsx @@ -284,7 +284,7 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => { {t('account_info:user_team_team_name')}:  - + )} diff --git a/projects/app/src/pages/account/team/index.tsx b/projects/app/src/pages/account/team/index.tsx index b4475cc47..57088d435 100644 --- a/projects/app/src/pages/account/team/index.tsx +++ b/projects/app/src/pages/account/team/index.tsx @@ -88,7 +88,7 @@ const Team = () => { - + {userInfo?.team?.role === TeamMemberRoleEnum.owner && ( diff --git a/projects/app/src/pages/api/common/system/getInitData.ts b/projects/app/src/pages/api/common/system/getInitData.ts index 6b10d6001..59bc2bc88 100644 --- a/projects/app/src/pages/api/common/system/getInitData.ts +++ b/projects/app/src/pages/api/common/system/getInitData.ts @@ -44,12 +44,22 @@ async function handler( defaultModels: global.systemDefaultModel }; } catch (error) { + const referer = req.headers.referer; + if (referer?.includes('/price')) { + return { + feConfigs: global.feConfigs, + subPlans: global.subPlans, + activeModelList + }; + } + const unAuthBufferId = global.systemInitBufferId ? `unAuth_${global.systemInitBufferId}` : ''; if (bufferId && unAuthBufferId === bufferId) { return { bufferId: unAuthBufferId }; } + return { bufferId: unAuthBufferId, feConfigs: global.feConfigs diff --git a/projects/app/src/pages/api/core/chat/chatTest.ts b/projects/app/src/pages/api/core/chat/chatTest.ts index 26e9b044d..d7276191b 100644 --- a/projects/app/src/pages/api/core/chat/chatTest.ts +++ b/projects/app/src/pages/api/core/chat/chatTest.ts @@ -5,7 +5,7 @@ import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import { responseWrite } from '@fastgpt/service/common/response'; -import { pushChatUsage } from '@/service/support/wallet/usage/push'; +import { createChatUsage } from '@fastgpt/service/support/wallet/usage/controller'; import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants'; import type { AIChatItemType, UserChatItemType } from '@fastgpt/global/core/chat/type'; import { authApp } from '@fastgpt/service/support/permission/app/auth'; @@ -244,7 +244,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { } } - pushChatUsage({ + createChatUsage({ appName, appId, teamId, diff --git a/projects/app/src/pages/api/core/workflow/debug.ts b/projects/app/src/pages/api/core/workflow/debug.ts index 87d7ce439..4bdbe2097 100644 --- a/projects/app/src/pages/api/core/workflow/debug.ts +++ b/projects/app/src/pages/api/core/workflow/debug.ts @@ -1,5 +1,5 @@ import type { NextApiRequest, NextApiResponse } from 'next'; -import { pushChatUsage } from '@/service/support/wallet/usage/push'; +import { createChatUsage } from '@fastgpt/service/support/wallet/usage/controller'; import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants'; import { authApp } from '@fastgpt/service/support/permission/app/auth'; import { dispatchWorkFlow } from '@fastgpt/service/core/workflow/dispatch'; @@ -66,8 +66,8 @@ async function handler( maxRunTimes: WORKFLOW_MAX_RUN_TIMES }); - pushChatUsage({ - appName: '工作流Debug', + createChatUsage({ + appName: `${app.name}-Debug`, appId, teamId, tmbId, diff --git a/projects/app/src/pages/api/v1/chat/completions.ts b/projects/app/src/pages/api/v1/chat/completions.ts index f75e9a3b1..0ed305014 100644 --- a/projects/app/src/pages/api/v1/chat/completions.ts +++ b/projects/app/src/pages/api/v1/chat/completions.ts @@ -20,7 +20,7 @@ import { GPTMessages2Chats, chatValue2RuntimePrompt } from '@fastgpt/global/core import { getChatItems } from '@fastgpt/service/core/chat/controller'; import { saveChat, updateInteractiveChat } from '@fastgpt/service/core/chat/saveChat'; import { responseWrite } from '@fastgpt/service/common/response'; -import { pushChatUsage } from '@/service/support/wallet/usage/push'; +import { createChatUsage } from '@fastgpt/service/support/wallet/usage/controller'; import { authOutLinkChatStart } from '@/service/support/permission/auth/outLink'; import { pushResult2Remote, addOutLinkUsage } from '@fastgpt/service/support/outLink/tools'; import requestIp from 'request-ip'; @@ -423,7 +423,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { } // add record - const { totalPoints } = pushChatUsage({ + const { totalPoints } = createChatUsage({ appName: app.name, appId: app._id, teamId, diff --git a/projects/app/src/pages/login/index.tsx b/projects/app/src/pages/login/index.tsx index 3d061fb27..add812a0a 100644 --- a/projects/app/src/pages/login/index.tsx +++ b/projects/app/src/pages/login/index.tsx @@ -67,9 +67,7 @@ const Login = ({ ChineseRedirectUrl }: { ChineseRedirectUrl: string }) => { // 检查是否是当前的 route const navigateTo = decodeLastRoute && !decodeLastRoute.includes('/login') ? decodeLastRoute : '/app/list'; - setTimeout(() => { - router.push(navigateTo); - }, 300); + router.push(navigateTo); }, [setUserInfo, lastRoute, router] ); diff --git a/projects/app/src/service/core/app/utils.ts b/projects/app/src/service/core/app/utils.ts index 8e7e8e285..b4c0c6db8 100644 --- a/projects/app/src/service/core/app/utils.ts +++ b/projects/app/src/service/core/app/utils.ts @@ -1,5 +1,5 @@ import { getUserChatInfoAndAuthTeamPoints } from '@fastgpt/service/support/permission/auth/team'; -import { pushChatUsage } from '@/service/support/wallet/usage/push'; +import { createChatUsage } from '@fastgpt/service/support/wallet/usage/controller'; import { getNextTimeByCronStringAndTimezone } from '@fastgpt/global/common/string/time'; import { getNanoid } from '@fastgpt/global/common/string/tools'; import { delay, retryFn } from '@fastgpt/global/common/system/utils'; @@ -113,7 +113,7 @@ export const getScheduleTriggerApp = async () => { } ] }); - pushChatUsage({ + createChatUsage({ appName: app.name, appId: app._id, teamId: String(app.teamId), diff --git a/projects/app/src/service/support/wallet/usage/controller.ts b/projects/app/src/service/support/wallet/usage/controller.ts deleted file mode 100644 index 4f9a1bd64..000000000 --- a/projects/app/src/service/support/wallet/usage/controller.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ConcatUsageProps, CreateUsageProps } from '@fastgpt/global/support/wallet/usage/api'; -import { addLog } from '@fastgpt/service/common/system/log'; -import { POST } from '@fastgpt/service/common/api/plusRequest'; -import { FastGPTProUrl } from '@fastgpt/service/common/system/constants'; - -export async function createUsage(data: CreateUsageProps) { - if (!FastGPTProUrl) return; - if (data.totalPoints === 0) { - addLog.info('0 totalPoints', data); - } - try { - await POST('/support/wallet/usage/createUsage', data); - } catch (error) { - addLog.error('createUsage error', error); - } -} -export async function concatUsage(data: ConcatUsageProps) { - if (!FastGPTProUrl) return; - if (data.totalPoints === 0) { - addLog.info('0 totalPoints', data); - } - try { - await POST('/support/wallet/usage/concatUsage', data); - } catch (error) { - addLog.error('concatUsage error', error); - } -} diff --git a/projects/app/src/service/support/wallet/usage/push.ts b/projects/app/src/service/support/wallet/usage/push.ts index d0d74564b..fe14f7058 100644 --- a/projects/app/src/service/support/wallet/usage/push.ts +++ b/projects/app/src/service/support/wallet/usage/push.ts @@ -1,55 +1,10 @@ import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants'; -import { addLog } from '@fastgpt/service/common/system/log'; -import { createUsage, concatUsage } from './controller'; +import { createUsage, concatUsage } from '@fastgpt/service/support/wallet/usage/controller'; import { formatModelChars2Points } from '@fastgpt/service/support/wallet/usage/utils'; -import { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type'; import { i18nT } from '@fastgpt/web/i18n/utils'; import { ModelTypeEnum } from '@fastgpt/global/core/ai/model'; import { getDefaultTTSModel } from '@fastgpt/service/core/ai/model'; -export const pushChatUsage = ({ - appName, - appId, - pluginId, - teamId, - tmbId, - source, - flowUsages -}: { - appName: string; - appId?: string; - pluginId?: string; - teamId: string; - tmbId: string; - source: UsageSourceEnum; - flowUsages: ChatNodeUsageType[]; -}) => { - const totalPoints = flowUsages.reduce((sum, item) => sum + (item.totalPoints || 0), 0); - - createUsage({ - teamId, - tmbId, - appName, - appId, - pluginId, - totalPoints, - source, - list: flowUsages.map((item) => ({ - moduleName: item.moduleName, - amount: item.totalPoints || 0, - model: item.model, - inputTokens: item.inputTokens, - outputTokens: item.outputTokens - })) - }); - addLog.info(`finish completions`, { - source, - teamId, - totalPoints - }); - return { totalPoints }; -}; - export const pushQAUsage = async ({ teamId, tmbId, diff --git a/projects/app/src/web/common/file/controller.ts b/projects/app/src/web/common/file/controller.ts index a02ca0283..89068ecd1 100644 --- a/projects/app/src/web/common/file/controller.ts +++ b/projects/app/src/web/common/file/controller.ts @@ -31,7 +31,7 @@ export const uploadFile2DB = ({ if (!e.total) return; const percent = Math.round((e.loaded / e.total) * 100); - percentListen && percentListen(percent); + percentListen?.(percent); }); };