V4.9.7 feature (#4669)

* update doc

* feat: Add coupon redemption feature for team subscriptions (#4595)

* feat: Add coupon redemption feature for team subscriptions

- Introduced `TeamCouponSub` and `TeamCouponSchema` types
- Added `redeemCoupon` API endpoint
- Updated UI to include a modal for coupon redemption
- Added new icon and translations for "Redeem coupon"

* perf: remove field teamId

* perf: use dynamic import

* refactor: move to page component

* perf: coupon code

* perf: mcp server

* perf: test

* auto layout (#4634)

* fix 4.9.6 (#4631)

* fix debug quote list

* delete next text node match

* fix extract default boolean value

* export latest 100 chat items

* fix quote item ui

* doc

* fix doc

* feat: auto layout

* perf: auto layout

* fix: auto layout null

* add start node

---------

Co-authored-by: heheer <heheer@sealos.io>

* fix: share link (#4644)

* Add workflow run duration;Get audio duration (#4645)

* add duration

* get audio duration

* Custom config path (#4649)

* feat: 通过环境变量DATA_PATH获取配置文件目录 (#4622)

通过环境变量DATA_PATH获取配置文件目录,以应对不同的部署方式的多样化需求

* feat: custom configjson path

* doc

---------

Co-authored-by: John Chen <sss1991@163.com>

* 程序api调用场景下,如果大量调用带有图片或视频,产生的聊天记录会导致后台mongo数据库异常。这个修改给api客户端一个禁止生成聊天记录的选项,避免这个后果。 (#3964)

* update special chatId

* perf: vector db rename

* update operationLog (#4647)

* update operationLog

* combine operationLogMap

* solve operationI18nLogMap bug

* remoce log

* feat: Rerank usage (#4654)

* refresh concat when update (#4655)

* fix: refresh code

* perf: timer lock

* Fix operationLog (#4657)

* perf: http streamable mcp

* add alipay (#4630)

* perf: subplan ui

* perf: pay code

* hiden bank tip

* Fix: pay error (#4665)

* fix quote number (#4666)

* remove log

---------

Co-authored-by: a.e. <49438478+I-Info@users.noreply.github.com>
Co-authored-by: heheer <heheer@sealos.io>
Co-authored-by: John Chen <sss1991@163.com>
Co-authored-by: gaord <bengao168@msn.com>
Co-authored-by: gggaaallleee <91131304+gggaaallleee@users.noreply.github.com>
This commit is contained in:
Archer
2025-04-26 16:17:21 +08:00
committed by GitHub
parent a669a60fe6
commit 0720bbe4da
143 changed files with 2067 additions and 1093 deletions

View File

@@ -25,7 +25,7 @@ import Avatar from '@fastgpt/web/components/common/Avatar';
import MyIcon from '@fastgpt/web/components/common/Icon';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/usage/tools';
import { putUpdateMemberName } from '@/web/support/user/team/api';
import { putUpdateMemberName, redeemCoupon } from '@/web/support/user/team/api';
import { getDocPath } from '@/web/common/system/doc';
import {
StandardSubLevelEnum,
@@ -47,6 +47,9 @@ import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useMount } from 'ahooks';
import MyDivider from '@fastgpt/web/components/common/MyDivider';
const RedeemCouponModal = dynamic(() => import('@/pageComponents/account/info/RedeemCouponModal'), {
ssr: false
});
const StandDetailModal = dynamic(
() => import('@/pageComponents/account/info/standardDetailModal'),
{ ssr: false }
@@ -353,8 +356,8 @@ const MyInfo = ({ onOpenContact }: { onOpenContact: () => void }) => {
const PlanUsage = () => {
const router = useRouter();
const { t } = useTranslation();
const { userInfo, initUserInfo, teamPlanStatus } = useUserStore();
const { subPlans } = useSystemStore();
const { userInfo, initUserInfo, teamPlanStatus, initTeamPlanStatus } = useUserStore();
const { subPlans, feConfigs } = useSystemStore();
const { reset } = useForm<UserUpdateParams>({
defaultValues: userInfo as UserType
});
@@ -365,6 +368,12 @@ const PlanUsage = () => {
onOpen: onOpenStandardModal
} = useDisclosure();
const {
isOpen: isOpenRedeemCouponModal,
onClose: onCloseRedeemCouponModal,
onOpen: onOpenRedeemCouponModal
} = useDisclosure();
const planName = useMemo(() => {
if (!teamPlanStatus?.standard?.currentSubLevel) return '';
return standardSubLevelMap[teamPlanStatus.standard.currentSubLevel].label;
@@ -460,14 +469,19 @@ const PlanUsage = () => {
</Flex>
<ModelPriceModal>
{({ onOpen }) => (
<Button ml={4} size={'sm'} onClick={onOpen}>
<Button ml={3} size={'sm'} onClick={onOpen}>
{t('account_info:billing_standard')}
</Button>
)}
</ModelPriceModal>
<Button ml={4} variant={'whitePrimary'} size={'sm'} onClick={onOpenStandardModal}>
<Button ml={3} variant={'whitePrimary'} size={'sm'} onClick={onOpenStandardModal}>
{t('account_info:package_details')}
</Button>
{userInfo?.permission.isOwner && feConfigs?.show_coupon && (
<Button ml={3} variant={'whitePrimary'} size={'sm'} onClick={onOpenRedeemCouponModal}>
{t('account_info:redeem_coupon')}
</Button>
)}
</Flex>
<Box
mt={[3, 6]}
@@ -603,6 +617,12 @@ const PlanUsage = () => {
</Box>
</Box>
{isOpenStandardModal && <StandDetailModal onClose={onCloseStandardModal} />}
{isOpenRedeemCouponModal && (
<RedeemCouponModal
onClose={onCloseRedeemCouponModal}
onSuccess={() => initTeamPlanStatus()}
/>
)}
</Box>
) : null;
};

View File

@@ -13,6 +13,8 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
import { TeamMemberRoleEnum } from '@fastgpt/global/support/user/team/constant';
import { TeamContext, TeamModalContextProvider } from '@/pageComponents/account/team/context';
import dynamic from 'next/dynamic';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useToast } from '@fastgpt/web/hooks/useToast';
const MemberTable = dynamic(() => import('@/pageComponents/account/team/MemberTable'));
const PermissionManage = dynamic(
@@ -48,7 +50,19 @@ const Team = () => {
const { teamTab = TeamTabEnum.member } = router.query as { teamTab: `${TeamTabEnum}` };
const { t } = useTranslation();
const { userInfo } = useUserStore();
const { userInfo, teamPlanStatus } = useUserStore();
const standardPlan = teamPlanStatus?.standard;
const level = standardPlan?.currentSubLevel;
const { subPlans } = useSystemStore();
const planContent = useMemo(() => {
const plan = level !== undefined ? subPlans?.standard?.[level] : undefined;
if (!plan) return;
return {
permissionTeamOperationLog: plan.permissionTeamOperationLog
};
}, [subPlans?.standard, level]);
const { toast } = useToast();
const { setEditTeamData, teamSize } = useContextSelector(TeamContext, (v) => v);
@@ -65,6 +79,13 @@ const Team = () => {
px={'1rem'}
value={teamTab}
onChange={(e) => {
if (e === TeamTabEnum.operationLog && !planContent?.permissionTeamOperationLog) {
toast({
status: 'warning',
title: t('common:not_permission')
});
return;
}
router.replace({
query: {
...router.query,

View File

@@ -1,7 +1,7 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { PgClient } from '@fastgpt/service/common/vectorStore/pg';
import { PgClient } from '@fastgpt/service/common/vectorDB/pg/controller';
/* pg 中的数据搬到 mongo dataset.datas 中,并做映射 */
export default async function handler(req: NextApiRequest, res: NextApiResponse) {

View File

@@ -11,7 +11,7 @@ import { MongoDatasetDataText } from '@fastgpt/service/core/dataset/data/dataTex
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
import { DatasetCollectionSchemaType } from '@fastgpt/global/core/dataset/type';
import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/schema';
import { deleteDatasetDataVector } from '@fastgpt/service/common/vectorStore/controller';
import { deleteDatasetDataVector } from '@fastgpt/service/common/vectorDB/controller';
// 删了库,没删集合
const checkInvalidCollection = async () => {

View File

@@ -5,8 +5,8 @@ import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection
import { DatasetCollectionDataProcessModeEnum } from '@fastgpt/global/core/dataset/constants';
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
import { DatasetDataIndexTypeEnum } from '@fastgpt/global/core/dataset/data/constants';
import { PgClient } from '@fastgpt/service/common/vectorStore/pg';
import { PG_ADDRESS } from '@fastgpt/service/common/vectorStore/constants';
import { PgClient } from '@fastgpt/service/common/vectorDB/pg/controller';
import { PG_ADDRESS } from '@fastgpt/service/common/vectorDB/constants';
// 所有 trainingType=auto 的 collection都改成 trainingType=chunk
const updateCollections = async () => {

View File

@@ -1,7 +1,7 @@
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
import { NextAPI } from '@/service/middleware/entry';
import { MilvusCtrl } from '@fastgpt/service/common/vectorStore/milvus/class';
import { DatasetVectorTableName } from '@fastgpt/service/common/vectorStore/constants';
import { MilvusCtrl } from '@fastgpt/service/common/vectorDB/milvus/index';
import { DatasetVectorTableName } from '@fastgpt/service/common/vectorDB/constants';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';

View File

@@ -63,14 +63,6 @@ export type Props = {
};
async function handler(req: NextApiRequest, res: NextApiResponse) {
res.on('close', () => {
res.end();
});
res.on('error', () => {
console.log('error: ', 'request error');
res.end();
});
let {
nodes = [],
edges = [],
@@ -170,39 +162,40 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
});
/* start process */
const { flowResponses, assistantResponses, newVariables, flowUsages } = await dispatchWorkFlow({
res,
requestOrigin: req.headers.origin,
mode: 'test',
timezone,
externalProvider,
uid: tmbId,
const { flowResponses, assistantResponses, newVariables, flowUsages, durationSeconds } =
await dispatchWorkFlow({
res,
requestOrigin: req.headers.origin,
mode: 'test',
timezone,
externalProvider,
uid: tmbId,
runningAppInfo: {
id: appId,
teamId: app.teamId,
tmbId: app.tmbId
},
runningUserInfo: {
teamId,
tmbId
},
runningAppInfo: {
id: appId,
teamId: app.teamId,
tmbId: app.tmbId
},
runningUserInfo: {
teamId,
tmbId
},
chatId,
responseChatItemId,
runtimeNodes,
runtimeEdges: storeEdges2RuntimeEdges(edges, interactive),
variables,
query: removeEmptyUserInput(userQuestion.value),
lastInteractive: interactive,
chatConfig,
histories: newHistories,
stream: true,
maxRunTimes: WORKFLOW_MAX_RUN_TIMES,
workflowStreamResponse: workflowResponseWrite,
version: 'v2',
responseDetail: true
});
chatId,
responseChatItemId,
runtimeNodes,
runtimeEdges: storeEdges2RuntimeEdges(edges, interactive),
variables,
query: removeEmptyUserInput(userQuestion.value),
lastInteractive: interactive,
chatConfig,
histories: newHistories,
stream: true,
maxRunTimes: WORKFLOW_MAX_RUN_TIMES,
workflowStreamResponse: workflowResponseWrite,
version: 'v2',
responseDetail: true
});
workflowResponseWrite({
event: SseResponseEventEnum.answer,
@@ -238,7 +231,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
appId: app._id,
userInteractiveVal,
aiResponse,
newVariables
newVariables,
durationSeconds
});
} else {
await saveChat({
@@ -252,7 +246,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
isUpdateUseTime: false, // owner update use time
newTitle,
source: ChatSourceEnum.test,
content: [userQuestion, aiResponse]
content: [userQuestion, aiResponse],
durationSeconds
});
}

View File

@@ -53,11 +53,11 @@ async function handler(
const isOutLink = authType === GetChatTypeEnum.outLink;
const fieldMap = {
[GetChatTypeEnum.normal]: `dataId obj value adminFeedback userBadFeedback userGoodFeedback time hideInUI ${
[GetChatTypeEnum.normal]: `dataId obj value adminFeedback userBadFeedback userGoodFeedback time hideInUI durationSeconds ${
DispatchNodeResponseKeyEnum.nodeResponse
} ${loadCustomFeedbacks ? 'customFeedbacks' : ''}`,
[GetChatTypeEnum.outLink]: `dataId obj value userGoodFeedback userBadFeedback adminFeedback time hideInUI ${DispatchNodeResponseKeyEnum.nodeResponse}`,
[GetChatTypeEnum.team]: `dataId obj value userGoodFeedback userBadFeedback adminFeedback time hideInUI ${DispatchNodeResponseKeyEnum.nodeResponse}`
[GetChatTypeEnum.outLink]: `dataId obj value userGoodFeedback userBadFeedback adminFeedback time hideInUI durationSeconds ${DispatchNodeResponseKeyEnum.nodeResponse}`,
[GetChatTypeEnum.team]: `dataId obj value userGoodFeedback userBadFeedback adminFeedback time hideInUI durationSeconds ${DispatchNodeResponseKeyEnum.nodeResponse}`
};
const { total, histories } = await getChatItems({

View File

@@ -11,9 +11,8 @@ import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { DatasetCollectionItemType } from '@fastgpt/global/core/dataset/type';
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
import { collectionTagsToTagLabel } from '@fastgpt/service/core/dataset/collection/utils';
import { getVectorCountByCollectionId } from '@fastgpt/service/common/vectorStore/controller';
import { getVectorCountByCollectionId } from '@fastgpt/service/common/vectorDB/controller';
import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/schema';
import { Types } from 'mongoose';
import { readFromSecondary } from '@fastgpt/service/common/mongo/utils';
async function handler(req: NextApiRequest): Promise<DatasetCollectionItemType> {

View File

@@ -1,16 +1,13 @@
import type { SearchTestProps, SearchTestResponse } from '@/global/core/dataset/api.d';
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
import { pushGenerateVectorUsage } from '@/service/support/wallet/usage/push';
import { pushGenerateVectorUsage, pushRerankUsage } from '@/service/support/wallet/usage/push';
import {
deepRagSearch,
defaultSearchDatasetData
} from '@fastgpt/service/core/dataset/search/controller';
import { updateApiKeyUsage } from '@fastgpt/service/support/openapi/tools';
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
import {
checkTeamAIPoints,
checkTeamReRankPermission
} from '@fastgpt/service/support/permission/teamLimit';
import { checkTeamAIPoints } from '@fastgpt/service/support/permission/teamLimit';
import { NextAPI } from '@/service/middleware/entry';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
@@ -58,6 +55,8 @@ async function handler(req: ApiRequestProps<SearchTestProps>): Promise<SearchTes
// auth balance
await checkTeamAIPoints(teamId);
const rerankModelData = getRerankModel(rerankModel);
const searchData = {
histories: [],
teamId,
@@ -69,11 +68,19 @@ async function handler(req: ApiRequestProps<SearchTestProps>): Promise<SearchTes
datasetIds: [datasetId],
searchMode,
embeddingWeight,
usingReRank: usingReRank && (await checkTeamReRankPermission(teamId)),
rerankModel: getRerankModel(rerankModel),
usingReRank,
rerankModel: rerankModelData,
rerankWeight
};
const { searchRes, tokens, queryExtensionResult, deepSearchResult, ...result } = datasetDeepSearch
const {
searchRes,
embeddingTokens,
reRankInputTokens,
usingReRank: searchUsingReRank,
queryExtensionResult,
deepSearchResult,
...result
} = datasetDeepSearch
? await deepRagSearch({
...searchData,
datasetDeepSearchModel,
@@ -88,10 +95,10 @@ async function handler(req: ApiRequestProps<SearchTestProps>): Promise<SearchTes
});
// push bill
const { totalPoints } = pushGenerateVectorUsage({
const { totalPoints: embeddingTotalPoints } = pushGenerateVectorUsage({
teamId,
tmbId,
inputTokens: tokens,
inputTokens: reRankInputTokens,
model: dataset.vectorModel,
source: apikey ? UsageSourceEnum.api : UsageSourceEnum.fastgpt,
@@ -106,10 +113,19 @@ async function handler(req: ApiRequestProps<SearchTestProps>): Promise<SearchTes
deepSearchOutputTokens: deepSearchResult.outputTokens
})
});
const { totalPoints: reRankTotalPoints } = searchUsingReRank
? pushRerankUsage({
teamId,
tmbId,
inputTokens: reRankInputTokens,
model: rerankModelData.model
})
: { totalPoints: 0 };
if (apikey) {
updateApiKeyUsage({
apikey,
totalPoints: totalPoints
totalPoints: embeddingTotalPoints + reRankTotalPoints
});
}
@@ -117,6 +133,7 @@ async function handler(req: ApiRequestProps<SearchTestProps>): Promise<SearchTes
list: searchRes,
duration: `${((Date.now() - start) / 1000).toFixed(3)}s`,
queryExtensionModel: queryExtensionResult?.model,
usingReRank: searchUsingReRank,
...result
};
}

View File

@@ -1,7 +1,7 @@
import { NextAPI } from '@/service/middleware/entry';
import { ToolType } from '@fastgpt/global/core/app/type';
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
import getMCPClient from '@fastgpt/service/core/app/mcp';
import { MCPClient } from '@fastgpt/service/core/app/mcp';
export type getMCPToolsQuery = {};
@@ -15,14 +15,9 @@ async function handler(
): Promise<getMCPToolsResponse> {
const { url } = req.body;
const mcpClient = getMCPClient({ url });
const mcpClient = new MCPClient({ url });
try {
const tools = await mcpClient.getTools();
return tools;
} catch (error) {
return Promise.reject(error);
}
return mcpClient.getTools();
}
export default NextAPI(handler);

View File

@@ -1,6 +1,6 @@
import { NextAPI } from '@/service/middleware/entry';
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
import getMCPClient from '@fastgpt/service/core/app/mcp';
import { MCPClient } from '@fastgpt/service/core/app/mcp';
export type RunMCPToolQuery = {};
@@ -18,14 +18,9 @@ async function handler(
): Promise<RunMCPToolResponse> {
const { url, toolName, params } = req.body;
const mcpClient = getMCPClient({ url });
const mcpClient = new MCPClient({ url });
try {
const result = await mcpClient.toolCall(toolName, params);
return result;
} catch (error) {
return Promise.reject(error);
}
return mcpClient.toolCall(toolName, params);
}
export default NextAPI(handler);

View File

@@ -85,30 +85,31 @@ const dispatchApp = async (app: AppSchema, variables: Record<string, any>) => {
const chatId = getNanoid();
const { flowUsages, assistantResponses, newVariables, flowResponses } = await dispatchWorkFlow({
chatId,
timezone,
externalProvider,
mode: 'chat',
runningAppInfo: {
id: String(app._id),
teamId: String(app.teamId),
tmbId: String(app.tmbId)
},
runningUserInfo: {
teamId: String(app.teamId),
tmbId: String(app.tmbId)
},
uid: String(app.tmbId),
runtimeNodes,
runtimeEdges: storeEdges2RuntimeEdges(edges),
variables,
query: removeEmptyUserInput(userQuestion.value),
chatConfig,
histories: [],
stream: false,
maxRunTimes: WORKFLOW_MAX_RUN_TIMES
});
const { flowUsages, assistantResponses, newVariables, flowResponses, durationSeconds } =
await dispatchWorkFlow({
chatId,
timezone,
externalProvider,
mode: 'chat',
runningAppInfo: {
id: String(app._id),
teamId: String(app.teamId),
tmbId: String(app.tmbId)
},
runningUserInfo: {
teamId: String(app.teamId),
tmbId: String(app.tmbId)
},
uid: String(app.tmbId),
runtimeNodes,
runtimeEdges: storeEdges2RuntimeEdges(edges),
variables,
query: removeEmptyUserInput(userQuestion.value),
chatConfig,
histories: [],
stream: false,
maxRunTimes: WORKFLOW_MAX_RUN_TIMES
});
// Save chat
const aiResponse: AIChatItemType & { dataId?: string } = {
@@ -128,7 +129,8 @@ const dispatchApp = async (app: AppSchema, variables: Record<string, any>) => {
isUpdateUseTime: false, // owner update use time
newTitle,
source: ChatSourceEnum.mcp,
content: [userQuestion, aiResponse]
content: [userQuestion, aiResponse],
durationSeconds
});
// Push usage
@@ -184,7 +186,7 @@ async function handler(
const app = appList.find((app) => {
const mcpApp = mcp.apps.find((mcpApp) => String(mcpApp.appId) === String(app._id))!;
return toolName === mcpApp.toolAlias || toolName === mcpApp.toolName;
return toolName === mcpApp.toolName;
});
if (!app) {

View File

@@ -8,10 +8,10 @@ import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controller';
import { Tool } from '@modelcontextprotocol/sdk/types';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
import { toolValueTypeList } from '@fastgpt/global/core/workflow/constants';
import { AppChatConfigType } from '@fastgpt/global/core/app/type';
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
import { FlowNodeInputItemType } from '@fastgpt/global/core/workflow/type/io';
export type listToolsQuery = { key: string };
@@ -19,7 +19,9 @@ export type listToolsBody = {};
export type listToolsResponse = {};
const pluginNodes2InputSchema = (nodes: StoreNodeItemType[]) => {
export const pluginNodes2InputSchema = (
nodes: { flowNodeType: FlowNodeTypeEnum; inputs: FlowNodeInputItemType[] }[]
) => {
const pluginInput = nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput);
const schema: Tool['inputSchema'] = {
@@ -47,7 +49,10 @@ const pluginNodes2InputSchema = (nodes: StoreNodeItemType[]) => {
return schema;
};
const workflow2InputSchema = (chatConfig?: AppChatConfigType) => {
export const workflow2InputSchema = (chatConfig?: {
fileSelectConfig?: AppChatConfigType['fileSelectConfig'];
variables?: AppChatConfigType['variables'];
}) => {
const schema: Tool['inputSchema'] = {
type: 'object',
properties: {
@@ -138,7 +143,7 @@ async function handler(
);
return {
name: mcpApp.toolAlias || mcpApp.toolName,
name: mcpApp.toolName,
description: mcpApp.description,
inputSchema: isPlugin
? pluginNodes2InputSchema(version.nodes)
@@ -150,5 +155,3 @@ async function handler(
}
export default NextAPI(handler);
export { pluginNodes2InputSchema, workflow2InputSchema, handler };

View File

@@ -56,15 +56,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
...req.body
});
// auth app
// const app = await MongoApp.findById(appId, 'modules').lean();
// if (!app) {
// throw new Error('app not found');
// }
// if (!whisperConfig?.open) {
// throw new Error('Whisper is not open in the app');
// }
const result = await aiTranscriptions({
model: getDefaultSTTModel(),
fileStream: fs.createReadStream(file.path)
@@ -73,7 +64,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
pushWhisperUsage({
teamId,
tmbId,
duration
duration: result?.usage?.total_tokens || duration
});
jsonRes(res, {

View File

@@ -93,14 +93,6 @@ type AuthResponseType = {
};
async function handler(req: NextApiRequest, res: NextApiResponse) {
res.on('close', () => {
res.end();
});
res.on('error', () => {
console.log('error: ', 'request error');
res.end();
});
let {
chatId,
appId,
@@ -266,42 +258,43 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
});
/* start flow controller */
const { flowResponses, flowUsages, assistantResponses, newVariables } = await (async () => {
if (app.version === 'v2') {
return dispatchWorkFlow({
res,
requestOrigin: req.headers.origin,
mode: 'chat',
timezone,
externalProvider,
const { flowResponses, flowUsages, assistantResponses, newVariables, durationSeconds } =
await (async () => {
if (app.version === 'v2') {
return dispatchWorkFlow({
res,
requestOrigin: req.headers.origin,
mode: 'chat',
timezone,
externalProvider,
runningAppInfo: {
id: String(app._id),
teamId: String(app.teamId),
tmbId: String(app.tmbId)
},
runningUserInfo: {
teamId,
tmbId
},
uid: String(outLinkUserId || tmbId),
runningAppInfo: {
id: String(app._id),
teamId: String(app.teamId),
tmbId: String(app.tmbId)
},
runningUserInfo: {
teamId,
tmbId
},
uid: String(outLinkUserId || tmbId),
chatId,
responseChatItemId,
runtimeNodes,
runtimeEdges: storeEdges2RuntimeEdges(edges, interactive),
variables,
query: removeEmptyUserInput(userQuestion.value),
lastInteractive: interactive,
chatConfig,
histories: newHistories,
stream,
maxRunTimes: WORKFLOW_MAX_RUN_TIMES,
workflowStreamResponse: workflowResponseWrite
});
}
return Promise.reject('您的工作流版本过低,请重新发布一次');
})();
chatId,
responseChatItemId,
runtimeNodes,
runtimeEdges: storeEdges2RuntimeEdges(edges, interactive),
variables,
query: removeEmptyUserInput(userQuestion.value),
lastInteractive: interactive,
chatConfig,
histories: newHistories,
stream,
maxRunTimes: WORKFLOW_MAX_RUN_TIMES,
workflowStreamResponse: workflowResponseWrite
});
}
return Promise.reject('您的工作流版本过低,请重新发布一次');
})();
// save chat
const isOwnerUse = !shareId && !spaceTeamId && String(tmbId) === String(app.tmbId);
@@ -339,7 +332,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
appId: app._id,
userInteractiveVal,
aiResponse,
newVariables
newVariables,
durationSeconds
});
} else {
await saveChat({
@@ -360,7 +354,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
metadata: {
originIp,
...metadata
}
},
durationSeconds
});
}

View File

@@ -93,14 +93,6 @@ type AuthResponseType = {
};
async function handler(req: NextApiRequest, res: NextApiResponse) {
res.on('close', () => {
res.end();
});
res.on('error', () => {
console.log('error: ', 'request error');
res.end();
});
let {
chatId,
appId,
@@ -265,44 +257,46 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
});
/* start flow controller */
const { flowResponses, flowUsages, assistantResponses, newVariables } = await (async () => {
if (app.version === 'v2') {
return dispatchWorkFlow({
res,
requestOrigin: req.headers.origin,
mode: 'chat',
timezone,
externalProvider,
const { flowResponses, flowUsages, assistantResponses, newVariables, durationSeconds } =
await (async () => {
if (app.version === 'v2') {
return dispatchWorkFlow({
res,
requestOrigin: req.headers.origin,
mode: 'chat',
timezone,
externalProvider,
runningAppInfo: {
id: String(app._id),
teamId: String(app.teamId),
tmbId: String(app.tmbId)
},
runningUserInfo: {
teamId,
tmbId
},
uid: String(outLinkUserId || tmbId),
runningAppInfo: {
id: String(app._id),
teamId: String(app.teamId),
tmbId: String(app.tmbId)
},
runningUserInfo: {
teamId,
tmbId
},
uid: String(outLinkUserId || tmbId),
chatId,
responseChatItemId,
runtimeNodes,
runtimeEdges: storeEdges2RuntimeEdges(edges, interactive),
variables,
query: removeEmptyUserInput(userQuestion.value),
lastInteractive: interactive,
chatConfig,
histories: newHistories,
stream,
maxRunTimes: WORKFLOW_MAX_RUN_TIMES,
workflowStreamResponse: workflowResponseWrite,
version: 'v2',
responseDetail
});
}
return Promise.reject('您的工作流版本过低,请重新发布一次');
})();
chatId,
responseChatItemId,
runtimeNodes,
runtimeEdges: storeEdges2RuntimeEdges(edges, interactive),
variables,
query: removeEmptyUserInput(userQuestion.value),
lastInteractive: interactive,
chatConfig,
histories: newHistories,
stream,
maxRunTimes: WORKFLOW_MAX_RUN_TIMES,
workflowStreamResponse: workflowResponseWrite,
version: 'v2',
responseAllData,
responseDetail
});
}
return Promise.reject('您的工作流版本过低,请重新发布一次');
})();
// save chat
const isOwnerUse = !shareId && !spaceTeamId && String(tmbId) === String(app.tmbId);
@@ -340,7 +334,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
appId: app._id,
userInteractiveVal,
aiResponse,
newVariables
newVariables,
durationSeconds
});
} else {
await saveChat({
@@ -361,7 +356,8 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
metadata: {
originIp,
...metadata
}
},
durationSeconds
});
}