sub plan page (#885)

* perf: insert mongo dataset data session

* perf: dataset data index

* remove delay

* rename bill schema

* rename bill record

* perf: bill table

* perf: prompt

* perf: sub plan

* change the usage count

* feat: usage bill

* publish usages

* doc

* 新增团队聊天功能 (#20)

* perf: doc

* feat 添加标签部分

feat 信息团队标签配置

feat 新增团队同步管理

feat team分享页面

feat 完成team分享页面

feat 实现模糊搜索

style 格式化

fix 修复迷糊匹配

style 样式修改

fix 团队标签功能修复

* fix 修复鉴权功能

* merge 合并代码

* fix 修复引用错误

* fix 修复pr问题

* fix 修复ts格式问题

---------

Co-authored-by: archer <545436317@qq.com>
Co-authored-by: liuxingwan <liuxingwan.lxw@alibaba-inc.com>

* update extra plan

* fix: ts

* format

* perf: bill field

* feat: standard plan

* fix: ts

* feat 个人账号页面修改 (#22)

* feat 添加标签部分

feat 信息团队标签配置

feat 新增团队同步管理

feat team分享页面

feat 完成team分享页面

feat 实现模糊搜索

style 格式化

fix 修复迷糊匹配

style 样式修改

fix 团队标签功能修复

* fix 修复鉴权功能

* merge 合并代码

* fix 修复引用错误

* fix 修复pr问题

* fix 修复ts格式问题

* feat 修改个人账号页

---------

Co-authored-by: liuxingwan <liuxingwan.lxw@alibaba-inc.com>

* fix chunk index; error page text

* feat: dataset process Integral prediction

* feat: stand plan field

* feat: sub plan limit

* perf: index

* query extension

* perf: share link push app name

* perf: plan point unit

* perf: get sub plan

* perf: account page

---------

Co-authored-by: yst <77910600+yu-and-liu@users.noreply.github.com>
Co-authored-by: liuxingwan <liuxingwan.lxw@alibaba-inc.com>
This commit is contained in:
Archer
2024-02-23 17:47:34 +08:00
committed by GitHub
parent 7a87f13aa8
commit 443ad37b6a
246 changed files with 6277 additions and 4272 deletions

View File

@@ -0,0 +1,99 @@
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 { PgClient } from '@fastgpt/service/common/vectorStore/pg';
import { PgDatasetTableName } from '@fastgpt/global/common/vectorStore/constants';
import { MongoImage } from '@fastgpt/service/common/file/image/schema';
import { MongoImageSchemaType } from '@fastgpt/global/common/file/image/type';
import { delay } from '@fastgpt/global/common/system/utils';
import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection/schema';
import { getNanoid } from '@fastgpt/global/common/string/tools';
import { MongoApp } from '@fastgpt/service/core/app/schema';
import { ModuleItemType } from '@fastgpt/global/core/module/type';
import { DYNAMIC_INPUT_KEY, ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
let success = 0;
let deleteImg = 0;
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
// 设置所有app为 inited = false
const result = await MongoApp.updateMany({}, { $set: { inited: false } });
console.log(result);
await initApp();
jsonRes(res, {
message: 'success'
});
} catch (error) {
console.log(error);
jsonRes(res, {
code: 500,
error
});
}
}
const systemKeys: string[] = [
ModuleInputKeyEnum.switch,
ModuleInputKeyEnum.httpMethod,
ModuleInputKeyEnum.httpReqUrl,
ModuleInputKeyEnum.httpHeaders,
DYNAMIC_INPUT_KEY,
ModuleInputKeyEnum.addInputParam
];
const initApp = async (): Promise<any> => {
const app = await MongoApp.findOne({ inited: false }).sort({ updateTime: -1 });
if (!app) {
return;
}
try {
const modules = JSON.parse(JSON.stringify(app.modules)) as ModuleItemType[];
let update = false;
// 找到http模块
modules.forEach((module) => {
if (module.flowType === 'httpRequest') {
const method = module.inputs.find((input) => input.key === ModuleInputKeyEnum.httpMethod);
if (method?.value === 'POST') {
module.inputs.forEach((input) => {
// 更新非系统字段的key
if (!systemKeys.includes(input.key)) {
// 更新output的target
modules.forEach((item) => {
item.outputs.forEach((output) => {
output.targets.forEach((target) => {
if (target.moduleId === module.moduleId && target.key === input.key) {
target.key = `data.${input.key}`;
}
});
});
});
// 更新key
input.key = `data.${input.key}`;
update = true;
}
});
}
}
});
if (update) {
console.log('update http app');
app.modules = modules;
}
app.inited = true;
await app.save();
console.log(++success);
return initApp();
} catch (error) {
console.log(error);
await delay(1000);
return initApp();
}
};

View File

@@ -0,0 +1,35 @@
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 { MongoUsage } from '@fastgpt/service/support/wallet/usage/schema';
import { connectionMongo } from '@fastgpt/service/common/mongo';
/* pg 中的数据搬到 mongo dataset.datas 中,并做映射 */
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
await connectToDatabase();
await authCert({ req, authRoot: true });
// 检查 usage 是否有记录
const totalUsages = await MongoUsage.countDocuments();
if (totalUsages === 0) {
// 重命名 bills 集合成 usages
await connectionMongo.connection.db.renameCollection('bills', 'usages', {
// 强制
dropTarget: true
});
}
jsonRes(res, {
message: 'success'
});
} catch (error) {
console.log(error);
jsonRes(res, {
code: 500,
error
});
}
}

View File

@@ -16,7 +16,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
let filePaths: string[] = [];
try {
const { userId, teamId, tmbId } = await authCert({ req, authToken: true });
const { teamId, tmbId } = await authCert({ req, authToken: true });
const { file, bucketName, metadata } = await upload.doUpload(req, res);

View File

@@ -2,7 +2,7 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { connectToDatabase } from '@/service/mongo';
import type { CreateQuestionGuideParams } from '@/global/core/ai/api.d';
import { pushQuestionGuideBill } from '@/service/support/wallet/bill/push';
import { pushQuestionGuideUsage } from '@/service/support/wallet/usage/push';
import { createQuestionGuide } from '@fastgpt/service/core/ai/functions/createQuestionGuide';
import { authCertOrShareId } from '@fastgpt/service/support/permission/auth/common';
@@ -19,7 +19,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
const qgModel = global.llmModels[0];
const { result, inputTokens, outputTokens } = await createQuestionGuide({
const { result, charsLength } = await createQuestionGuide({
messages,
model: qgModel.model
});
@@ -28,9 +28,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
data: result
});
pushQuestionGuideBill({
inputTokens,
outputTokens,
pushQuestionGuideUsage({
charsLength,
teamId,
tmbId
});

View File

@@ -6,6 +6,7 @@ import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
import { MongoApp } from '@fastgpt/service/core/app/schema';
import { authUserNotVisitor } from '@fastgpt/service/support/permission/auth/user';
import { SimpleModeTemplate_FastGPT_Universal } from '@/global/core/app/constants';
import { checkTeamAppLimit } from '@/service/support/permission/teamLimit';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -25,12 +26,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
const { teamId, tmbId } = await authUserNotVisitor({ req, authToken: true });
// 上限校验
const authCount = await MongoApp.countDocuments({
teamId
});
if (authCount >= 50) {
throw new Error('每个团队上限 50 个应用');
}
await checkTeamAppLimit(teamId);
// 创建模型
const response = await MongoApp.create({

View File

@@ -1,51 +0,0 @@
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 { Types } from '@fastgpt/service/common/mongo';
import { MongoBill } from '@fastgpt/service/support/wallet/bill/schema';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
await connectToDatabase();
const { appId, start, end } = req.body as { appId: string; start: number; end: number };
const { userId } = await authCert({ req, authToken: true });
const result = await MongoBill.aggregate([
{
$match: {
appId: new Types.ObjectId(appId),
userId: new Types.ObjectId(userId),
time: { $gte: new Date(start) }
}
},
{
$group: {
_id: {
year: { $year: '$time' },
month: { $month: '$time' },
day: { $dayOfMonth: '$time' }
},
total: { $sum: '$total' }
}
},
{
$project: {
_id: 0,
date: { $dateFromParts: { year: '$_id.year', month: '$_id.month', day: '$_id.day' } },
total: 1
}
},
{ $sort: { date: 1 } }
]);
jsonRes(res, {
data: result
});
} catch (err) {
jsonRes(res, {
code: 500,
error: err
});
}
}

View File

@@ -92,7 +92,7 @@ function simpleChatTemplate({ formData, maxToken }: Props): ModuleItemType[] {
},
{
key: 'model',
type: 'selectChatModel',
type: 'selectLLMModel',
label: 'core.module.input.label.aiModel',
required: true,
valueType: 'string',
@@ -471,7 +471,7 @@ function datasetTemplate({ formData, maxToken }: Props): ModuleItemType[] {
},
{
key: 'model',
type: 'selectChatModel',
type: 'selectLLMModel',
label: 'core.module.input.label.aiModel',
required: true,
valueType: 'string',

View File

@@ -88,7 +88,7 @@ function simpleChatTemplate(formData: AppSimpleEditFormType): ModuleItemType[] {
},
{
key: 'model',
type: 'selectChatModel',
type: 'selectLLMModel',
label: 'core.module.input.label.aiModel',
required: true,
valueType: 'string',
@@ -498,7 +498,7 @@ function datasetTemplate(formData: AppSimpleEditFormType): ModuleItemType[] {
},
{
key: 'model',
type: 'selectChatModel',
type: 'selectLLMModel',
label: 'core.module.input.label.aiModel',
required: true,
valueType: 'string',

View File

@@ -12,7 +12,7 @@ import { getLLMModel } from '@/service/core/ai/model';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
await connectToDatabase();
const { name, avatar, type, simpleTemplateId, intro, modules, permission } =
const { name, avatar, type, simpleTemplateId, intro, modules, permission, teamTags } =
req.body as AppUpdateParams;
const { appId } = req.query as { appId: string };
@@ -65,6 +65,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
avatar,
intro,
permission,
teamTags: teamTags,
...(modules && {
modules
})

View File

@@ -0,0 +1,82 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { connectToDatabase } from '@/service/mongo';
import { MongoApp } from '@fastgpt/service/core/app/schema';
import type { AppUpdateParams } from '@fastgpt/global/core/app/api';
import { authApp } from '@fastgpt/service/support/permission/auth/app';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/module/node/constant';
import { ModuleInputKeyEnum } from '@fastgpt/global/core/module/constants';
import { getLLMModel } from '@/service/core/ai/model';
/* 获取我的模型 */
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
await connectToDatabase();
const { name, avatar, type, simpleTemplateId, intro, modules, permission, teamTags } =
req.body as AppUpdateParams;
const { appId } = req.query as { appId: string };
if (!appId) {
throw new Error('appId is empty');
}
// 凭证校验
await authApp({ req, authToken: true, appId, per: permission ? 'owner' : 'w' });
// check modules
// 1. dataset search limit, less than model quoteMaxToken
if (modules) {
let maxTokens = 3000;
modules.forEach((item) => {
if (item.flowType === FlowNodeTypeEnum.chatNode) {
const model =
item.inputs.find((item) => item.key === ModuleInputKeyEnum.aiModel)?.value || '';
const chatModel = getLLMModel(model);
const quoteMaxToken = chatModel.quoteMaxToken || 3000;
maxTokens = Math.max(maxTokens, quoteMaxToken);
}
});
modules.forEach((item) => {
if (item.flowType === FlowNodeTypeEnum.datasetSearchNode) {
item.inputs.forEach((input) => {
if (input.key === ModuleInputKeyEnum.datasetMaxTokens) {
const val = input.value as number;
if (val > maxTokens) {
input.value = maxTokens;
}
}
});
}
});
}
// 更新模型
await MongoApp.findOneAndUpdate(
{
_id: appId
},
{
name,
type,
simpleTemplateId,
avatar,
intro,
permission,
teamTags: teamTags,
...(modules && {
modules
})
}
);
jsonRes(res);
} catch (err) {
jsonRes(res, {
code: 500,
error: err
});
}
}

View File

@@ -4,13 +4,13 @@ import { sseErrRes } from '@fastgpt/service/common/response';
import { sseResponseEventEnum } from '@fastgpt/service/common/response/constant';
import { responseWrite } from '@fastgpt/service/common/response';
import type { ModuleItemType } from '@fastgpt/global/core/module/type.d';
import { pushChatBill } from '@/service/support/wallet/bill/push';
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
import { pushChatUsage } from '@/service/support/wallet/usage/push';
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
import type { ChatItemType } from '@fastgpt/global/core/chat/type';
import { authApp } from '@fastgpt/service/support/permission/auth/app';
import { dispatchModules } from '@/service/moduleDispatch';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { getUserAndAuthBalance } from '@fastgpt/service/support/user/controller';
import { getUserChatInfoAndAuthTeamPoints } from '@/service/support/permission/auth/team';
export type Props = {
history: ChatItemType[];
@@ -50,13 +50,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
]);
// auth balance
const user = await getUserAndAuthBalance({
tmbId,
minBalance: 0
});
const { user } = await getUserChatInfoAndAuthTeamPoints(tmbId);
/* start process */
const { responseData } = await dispatchModules({
const { responseData, moduleDispatchBills } = await dispatchModules({
res,
mode: 'test',
teamId,
@@ -85,13 +82,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
res.end();
pushChatBill({
pushChatUsage({
appName,
appId,
teamId,
tmbId,
source: BillSourceEnum.fastgpt,
response: responseData
source: UsageSourceEnum.fastgpt,
moduleDispatchBills
});
} catch (err: any) {
res.status(500);

View File

@@ -14,10 +14,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
await connectToDatabase();
const { appId, shareId, outLinkUid } = req.query as ClearHistoriesProps;
let chatAppId = appId;
const match = await (async () => {
if (shareId && outLinkUid) {
const { uid } = await authOutLink({ shareId, outLinkUid });
const { appId, uid } = await authOutLink({ shareId, outLinkUid });
chatAppId = appId;
return {
shareId,
outLinkUid: uid
@@ -41,11 +44,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const idList = list.map((item) => item.chatId);
await MongoChatItem.deleteMany({
appId,
appId: chatAppId,
chatId: { $in: idList }
});
await MongoChat.deleteMany({
appId,
appId: chatAppId,
chatId: { $in: idList }
});

View File

@@ -28,6 +28,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
};
}
if (appId && outLinkUid) {
return {
shareId,
outLinkUid: outLinkUid,
source: ChatSourceEnum.team
};
}
if (appId) {
const { tmbId } = await authCert({ req, authToken: true });
return {
@@ -36,6 +43,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
source: ChatSourceEnum.online
};
}
return Promise.reject('Params are error');
})();

View File

@@ -3,9 +3,9 @@ import { jsonRes } from '@fastgpt/service/common/response';
import { connectToDatabase } from '@/service/mongo';
import { GetChatSpeechProps } from '@/global/core/chat/api.d';
import { text2Speech } from '@fastgpt/service/core/ai/audio/speech';
import { pushAudioSpeechBill } from '@/service/support/wallet/bill/push';
import { pushAudioSpeechUsage } from '@/service/support/wallet/usage/push';
import { authCertOrShareId } from '@fastgpt/service/support/permission/auth/common';
import { authType2BillSource } from '@/service/support/wallet/bill/utils';
import { authType2UsageSource } from '@/service/support/wallet/usage/utils';
import { getAudioSpeechModel } from '@/service/core/ai/model';
import { MongoTTSBuffer } from '@fastgpt/service/common/buffer/tts/schema';
@@ -54,12 +54,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
speed: ttsConfig.speed,
onSuccess: async ({ model, buffer }) => {
try {
pushAudioSpeechBill({
pushAudioSpeechUsage({
model: model,
charsLength: input.length,
tmbId,
teamId,
source: authType2BillSource({ authType })
source: authType2UsageSource({ authType })
});
await MongoTTSBuffer.create({

View File

@@ -0,0 +1,37 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { connectToDatabase } from '@/service/mongo';
import type { chatByTeamProps } from '@/global/core/chat/api.d';
import axios from 'axios';
import { MongoChatItem } from '@fastgpt/service/core/chat/chatItemSchema';
import { getChatItems } from '@fastgpt/service/core/chat/controller';
import { selectShareResponse } from '@/utils/service/core/chat';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
await connectToDatabase();
let { teamId, appId, outLinkUid } = req.query as chatByTeamProps;
const history = await MongoChatItem.find({
appId: appId,
outLinkUid: outLinkUid,
teamId: teamId
});
jsonRes(res, {
data: history
});
} catch (err) {
jsonRes(res, {
code: 500,
data: req.query,
error: err
});
}
}
export const config = {
api: {
responseLimit: '10mb'
}
};

View File

@@ -0,0 +1,91 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { connectToDatabase } from '@/service/mongo';
import { getGuideModule } from '@fastgpt/global/core/module/utils';
import { getChatModelNameListByModules } from '@/service/core/app/module';
import { ModuleOutputKeyEnum } from '@fastgpt/global/core/module/constants';
import type { InitChatProps, InitChatResponse } from '@/global/core/chat/api.d';
import { MongoChat } from '@fastgpt/service/core/chat/chatSchema';
import { MongoApp } from '@fastgpt/service/core/app/schema';
import { getChatItems } from '@fastgpt/service/core/chat/controller';
import { AppErrEnum } from '@fastgpt/global/common/error/code/app';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
await connectToDatabase();
let { appId, chatId, outLinkUid } = req.query as {
chatId?: string;
appId?: string;
outLinkUid?: string;
};
if (!appId) {
return jsonRes(res, {
code: 501,
message: "You don't have an app yet"
});
}
// auth app permission
const [chat, app] = await Promise.all([
// authApp({
// req,
// authToken: false,
// appId,
// per: 'r'
// }),
chatId ? MongoChat.findOne({ appId, chatId }) : undefined,
MongoApp.findById(appId).lean()
]);
if (!app) {
throw new Error(AppErrEnum.unExist);
}
// auth chat permission
// if (chat && chat.outLinkUid !== outLinkUid) {
// throw new Error(ChatErrEnum.unAuthChat);
// }
// // auth chat permission
// if (chat && !app.canWrite && String(tmbId) !== String(chat?.tmbId)) {
// throw new Error(ChatErrEnum.unAuthChat);
// }
// get app and history
const { history } = await getChatItems({
appId,
chatId,
limit: 30,
field: `dataId obj value adminFeedback userBadFeedback userGoodFeedback ${ModuleOutputKeyEnum.responseData}`
});
jsonRes<InitChatResponse>(res, {
data: {
chatId,
appId,
title: chat?.title || '新对话',
userAvatar: undefined,
variables: chat?.variables || {},
history,
app: {
userGuideModule: getGuideModule(app.modules),
chatModels: getChatModelNameListByModules(app.modules),
name: app.name,
avatar: app.avatar,
intro: app.intro
}
}
});
} catch (err) {
jsonRes(res, {
code: 500,
error: err
});
}
}
export const config = {
api: {
responseLimit: '10mb'
}
};

View File

@@ -0,0 +1,81 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { connectToDatabase } from '@/service/mongo';
import { authApp } from '@fastgpt/service/support/permission/auth/app';
import { getGuideModule } from '@fastgpt/global/core/module/utils';
import { getChatModelNameListByModules } from '@/service/core/app/module';
import { ModuleOutputKeyEnum } from '@fastgpt/global/core/module/constants';
import type { InitChatProps, InitChatResponse } from '@/global/core/chat/api.d';
import { MongoChat } from '@fastgpt/service/core/chat/chatSchema';
import { getChatItems } from '@fastgpt/service/core/chat/controller';
import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
await connectToDatabase();
let { appId, chatId, loadCustomFeedbacks } = req.query as InitChatProps;
if (!appId) {
return jsonRes(res, {
code: 501,
message: "You don't have an app yet"
});
}
// auth app permission
const [{ app, tmbId }, chat] = await Promise.all([
authApp({
req,
authToken: true,
appId,
per: 'r'
}),
chatId ? MongoChat.findOne({ appId, chatId }) : undefined
]);
// // auth chat permission
// if (chat && !app.canWrite && String(tmbId) !== String(chat?.tmbId)) {
// throw new Error(ChatErrEnum.unAuthChat);
// }
// get app and history
const { history } = await getChatItems({
appId,
chatId,
limit: 30,
field: `dataId obj value adminFeedback userBadFeedback userGoodFeedback ${
ModuleOutputKeyEnum.responseData
} ${loadCustomFeedbacks ? 'customFeedbacks' : ''}`
});
jsonRes<InitChatResponse>(res, {
data: {
chatId,
appId,
title: chat?.title || '新对话',
userAvatar: undefined,
variables: chat?.variables || {},
history,
app: {
userGuideModule: getGuideModule(app.modules),
chatModels: getChatModelNameListByModules(app.modules),
name: app.name,
avatar: app.avatar,
intro: app.intro
}
}
});
} catch (err) {
jsonRes(res, {
code: 500,
error: err
});
}
}
export const config = {
api: {
responseLimit: '10mb'
}
};

View File

@@ -24,6 +24,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
await MongoChat.findOneAndUpdate(
{ appId, chatId },
{
updateTime: new Date(),
...(customTitle !== undefined && { customTitle }),
...(top !== undefined && { top })
}

View File

@@ -11,13 +11,12 @@ import {
TrainingModeEnum,
DatasetCollectionTypeEnum
} from '@fastgpt/global/core/dataset/constants';
import { checkDatasetLimit } from '@fastgpt/service/support/permission/limit/dataset';
import { checkDatasetLimit } from '@/service/support/permission/teamLimit';
import { predictDataLimitLength } from '@fastgpt/global/core/dataset/utils';
import { createTrainingBill } from '@fastgpt/service/support/wallet/bill/controller';
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
import { createTrainingUsage } from '@fastgpt/service/support/wallet/usage/controller';
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
import { getLLMModel, getVectorModel } from '@/service/core/ai/model';
import { reloadCollectionChunks } from '@fastgpt/service/core/dataset/collection/utils';
import { getStandardSubPlan } from '@/service/support/wallet/sub/utils';
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
@@ -43,8 +42,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
// 1. check dataset limit
await checkDatasetLimit({
teamId,
insertLen: predictDataLimitLength(trainingType, new Array(10)),
standardPlans: getStandardSubPlan()
insertLen: predictDataLimitLength(trainingType, new Array(10))
});
const { _id: collectionId } = await mongoSessionRun(async (session) => {
@@ -66,11 +64,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
});
// 3. create bill and start sync
const { billId } = await createTrainingBill({
const { billId } = await createTrainingUsage({
teamId,
tmbId,
appName: 'core.dataset.collection.Sync Collection',
billSource: BillSourceEnum.training,
billSource: UsageSourceEnum.training,
vectorModel: getVectorModel(dataset.vectorModel).name,
agentModel: getLLMModel(dataset.agentModel).name,
session

View File

@@ -12,14 +12,13 @@ import {
DatasetCollectionTypeEnum
} from '@fastgpt/global/core/dataset/constants';
import { splitText2Chunks } from '@fastgpt/global/common/string/textSplitter';
import { checkDatasetLimit } from '@fastgpt/service/support/permission/limit/dataset';
import { checkDatasetLimit } from '@/service/support/permission/teamLimit';
import { predictDataLimitLength } from '@fastgpt/global/core/dataset/utils';
import { pushDataToTrainingQueue } from '@/service/core/dataset/data/controller';
import { hashStr } from '@fastgpt/global/common/string/tools';
import { createTrainingBill } from '@fastgpt/service/support/wallet/bill/controller';
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
import { createTrainingUsage } from '@fastgpt/service/support/wallet/usage/controller';
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
import { getLLMModel, getVectorModel } from '@/service/core/ai/model';
import { getStandardSubPlan } from '@/service/support/wallet/sub/utils';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -53,8 +52,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
// 2. check dataset limit
await checkDatasetLimit({
teamId,
insertLen: predictDataLimitLength(trainingType, chunks),
standardPlans: getStandardSubPlan()
insertLen: predictDataLimitLength(trainingType, chunks)
});
// 3. create collection and training bill
@@ -74,11 +72,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
hashRawText: hashStr(text),
rawTextLength: text.length
}),
createTrainingBill({
createTrainingUsage({
teamId,
tmbId,
appName: name,
billSource: BillSourceEnum.training,
billSource: UsageSourceEnum.training,
vectorModel: getVectorModel(dataset.vectorModel)?.name,
agentModel: getLLMModel(dataset.agentModel)?.name
})

View File

@@ -12,8 +12,8 @@ import {
DatasetCollectionTypeEnum
} from '@fastgpt/global/core/dataset/constants';
import { DatasetErrEnum } from '@fastgpt/global/common/error/code/dataset';
import { createTrainingBill } from '@fastgpt/service/support/wallet/bill/controller';
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
import { createTrainingUsage } from '@fastgpt/service/support/wallet/usage/controller';
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
import { getLLMModel, getVectorModel } from '@/service/core/ai/model';
import { createOneCollection } from '@fastgpt/service/core/dataset/collection/controller';
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
@@ -56,11 +56,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
await mongoSessionRun(async (session) => {
// create training bill
const { billId } = await createTrainingBill({
const { billId } = await createTrainingUsage({
teamId: collection.teamId,
tmbId,
appName: 'core.dataset.collection.Sync Collection',
billSource: BillSourceEnum.training,
billSource: UsageSourceEnum.training,
vectorModel: vectorModelData.name,
agentModel: agentModelData.name,
session

View File

@@ -7,6 +7,7 @@ import { createDefaultCollection } from '@fastgpt/service/core/dataset/collectio
import { authUserNotVisitor } from '@fastgpt/service/support/permission/auth/user';
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
import { getLLMModel, getVectorModel, getDatasetModel } from '@/service/core/ai/model';
import { checkTeamDatasetLimit } from '@/service/support/permission/teamLimit';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -31,13 +32,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
}
// check limit
const authCount = await MongoDataset.countDocuments({
teamId,
type: DatasetTypeEnum.dataset
});
if (authCount >= 50) {
throw new Error('每个团队上限 50 个知识库');
}
await checkTeamDatasetLimit(teamId);
const { _id } = await MongoDataset.create({
name,

View File

@@ -3,8 +3,7 @@ import { jsonRes } from '@fastgpt/service/common/response';
import { withNextCors } from '@fastgpt/service/common/middle/cors';
import { connectToDatabase } from '@/service/mongo';
import { authDatasetData } from '@/service/support/permission/auth/dataset';
import { MongoDatasetData } from '@fastgpt/service/core/dataset/data/schema';
import { deleteDatasetDataVector } from '@fastgpt/service/common/vectorStore/controller';
import { deleteDatasetData } from '@/service/core/dataset/data/controller';
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -26,19 +25,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
per: 'w'
});
// update mongo data update time
await MongoDatasetData.findByIdAndUpdate(dataId, {
updateTime: new Date()
});
// delete vector data
await deleteDatasetDataVector({
teamId,
idList: datasetData.indexes.map((item) => item.dataId)
});
// delete mongo data
await MongoDatasetData.findByIdAndDelete(dataId);
await deleteDatasetData(datasetData);
jsonRes(res, {
data: 'success'

View File

@@ -12,12 +12,10 @@ import { hasSameValue } from '@/service/core/dataset/data/utils';
import { insertData2Dataset } from '@/service/core/dataset/data/controller';
import { authDatasetCollection } from '@fastgpt/service/support/permission/auth/dataset';
import { getCollectionWithDataset } from '@fastgpt/service/core/dataset/controller';
import { authTeamBalance } from '@/service/support/permission/auth/bill';
import { pushGenerateVectorBill } from '@/service/support/wallet/bill/push';
import { pushGenerateVectorUsage } from '@/service/support/wallet/usage/push';
import { InsertOneDatasetDataProps } from '@/global/core/dataset/api';
import { simpleText } from '@fastgpt/global/common/string/tools';
import { checkDatasetLimit } from '@fastgpt/service/support/permission/limit/dataset';
import { getStandardSubPlan } from '@/service/support/wallet/sub/utils';
import { checkDatasetLimit } from '@/service/support/permission/teamLimit';
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -43,8 +41,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
await checkDatasetLimit({
teamId,
insertLen: 1,
standardPlans: getStandardSubPlan()
insertLen: 1
});
// auth collection and get dataset
@@ -52,7 +49,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
{
datasetId: { _id: datasetId, vectorModel }
}
] = await Promise.all([getCollectionWithDataset(collectionId), authTeamBalance(teamId)]);
] = await Promise.all([getCollectionWithDataset(collectionId)]);
// format data
const formatQ = simpleText(q);
@@ -90,7 +87,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
indexes: formatIndexes
});
pushGenerateVectorBill({
pushGenerateVectorUsage({
teamId,
tmbId,
charsLength,

View File

@@ -8,10 +8,9 @@ import type {
PushDatasetDataResponse
} from '@fastgpt/global/core/dataset/api.d';
import { authDatasetCollection } from '@fastgpt/service/support/permission/auth/dataset';
import { checkDatasetLimit } from '@fastgpt/service/support/permission/limit/dataset';
import { checkDatasetLimit } from '@/service/support/permission/teamLimit';
import { predictDataLimitLength } from '@fastgpt/global/core/dataset/utils';
import { pushDataToTrainingQueue } from '@/service/core/dataset/data/controller';
import { getStandardSubPlan } from '@/service/support/wallet/sub/utils';
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -38,8 +37,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
// auth dataset limit
await checkDatasetLimit({
teamId,
insertLen: predictDataLimitLength(collection.trainingType, data),
standardPlans: getStandardSubPlan()
insertLen: predictDataLimitLength(collection.trainingType, data)
});
jsonRes<PushDatasetDataResponse>(res, {

View File

@@ -4,9 +4,9 @@ import { withNextCors } from '@fastgpt/service/common/middle/cors';
import { connectToDatabase } from '@/service/mongo';
import { updateData2Dataset } from '@/service/core/dataset/data/controller';
import { authDatasetData } from '@/service/support/permission/auth/dataset';
import { authTeamBalance } from '@/service/support/permission/auth/bill';
import { pushGenerateVectorBill } from '@/service/support/wallet/bill/push';
import { pushGenerateVectorUsage } from '@/service/support/wallet/usage/push';
import { UpdateDatasetDataProps } from '@/global/core/dataset/api';
import { checkDatasetLimit } from '@/service/support/permission/teamLimit';
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -29,7 +29,10 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
});
// auth team balance
await authTeamBalance(teamId);
await checkDatasetLimit({
teamId,
insertLen: 1
});
const { charsLength } = await updateData2Dataset({
dataId: id,
@@ -39,7 +42,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
model: vectorModel
});
pushGenerateVectorBill({
pushGenerateVectorUsage({
teamId,
tmbId,
charsLength,

View File

@@ -4,14 +4,16 @@ import { withNextCors } from '@fastgpt/service/common/middle/cors';
import type { SearchTestProps, SearchTestResponse } from '@/global/core/dataset/api.d';
import { connectToDatabase } from '@/service/mongo';
import { authDataset } from '@fastgpt/service/support/permission/auth/dataset';
import { authTeamBalance } from '@/service/support/permission/auth/bill';
import { pushGenerateVectorBill } from '@/service/support/wallet/bill/push';
import { pushGenerateVectorUsage } from '@/service/support/wallet/usage/push';
import { searchDatasetData } from '@/service/core/dataset/data/controller';
import { updateApiKeyUsage } from '@fastgpt/service/support/openapi/tools';
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
import { getLLMModel } from '@/service/core/ai/model';
import { queryExtension } from '@fastgpt/service/core/ai/functions/queryExtension';
import { datasetSearchQueryExtension } from '@fastgpt/service/core/dataset/search/utils';
import {
checkTeamAIPoints,
checkTeamReRankPermission
} from '@/service/support/permission/teamLimit';
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -43,7 +45,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
per: 'r'
});
// auth balance
await authTeamBalance(teamId);
await checkTeamAIPoints(teamId);
// query extension
const extensionModel =
@@ -65,28 +67,27 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
similarity,
datasetIds: [datasetId],
searchMode,
usingReRank
usingReRank: usingReRank && (await checkTeamReRankPermission(teamId))
});
// push bill
const { total } = pushGenerateVectorBill({
const { totalPoints } = pushGenerateVectorUsage({
teamId,
tmbId,
charsLength,
model: dataset.vectorModel,
source: apikey ? BillSourceEnum.api : BillSourceEnum.fastgpt,
source: apikey ? UsageSourceEnum.api : UsageSourceEnum.fastgpt,
...(aiExtensionResult &&
extensionModel && {
extensionModel: extensionModel.name,
extensionInputTokens: aiExtensionResult.inputTokens,
extensionOutputTokens: aiExtensionResult.outputTokens
extensionCharsLength: aiExtensionResult.charsLength
})
});
if (apikey) {
updateApiKeyUsage({
apikey,
usage: total
totalPoints: totalPoints
});
}

View File

@@ -4,6 +4,7 @@ import { connectToDatabase } from '@/service/mongo';
import type { CreateOnePluginParams } from '@fastgpt/global/core/plugin/controller';
import { authUserNotVisitor } from '@fastgpt/service/support/permission/auth/user';
import { MongoPlugin } from '@fastgpt/service/core/plugin/schema';
import { checkTeamPluginLimit } from '@/service/support/permission/teamLimit';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -11,6 +12,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
const { teamId, tmbId } = await authUserNotVisitor({ req, authToken: true });
const body = req.body as CreateOnePluginParams;
await checkTeamPluginLimit(teamId);
const { _id } = await MongoPlugin.create({
...body,
teamId,

View File

@@ -34,7 +34,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
});
const textResult = replaceVariable(text, obj);
res.json({
text: textResult
});

View File

@@ -5,6 +5,7 @@ import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { UserUpdateParams } from '@/types/user';
import { getAIApi, openaiBaseUrl } from '@fastgpt/service/core/ai/config';
import { connectToDatabase } from '@/service/mongo';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
/* update user info */
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
@@ -12,8 +13,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
await connectToDatabase();
const { avatar, timezone, openaiAccount } = req.body as UserUpdateParams;
const { userId } = await authCert({ req, authToken: true });
const { tmbId } = await authCert({ req, authToken: true });
const tmb = await MongoTeamMember.findById(tmbId);
if (!tmb) {
throw new Error('can not find it');
}
const userId = tmb.userId;
// auth key
if (openaiAccount?.key) {
console.log('auth user openai key', openaiAccount?.key);

View File

@@ -3,6 +3,7 @@ import { jsonRes } from '@fastgpt/service/common/response';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { MongoUser } from '@fastgpt/service/support/user/schema';
import { connectToDatabase } from '@/service/mongo';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -13,8 +14,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
throw new Error('Params is missing');
}
const { userId } = await authCert({ req, authToken: true });
const { tmbId } = await authCert({ req, authToken: true });
const tmb = await MongoTeamMember.findById(tmbId);
if (!tmb) {
throw new Error('can not find it');
}
const userId = tmb.userId;
// auth old password
const user = await MongoUser.findOne({
_id: userId,

View File

@@ -2,8 +2,7 @@ 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 { checkDatasetLimit } from '@fastgpt/service/support/permission/limit/dataset';
import { getStandardSubPlan } from '@/service/support/wallet/sub/utils';
import { checkDatasetLimit } from '@/service/support/permission/teamLimit';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
@@ -23,8 +22,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
await checkDatasetLimit({
teamId,
insertLen: numberSize,
standardPlans: getStandardSubPlan()
insertLen: numberSize
});
jsonRes(res);

View File

@@ -2,22 +2,21 @@ 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 { getTeamSubPlanStatus } from '@fastgpt/service/support/wallet/sub/utils';
import { getTeamSubPlans } from '@fastgpt/service/support/wallet/sub/utils';
import { getStandardSubPlan } from '@/service/support/wallet/sub/utils';
import { FeTeamSubType } from '@fastgpt/global/support/wallet/sub/type';
import { FeTeamPlanStatusType } from '@fastgpt/global/support/wallet/sub/type';
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
try {
await connectToDatabase();
// 凭证校验
const { teamId } = await authCert({
req,
authToken: true
});
jsonRes<FeTeamSubType>(res, {
data: await getTeamSubPlanStatus({
jsonRes<FeTeamPlanStatusType>(res, {
data: await getTeamSubPlans({
teamId,
standardPlans: getStandardSubPlan()
})

View File

@@ -1,16 +1,16 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { connectToDatabase } from '@/service/mongo';
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
import { CreateTrainingBillProps } from '@fastgpt/global/support/wallet/bill/api.d';
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
import { CreateTrainingUsageProps } from '@fastgpt/global/support/wallet/usage/api.d';
import { getLLMModel, getVectorModel } from '@/service/core/ai/model';
import { createTrainingBill } from '@fastgpt/service/support/wallet/bill/controller';
import { createTrainingUsage } from '@fastgpt/service/support/wallet/usage/controller';
import { authDataset } from '@fastgpt/service/support/permission/auth/dataset';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
await connectToDatabase();
const { name, datasetId } = req.body as CreateTrainingBillProps;
const { name, datasetId } = req.body as CreateTrainingUsageProps;
const { teamId, tmbId, dataset } = await authDataset({
req,
@@ -20,11 +20,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
per: 'w'
});
const { billId } = await createTrainingBill({
const { billId } = await createTrainingUsage({
teamId,
tmbId,
appName: name,
billSource: BillSourceEnum.training,
billSource: UsageSourceEnum.training,
vectorModel: getVectorModel(dataset.vectorModel).name,
agentModel: getLLMModel(dataset.agentModel).name
});

View File

@@ -6,7 +6,7 @@ import { getUploadModel } from '@fastgpt/service/common/file/multer';
import { removeFilesByPaths } from '@fastgpt/service/common/file/utils';
import fs from 'fs';
import { getAIApi } from '@fastgpt/service/core/ai/config';
import { pushWhisperBill } from '@/service/support/wallet/bill/push';
import { pushWhisperUsage } from '@/service/support/wallet/usage/push';
const upload = getUploadModel({
maxSize: 2
@@ -40,7 +40,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
model: global.whisperModel.model
});
pushWhisperBill({
pushWhisperUsage({
teamId,
tmbId,
duration

View File

@@ -13,16 +13,16 @@ import { gptMessage2ChatType, textAdaptGptResponse } from '@/utils/adapt';
import { getChatItems } from '@fastgpt/service/core/chat/controller';
import { saveChat } from '@/service/utils/chat/saveChat';
import { responseWrite } from '@fastgpt/service/common/response';
import { pushChatBill } from '@/service/support/wallet/bill/push';
import { pushChatUsage } from '@/service/support/wallet/usage/push';
import { authOutLinkChatStart } from '@/service/support/permission/auth/outLink';
import { pushResult2Remote, updateOutLinkUsage } from '@fastgpt/service/support/outLink/tools';
import { pushResult2Remote, addOutLinkUsage } from '@fastgpt/service/support/outLink/tools';
import requestIp from 'request-ip';
import { getBillSourceByAuthType } from '@fastgpt/global/support/wallet/bill/tools';
import { getUsageSourceByAuthType } from '@fastgpt/global/support/wallet/usage/tools';
import { selectShareResponse } from '@/utils/service/core/chat';
import { updateApiKeyUsage } from '@fastgpt/service/support/openapi/tools';
import { connectToDatabase } from '@/service/mongo';
import { getUserAndAuthBalance } from '@fastgpt/service/support/user/controller';
import { getUserChatInfoAndAuthTeamPoints } from '@/service/support/permission/auth/team';
import { AuthUserTypeEnum } from '@fastgpt/global/support/permission/constant';
import { MongoApp } from '@fastgpt/service/core/app/schema';
import { autChatCrud } from '@/service/support/permission/auth/chat';
@@ -35,9 +35,14 @@ type FastGptShareChatProps = {
shareId?: string;
outLinkUid?: string;
};
type FastGptTeamShareChatProps = {
teamId?: string;
outLinkUid?: string;
};
export type Props = ChatCompletionCreateParams &
FastGptWebChatProps &
FastGptShareChatProps & {
FastGptShareChatProps &
FastGptTeamShareChatProps & {
messages: ChatMessageItemType[];
stream?: boolean;
detail?: boolean;
@@ -60,6 +65,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
const {
chatId,
appId,
teamId,
shareId,
outLinkUid,
stream = false,
@@ -97,90 +103,96 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
}
/* auth app permission */
const { user, app, responseDetail, authType, apikey, canWrite, uid } = await (async () => {
if (shareId && outLinkUid) {
const { user, appId, authType, responseDetail, uid } = await authOutLinkChatStart({
shareId,
ip: originIp,
outLinkUid,
question: question.value
});
const app = await MongoApp.findById(appId);
const { teamId, tmbId, user, app, responseDetail, authType, apikey, canWrite, outLinkUserId } =
await (async () => {
if (shareId && outLinkUid) {
const { teamId, tmbId, user, appId, authType, responseDetail, uid } =
await authOutLinkChatStart({
shareId,
ip: originIp,
outLinkUid,
question: question.value
});
const app = await MongoApp.findById(appId);
if (!app) {
return Promise.reject('app is empty');
if (!app) {
return Promise.reject('app is empty');
}
return {
teamId,
tmbId,
user,
app,
responseDetail,
apikey: '',
authType,
canWrite: false,
outLinkUserId: uid
};
}
return {
user,
app,
responseDetail,
apikey: '',
const {
appId: apiKeyAppId,
teamId,
tmbId,
authType,
canWrite: false,
uid
};
}
apikey
} = await authCert({
req,
authToken: true,
authApiKey: true
});
const {
appId: apiKeyAppId,
tmbId,
authType,
apikey
} = await authCert({
req,
authToken: true,
authApiKey: true
});
const user = await getUserChatInfoAndAuthTeamPoints(tmbId);
const user = await getUserAndAuthBalance({
tmbId,
minBalance: 0
});
// openapi key
if (authType === AuthUserTypeEnum.apikey) {
if (!apiKeyAppId) {
return Promise.reject(
'Key is error. You need to use the app key rather than the account key.'
);
}
const app = await MongoApp.findById(apiKeyAppId);
// openapi key
if (authType === AuthUserTypeEnum.apikey) {
if (!apiKeyAppId) {
return Promise.reject(
'Key is error. You need to use the app key rather than the account key.'
);
if (!app) {
return Promise.reject('app is empty');
}
return {
teamId,
tmbId,
user,
app,
responseDetail: detail,
apikey,
authType,
canWrite: true
};
}
const app = await MongoApp.findById(apiKeyAppId);
if (!app) {
return Promise.reject('app is empty');
// token auth
if (!appId) {
return Promise.reject('appId is empty');
}
const { app, canWrite } = await authApp({
req,
authToken: true,
appId,
per: 'r'
});
return {
teamId,
tmbId,
user,
app,
responseDetail: detail,
apikey,
authType,
canWrite: true
canWrite: canWrite || false
};
}
// token auth
if (!appId) {
return Promise.reject('appId is empty');
}
const { app, canWrite } = await authApp({
req,
authToken: true,
appId,
per: 'r'
});
return {
user,
app,
responseDetail: detail,
apikey,
authType,
canWrite: canWrite || false
};
})();
})();
// auth chat permission
await autChatCrud({
@@ -201,16 +213,17 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
limit: 30,
field: `dataId obj value`
});
const concatHistories = history.concat(chatMessages);
const responseChatItemId: string | undefined = messages[messages.length - 1].dataId;
/* start flow controller */
const { responseData, answerText } = await dispatchModules({
const { responseData, moduleDispatchBills, answerText } = await dispatchModules({
res,
mode: 'chat',
user,
teamId: String(user.team.teamId),
tmbId: String(user.team.tmbId),
teamId: String(teamId),
tmbId: String(tmbId),
appId: String(app._id),
chatId,
responseChatItemId,
@@ -223,18 +236,19 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
stream,
detail
});
console.log('af');
// save chat
if (chatId) {
await saveChat({
chatId,
appId: app._id,
teamId: user.team.teamId,
tmbId: user.team.tmbId,
teamId: teamId,
tmbId: tmbId,
variables,
updateUseTime: !shareId && String(user.team.tmbId) === String(app.tmbId), // owner update use time
updateUseTime: !shareId && String(tmbId) === String(app.tmbId), // owner update use time
shareId,
outLinkUid: uid,
outLinkUid: outLinkUserId,
source: (() => {
if (shareId) {
return ChatSourceEnum.share;
@@ -305,29 +319,29 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
}
// add record
const { total } = pushChatBill({
const { totalPoints } = pushChatUsage({
appName: app.name,
appId: app._id,
teamId: user.team.teamId,
tmbId: user.team.tmbId,
source: getBillSourceByAuthType({ shareId, authType }),
response: responseData
teamId: teamId,
tmbId: tmbId,
source: getUsageSourceByAuthType({ shareId, authType }),
moduleDispatchBills
});
if (shareId) {
pushResult2Remote({ outLinkUid, shareId, responseData });
updateOutLinkUsage({
pushResult2Remote({ outLinkUid, shareId, appName: app.name, responseData });
addOutLinkUsage({
shareId,
total
totalPoints
});
}
if (apikey) {
updateApiKeyUsage({
apikey,
usage: total
totalPoints
});
}
} catch (err: any) {
} catch (err) {
if (stream) {
sseErrRes(res, err);
res.end();

View File

@@ -2,13 +2,13 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { withNextCors } from '@fastgpt/service/common/middle/cors';
import { pushGenerateVectorBill } from '@/service/support/wallet/bill/push';
import { pushGenerateVectorUsage } from '@/service/support/wallet/usage/push';
import { connectToDatabase } from '@/service/mongo';
import { authTeamBalance } from '@/service/support/permission/auth/bill';
import { getVectorsByText } from '@fastgpt/service/core/ai/embedding';
import { updateApiKeyUsage } from '@fastgpt/service/support/openapi/tools';
import { getBillSourceByAuthType } from '@fastgpt/global/support/wallet/bill/tools';
import { getUsageSourceByAuthType } from '@fastgpt/global/support/wallet/usage/tools';
import { getVectorModel } from '@/service/core/ai/model';
import { checkTeamAIPoints } from '@/service/support/permission/teamLimit';
type Props = {
input: string | string[];
@@ -34,7 +34,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
authApiKey: true
});
await authTeamBalance(teamId);
await checkTeamAIPoints(teamId);
const { charsLength, vectors } = await getVectorsByText({
input: query,
@@ -55,19 +55,19 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
}
});
const { total } = pushGenerateVectorBill({
const { totalPoints } = pushGenerateVectorUsage({
teamId,
tmbId,
charsLength,
model,
billId,
source: getBillSourceByAuthType({ authType })
source: getUsageSourceByAuthType({ authType })
});
if (apikey) {
updateApiKeyUsage({
apikey,
usage: total
totalPoints: totalPoints
});
}
} catch (err) {

View File

@@ -1,50 +0,0 @@
import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { withNextCors } from '@fastgpt/service/common/middle/cors';
import { pushReRankBill } from '@/service/support/wallet/bill/push';
import { connectToDatabase } from '@/service/mongo';
import { authTeamBalance } from '@/service/support/permission/auth/bill';
import { PostReRankProps, PostReRankResponse } from '@fastgpt/global/core/ai/api';
import { reRankRecall } from '@/service/core/ai/rerank';
import { updateApiKeyUsage } from '@fastgpt/service/support/openapi/tools';
export default withNextCors(async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
let { query, inputs } = req.body as PostReRankProps;
try {
await connectToDatabase();
const { teamId, tmbId, apikey } = await authCert({
req,
authApiKey: true
});
await authTeamBalance(teamId);
// max 150 length
inputs = inputs.slice(0, 150);
const result = await reRankRecall({ query, inputs });
const { total } = pushReRankBill({
teamId,
tmbId,
source: 'api',
inputs
});
if (apikey) {
updateApiKeyUsage({
apikey,
usage: total
});
}
jsonRes<PostReRankResponse>(res, {
data: result
});
} catch (err) {
jsonRes(res, {
code: 500,
error: err
});
}
});